XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/gpt4free

Add HTTP transport mode for MCP server with --http flag

Co-authored-by: hlohaus <983577+hlohaus@users.noreply.github.com>

a15618a8
copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
提交于

代码差异

6 个文件 +266 -10
Modified README.md +14 -1
@@ -207,7 +207,7 @@ python -m g4f.cli gui --port 8080 --debug
207 207 ### MCP Server
208 208 GPT4Free now includes a Model Context Protocol (MCP) server that allows AI assistants like Claude to access web search, scraping, and image generation capabilities.
209 209
210 **Starting the MCP server:**
210 **Starting the MCP server (stdio mode):**
211 211 ```bash
212 212 # Using g4f command
213 213 g4f mcp
@@ -216,6 +216,19 @@ g4f mcp
216 216 python -m g4f.mcp
217 217 ```
218 218
219 **Starting the MCP server (HTTP mode):**
220 ```bash
221 # Start HTTP server on port 8765
222 g4f mcp --http --port 8765
223
224 # Custom host and port
225 g4f mcp --http --host 127.0.0.1 --port 3000
226 ```
227
228 HTTP mode provides:
229 - `POST http://localhost:8765/mcp` - JSON-RPC endpoint
230 - `GET http://localhost:8765/health` - Health check
231
219 232 **Configuring with Claude Desktop:**
220 233
221 234 Add to your `claude_desktop_config.json`:
Modified docs/mcp-usage-guide.md +42 -0
@@ -33,6 +33,8 @@ pip install -e .
33 33
34 34 ### 2. Start the MCP Server
35 35
36 **Stdio Mode (Default):**
37
36 38 ```bash
37 39 # Using g4f command
38 40 g4f mcp
@@ -49,8 +51,33 @@ The server will:
49 51 - Write responses to stdout
50 52 - Write debug/error messages to stderr
51 53
54 **HTTP Mode:**
55
56 ```bash
57 # Start HTTP server on default port 8765
58 g4f mcp --http
59
60 # Custom port
61 g4f mcp --http --port 3000
62
63 # Custom host and port
64 g4f mcp --http --host 127.0.0.1 --port 8765
65 ```
66
67 The HTTP server provides:
68 - `POST http://localhost:8765/mcp` - JSON-RPC endpoint
69 - `GET http://localhost:8765/health` - Health check endpoint
70
71 HTTP mode is useful for:
72 - Web-based integrations
73 - Testing with HTTP clients
74 - Remote access
75 - Debugging with tools like curl or Postman
76
52 77 ### 3. Test the Server
53 78
79 **Stdio Mode:**
80
54 81 ```bash
55 82 # Send a test request
56 83 echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | python -m g4f.mcp
@@ -61,6 +88,21 @@ Expected output:
61 88 {"jsonrpc": "2.0", "id": 1, "result": {"protocolVersion": "2024-11-05", "serverInfo": {...}}}
62 89 ```
63 90
91 **HTTP Mode:**
92
93 ```bash
94 # Start server
95 g4f mcp --http --port 8765
96
97 # In another terminal, test with curl
98 curl -X POST http://localhost:8765/mcp \
99 -H "Content-Type: application/json" \
100 -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}'
101
102 # Health check
103 curl http://localhost:8765/health
104 ```
105
64 106 ## Configuration
65 107
66 108 ### Claude Desktop
Added etc/testing/test_mcp_http.py +61 -0
@@ -0,0 +1,61 @@
1 #!/usr/bin/env python
2 """Test HTTP MCP server functionality
3
4 This script tests the HTTP transport for the MCP server.
5 """
6
7 import asyncio
8 import json
9 from g4f.mcp.server import MCPServer, MCPRequest
10
11
12 async def test_http_server():
13 """Test HTTP server methods"""
14 server = MCPServer()
15
16 print("Testing HTTP MCP Server Functionality")
17 print("=" * 70)
18
19 # Test that server can be initialized
20 print("\n✓ Server initialized successfully")
21 print(f" Server: {server.server_info['name']}")
22 print(f" Version: {server.server_info['version']}")
23
24 # Test that run_http method exists
25 if hasattr(server, 'run_http'):
26 print("\n✓ HTTP transport method (run_http) available")
27 print(f" Signature: run_http(host, port)")
28 else:
29 print("\n✗ HTTP transport method not found")
30 return
31
32 # Test request handling (same for both transports)
33 print("\n✓ Testing request handling...")
34
35 init_request = MCPRequest(
36 jsonrpc="2.0",
37 id=1,
38 method="initialize",
39 params={}
40 )
41 response = await server.handle_request(init_request)
42
43 if response.result and response.result.get("protocolVersion"):
44 print(f" Protocol Version: {response.result['protocolVersion']}")
45 print(" ✓ Request handling works correctly")
46
47 print("\n" + "=" * 70)
48 print("HTTP MCP Server Tests Passed!")
49 print("\nTo start HTTP server:")
50 print(" g4f mcp --http --port 8765")
51 print("\nHTTP endpoints:")
52 print(" POST http://localhost:8765/mcp - MCP JSON-RPC endpoint")
53 print(" GET http://localhost:8765/health - Health check")
54 print("\nExample HTTP request:")
55 print(' curl -X POST http://localhost:8765/mcp \\')
56 print(' -H "Content-Type: application/json" \\')
57 print(' -d \'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}\'')
58
59
60 if __name__ == "__main__":
61 asyncio.run(test_http_server())
Modified g4f/cli/__init__.py +4 -1
@@ -81,11 +81,14 @@ def run_api_args(args):
81 81 def get_mcp_parser():
82 82 mcp_parser = ArgumentParser(description="Run the MCP (Model Context Protocol) server")
83 83 mcp_parser.add_argument("--debug", "-d", action="store_true", help="Enable verbose logging.")
84 mcp_parser.add_argument("--http", action="store_true", help="Use HTTP transport instead of stdio.")
85 mcp_parser.add_argument("--host", default="0.0.0.0", help="Host to bind HTTP server to (default: 0.0.0.0)")
86 mcp_parser.add_argument("--port", type=int, default=8765, help="Port to bind HTTP server to (default: 8765)")
84 87 return mcp_parser
85 88
86 89 def run_mcp_args(args):
87 90 from ..mcp.server import main as mcp_main
88 mcp_main()
91 mcp_main(http=args.http, host=args.host, port=args.port)
89 92
90 93 def main():
91 94 parser = argparse.ArgumentParser(description="Run gpt4free", exit_on_error=False)
Modified g4f/mcp/README.md +36 -3
@@ -22,6 +22,8 @@ pip install -e .
22 22
23 23 ### Running the MCP Server
24 24
25 **Stdio Mode (Default)**
26
25 27 Start the MCP server using:
26 28
27 29 ```bash
@@ -36,11 +38,31 @@ g4f mcp
36 38
37 39 The server communicates over stdin/stdout using JSON-RPC 2.0 protocol.
38 40
39 ### Configuration for AI Assistants
41 **HTTP Mode**
42
43 Start the MCP server with HTTP transport:
44
45 ```bash
46 g4f mcp --http --port 8765
47 ```
40 48
41 To use this MCP server with an AI assistant like Claude Desktop, add the following to your MCP configuration:
49 This starts an HTTP server with the following endpoints:
50 - `POST http://localhost:8765/mcp` - MCP JSON-RPC endpoint
51 - `GET http://localhost:8765/health` - Health check endpoint
42 52
43 **For Claude Desktop** (`claude_desktop_config.json`):
53 HTTP mode is useful for:
54 - Web-based integrations
55 - Testing with curl or HTTP clients
56 - Remote access (configure host with `--host`)
57
58 Options:
59 - `--http`: Enable HTTP transport instead of stdio
60 - `--host HOST`: Host to bind to (default: 0.0.0.0)
61 - `--port PORT`: Port to bind to (default: 8765)
62
63 ### Configuration for AI Assistants
64
65 **For Claude Desktop (Stdio)** - `claude_desktop_config.json`:
44 66
45 67 ```json
46 68 {
@@ -53,6 +75,17 @@ To use this MCP server with an AI assistant like Claude Desktop, add the followi
53 75 }
54 76 ```
55 77
78 **For HTTP-based clients**:
79
80 Make POST requests to `http://localhost:8765/mcp` with JSON-RPC payloads.
81
82 Example with curl:
83 ```bash
84 curl -X POST http://localhost:8765/mcp \
85 -H "Content-Type: application/json" \
86 -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
87 ```
88
56 89 **For VS Code with Cline**:
57 90
58 91 ```json
Modified g4f/mcp/server.py +109 -5
@@ -1,7 +1,8 @@
1 """MCP Server implementation using stdio transport
1 """MCP Server implementation with stdio and HTTP transports
2 2
3 3 This module implements a Model Context Protocol (MCP) server that communicates
4 over standard input/output using JSON-RPC 2.0. The server exposes tools for:
4 over standard input/output using JSON-RPC 2.0, or via HTTP POST endpoints.
5 The server exposes tools for:
5 6 - Web search
6 7 - Web scraping
7 8 - Image generation
@@ -190,12 +191,115 @@ class MCPServer:
190 191 except Exception as e:
191 192 sys.stderr.write(f"Error: {e}\n")
192 193 sys.stderr.flush()
194
195 async def run_http(self, host: str = "0.0.0.0", port: int = 8765):
196 """Run the MCP server with HTTP transport
197
198 Args:
199 host: Host to bind the HTTP server to
200 port: Port to bind the HTTP server to
201 """
202 try:
203 from aiohttp import web
204 except ImportError:
205 sys.stderr.write("Error: aiohttp is required for HTTP transport\n")
206 sys.stderr.write("Install it with: pip install aiohttp\n")
207 sys.exit(1)
208
209 async def handle_mcp_request(request: web.Request) -> web.Response:
210 """Handle MCP JSON-RPC request over HTTP POST"""
211 try:
212 # Parse JSON-RPC request from POST body
213 request_data = await request.json()
214
215 mcp_request = MCPRequest(
216 jsonrpc=request_data.get("jsonrpc", "2.0"),
217 id=request_data.get("id"),
218 method=request_data.get("method"),
219 params=request_data.get("params")
220 )
221
222 # Handle request
223 response = await self.handle_request(mcp_request)
224
225 # Build response dict
226 response_dict = {
227 "jsonrpc": response.jsonrpc,
228 "id": response.id
229 }
230 if response.result is not None:
231 response_dict["result"] = response.result
232 if response.error is not None:
233 response_dict["error"] = response.error
234
235 return web.json_response(response_dict)
236
237 except json.JSONDecodeError as e:
238 return web.json_response({
239 "jsonrpc": "2.0",
240 "id": None,
241 "error": {
242 "code": -32700,
243 "message": f"Parse error: {str(e)}"
244 }
245 }, status=400)
246 except Exception as e:
247 return web.json_response({
248 "jsonrpc": "2.0",
249 "id": None,
250 "error": {
251 "code": -32603,
252 "message": f"Internal error: {str(e)}"
253 }
254 }, status=500)
255
256 async def handle_health(request: web.Request) -> web.Response:
257 """Health check endpoint"""
258 return web.json_response({
259 "status": "ok",
260 "server": self.server_info
261 })
262
263 # Create aiohttp application
264 app = web.Application()
265 app.router.add_post('/mcp', handle_mcp_request)
266 app.router.add_get('/health', handle_health)
267
268 # Start server
269 sys.stderr.write(f"Starting {self.server_info['name']} v{self.server_info['version']} (HTTP mode)\n")
270 sys.stderr.write(f"Listening on http://{host}:{port}\n")
271 sys.stderr.write(f"MCP endpoint: http://{host}:{port}/mcp\n")
272 sys.stderr.write(f"Health check: http://{host}:{port}/health\n")
273 sys.stderr.flush()
274
275 runner = web.AppRunner(app)
276 await runner.setup()
277 site = web.TCPSite(runner, host, port)
278 await site.start()
279
280 # Keep server running
281 try:
282 await asyncio.Event().wait()
283 except KeyboardInterrupt:
284 sys.stderr.write("\nShutting down HTTP server...\n")
285 sys.stderr.flush()
286 finally:
287 await runner.cleanup()
193 288
194 289
195 def main():
196 """Main entry point for MCP server"""
290 def main(http: bool = False, host: str = "0.0.0.0", port: int = 8765):
291 """Main entry point for MCP server
292
293 Args:
294 http: If True, use HTTP transport instead of stdio
295 host: Host to bind HTTP server to (only used when http=True)
296 port: Port to bind HTTP server to (only used when http=True)
297 """
197 298 server = MCPServer()
198 asyncio.run(server.run())
299 if http:
300 asyncio.run(server.run_http(host, port))
301 else:
302 asyncio.run(server.run())
199 303
200 304
201 305 if __name__ == "__main__":