MCP JSON RPC Guide¶
This comprehensive guide demonstrates how to interact with MCP (Model Context Protocol) servers using raw JSON-RPC commands via curl
or through STDIO. This is essential for developers who want to understand the MCP protocol at a low level, integrate MCP into custom applications, or debug MCP implementations.
Overview¶
The Model Context Protocol (MCP) is a standardized protocol for connecting language models to various data sources and tools. MCP Gateway acts as a federation layer that aggregates multiple MCP servers and provides unified access through various transport mechanisms.
Prerequisites¶
Before starting, ensure you have:
- MCP Gateway server running (typically on
http://localhost:4444
) curl
command-line tool installedjq
for JSON formatting (optional but recommended)- Basic understanding of JSON-RPC 2.0 protocol
Authentication Setup¶
MCP Gateway uses JWT Bearer tokens for authentication. Generate a token before making any requests:
# Generate authentication token
export MCPGATEWAY_BEARER_TOKEN=$(python3 -m mcpgateway.utils.create_jwt_token \
--username admin --exp 10080 --secret my-test-key)
# Verify the token was generated
echo "Token: ${MCPGATEWAY_BEARER_TOKEN}"
# Test connectivity
curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
http://localhost:4444/health | jq
Expected health response:
Understanding MCP Protocol Flow¶
MCP follows a specific initialization sequence that must be followed for proper communication:
- Initialize - Establish protocol version and capabilities
- Initialized Notification - Confirm initialization completion
- Protocol Operations - List and call tools, read resources, get prompts
Transport Methods¶
MCP Gateway supports multiple transport methods:
- HTTP JSON-RPC (
/rpc
) - Standard JSON-RPC 2.0 over HTTP - Server-Sent Events (
/sse
) - Real-time streaming communication - Protocol Endpoints (
/protocol/*
) - Specialized endpoints for specific operations
MCP Protocol Implementation¶
1. Initialize the Connection¶
Every MCP session must begin with proper initialization:
Method 1: Using Protocol Endpoint (Recommended)¶
# Initialize using dedicated protocol endpoint
curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"protocol_version": "2025-03-26",
"capabilities": {
"tools": {},
"resources": {},
"prompts": {}
},
"client_info": {
"name": "cli-developer",
"version": "1.0.0"
}
}' \
http://localhost:4444/protocol/initialize | jq
Method 2: Using JSON-RPC Endpoint¶
# Initialize using JSON-RPC endpoint
curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-03-26",
"capabilities": {
"tools": {},
"resources": {},
"prompts": {}
},
"clientInfo": {
"name": "cli-developer",
"version": "1.0.0"
}
}
}' \
http://localhost:4444/rpc | jq
Expected Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-03-26",
"capabilities": {
"experimental": {},
"prompts": {
"listChanged": false
},
"resources": {
"subscribe": false,
"listChanged": false
},
"tools": {
"listChanged": false
}
},
"serverInfo": {
"name": "mcpgateway",
"version": "0.6.0"
}
}
}
2. Send Initialized Notification¶
After successful initialization, send the initialized notification:
# Send initialized notification
curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "notifications/initialized",
"params": {}
}' \
http://localhost:4444/rpc
Working with Tools¶
List Available Tools¶
# List all available tools
curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}' \
http://localhost:4444/rpc | jq
Response with no tools:
Response with tools available:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"tools": [
{
"name": "get_system_time",
"description": "Get current system time in specified timezone",
"inputSchema": {
"type": "object",
"properties": {
"timezone": {
"type": "string",
"description": "IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Defaults to UTC if not specified."
}
}
}
},
{
"name": "convert_time",
"description": "Convert time between different timezones",
"inputSchema": {
"type": "object",
"properties": {
"time": {
"type": "string",
"description": "Time to convert in RFC3339 format"
},
"source_timezone": {
"type": "string",
"description": "Source IANA timezone name"
},
"target_timezone": {
"type": "string",
"description": "Target IANA timezone name"
}
},
"required": ["time", "source_timezone", "target_timezone"]
}
}
]
}
}
Call a Tool¶
# Call a tool with arguments
curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "get_system_time",
"arguments": {
"timezone": "Europe/Dublin"
}
}
}' \
http://localhost:4444/rpc | jq
Expected Response:
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "{\n \"timezone\": \"Europe/Dublin\",\n \"datetime\": \"2025-01-15T16:30:45+00:00\",\n \"is_dst\": false\n}"
}
],
"isError": false
}
}
Tool Call Examples¶
Convert Time Between Timezones:
curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "convert_time",
"arguments": {
"time": "2025-01-15T10:00:00Z",
"source_timezone": "UTC",
"target_timezone": "America/New_York"
}
}
}' \
http://localhost:4444/rpc | jq
Working with Resources¶
List Available Resources¶
# List all available resources
curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 5,
"method": "resources/list",
"params": {}
}' \
http://localhost:4444/rpc | jq
Expected Response:
{
"jsonrpc": "2.0",
"id": 5,
"result": {
"resources": [
{
"uri": "timezone://info",
"name": "Timezone Information",
"description": "Comprehensive timezone information including offsets, DST status, and major cities",
"mimeType": "application/json"
},
{
"uri": "time://current/world",
"name": "World Clock",
"description": "Current time in major cities around the world",
"mimeType": "application/json"
}
]
}
}
Read a Specific Resource¶
# Read a specific resource
curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 6,
"method": "resources/read",
"params": {
"uri": "timezone://info"
}
}' \
http://localhost:4444/rpc | jq
Working with Prompts¶
List Available Prompts¶
# List all available prompts
curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 7,
"method": "prompts/list",
"params": {}
}' \
http://localhost:4444/rpc | jq
Get a Specific Prompt¶
# Get a prompt with arguments
curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 8,
"method": "prompts/get",
"params": {
"name": "compare_timezones",
"arguments": {
"timezones": "UTC,America/New_York,Europe/London",
"reference_time": "2025-01-15T12:00:00Z"
}
}
}' \
http://localhost:4444/rpc | jq
Server-Sent Events (SSE) Transport¶
For real-time communication and better handling of long-running operations, use the SSE transport:
Establishing SSE Connection¶
# Terminal 1: Start SSE connection (keeps connection open)
curl -N -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
http://localhost:4444/sse
Sending Messages via SSE¶
In a separate terminal, send JSON-RPC messages:
# Initialize via SSE
curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-03-26",
"capabilities": {},
"clientInfo": {"name": "sse-client", "version": "1.0"}
}
}' \
http://localhost:4444/message
# List tools via SSE
curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list"
}' \
http://localhost:4444/message
# Call a tool via SSE
curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "get_system_time",
"arguments": {"timezone": "Asia/Tokyo"}
}
}' \
http://localhost:4444/message
Utility Operations¶
Ping the Server¶
# Test server responsiveness
curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 9,
"method": "ping"
}' \
http://localhost:4444/rpc | jq
Expected Response:
STDIO Transport¶
For command-line integration and desktop client compatibility, use the STDIO wrapper:
Setting Up STDIO Environment¶
# Configure environment variables
export MCP_AUTH_TOKEN=${MCPGATEWAY_BEARER_TOKEN}
export MCP_SERVER_CATALOG_URLS="http://localhost:4444/servers/your-server-id"
export MCP_TOOL_CALL_TIMEOUT=120
export MCP_WRAPPER_LOG_LEVEL=INFO
# Run the wrapper
python3 -m mcpgateway.wrapper
STDIO Communication¶
Send JSON-RPC commands directly to stdin:
# Send commands to stdin (each on a single line)
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"stdio-client","version":"1.0"}}}' | python3 -m mcpgateway.wrapper
echo '{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}' | python3 -m mcpgateway.wrapper
echo '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' | python3 -m mcpgateway.wrapper
Complete Session Examples¶
HTTP JSON-RPC Complete Session¶
#!/bin/bash
# Complete MCP Gateway session via HTTP JSON-RPC
# Setup
export MCPGATEWAY_BEARER_TOKEN=$(python3 -m mcpgateway.utils.create_jwt_token \
--username admin --exp 10080 --secret my-test-key)
# Function to make authenticated JSON-RPC calls
make_call() {
curl -s -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
-H "Content-Type: application/json" \
-d "$1" \
http://localhost:4444/rpc | jq
}
# Function for protocol-specific calls
make_protocol_call() {
curl -s -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
-H "Content-Type: application/json" \
-d "$1" \
http://localhost:4444/protocol/initialize | jq
}
echo "=== MCP Gateway Complete Session ==="
# 1. Test connectivity
echo "=== Testing Connectivity ==="
curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
http://localhost:4444/health | jq
# 2. Initialize (using protocol endpoint for reliability)
echo "=== Initializing Session ==="
make_protocol_call '{
"protocol_version": "2025-03-26",
"capabilities": {
"tools": {},
"resources": {},
"prompts": {}
},
"client_info": {
"name": "complete-session-demo",
"version": "1.0"
}
}'
# 3. Send initialized notification
echo "=== Sending Initialized Notification ==="
make_call '{
"jsonrpc": "2.0",
"method": "notifications/initialized",
"params": {}
}'
# 4. List available tools
echo "=== Listing Available Tools ==="
make_call '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}'
# 5. List available resources
echo "=== Listing Available Resources ==="
make_call '{
"jsonrpc": "2.0",
"id": 3,
"method": "resources/list",
"params": {}
}'
# 6. List available prompts
echo "=== Listing Available Prompts ==="
make_call '{
"jsonrpc": "2.0",
"id": 4,
"method": "prompts/list",
"params": {}
}'
# 7. Call a tool (if available)
echo "=== Calling Tool (get_system_time) ==="
make_call '{
"jsonrpc": "2.0",
"id": 5,
"method": "tools/call",
"params": {
"name": "get_system_time",
"arguments": {
"timezone": "UTC"
}
}
}'
# 8. Read a resource (if available)
echo "=== Reading Resource ==="
make_call '{
"jsonrpc": "2.0",
"id": 6,
"method": "resources/read",
"params": {
"uri": "timezone://info"
}
}'
# 9. Test ping
echo "=== Testing Ping ==="
make_call '{
"jsonrpc": "2.0",
"id": 7,
"method": "ping"
}'
echo "=== Session Complete ==="
SSE Complete Session¶
#!/bin/bash
# Complete MCP Gateway session via Server-Sent Events
# Setup
export MCPGATEWAY_BEARER_TOKEN=$(python3 -m mcpgateway.utils.create_jwt_token \
--username admin --exp 10080 --secret my-test-key)
echo "=== Starting SSE Session ==="
# Start SSE connection in background
curl -N -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
http://localhost:4444/sse &
SSE_PID=$!
# Give SSE time to connect
sleep 2
# Function to send messages via SSE
send_sse_message() {
curl -s -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
-H "Content-Type: application/json" \
-d "$1" \
http://localhost:4444/message
sleep 1 # Allow time for response
}
echo "=== Sending Initialize Message ==="
send_sse_message '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-03-26",
"capabilities": {},
"clientInfo": {
"name": "sse-session-demo",
"version": "1.0"
}
}
}'
echo "=== Sending Initialized Notification ==="
send_sse_message '{
"jsonrpc": "2.0",
"method": "notifications/initialized",
"params": {}
}'
echo "=== Listing Tools ==="
send_sse_message '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list"
}'
echo "=== Calling Tool ==="
send_sse_message '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "get_system_time",
"arguments": {
"timezone": "Europe/Dublin"
}
}
}'
echo "=== Testing Ping ==="
send_sse_message '{
"jsonrpc": "2.0",
"id": 4,
"method": "ping"
}'
# Allow time for final responses
sleep 3
# Clean up
kill $SSE_PID 2>/dev/null
echo "=== SSE Session Complete ==="
Error Handling and Troubleshooting¶
Common Error Responses¶
MCP follows JSON-RPC 2.0 error handling standards:
Authentication Error:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32000,
"message": "Authentication required",
"data": "Missing or invalid authorization header"
}
}
Invalid Parameters:
{
"jsonrpc": "2.0",
"id": 2,
"error": {
"code": -32602,
"message": "Invalid params",
"data": "Missing required parameter: name"
}
}
Method Not Found:
{
"jsonrpc": "2.0",
"id": 3,
"error": {
"code": -32601,
"message": "Method not found",
"data": "Unknown method: invalid_method"
}
}
Standard JSON-RPC Error Codes¶
Code | Meaning | Description |
---|---|---|
-32700 | Parse error | Invalid JSON was received |
-32600 | Invalid Request | The JSON sent is not a valid Request object |
-32601 | Method not found | The method does not exist / is not available |
-32602 | Invalid params | Invalid method parameter(s) |
-32603 | Internal error | Internal JSON-RPC error |
-32000 to -32099 | Server error | Reserved for implementation-defined server-errors |
Troubleshooting Common Issues¶
1. Authentication Problems¶
Symptoms: - 401 Unauthorized responses - "Authentication required" errors
Solutions:
# Verify token generation
export MCPGATEWAY_BEARER_TOKEN=$(python3 -m mcpgateway.utils.create_jwt_token \
--username admin --exp 10080 --secret my-test-key)
# Test token validity
curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
http://localhost:4444/health
# Check token expiration
echo $MCPGATEWAY_BEARER_TOKEN | cut -d'.' -f2 | base64 -d | jq .exp
2. Connection Issues¶
Symptoms: - Connection refused errors - Timeout errors
Solutions:
# Check if MCP Gateway is running
curl -f http://localhost:4444/health || echo "Gateway not running"
# Check port availability
lsof -i :4444
# Verify network connectivity
ping localhost
3. Initialize Method Errors¶
Known Issue: 'coroutine' object has no attribute 'model_dump'
Workaround:
# Use protocol endpoint instead of /rpc for initialization
curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"protocol_version": "2025-03-26",
"capabilities": {},
"client_info": {"name": "workaround", "version": "1.0"}
}' \
http://localhost:4444/protocol/initialize
4. Empty Tool/Resource Lists¶
Symptoms: - tools/list
returns empty array - resources/list
returns empty array
Solutions:
# Check if MCP servers are registered
curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
http://localhost:4444/gateways | jq
# Verify virtual servers are configured
curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
http://localhost:4444/servers | jq
# Check individual server status
curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
http://localhost:4444/servers/{server-id} | jq
5. Tool Call Failures¶
Symptoms: - Tool calls return isError: true
- Timeout errors
Solutions:
# Check tool schema and required parameters
curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' \
http://localhost:4444/rpc | jq '.result.tools[0].inputSchema'
# Verify argument types match schema
# Increase timeout for long-running tools
export MCP_TOOL_CALL_TIMEOUT=300
Integration Examples¶
Python Client Implementation¶
import json
import requests
import subprocess
from typing import Dict, Any, Optional
class MCPGatewayClient:
def __init__(self, base_url: str = "http://localhost:4444", auth_token: Optional[str] = None):
self.base_url = base_url
self.session = requests.Session()
self.request_id = 0
if auth_token:
self.session.headers.update({
"Authorization": f"Bearer {auth_token}",
"Content-Type": "application/json"
})
def _make_request(self, method: str, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
"""Make a JSON-RPC request to the gateway."""
self.request_id += 1
payload = {
"jsonrpc": "2.0",
"id": self.request_id,
"method": method
}
if params is not None:
payload["params"] = params
response = self.session.post(f"{self.base_url}/rpc", json=payload)
response.raise_for_status()
return response.json()
def initialize(self) -> Dict[str, Any]:
"""Initialize the MCP session."""
# Use protocol endpoint for reliable initialization
payload = {
"protocol_version": "2025-03-26",
"capabilities": {
"tools": {},
"resources": {},
"prompts": {}
},
"client_info": {
"name": "python-mcp-client",
"version": "1.0.0"
}
}
response = self.session.post(f"{self.base_url}/protocol/initialize", json=payload)
response.raise_for_status()
# Send initialized notification
self._make_request("notifications/initialized", {})
return response.json()
def list_tools(self) -> Dict[str, Any]:
"""List available tools."""
return self._make_request("tools/list")
def call_tool(self, name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
"""Call a specific tool with arguments."""
return self._make_request("tools/call", {
"name": name,
"arguments": arguments
})
def list_resources(self) -> Dict[str, Any]:
"""List available resources."""
return self._make_request("resources/list")
def read_resource(self, uri: str) -> Dict[str, Any]:
"""Read a specific resource."""
return self._make_request("resources/read", {"uri": uri})
def list_prompts(self) -> Dict[str, Any]:
"""List available prompts."""
return self._make_request("prompts/list")
def get_prompt(self, name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
"""Get a specific prompt with arguments."""
return self._make_request("prompts/get", {
"name": name,
"arguments": arguments
})
def ping(self) -> Dict[str, Any]:
"""Test server connectivity."""
return self._make_request("ping")
# Usage example
def main():
# Generate authentication token
result = subprocess.run([
"python3", "-m", "mcpgateway.utils.create_jwt_token",
"--username", "admin", "--exp", "10080", "--secret", "my-test-key"
], capture_output=True, text=True)
if result.returncode != 0:
raise Exception(f"Failed to generate token: {result.stderr}")
auth_token = result.stdout.strip()
# Create client and initialize
client = MCPGatewayClient(auth_token=auth_token)
try:
# Initialize session
init_result = client.initialize()
print("Initialized:", json.dumps(init_result, indent=2))
# List available tools
tools = client.list_tools()
print("Tools:", json.dumps(tools, indent=2))
# Call a tool if available
if tools["result"]["tools"]:
tool_name = tools["result"]["tools"][0]["name"]
result = client.call_tool(tool_name, {"timezone": "UTC"})
print(f"Tool result:", json.dumps(result, indent=2))
# Test ping
ping_result = client.ping()
print("Ping:", json.dumps(ping_result, indent=2))
except Exception as e:
print(f"Error: {e}")
if __name__ == "__main__":
main()
Node.js Client Implementation¶
const axios = require('axios');
const { execSync } = require('child_process');
class MCPGatewayClient {
constructor(baseUrl = 'http://localhost:4444', authToken = null) {
this.baseUrl = baseUrl;
this.requestId = 0;
this.axiosInstance = axios.create({
baseURL: baseUrl,
headers: {
'Content-Type': 'application/json',
...(authToken && { 'Authorization': `Bearer ${authToken}` })
}
});
}
async makeRequest(method, params = null) {
this.requestId++;
const payload = {
jsonrpc: '2.0',
id: this.requestId,
method
};
if (params !== null) {
payload.params = params;
}
const response = await this.axiosInstance.post('/rpc', payload);
return response.data;
}
async initialize() {
// Use protocol endpoint for reliable initialization
const payload = {
protocol_version: '2025-03-26',
capabilities: {
tools: {},
resources: {},
prompts: {}
},
client_info: {
name: 'nodejs-mcp-client',
version: '1.0.0'
}
};
const response = await this.axiosInstance.post('/protocol/initialize', payload);
// Send initialized notification
await this.makeRequest('notifications/initialized', {});
return response.data;
}
async listTools() {
return this.makeRequest('tools/list');
}
async callTool(name, arguments) {
return this.makeRequest('tools/call', { name, arguments });
}
async listResources() {
return this.makeRequest('resources/list');
}
async readResource(uri) {
return this.makeRequest('resources/read', { uri });
}
async listPrompts() {
return this.makeRequest('prompts/list');
}
async getPrompt(name, arguments) {
return this.makeRequest('prompts/get', { name, arguments });
}
async ping() {
return this.makeRequest('ping');
}
}
// Usage example
async function main() {
try {
// Generate authentication token
const authToken = execSync(
'python3 -m mcpgateway.utils.create_jwt_token --username admin --exp 10080 --secret my-test-key',
{ encoding: 'utf8' }
).trim();
// Create client and initialize
const client = new MCPGatewayClient('http://localhost:4444', authToken);
// Initialize session
const initResult = await client.initialize();
console.log('Initialized:', JSON.stringify(initResult, null, 2));
// List available tools
const tools = await client.listTools();
console.log('Tools:', JSON.stringify(tools, null, 2));
// Call a tool if available
if (tools.result.tools.length > 0) {
const toolName = tools.result.tools[0].name;
const result = await client.callTool(toolName, { timezone: 'UTC' });
console.log('Tool result:', JSON.stringify(result, null, 2));
}
// Test ping
const pingResult = await client.ping();
console.log('Ping:', JSON.stringify(pingResult, null, 2));
} catch (error) {
console.error('Error:', error.message);
if (error.response) {
console.error('Response:', error.response.data);
}
}
}
if (require.main === module) {
main();
}
module.exports = MCPGatewayClient;
Best Practices¶
1. Session Management¶
- Always initialize before making other requests
- Send the initialized notification after successful initialization
- Use unique request IDs for correlation
- Handle errors gracefully and implement retry logic
2. Authentication¶
- Store tokens securely and refresh them before expiration
- Use environment variables for token management
- Implement proper token validation and error handling
3. Transport Selection¶
- Use HTTP JSON-RPC for simple request-response patterns
- Use SSE for real-time communication and long-running operations
- Use STDIO for desktop client integration
4. Error Handling¶
- Check for JSON-RPC error objects in all responses
- Implement appropriate retry strategies for transient errors
- Log errors with sufficient context for debugging
5. Performance Optimization¶
- Reuse HTTP connections when possible
- Implement proper timeout configurations
- Cache tool schemas and capabilities to reduce redundant calls