mirror of
https://github.com/xtekky/gpt4free.git
synced 2025-12-06 02:30:41 -08:00
Add MCP server tests, documentation, and README updates
Co-authored-by: hlohaus <983577+hlohaus@users.noreply.github.com>
This commit is contained in:
parent
e1214e4372
commit
0c2a2b00c3
3 changed files with 285 additions and 0 deletions
149
etc/testing/test_mcp_interactive.py
Normal file
149
etc/testing/test_mcp_interactive.py
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
#!/usr/bin/env python
|
||||
"""Interactive MCP server test
|
||||
|
||||
This script simulates a client sending requests to the MCP server
|
||||
and demonstrates how the tools work.
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import asyncio
|
||||
from io import StringIO
|
||||
|
||||
|
||||
async def simulate_mcp_client():
|
||||
"""Simulate an MCP client interacting with the server"""
|
||||
|
||||
print("MCP Server Interactive Test")
|
||||
print("=" * 70)
|
||||
print("\nThis test simulates JSON-RPC 2.0 messages between client and server.")
|
||||
print("The MCP server uses stdio transport for communication.\n")
|
||||
|
||||
from g4f.mcp.server import MCPServer, MCPRequest
|
||||
server = MCPServer()
|
||||
|
||||
# Test sequence of requests
|
||||
test_requests = [
|
||||
{
|
||||
"name": "Initialize Connection",
|
||||
"request": {
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"method": "initialize",
|
||||
"params": {
|
||||
"protocolVersion": "2024-11-05",
|
||||
"clientInfo": {
|
||||
"name": "test-client",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "List Available Tools",
|
||||
"request": {
|
||||
"jsonrpc": "2.0",
|
||||
"id": 2,
|
||||
"method": "tools/list",
|
||||
"params": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Ping Server",
|
||||
"request": {
|
||||
"jsonrpc": "2.0",
|
||||
"id": 3,
|
||||
"method": "ping",
|
||||
"params": {}
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
for test in test_requests:
|
||||
print(f"\n{'─' * 70}")
|
||||
print(f"Test: {test['name']}")
|
||||
print(f"{'─' * 70}")
|
||||
|
||||
# Show request
|
||||
print("\nClient Request:")
|
||||
print(json.dumps(test['request'], indent=2))
|
||||
|
||||
# Create request object
|
||||
req_data = test['request']
|
||||
request = MCPRequest(
|
||||
jsonrpc=req_data.get("jsonrpc", "2.0"),
|
||||
id=req_data.get("id"),
|
||||
method=req_data.get("method"),
|
||||
params=req_data.get("params")
|
||||
)
|
||||
|
||||
# Handle request
|
||||
response = await server.handle_request(request)
|
||||
|
||||
# Show response
|
||||
print("\nServer Response:")
|
||||
response_dict = {
|
||||
"jsonrpc": response.jsonrpc,
|
||||
"id": response.id
|
||||
}
|
||||
if response.result is not None:
|
||||
response_dict["result"] = response.result
|
||||
if response.error is not None:
|
||||
response_dict["error"] = response.error
|
||||
|
||||
print(json.dumps(response_dict, indent=2))
|
||||
|
||||
await asyncio.sleep(0.1) # Small delay between requests
|
||||
|
||||
print(f"\n{'═' * 70}")
|
||||
print("Interactive Test Complete!")
|
||||
print(f"{'═' * 70}\n")
|
||||
|
||||
print("Tool Descriptions:")
|
||||
print("-" * 70)
|
||||
for name, tool in server.tools.items():
|
||||
print(f"\n• {name}")
|
||||
print(f" {tool.description}")
|
||||
schema = tool.input_schema
|
||||
if 'required' in schema:
|
||||
print(f" Required: {', '.join(schema['required'])}")
|
||||
if 'properties' in schema:
|
||||
optional = [k for k in schema['properties'].keys() if k not in schema.get('required', [])]
|
||||
if optional:
|
||||
print(f" Optional: {', '.join(optional)}")
|
||||
|
||||
print(f"\n{'═' * 70}")
|
||||
print("How to Use the MCP Server:")
|
||||
print(f"{'═' * 70}\n")
|
||||
print("1. Start the server:")
|
||||
print(" $ python -m g4f.mcp")
|
||||
print(" or")
|
||||
print(" $ g4f mcp")
|
||||
print()
|
||||
print("2. Configure in Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):")
|
||||
print(' {')
|
||||
print(' "mcpServers": {')
|
||||
print(' "gpt4free": {')
|
||||
print(' "command": "python",')
|
||||
print(' "args": ["-m", "g4f.mcp"]')
|
||||
print(' }')
|
||||
print(' }')
|
||||
print(' }')
|
||||
print()
|
||||
print("3. Or test via stdin/stdout:")
|
||||
print(' $ echo \'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}\' | python -m g4f.mcp')
|
||||
print()
|
||||
print("The server will:")
|
||||
print(" • Read JSON-RPC requests from stdin (one per line)")
|
||||
print(" • Process the request and execute tools if needed")
|
||||
print(" • Write JSON-RPC responses to stdout (one per line)")
|
||||
print(" • Write debug/error messages to stderr")
|
||||
print()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
asyncio.run(simulate_mcp_client())
|
||||
except KeyboardInterrupt:
|
||||
print("\n\nTest interrupted by user.")
|
||||
sys.exit(0)
|
||||
103
etc/testing/test_mcp_server.py
Normal file
103
etc/testing/test_mcp_server.py
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
#!/usr/bin/env python
|
||||
"""Test script for MCP server
|
||||
|
||||
This script tests the MCP server by simulating client interactions.
|
||||
It sends JSON-RPC requests and verifies responses.
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import asyncio
|
||||
from g4f.mcp.server import MCPServer, MCPRequest
|
||||
|
||||
|
||||
async def test_mcp_server():
|
||||
"""Test MCP server functionality"""
|
||||
server = MCPServer()
|
||||
|
||||
print("Testing MCP Server...")
|
||||
print("=" * 60)
|
||||
|
||||
# Test 1: Initialize
|
||||
print("\n1. Testing initialize request...")
|
||||
init_request = MCPRequest(
|
||||
jsonrpc="2.0",
|
||||
id=1,
|
||||
method="initialize",
|
||||
params={}
|
||||
)
|
||||
response = await server.handle_request(init_request)
|
||||
print(f" Response ID: {response.id}")
|
||||
print(f" Protocol Version: {response.result['protocolVersion']}")
|
||||
print(f" Server Name: {response.result['serverInfo']['name']}")
|
||||
print(" ✓ Initialize test passed")
|
||||
|
||||
# Test 2: List tools
|
||||
print("\n2. Testing tools/list request...")
|
||||
list_request = MCPRequest(
|
||||
jsonrpc="2.0",
|
||||
id=2,
|
||||
method="tools/list",
|
||||
params={}
|
||||
)
|
||||
response = await server.handle_request(list_request)
|
||||
print(f" Number of tools: {len(response.result['tools'])}")
|
||||
for tool in response.result['tools']:
|
||||
print(f" - {tool['name']}: {tool['description'][:50]}...")
|
||||
print(" ✓ Tools list test passed")
|
||||
|
||||
# Test 3: Ping
|
||||
print("\n3. Testing ping request...")
|
||||
ping_request = MCPRequest(
|
||||
jsonrpc="2.0",
|
||||
id=3,
|
||||
method="ping",
|
||||
params={}
|
||||
)
|
||||
response = await server.handle_request(ping_request)
|
||||
print(f" Response ID: {response.id}")
|
||||
print(" ✓ Ping test passed")
|
||||
|
||||
# Test 4: Invalid method
|
||||
print("\n4. Testing invalid method request...")
|
||||
invalid_request = MCPRequest(
|
||||
jsonrpc="2.0",
|
||||
id=4,
|
||||
method="invalid_method",
|
||||
params={}
|
||||
)
|
||||
response = await server.handle_request(invalid_request)
|
||||
if response.error:
|
||||
print(f" Error code: {response.error['code']}")
|
||||
print(f" Error message: {response.error['message']}")
|
||||
print(" ✓ Invalid method test passed")
|
||||
|
||||
# Test 5: Tool schemas
|
||||
print("\n5. Testing tool input schemas...")
|
||||
list_request = MCPRequest(
|
||||
jsonrpc="2.0",
|
||||
id=5,
|
||||
method="tools/list",
|
||||
params={}
|
||||
)
|
||||
response = await server.handle_request(list_request)
|
||||
for tool in response.result['tools']:
|
||||
print(f" Tool: {tool['name']}")
|
||||
schema = tool['inputSchema']
|
||||
required = schema.get('required', [])
|
||||
properties = schema.get('properties', {})
|
||||
print(f" Required params: {', '.join(required)}")
|
||||
print(f" All params: {', '.join(properties.keys())}")
|
||||
print(" ✓ Tool schemas test passed")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("All tests passed! ✓")
|
||||
print("\nMCP server is working correctly.")
|
||||
print("\nTo use the server, run:")
|
||||
print(" python -m g4f.mcp")
|
||||
print(" or")
|
||||
print(" g4f mcp")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(test_mcp_server())
|
||||
Loading…
Add table
Add a link
Reference in a new issue