返回提交历史
Modified
README.md
+33
-0
Added
etc/testing/test_mcp_interactive.py
+149
-0
Added
etc/testing/test_mcp_server.py
+103
-0
XFEstudio/gpt4free
Add MCP server tests, documentation, and README updates
Co-authored-by: hlohaus <983577+hlohaus@users.noreply.github.com>
0c2a2b00
代码差异
3 个文件
+285
-0
@@ -204,6 +204,39 @@ python -m g4f --port 8080 --debug
204
204
python -m g4f.cli gui --port 8080 --debug
205
205
```
206
206
207
### MCP Server
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
210
**Starting the MCP server:**
211
```bash
212
# Using g4f command
213
g4f mcp
214
215
# Or using Python module
216
python -m g4f.mcp
217
```
218
219
**Configuring with Claude Desktop:**
220
221
Add to your `claude_desktop_config.json`:
222
```json
223
{
224
"mcpServers": {
225
"gpt4free": {
226
"command": "python",
227
"args": ["-m", "g4f.mcp"]
228
}
229
}
230
}
231
```
232
233
**Available MCP Tools:**
234
- `web_search` - Search the web using DuckDuckGo
235
- `web_scrape` - Extract text content from web pages
236
- `image_generation` - Generate images from text prompts
237
238
For detailed MCP documentation, see [g4f/mcp/README.md](g4f/mcp/README.md)
239
207
240
### Optional provider login (desktop within container)
208
241
- Accessible at:
209
242
```
@@ -0,0 +1,149 @@
1
#!/usr/bin/env python
2
"""Interactive MCP server test
3
4
This script simulates a client sending requests to the MCP server
5
and demonstrates how the tools work.
6
"""
7
8
import json
9
import sys
10
import asyncio
11
from io import StringIO
12
13
14
async def simulate_mcp_client():
15
"""Simulate an MCP client interacting with the server"""
16
17
print("MCP Server Interactive Test")
18
print("=" * 70)
19
print("\nThis test simulates JSON-RPC 2.0 messages between client and server.")
20
print("The MCP server uses stdio transport for communication.\n")
21
22
from g4f.mcp.server import MCPServer, MCPRequest
23
server = MCPServer()
24
25
# Test sequence of requests
26
test_requests = [
27
{
28
"name": "Initialize Connection",
29
"request": {
30
"jsonrpc": "2.0",
31
"id": 1,
32
"method": "initialize",
33
"params": {
34
"protocolVersion": "2024-11-05",
35
"clientInfo": {
36
"name": "test-client",
37
"version": "1.0.0"
38
}
39
}
40
}
41
},
42
{
43
"name": "List Available Tools",
44
"request": {
45
"jsonrpc": "2.0",
46
"id": 2,
47
"method": "tools/list",
48
"params": {}
49
}
50
},
51
{
52
"name": "Ping Server",
53
"request": {
54
"jsonrpc": "2.0",
55
"id": 3,
56
"method": "ping",
57
"params": {}
58
}
59
},
60
]
61
62
for test in test_requests:
63
print(f"\n{'─' * 70}")
64
print(f"Test: {test['name']}")
65
print(f"{'─' * 70}")
66
67
# Show request
68
print("\nClient Request:")
69
print(json.dumps(test['request'], indent=2))
70
71
# Create request object
72
req_data = test['request']
73
request = MCPRequest(
74
jsonrpc=req_data.get("jsonrpc", "2.0"),
75
id=req_data.get("id"),
76
method=req_data.get("method"),
77
params=req_data.get("params")
78
)
79
80
# Handle request
81
response = await server.handle_request(request)
82
83
# Show response
84
print("\nServer Response:")
85
response_dict = {
86
"jsonrpc": response.jsonrpc,
87
"id": response.id
88
}
89
if response.result is not None:
90
response_dict["result"] = response.result
91
if response.error is not None:
92
response_dict["error"] = response.error
93
94
print(json.dumps(response_dict, indent=2))
95
96
await asyncio.sleep(0.1) # Small delay between requests
97
98
print(f"\n{'═' * 70}")
99
print("Interactive Test Complete!")
100
print(f"{'═' * 70}\n")
101
102
print("Tool Descriptions:")
103
print("-" * 70)
104
for name, tool in server.tools.items():
105
print(f"\n• {name}")
106
print(f" {tool.description}")
107
schema = tool.input_schema
108
if 'required' in schema:
109
print(f" Required: {', '.join(schema['required'])}")
110
if 'properties' in schema:
111
optional = [k for k in schema['properties'].keys() if k not in schema.get('required', [])]
112
if optional:
113
print(f" Optional: {', '.join(optional)}")
114
115
print(f"\n{'═' * 70}")
116
print("How to Use the MCP Server:")
117
print(f"{'═' * 70}\n")
118
print("1. Start the server:")
119
print(" $ python -m g4f.mcp")
120
print(" or")
121
print(" $ g4f mcp")
122
print()
123
print("2. Configure in Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):")
124
print(' {')
125
print(' "mcpServers": {')
126
print(' "gpt4free": {')
127
print(' "command": "python",')
128
print(' "args": ["-m", "g4f.mcp"]')
129
print(' }')
130
print(' }')
131
print(' }')
132
print()
133
print("3. Or test via stdin/stdout:")
134
print(' $ echo \'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}\' | python -m g4f.mcp')
135
print()
136
print("The server will:")
137
print(" • Read JSON-RPC requests from stdin (one per line)")
138
print(" • Process the request and execute tools if needed")
139
print(" • Write JSON-RPC responses to stdout (one per line)")
140
print(" • Write debug/error messages to stderr")
141
print()
142
143
144
if __name__ == "__main__":
145
try:
146
asyncio.run(simulate_mcp_client())
147
except KeyboardInterrupt:
148
print("\n\nTest interrupted by user.")
149
sys.exit(0)
@@ -0,0 +1,103 @@
1
#!/usr/bin/env python
2
"""Test script for MCP server
3
4
This script tests the MCP server by simulating client interactions.
5
It sends JSON-RPC requests and verifies responses.
6
"""
7
8
import json
9
import sys
10
import asyncio
11
from g4f.mcp.server import MCPServer, MCPRequest
12
13
14
async def test_mcp_server():
15
"""Test MCP server functionality"""
16
server = MCPServer()
17
18
print("Testing MCP Server...")
19
print("=" * 60)
20
21
# Test 1: Initialize
22
print("\n1. Testing initialize request...")
23
init_request = MCPRequest(
24
jsonrpc="2.0",
25
id=1,
26
method="initialize",
27
params={}
28
)
29
response = await server.handle_request(init_request)
30
print(f" Response ID: {response.id}")
31
print(f" Protocol Version: {response.result['protocolVersion']}")
32
print(f" Server Name: {response.result['serverInfo']['name']}")
33
print(" ✓ Initialize test passed")
34
35
# Test 2: List tools
36
print("\n2. Testing tools/list request...")
37
list_request = MCPRequest(
38
jsonrpc="2.0",
39
id=2,
40
method="tools/list",
41
params={}
42
)
43
response = await server.handle_request(list_request)
44
print(f" Number of tools: {len(response.result['tools'])}")
45
for tool in response.result['tools']:
46
print(f" - {tool['name']}: {tool['description'][:50]}...")
47
print(" ✓ Tools list test passed")
48
49
# Test 3: Ping
50
print("\n3. Testing ping request...")
51
ping_request = MCPRequest(
52
jsonrpc="2.0",
53
id=3,
54
method="ping",
55
params={}
56
)
57
response = await server.handle_request(ping_request)
58
print(f" Response ID: {response.id}")
59
print(" ✓ Ping test passed")
60
61
# Test 4: Invalid method
62
print("\n4. Testing invalid method request...")
63
invalid_request = MCPRequest(
64
jsonrpc="2.0",
65
id=4,
66
method="invalid_method",
67
params={}
68
)
69
response = await server.handle_request(invalid_request)
70
if response.error:
71
print(f" Error code: {response.error['code']}")
72
print(f" Error message: {response.error['message']}")
73
print(" ✓ Invalid method test passed")
74
75
# Test 5: Tool schemas
76
print("\n5. Testing tool input schemas...")
77
list_request = MCPRequest(
78
jsonrpc="2.0",
79
id=5,
80
method="tools/list",
81
params={}
82
)
83
response = await server.handle_request(list_request)
84
for tool in response.result['tools']:
85
print(f" Tool: {tool['name']}")
86
schema = tool['inputSchema']
87
required = schema.get('required', [])
88
properties = schema.get('properties', {})
89
print(f" Required params: {', '.join(required)}")
90
print(f" All params: {', '.join(properties.keys())}")
91
print(" ✓ Tool schemas test passed")
92
93
print("\n" + "=" * 60)
94
print("All tests passed! ✓")
95
print("\nMCP server is working correctly.")
96
print("\nTo use the server, run:")
97
print(" python -m g4f.mcp")
98
print(" or")
99
print(" g4f mcp")
100
101
102
if __name__ == "__main__":
103
asyncio.run(test_mcp_server())