Files
autoreg-skills-max/skills/chat2api-proxy/references/mcp-endpoint-pattern.md

4.6 KiB

MCP JSON-RPC 2.0 Endpoint — Pattern

Problem

Chat2API projects only expose OpenAI-compatible REST endpoints. MCP (Model Context Protocol) clients like Claude Desktop, Cursor, and other tools need JSON-RPC 2.0 endpoints.

Solution

Add a /mcp POST endpoint that implements the MCP JSON-RPC 2.0 protocol, proxying tool calls to the existing ChatGPT API pipeline.

Protocol

MCP uses JSON-RPC 2.0 over HTTP POST:

// Request
{"jsonrpc": "2.0", "method": "initialize", "params": {...}, "id": 1}

// Response
{"jsonrpc": "2.0", "id": 1, "result": {...}}

Required Methods

Method Purpose
initialize Handshake, returns capabilities + serverInfo
tools/list Returns available tools with JSON schemas
tools/call Executes a tool by name with arguments
resources/list Lists available resources (can be empty)
prompts/list Lists available prompts (can be empty)
notifications/initialized Acknowledgment (no-op)

Implementation

1. Define MCP Tools

MCP_TOOLS = [
    {
        "name": "chat_completion",
        "description": "Send a chat completion request to ChatGPT via the web API proxy.",
        "inputSchema": {
            "type": "object",
            "properties": {
                "messages": {"type": "array", "items": {"type": "object"}},
                "model": {"type": "string", "default": "gpt-4o"},
                "temperature": {"type": "number", "default": 0.7},
                "max_tokens": {"type": "integer", "default": 4096},
                "tools": {"type": "array", "items": {"type": "object"}}
            },
            "required": ["messages"]
        }
    }
]

2. JSON-RPC Helpers

def mcp_error(code: int, message: str, id: Any = None) -> dict:
    return {"jsonrpc": "2.0", "id": id, "error": {"code": code, "message": message}}

def mcp_response(result: Any, id: Any = None) -> dict:
    return {"jsonrpc": "2.0", "id": id, "result": result}

3. Initialize Handler

if method == "initialize":
    return JSONResponse(mcp_response({
        "protocolVersion": "2024-11-05",
        "capabilities": {"tools": {}, "resources": {}, "prompts": {}},
        "serverInfo": {"name": "ChatGPT2API-MCP", "version": "1.0.0"}
    }, req_id))

4. Tool Call Handler

if method == "tools/call":
    tool_name = params.get("name")
    tool_args = params.get("arguments", {})
    
    if tool_name == "chat_completion":
        # Build request data from MCP tool arguments
        request_data = {
            "model": tool_args.get("model", "gpt-4o"),
            "messages": tool_args.get("messages", []),
            "temperature": tool_args.get("temperature", 0.7),
            "max_tokens": tool_args.get("max_tokens", 4096),
            "stream": False
        }
        
        # Inject tools if provided
        if tool_args.get("tools"):
            request_data["messages"] = inject_tools_into_messages(
                request_data["messages"], tool_args["tools"]
            )
        
        # Forward to existing ChatService pipeline
        chat_service = ChatService(req_token)
        await chat_service.set_dynamic_data(request_data)
        await chat_service.get_chat_requirements()
        await chat_service.prepare_send_conversation()
        res = await chat_service.send_conversation()
        
        # Extract text content
        content = res["choices"][0]["message"]["content"]
        
        return JSONResponse(mcp_response(
            {"content": [{"type": "text", "text": content}]}, req_id
        ))

5. Registration in app.py

from api.mcp import register_mcp_endpoints
register_mcp_endpoints(app, api_prefix, security_scheme)

Error Codes

Code Meaning
-32700 Parse error
-32600 Invalid Request
-32601 Method not found
-32603 Internal error

Testing

# Initialize
curl -X POST http://localhost:5005/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{"jsonrpc":"2.0","method":"initialize","id":1}'

# List tools
curl -X POST .../mcp \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":2}'

# Call tool
curl -X POST .../mcp \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"chat_completion","arguments":{"messages":[{"role":"user","content":"hi"}]}},"id":3}'

Limitations

  • Synchronous only: tools/call blocks until completion (no streaming via MCP)
  • No MCP transport: Only HTTP POST, no stdio or WebSocket transport
  • Tool definitions are static: Must be updated in code, not dynamic from ChatGPT