autoreg-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
155
skills/chat2api-proxy/references/mcp-endpoint-pattern.md
Normal file
155
skills/chat2api-proxy/references/mcp-endpoint-pattern.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# 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:
|
||||
|
||||
```json
|
||||
// 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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
Reference in New Issue
Block a user