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@example.com --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": {
"prompts": {"listChanged": true},
"resources": {"subscribe": true, "listChanged": true},
"tools": {"listChanged": true},
"logging": {}
},
"serverInfo": {
"name": "MCP_Gateway",
"version": "0.7.0"
},
"instructions": "MCP Gateway providing federated tools, resources and prompts. Use /admin interface for configuration."
}
}
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 (e.g. after registering the Fast Time Server example):
{
"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
The first event emitted by the stream is an endpoint
payload with the per-session POST URL:
Copy that value (it changes each run) into an environment variable used by your second terminal:
Sending Messages via SSEΒΆ
Now send JSON-RPC messages to the captured endpoint:
# 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"}
}
}' \
"$MCP_SSE_ENDPOINT"
# 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"
}' \
"$MCP_SSE_ENDPOINT"
# Call a tool via SSE (after registering one)
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"}
}
}' \
"$MCP_SSE_ENDPOINT"
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="Bearer ${MCPGATEWAY_BEARER_TOKEN}"
export MCP_SERVER_URL="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ΒΆ
Feed multiple JSON-RPC messages in one stream (the wrapper exits when STDIN closes):
python3 -m mcpgateway.wrapper <<'EOF'
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"stdio-client","version":"1.0"}}}
{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
EOF
Run it interactively (without the here-doc) if you prefer to type requests by hand.
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@example.com --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@example.com --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@example.com --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@example.com --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