Skip to main content
Glama
CoinStatsHQ

CoinStats MCP Server

Official

get-ticker-exchanges

Retrieve a list of cryptocurrency exchanges supported by the CoinStats API for accessing market data and portfolio tracking.

Instructions

Get a list of supported exchanges.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • Generic handler function for all API-based tools, including get-ticker-exchanges. Determines if local or API call, then invokes universalApiHandler with the tool's endpoint '/tickers/exchanges', GET method, and basePath from constants.
    server.tool(config.name, config.description, config.parameters, async (params: Record<string, any>) => {
        // Handle local operations
        if (config.isLocal) {
            // Handle specific local tools
            if (config.name === 'save-share-token') {
                await saveToCache('shareToken', params.shareToken);
                return {
                    content: [
                        {
                            type: 'text',
                            text: 'Share token saved successfully',
                        },
                    ],
                };
            }
    
            if (config.name === 'get-share-token') {
                const shareToken = await getFromCache('shareToken');
    
                return {
                    content: [
                        {
                            type: 'text',
                            text: shareToken ? shareToken : 'No share token found in cache',
                            isError: !shareToken,
                        },
                    ],
                };
            }
            // Future local tools can be added here
    
            // Default response for unhandled local tools
            return {
                content: [
                    {
                        type: 'text',
                        text: 'Operation completed',
                    },
                ],
            };
        }
    
        // Handle API operations
        const basePath = config.basePath || COINSTATS_API_BASE;
        const method = config.method || 'GET';
    
        // Methods that typically have a request body
        const bodyMethods = ['POST', 'PUT', 'PATCH', 'DELETE'];
    
        // For GET/DELETE requests, all params go in the URL
        // For POST/PUT/PATCH, send params as the body
        if (bodyMethods.includes(method.toUpperCase())) {
            return universalApiHandler(basePath, config.endpoint, method, {}, params);
        } else {
            return universalApiHandler(basePath, config.endpoint, method, params);
        }
  • Schema definition for the get-ticker-exchanges tool, including name, description, endpoint, method, and empty parameters schema.
    {
        name: 'get-ticker-exchanges',
        description: 'Get a list of supported exchanges.',
        endpoint: '/tickers/exchanges',
        method: 'GET',
        parameters: {},
    },
  • src/index.ts:18-18 (registration)
    Registers all tools, including get-ticker-exchanges, by calling registerTools with the MCP server instance and allToolConfigs.
    registerTools(server, allToolConfigs);
  • Registers each tool configuration with the MCP server by calling server.tool for every config in allToolConfigs.
    export function registerTools(server: McpServer, toolConfigs: ToolConfig<any>[]) {
        toolConfigs.forEach((config) => {
            server.tool(config.name, config.description, config.parameters, async (params: Record<string, any>) => {
                // Handle local operations
                if (config.isLocal) {
                    // Handle specific local tools
                    if (config.name === 'save-share-token') {
                        await saveToCache('shareToken', params.shareToken);
                        return {
                            content: [
                                {
                                    type: 'text',
                                    text: 'Share token saved successfully',
                                },
                            ],
                        };
                    }
    
                    if (config.name === 'get-share-token') {
                        const shareToken = await getFromCache('shareToken');
    
                        return {
                            content: [
                                {
                                    type: 'text',
                                    text: shareToken ? shareToken : 'No share token found in cache',
                                    isError: !shareToken,
                                },
                            ],
                        };
                    }
                    // Future local tools can be added here
    
                    // Default response for unhandled local tools
                    return {
                        content: [
                            {
                                type: 'text',
                                text: 'Operation completed',
                            },
                        ],
                    };
                }
    
                // Handle API operations
                const basePath = config.basePath || COINSTATS_API_BASE;
                const method = config.method || 'GET';
    
                // Methods that typically have a request body
                const bodyMethods = ['POST', 'PUT', 'PATCH', 'DELETE'];
    
                // For GET/DELETE requests, all params go in the URL
                // For POST/PUT/PATCH, send params as the body
                if (bodyMethods.includes(method.toUpperCase())) {
                    return universalApiHandler(basePath, config.endpoint, method, {}, params);
                } else {
                    return universalApiHandler(basePath, config.endpoint, method, params);
                }
            });
        });
    }
  • Helper function that performs the actual HTTP API call to CoinStats using the specified endpoint (for this tool: '/tickers/exchanges'), handles path/query params, API key auth, and returns JSON response as MCP text content.
    export async function universalApiHandler<T>(
        basePath: string,
        endpoint: string,
        method: string = 'GET',
        params: Record<string, any> = {},
        body?: any
    ): Promise<{
        content: Array<{ type: 'text'; text: string; isError?: boolean }>;
    }> {
        try {
            // Handle path parameters - replace {paramName} in endpoint with actual values
            let processedEndpoint = endpoint;
            let processedParams = { ...params };
    
            // Find all path parameters in the endpoint (e.g., {coinId}, {id}, {type})
            const pathParamMatches = endpoint.match(/\{([^}]+)\}/g);
    
            if (pathParamMatches) {
                for (const match of pathParamMatches) {
                    const paramName = match.slice(1, -1); // Remove { and }
    
                    if (processedParams[paramName] !== undefined) {
                        // Replace the placeholder with the actual value
                        processedEndpoint = processedEndpoint.replace(match, processedParams[paramName]);
                        // Remove the parameter from query params since it's now part of the path
                        delete processedParams[paramName];
                    } else {
                        throw new Error(`Required path parameter '${paramName}' is missing`);
                    }
                }
            }
    
            // MCP clients might not support '~' in parameter names, so we replace '-' with '~' specifically for the /coins endpoint before making the request.
            if (endpoint === '/coins') {
                processedParams = Object.entries(processedParams).reduce((acc, [key, value]) => {
                    acc[key.replace(/-/g, '~')] = value;
                    return acc;
                }, {} as Record<string, any>);
            }
    
            const url = `${basePath}${processedEndpoint}`;
            const data = await makeRequestCsApi<T>(url, method, processedParams, body);
    
            if (!data) {
                return {
                    content: [{ type: 'text', text: 'Something went wrong', isError: true }],
                };
            }
    
            return {
                content: [
                    {
                        type: 'text',
                        text: JSON.stringify(data),
                    },
                ],
            };
        } catch (error) {
            return {
                content: [{ type: 'text', text: `Error: ${error}`, isError: true }],
            };
        }
    }

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/CoinStatsHQ/coinstats-mcp'

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