MCP ā Model Context Protocol
muLLM exposes its routing pipeline as MCP tools, allowing any MCP-compatible client (Claude Code, Cursor, custom agents) to use muLLM for cost-optimized AI queries.
MCP Client
→ JSON-RPC 2.0 →
muLLM MCP Server
→ classify → route →
Cheapest Model
Available MCP Tools
mullm_query
Route an AI query through the cost-optimized pipeline. Returns response from the cheapest capable model.
params: content (string, required), skip_cache (bool), force_tier (string)
mullm_split
Decompose a multi-part query and route each sub-task to the cheapest appropriate tier.
params: content (string, required)
mullm_budget
Get current budget and savings counters.
params: none
mullm_classify
Classify a prompt without executing it. Returns category, complexity, freshness, and suggested tier.
params: content (string, required)
mullm_budget
Return current budget counters and spend-limit state.
params: none
mullm_system
Return CPU, RAM, GPU, VRAM, and Ollama status.
params: none
Usage Examples
curl
Python
Node.js
Claude Code
List tools
bashcurl -s https://localhost:6856/mcp/tools | jq
Call a tool (MCP tools/call)
bashcurl -s -X POST https://localhost:6856/mcp/call \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "mullm_query",
"arguments": {
"content": "What is the capital of France?"
}
}
}' | jq
Query the pipeline directly
bashcurl -s -X POST https://localhost:6856/query \
-H 'Content-Type: application/json' \
-d '{"content": "Explain quicksort", "source": "api"}' | jq
Split routing
bashcurl -s -X POST https://localhost:6856/query/split \
-H 'Content-Type: application/json' \
-d '{"content": "What is 2+2? Also write a haiku about rain."}' | jq
Get budget status
bashcurl -s https://localhost:6856/api/budget | jq
Get cost stats
bashcurl -s https://localhost:6856/api/stats | jq
Basic query
pythonimport httpx
client = httpx.Client(base_url="https://localhost:6856", verify=False)
# Simple query
r = client.post("/query", json={"content": "What is quicksort?", "source": "api"})
data = r.json()
print(f"Tier: {data['tier_used']}, Cost: ${data['cost']:.4f}")
print(data["response"])
MCP tool call
pythonimport httpx
client = httpx.Client(base_url="https://localhost:6856", verify=False)
# List available tools
tools = client.get("/mcp/tools").json()
for tool in tools["tools"]:
print(f" {tool['name']}: {tool['description']}")
# Call a tool via MCP protocol
r = client.post("/mcp/call", json={
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "mullm_query",
"arguments": {"content": "Explain async/await"}
}
})
print(r.json())
Streaming (SSE)
pythonimport httpx
with httpx.stream("GET", "https://localhost:6856/query/stream",
params={"q": "Write a poem about code"},
verify=False) as r:
for line in r.iter_lines():
if line.startswith("data: "):
chunk = line[6:]
if chunk == "[DONE]":
break
print(chunk, end="", flush=True)
Dashboard + Budget
pythonimport httpx
client = httpx.Client(base_url="https://localhost:6856", verify=False)
# Cost stats (real numbers, no estimates)
stats = client.get("/api/stats").json()
print(f"All-time cost: ${stats['all_time']['total_cost']:.4f}")
print(f"Total queries: {stats['all_time']['total_queries']}")
for tier, info in stats["by_tier"].items():
print(f" {tier}: {info['queries']}q, ${info['cost']:.4f}")
# Budget status
budget = client.get("/api/budget").json()
print(f"Daily: ${budget['daily_spend']:.2f} / ${budget['effective_daily_limit']:.2f}")
Basic query
javascriptconst r = await fetch('https://localhost:6856/query', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({content: 'What is quicksort?', source: 'api'})
});
const data = await r.json();
console.log(`Tier: ${data.tier_used}, Cost: $${data.cost.toFixed(4)}`);
console.log(data.response);
MCP tool call
javascript// List tools
const tools = await fetch('https://localhost:6856/mcp/tools').then(r => r.json());
tools.tools.forEach(t => console.log(` ${t.name}: ${t.description}`));
// Call tool
const r = await fetch('https://localhost:6856/mcp/call', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
jsonrpc: '2.0', id: 1,
method: 'tools/call',
params: {name: 'mullm_query', arguments: {content: 'Explain closures'}}
})
});
console.log(await r.json());
Streaming (SSE)
javascriptconst es = new EventSource(
'https://localhost:6856/query/stream?content=' + encodeURIComponent('Write a haiku')
);
es.onmessage = (e) => {
if (e.data === '[DONE]') { es.close(); return; }
process.stdout.write(e.data);
};
HTTP client note
json{
"endpoint": "https://localhost:6856/mcp/call",
"transport": "http-json-rpc"
}
Usage
textOnce configured, Claude Code can call muLLM tools directly:
"Use mullm_query to ask 'What is the time complexity of quicksort?'"
"Use mullm_split to decompose this multi-part question"
"Use mullm_budget to check current savings"
muLLM will route each query to the cheapest capable model,
saving you money on every call.
JSON-RPC 2.0 Protocol
All MCP communication follows the JSON-RPC 2.0 specification.
Request
{"jsonrpc":"2.0", "id":1, "method":"tools/call", "params":{...}}
Response (success)
{"jsonrpc":"2.0", "id":1, "result":{...}}
Response (error)
{"jsonrpc":"2.0", "id":1, "error":{"code":-32601, "message":"Method not found"}}
{"jsonrpc":"2.0", "id":1, "method":"tools/call", "params":{...}}
Response (success)
{"jsonrpc":"2.0", "id":1, "result":{...}}
Response (error)
{"jsonrpc":"2.0", "id":1, "error":{"code":-32601, "message":"Method not found"}}
Error Codes
reference-32700 Parse error Invalid JSON
-32600 Invalid request Missing required fields
-32601 Method not found Unknown tool/method
-32602 Invalid params Wrong argument types
-32603 Internal error Server-side failure