MCP Pass-Through - mcp-v8
mcp-v8
Home
Install
Overview
Release Script
Build from Source
Nix
Quick Start
Overview
Claude Code
Claude Desktop
Codex
Cursor
Generic MCP
curl
Bundled CLI
How-to
Overview
Run with stdio
Run with HTTP
Run with SSE
Use Local Storage
Use S3 Storage
Run a Cluster
Enable OPA Policies
Provide Sandboxed Filesystem Access
Configure Fetch Header Injection
Use SQLite WASM
Connect as an MCP Server
Use CLI
Concepts
Overview
JavaScript Runtime
Execution Model
Sessions and Heaps
Transports
Integration Surfaces
MCP Pass-Through
Module Loading
WASM and Native Modules
Policy System
Network Access
Filesystem Access
Clustering
Reference
Overview
CLI Flags
HTTP API
MCP Tools
Policy Files
Search
Previous
Next
Edit on r33drichards/mcp-js
MCP Pass-Through
Register sub-servers
Call upstream tools from JavaScript
Expose stub tools for discovery
Compose tools without pushing data through the context window
Policy and control boundaries
When to use pass-through
Related concepts
MCP Pass-Through¶
mcp-v8 can register MCP servers as function calls in the v8 runtime. When combined with stubs, this provides a robust surface for progressive tool disclosure, and composability of toolc calls.
Register sub-servers¶
You register upstream MCP servers with --mcp-server or --mcp-config.<br>Those definitions tell mcp-v8 which external servers to connect to at<br>startup.
At the conceptual level, each configured sub-server becomes another capability<br>source for the JavaScript runtime.
See Connect as an MCP Server and<br>CLI Flags for configuration details.
Call upstream tools from JavaScript¶
Inside the runtime, upstream tools are exposed through globalThis.mcp.
The important pieces are:
mcp.servers for connected server names
mcp.listTools() for discovery
mcp.callTool(server, tool, args) for execution
Conceptually, that means an agent can use JavaScript as the orchestration<br>layer while still reaching out to other MCP systems when needed.
const tools = mcp.listTools("github");<br>const result = await mcp.callTool("github", "create_issue", {<br>owner: "acme",<br>repo: "roadmap",<br>title: "Document MCP pass-through",<br>});
console.log(JSON.stringify(result, null, 2));
The tool call still happens through run_js, not as a separate direct tool<br>dispatch from the outer MCP client.
Expose stub tools for discovery¶
mcp-v8 can also publish optional stub tools on its own MCP surface. These<br>stubs mirror the upstream tools with names like<br>runjs__github__create_issue.
This is useful because it preserves native MCP tool discovery for downstream<br>agents:
the agent can see the tool in tools/list
the tool carries the upstream input schema
the agent can reason about the tool as if it were locally available
But the stub is intentionally not a direct proxy. Calling it returns<br>instructions telling the agent to invoke the tool through run_js and<br>mcp.callTool(...).
flowchart LR<br>A[Downstream MCP client] --> B[stub tool discovery]<br>B --> C[runjs__github__create_issue]<br>C --> D[instructional response]<br>D --> E[run_js plus mcp.callTool]<br>E --> F[JavaScript runtime]<br>F --> G[Upstream MCP server]
Compose tools without pushing data through the context window¶
One of the main benefits of pass-through is that JavaScript can compose local<br>runtime capabilities and upstream MCP tools in one workflow.
For example, an agent might:
fetch structured data from an external API
write the raw response to the sandboxed filesystem
transform it into a smaller report
call an upstream storage MCP server to upload the result to S3
call another upstream tool to create a signed URL
return only the signed URL and a short summary to the user
Conceptually:
flowchart LR<br>A[fetch remote data] --> B[write raw file with fs]<br>B --> C[transform in JavaScript]<br>C --> D[call upstream storage MCP tool]<br>D --> E[upload artifact to S3]<br>E --> F[create signed URL]<br>F --> G[return URL to user]
The key advantage is that the large payload never has to be copied into the<br>agent's context window. The runtime can fetch, store, transform, and hand off<br>artifacts in place, then return only the useful result.
That is a good fit for:
large API responses
multi-step document generation
binary or structured artifacts
workflows where the user only needs a link, summary, or final status
Policy and control boundaries¶
Pass-through does not mean "anything connected is automatically trusted."
mcp.callTool() can still be gated by policy. That lets operators control<br>which upstream servers and tools the runtime may use, and with what arguments.
So the control chain becomes:
discover or select an upstream tool
invoke it from JavaScript
evaluate policy
call the upstream MCP server only if allowed
See Policy System for the broader policy model.
When to use pass-through¶
Use MCP pass-through when:
JavaScript should orchestrate several steps around an upstream tool call
the agent benefits from heaps, sessions, or captured output
you...