-->
This project emerged from exploring Cloudflare’s “Code Mode” concept, which argues that LLMs are fundamentally better at writing regular code than making tool calls. Tool calls rely on synthetic tokens that aren’t well-represented in training data, while code generation leverages the vast amount of programming examples LLMs have been trained on.
https://github.com/jx-codes/mcp-rpc-runtime
https://github.com/jx-codes/mcp-rpc-bridge
The Model Context Protocol (MCP) typically requires LLMs to make sequential, individual tool calls. This approach has several limitations:
Instead of calling MCP servers directly, Code Mode lets LLMs write regular TypeScript code in a secure sandbox. This enables:
Promise.all()
While implementing a Code Mode wrapper for MCP, a simpler pattern emerged: why translate MCP schemas into TypeScript APIs when we could just write TypeScript functions directly?
MCP-RPC takes this approach:
This approach treats MCP servers, databases, APIs, and any other integration as just another TypeScript function. The LLM doesn’t need to know about protocols or schemas - it just calls functions with types, making the entire system more flexible and natural to use.
Each repo contains an install.sh script (be sure to read the contents before running the scripts).
curl -fsSL https://raw.githubusercontent.com/jx-codes/mcp-rpc-runtime/main/install.sh | bash
curl -fsSL https://raw.githubusercontent.com/jx-codes/mcp-rpc-bridge/main/install.sh | bash
After installing both the runtime and bridge, you’ll need to configure your MCP client to use the bridge.
Add this to your Claude Code MCP configuration file (typically ~/.config/claude/claude_desktop_config.json
or similar):
{
"mcpServers": {
"codemode": {
"command": "mcp-rpc-bridge",
"env": {
"RPC_WS_URL": "ws://localhost:8080/ws",
"RPC_HTTP_URL": "http://localhost:8080"
}
}
}
}
Note: The default URLs assume your RPC runtime is running on localhost:8080
. Adjust these if you’ve configured different ports or remote connections.
Before using the bridge, ensure the RPC runtime server is running:
mcp-rpc-runtime -r ./test-rpc -p 8080
This starts the WebSocket server that executes your TypeScript code in a secure Deno sandbox.
Command Options:
-r ./test-rpc
- Specifies the directory containing your RPC function files-p 8080
- Sets the port for the WebSocket server (default: 8080)Once configured, Claude will have access to three main tools through the codemode
MCP server:
get_available_rpc_tools
Discovers and retrieves all available RPC function definitions with their type signatures. This allows Claude to understand what functions it can call in its TypeScript code.
Usage: Claude will typically call this first to understand what functions are available to work with.
run_script
Executes TypeScript code in the secure Deno sandbox. This is where the magic happens - Claude writes regular TypeScript code using the rpc
object to call functions, and the runtime executes it.
Key Features:
rpc
object for calling server-side functionsPromise.all()
for performanceExample: Claude can write code like:
const results = await Promise.all([
rpc.getUserData(123),
rpc.getOrderHistory(123),
rpc.getPreferences(123),
]);
help
Provides runtime status and usage examples. Use this to get quick guidance on how to structure code and what capabilities are available.
The typical workflow when interacting with Claude looks like this:
get_available_rpc_tools
to see what functions are availablerun_script
to execute the code in the runtimeSimply ask Claude to perform tasks that would normally require multiple sequential operations:
"Fetch the user profile, their recent orders, and calculate their total spending"
Claude will automatically:
"Get all active users, filter those who haven't ordered in 30 days, and send them a reminder email"
Claude can write complex map/filter/reduce operations using familiar JavaScript patterns, all executed efficiently in the sandbox.
"Check the status of these 10 API endpoints and report which ones are down"
Instead of 10 sequential tool calls, Claude writes a single TypeScript script with Promise.all()
to check all endpoints concurrently.
┌─────────────┐ ┌──────────────┐ ┌───────────────────┐
│ Claude │ ◄─────► │ MCP Bridge │ ◄─────► │ MCP-RPC-Runtime │
│ (Client) │ MCP │ (Protocol) │ WS │ (Deno) │
└─────────────┘ └──────────────┘ └─────────┬─────────┘
spawns
|
┌─────────────────────┐
│ LLM Sandbox │
│ (Net Permissions) │
└─────────────────────┘
(and)
┌─────────────────────┐
│ RPC Functions │
│ (All Permissions) │
└─────────────────────┘
To extend the system with your own functions, add TypeScript files to the directory you specify with the -r
flag (e.g., ./test-rpc
). The runtime will automatically:
rpc
objectExample structure:
./test-rpc/
├── users.ts # User management functions
├── orders.ts # Order processing functions
└── notifications.ts # Notification functions
Each file should export typed functions that will become available as RPC endpoints.
Ensure:
mcp-rpc-runtime -r ./test-rpc -p 8080
)-r
flag) exists and contains your function filesCheck:
get_available_rpc_tools
)Try being explicit:
MIT
Built in response to Cloudflare’s “Code Mode: the better way to use MCP”