Skip to main content
Glama

302AI File Parser MCP Server

by 302ai
index.ts4.55 kB
#!/usr/bin/env node import { getParamValue, getAuthValue } from "@chatmcp/sdk/utils/index.js"; import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { ListToolsRequestSchema, CallToolRequestSchema, ErrorCode, McpError, Tool, } from "@modelcontextprotocol/sdk/types.js"; import { betterFetch } from "@better-fetch/fetch"; import { RestServerTransport } from "@chatmcp/sdk/server/rest.js"; import dotenv from "dotenv"; // support for mcp.so const ai302ApiKey = getParamValue("302ai_api_key"); const mode = getParamValue("mode") || "stdio"; const port = getParamValue("port") || 9593; const endpoint = getParamValue("endpoint") || "/rest"; dotenv.config(); interface ToolCallResponse { result: any; logs: any; } class AI302Api { private baseUrl = process.env.BASE_URL || "https://api.302.ai/mcp"; private apiKey: string; constructor(apiKey: string) { this.apiKey = apiKey; } getApiKey(): string { return this.apiKey; } async listTools(): Promise<Tool[]> { const url = new URL(`${this.baseUrl}/v1/tool/list`); url.searchParams.append("packId", "fileTools"); url.searchParams.append("user302", "user302"); const { data, error } = await betterFetch<{ tools: Tool[]; }>(url.toString(), { headers: { Authorization: `Bearer ${this.apiKey}`, }, }); if (error) { throw new McpError( ErrorCode.InternalError, error.message ?? "Unknown error", ); } return data.tools; } async callTool(name: string, arguments_: any): Promise<ToolCallResponse> { const { data, error } = await betterFetch<any>( `${this.baseUrl}/v1/tool/call`, { method: "POST", headers: { Authorization: `Bearer ${this.apiKey}`, "x-api-key": this.apiKey, }, body: { nameOrId: name, arguments: arguments_, }, }, ); if (error) { throw new McpError( ErrorCode.InternalError, error.message ?? "Unknown error", ); } return data; } } class AI302Server { private server: Server; private api: AI302Api | null = null; constructor() { this.server = new Server( { name: "302ai-file-parser-mcp", version: "0.1.2", }, { capabilities: { resources: {}, tools: {}, }, }, ); this.setupHandlers(); this.setupErrorHandling(); } private setupErrorHandling(): void { this.server.onerror = (error) => { console.error("[MCP Error]", error); }; process.on("SIGINT", async () => { await this.server.close(); process.exit(0); }); } private setupHandlers(): void { this.setupToolHandlers(); } private getApiInstance(request?: any): AI302Api { const apiKey = ai302ApiKey || (request && getAuthValue(request, "302AI_API_KEY")) || process.env["302AI_API_KEY"]; if (!apiKey) { throw new McpError( ErrorCode.InvalidParams, "API key is required to call the tool", ); } if (!this.api || this.api.getApiKey() !== apiKey) { this.api = new AI302Api(apiKey); } return this.api; } private async setupToolHandlers(): Promise<void> { this.server.setRequestHandler(ListToolsRequestSchema, async (request) => { // Re-fetch tools with request-specific API key if available const api = this.getApiInstance(request); const tools = await api.listTools(); return { tools }; }); this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const api = this.getApiInstance(request); const content = await api.callTool( request.params.name, request.params.arguments, ); return { content: [ { type: "text", text: JSON.stringify({ content }, null, 2), }, ], }; }); } async run(): Promise<void> { // for mcp.so if (mode === "rest") { const transport = new RestServerTransport({ port: Number(port), endpoint: endpoint, }); await this.server.connect(transport); await transport.startServer(); return; } // for local mcp server const transport = new StdioServerTransport(); await this.server.connect(transport); } } const server = new AI302Server(); server.run().catch(console.error);

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/302ai/302_file_parser_mcp'

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