返回提交历史
Modified
README.md
+14
-1
Modified
docs/mcp-usage-guide.md
+42
-0
Added
etc/testing/test_mcp_http.py
+61
-0
Modified
g4f/cli/__init__.py
+4
-1
Modified
g4f/mcp/README.md
+36
-3
Modified
g4f/mcp/server.py
+109
-5
XFEstudio/gpt4free
Add HTTP transport mode for MCP server with --http flag
Co-authored-by: hlohaus <983577+hlohaus@users.noreply.github.com>
a15618a8
代码差异
6 个文件
+266
-10
@@ -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`:
@@ -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
@@ -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())
@@ -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)
@@ -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
@@ -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__":