Skip to main content
Glama
index.ts12.6 kB
#!/usr/bin/env node import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, Tool, } from "@modelcontextprotocol/sdk/types.js"; import { z } from "zod"; import { Config, ConfigSchema } from "./types.js"; import { RestClient } from "./rest-client.js"; import { ConfigLoader } from "./config-loader.js"; class McpRestServer { private server: Server; private restClient?: RestClient; private autoConfigured: boolean = false; constructor() { this.server = new Server({ name: "mcp-rest-server", version: "1.0.0", }); this.setupHandlers(); } private async tryAutoConfiguration(): Promise<void> { try { const config = ConfigLoader.loadConfig(); this.restClient = new RestClient(config); await this.restClient.initialize(); this.autoConfigured = true; console.log(`✅ Auto-configured REST client for ${config.baseUrl}`); } catch (error) { // Auto-configuration failed, will require manual configuration console.log( "ℹ️ Auto-configuration not available. Use configure_rest_client tool to set up manually." ); console.log( "💡 For auto-configuration, provide configuration via CLI args, environment variables, or config file." ); } } private setupHandlers(): void { this.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "configure_rest_client", description: "Configure the REST client with base URL, authentication, and optional Swagger documentation URL", inputSchema: { type: "object", properties: { baseUrl: { type: "string", description: "Base URL for the REST API", }, swaggerUrl: { type: "string", description: "URL to Swagger/OpenAPI documentation (optional)", }, auth: { type: "object", oneOf: [ { type: "object", properties: { type: { type: "string", enum: ["token"] }, token: { type: "string", description: "Authentication token", }, }, required: ["type", "token"], }, { type: "object", properties: { type: { type: "string", enum: ["login"] }, username: { type: "string", description: "Username for login", }, password: { type: "string", description: "Password for login", }, loginEndpoint: { type: "string", description: "Login endpoint path", }, tokenField: { type: "string", description: "Field name for access token in response (default: access_token)", }, }, required: [ "type", "username", "password", "loginEndpoint", ], }, ], }, timeout: { type: "number", description: "Request timeout in milliseconds (default: 30000)", }, retries: { type: "number", description: "Number of retries for failed requests (default: 3)", }, }, required: ["baseUrl", "auth"], }, }, { name: "http_request", description: "Make an HTTP request to the configured API", inputSchema: { type: "object", properties: { method: { type: "string", enum: ["GET", "POST", "PUT", "DELETE", "PATCH"], description: "HTTP method", }, path: { type: "string", description: "API endpoint path", }, params: { type: "object", description: "Query parameters (for GET) or request body parameters", }, body: { type: "object", description: "Request body (for POST, PUT, PATCH)", }, headers: { type: "object", description: "Additional headers", }, }, required: ["method", "path"], }, }, { name: "get_swagger_documentation", description: "Get the complete Swagger/OpenAPI documentation for available endpoints", inputSchema: { type: "object", properties: {}, }, }, { name: "search_endpoints", description: "Search for endpoints in the Swagger documentation", inputSchema: { type: "object", properties: { query: { type: "string", description: "Search query to find matching endpoints", }, }, required: ["query"], }, }, { name: "get_endpoint_info", description: "Get detailed information about a specific endpoint", inputSchema: { type: "object", properties: { path: { type: "string", description: "Endpoint path", }, method: { type: "string", description: "HTTP method", }, }, required: ["path", "method"], }, }, { name: "check_authentication", description: "Check if the client is currently authenticated", inputSchema: { type: "object", properties: {}, }, }, { name: "logout", description: "Logout and clear authentication state", inputSchema: { type: "object", properties: {}, }, }, ] as Tool[], }; }); this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { switch (name) { case "configure_rest_client": return await this.configureRestClient(args); case "http_request": return await this.makeHttpRequest(args); case "get_swagger_documentation": return await this.getSwaggerDocumentation(); case "search_endpoints": return await this.searchEndpoints(args); case "get_endpoint_info": return await this.getEndpointInfo(args); case "check_authentication": return await this.checkAuthentication(); case "logout": return await this.logout(); default: throw new Error(`Unknown tool: ${name}`); } } catch (error) { return { content: [ { type: "text", text: `Error: ${ error instanceof Error ? error.message : "Unknown error" }`, }, ], isError: true, }; } }); } private async configureRestClient(args: any) { try { const config = ConfigSchema.parse(args); this.restClient = new RestClient(config); await this.restClient.initialize(); return { content: [ { type: "text", text: `REST client configured successfully for ${config.baseUrl}${ config.swaggerUrl ? ` with Swagger documentation from ${config.swaggerUrl}` : "" }`, }, ], }; } catch (error) { throw new Error( `Configuration failed: ${ error instanceof Error ? error.message : "Unknown error" }` ); } } private async makeHttpRequest(args: any) { if (!this.restClient) { throw new Error( "REST client not configured. Use configure_rest_client tool or provide configuration via CLI/environment variables." ); } const { method, path, params, body, headers } = args; const response = await this.restClient.makeRequest({ method, path, params, body, headers, }); return { content: [ { type: "text", text: JSON.stringify( { status: response.status, statusText: response.statusText, data: response.data, headers: response.headers, }, null, 2 ), }, ], }; } private async getSwaggerDocumentation() { if (!this.restClient) { throw new Error( "REST client not configured. Use configure_rest_client tool or provide configuration via CLI/environment variables." ); } const documentation = this.restClient.getSwaggerDocumentation(); return { content: [ { type: "text", text: documentation, }, ], }; } private async searchEndpoints(args: any) { if (!this.restClient) { throw new Error( "REST client not configured. Use configure_rest_client tool or provide configuration via CLI/environment variables." ); } const { query } = args; const results = this.restClient.searchEndpoints(query); return { content: [ { type: "text", text: results, }, ], }; } private async getEndpointInfo(args: any) { if (!this.restClient) { throw new Error( "REST client not configured. Use configure_rest_client tool or provide configuration via CLI/environment variables." ); } const { path, method } = args; const info = this.restClient.getEndpointInfo(path, method); return { content: [ { type: "text", text: info, }, ], }; } private async checkAuthentication() { if (!this.restClient) { throw new Error( "REST client not configured. Use configure_rest_client tool or provide configuration via CLI/environment variables." ); } const isAuthenticated = this.restClient.isAuthenticated(); return { content: [ { type: "text", text: `Authentication status: ${ isAuthenticated ? "Authenticated" : "Not authenticated" }`, }, ], }; } private async logout() { if (!this.restClient) { throw new Error( "REST client not configured. Use configure_rest_client tool or provide configuration via CLI/environment variables." ); } await this.restClient.logout(); return { content: [ { type: "text", text: "Successfully logged out", }, ], }; } async run(): Promise<void> { await this.tryAutoConfiguration(); const transport = new StdioServerTransport(); await this.server.connect(transport); } } async function main() { // Check for help flag if (process.argv.includes("--help") || process.argv.includes("-h")) { ConfigLoader.printUsage(); process.exit(0); } const server = new McpRestServer(); await server.run(); } main().catch((error) => { console.error("Server error:", error); process.exit(1); });

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/gyuco/mcp-http-client'

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