Skip to main content
Glama
crazyrabbitLTC

Morpho API MCP Server

get_market_positions

Retrieve and organize market positions by specifying a unique market key, with options for pagination, ordering, and sorting to streamline data analysis.

Instructions

Get positions overview for specific markets with pagination and ordering.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
firstNoNumber of positions to return (default: 30)
marketUniqueKeyYesUnique key of the market
orderByNoField to order by
orderDirectionNoOrder direction
skipNoNumber of positions to skip

Implementation Reference

  • Handler for the 'get_market_positions' tool. Constructs a GraphQL query using the provided marketUniqueKey and pagination/ordering params, fetches data from Morpho API via axios, validates with MarketPositionsResponseSchema, and returns the paginated list of market positions as JSON.
    if (name === GET_MARKET_POSITIONS_TOOL) {
        try {
              const { marketUniqueKey, ...queryParams } = params as MarketPositionsParams;
              const finalParams = buildQueryParams({
                ...queryParams,
                where: { marketUniqueKey_in: [marketUniqueKey] }
              });
    
              const query = `
              query {
                marketPositions${finalParams} {
                  pageInfo {
                    count
                    countTotal
                  }
                  items {
                    supplyShares
                    supplyAssets
                    supplyAssetsUsd
                    borrowShares
                    borrowAssets
                    borrowAssetsUsd
                    collateral
                    collateralUsd
                    market {
                      uniqueKey
                      loanAsset {
                        address
                        symbol
                      }
                      collateralAsset {
                        address
                        symbol
                      }
                    }
                    user {
                      address
                    }
                  }
                }
              }
            `;
    
              const response = await axios.post(MORPHO_API_BASE, { query });
              const validatedData = MarketPositionsResponseSchema.parse(response.data);
    
              return {
                content: [
                  {
                      type: 'text',
                      text: JSON.stringify(validatedData.data.marketPositions, null, 2),
                  },
                ],
              };
        } catch (error: any) {
          console.error('Error calling Morpho API:', error.message);
          return {
            isError: true,
            content: [{ type: 'text', text: `Error retrieving market positions: ${error.message}` }],
          };
        }
    }
  • src/index.ts:668-699 (registration)
    Registration of the 'get_market_positions' tool in the ListTools response, including name, description, and input schema definition.
    {
      name: GET_MARKET_POSITIONS_TOOL,
      description: 'Get positions overview for specific markets with pagination and ordering.',
      inputSchema: {
        type: 'object',
        properties: {
          marketUniqueKey: {
            type: 'string',
            description: 'Unique key of the market'
          },
          first: {
            type: 'number',
            description: 'Number of positions to return (default: 30)'
          },
          skip: {
            type: 'number',
            description: 'Number of positions to skip'
          },
          orderBy: {
            type: 'string',
            enum: ['SupplyShares', 'BorrowShares', 'SupplyAssets', 'BorrowAssets'],
            description: 'Field to order by'
          },
          orderDirection: {
            type: 'string',
            enum: ['Asc', 'Desc'],
            description: 'Order direction'
          }
        },
        required: ['marketUniqueKey']
      },
    },
  • Zod schema for validating the Morpho API response for market positions, including pagination info and array of MarketPositionSchema items.
    const MarketPositionsResponseSchema = z.object({
      data: z.object({
        marketPositions: z.object({
          pageInfo: z.object({
            count: z.number(),
            countTotal: z.number(),
          }),
          items: z.array(MarketPositionSchema)
        })
      })
    });
  • Zod schema defining the structure of a single market position, used in the response validation. Includes supply/borrow amounts, market details, and user address.
    const MarketPositionSchema = z.object({
      supplyShares: z.union([z.string(), z.number()]).transform(stringToNumber).optional(),
      supplyAssets: z.union([z.string(), z.number()]).transform(stringToNumber),
      supplyAssetsUsd: z.union([z.string(), z.number()]).transform(stringToNumber),
      borrowShares: z.union([z.string(), z.number()]).transform(stringToNumber).optional(),
      borrowAssets: z.union([z.string(), z.number()]).transform(stringToNumber),
      borrowAssetsUsd: z.union([z.string(), z.number()]).transform(stringToNumber),
      collateral: z.union([z.string(), z.number()]).transform(stringToNumber).optional(),
      collateralUsd: z.union([z.string(), z.number()]).transform(stringToNumber).optional(),
      market: z.object({
        uniqueKey: z.string(),
        loanAsset: AssetSchema,
        collateralAsset: AssetSchema,
      }),
      user: z.object({
        address: z.string()
      })
    });
  • Helper function to build GraphQL query parameters string from pagination, ordering, and where inputs. Used in the handler to construct the dynamic query.
    function buildQueryParams(params: PaginationParams & { orderBy?: string, orderDirection?: OrderDirection, where?: Record<string, any> } = {}): string {
      const queryParts: string[] = [];
      
      if (params.first !== undefined) queryParts.push(`first: ${params.first}`);
      if (params.skip !== undefined) queryParts.push(`skip: ${params.skip}`);
      if (params.orderBy) queryParts.push(`orderBy: ${params.orderBy}`);
      if (params.orderDirection) queryParts.push(`orderDirection: ${params.orderDirection}`);
      if (params.where && Object.keys(params.where).length > 0) {
        const whereStr = JSON.stringify(params.where).replace(/"([^"]+)":/g, '$1:');
        queryParts.push(`where: ${whereStr}`);
      }
    
      return queryParts.length > 0 ? `(${queryParts.join(', ')})` : '';
    }
Behavior2/5

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

With no annotations provided, the description carries full burden for behavioral disclosure. It mentions 'pagination and ordering' which are useful behavioral traits, but doesn't cover critical aspects like whether this is a read-only operation, potential rate limits, authentication requirements, error conditions, or what the response format looks like. For a tool with 5 parameters and no annotation coverage, this leaves significant behavioral gaps.

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 that communicates the core functionality and key behavioral aspects (pagination and ordering). Every word earns its place with zero redundancy. It's appropriately sized for the tool's complexity and gets straight to the point without unnecessary elaboration.

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

Completeness3/5

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

Given 5 parameters, 100% schema coverage, but no annotations and no output schema, the description is minimally adequate. It covers the basic purpose and mentions pagination/ordering behavior, but doesn't address what the tool returns, error conditions, or other contextual information that would help an agent use it effectively. The description works with the schema but leaves gaps in behavioral understanding.

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 already documents all parameters thoroughly. The description adds minimal value beyond the schema by mentioning 'pagination and ordering' which corresponds to 'first', 'skip', 'orderBy', and 'orderDirection' parameters, but doesn't provide additional semantic context. With complete schema coverage, the baseline of 3 is appropriate.

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 verb 'Get' and resource 'positions overview for specific markets', making the purpose understandable. It distinguishes from siblings like 'get_markets' (general market info) and 'get_vault_positions' (vault-specific positions), but doesn't explicitly contrast them. The description is specific about what's being retrieved but could be more precise about what 'positions overview' entails.

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?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention when this tool is appropriate compared to siblings like 'get_vault_positions' or 'get_account_overview', nor does it specify prerequisites or exclusions. Usage context is implied through the mention of 'specific markets' but not explicitly stated.

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/crazyrabbitLTC/mcp-morpho-server'

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