Programmatic Tool Calling for Any MCP

someguy1010101 pts1 comments

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...

tool through upstream tools pass javascript

Related Articles