Skip to main content
Glama
sammcj

Bybit MCP Server

by sammcj

get_market_info

Retrieve real-time market data for cryptocurrency trading pairs on Bybit, including spot, linear, and inverse categories. Specify symbols and limit results for precise insights.

Instructions

Get detailed market information for trading pairs

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
categoryNoCategory of the instrument (spot, linear, inverse)
limitNoLimit for the number of results (max 1000)
symbolNoOptional: Trading pair symbol (e.g., 'BTCUSDT'). If not provided, returns info for all symbols in the category

Implementation Reference

  • Core handler function `toolCall` that validates input parameters (category, symbol, limit), calls Bybit's getInstrumentsInfo API, and formats the response or error.
    async toolCall(request: z.infer<typeof CallToolRequestSchema>) {
      try {
        const args = request.params.arguments as unknown
        if (!args || typeof args !== 'object') {
          throw new Error("Invalid arguments")
        }
    
        const typedArgs = args as Record<string, unknown>
    
        // Validate category explicitly
        if (typedArgs.category && typeof typedArgs.category === 'string') {
          if (!["spot", "linear", "inverse"].includes(typedArgs.category)) {
            throw new Error(`Invalid category: ${typedArgs.category}. Must be one of: spot, linear, inverse`)
          }
        }
    
        const category = (
          typedArgs.category &&
          typeof typedArgs.category === 'string' &&
          ["spot", "linear", "inverse"].includes(typedArgs.category)
        ) ? typedArgs.category as SupportedCategory
          : CONSTANTS.DEFAULT_CATEGORY as SupportedCategory
    
        const symbol = typedArgs.symbol && typeof typedArgs.symbol === 'string'
          ? typedArgs.symbol
          : undefined
    
        const limit = (
          typedArgs.limit &&
          typeof typedArgs.limit === 'string' &&
          ["1", "10", "50", "100", "200", "500", "1000"].includes(typedArgs.limit)
        ) ? parseInt(typedArgs.limit, 10) : 200
    
        const params: GetInstrumentsInfoParamsV5 = {
          category,
          symbol,
          limit,
        }
    
        const response = await this.client.getInstrumentsInfo(params)
    
        if (response.retCode !== 0) {
          throw new Error(`Bybit API error: ${response.retMsg}`)
        }
    
        // Return the list array directly
        return this.formatResponse(response.result.list)
      } catch (error) {
        // Ensure error responses are properly formatted
        const errorMessage = error instanceof Error ? error.message : String(error)
        return {
          content: [{
            type: "text" as const,
            text: errorMessage
          }],
          isError: true
        }
      }
    }
  • Tool schema definition including input schema with properties for category (spot/linear/inverse), optional symbol, and limit.
    toolDefinition: Tool = {
      name: this.name,
      description: "Get detailed market information for trading pairs",
      inputSchema: {
        type: "object",
        properties: {
          category: {
            type: "string",
            description: "Category of the instrument (spot, linear, inverse)",
            enum: ["spot", "linear", "inverse"],
          },
          symbol: {
            type: "string",
            description: "Optional: Trading pair symbol (e.g., 'BTCUSDT'). If not provided, returns info for all symbols in the category",
          },
          limit: {
            type: "string",
            description: "Limit for the number of results (max 1000)",
            enum: ["1", "10", "50", "100", "200", "500", "1000"],
          },
        },
        required: [],
      },
  • src/index.ts:134-136 (registration)
    Loads all tools dynamically using toolLoader and creates a map keyed by tool name for dispatching calls.
    const tools = await loadTools()
    toolsMap = createToolsMap(tools)
  • Dynamically discovers and instantiates all tool classes from src/tools directory, including GetMarketInfo, validating they extend BaseToolImplementation.
    export async function loadTools(): Promise<BaseToolImplementation[]> {
      try {
        const toolsPath = await findToolsPath()
        const files = await fs.readdir(toolsPath)
        const tools: BaseToolImplementation[] = []
    
        for (const file of files) {
          if (!isToolFile(file)) {
            continue
          }
    
          try {
            const modulePath = `file://${join(toolsPath, file)}`
            const { default: ToolClass } = await import(modulePath)
    
            if (!ToolClass || typeof ToolClass !== 'function') {
              console.warn(JSON.stringify({
                type: "warning",
                message: `Invalid tool class in ${file}`
              }))
              continue
            }
    
            const tool = new ToolClass()
    
            if (
              tool instanceof BaseToolImplementation &&
              tool.name &&
              tool.toolDefinition &&
              typeof tool.toolCall === "function"
            ) {
              tools.push(tool)
              console.info(JSON.stringify({
                type: "info",
                message: `Loaded tool: ${tool.name}`
              }))
            } else {
              console.warn(JSON.stringify({
                type: "warning",
                message: `Invalid tool implementation in ${file}`
              }))
            }
          } catch (error) {
            console.error(JSON.stringify({
              type: "error",
              message: `Error loading tool from ${file}: ${error instanceof Error ? error.message : String(error)}`
            }))
          }
        }
    
        return tools
      } catch (error) {
        console.error(JSON.stringify({
          type: "error",
          message: `Failed to load tools: ${error instanceof Error ? error.message : String(error)}`
        }))
        return []
      }
    }
  • Helper method used by the handler to format successful API responses as MCP CallToolResult.
    protected formatResponse(data: any): CallToolResult {
      this.ensureInitialized()
      const content: TextContent = {
        type: "text",
        text: JSON.stringify(data, null, 2),
        annotations: {
          audience: ["assistant", "user"],
          priority: 1
        }
      }
    
      return {
        content: [content]
      }
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden for behavioral disclosure. It states the tool 'gets' information, implying a read-only operation, but doesn't cover aspects like rate limits, authentication needs, error handling, or response format. This is inadequate for a tool with no annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence with no wasted words. It's appropriately sized and front-loaded, clearly stating the tool's purpose without unnecessary elaboration.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations and no output schema, the description is incomplete. It doesn't explain what 'detailed market information' includes, how results are structured, or any behavioral traits like pagination or errors. For a tool with rich context signals and siblings, this leaves significant gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents the three parameters. The description adds no additional meaning beyond the schema, such as explaining how parameters interact or providing examples. Baseline 3 is appropriate as the schema handles the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Get') and resource ('detailed market information for trading pairs'), making the purpose understandable. However, it doesn't differentiate from sibling tools like 'get_ticker' or 'get_instrument_info' that might provide similar market-related data, preventing a perfect score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. With siblings like 'get_ticker', 'get_instrument_info', and 'get_market_structure', the description lacks any indication of context, prerequisites, or distinctions, leaving the agent without usage direction.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sammcj/bybit-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server