
Security News
Happy Birthday, Shai-Hulud
It has been one year since Shai-Hulud made its first appearance on npm.
@openrouter/mcp
Advanced tools
Expose remote MCP server tools (Streamable HTTP / SSE) as tools for @openrouter/agent's callModel, with serializable caching and pluggable auth.
[!NOTE] This package is a migration-only compatibility facade. New code should import the canonical
@openrouter/agent/mcpsubpath. Existing@openrouter/mcproot and subpath imports remain functional and would only be removed in a future breaking release after migration notice.
Expose the tools of a remote Model Context Protocol server
(Streamable HTTP or SSE) as tools you can pass straight into
@openrouter/agent's callModel.
tools/list_changed auto-refresh, cancellation, resources, and elicitation.stdio servers are intentionally out of scope.
For new code, install the agent plus the optional MCP peer:
pnpm add @openrouter/agent @modelcontextprotocol/client
Existing applications can keep installing only the compatibility package; it retains @modelcontextprotocol/client as a dependency, so the prior transitive-install behavior is unchanged:
pnpm add @openrouter/mcp
The agent package is marked sideEffects: false, and MCP code is exposed only
through explicit /mcp exports. Root and /tool-set imports do not statically
load MCP modules; the MCP SDK is not installed transitively for base agent users.
The /mcp entry point also loads the optional SDK lazily: importing it is safe
without the peer, while the first connection attempt throws an actionable
MCPMissingPeerDependencyError when the SDK has not been installed.
| Existing facade | Canonical replacement |
|---|---|
@openrouter/mcp | @openrouter/agent/mcp |
@openrouter/mcp/create-mcp-tools | @openrouter/agent/mcp/create-mcp-tools |
@openrouter/mcp/types | @openrouter/agent/mcp/types |
@openrouter/mcp/schema | @openrouter/agent/mcp/schema |
@openrouter/mcp/cache | @openrouter/agent/mcp/cache |
import { OpenRouter } from '@openrouter/agent';
import { callModel } from '@openrouter/agent/call-model';
import { createMCPTools } from '@openrouter/agent/mcp';
const client = new OpenRouter({ apiKey: process.env.OPENROUTER_API_KEY });
const mcp = await createMCPTools({
url: 'https://mcp.example.com/mcp',
auth: { kind: 'bearer', token: process.env.MCP_TOKEN },
});
const result = callModel(client, {
model: 'anthropic/claude-opus-4-8',
input: 'What are my three most recently updated issues?',
tools: mcp.tools,
});
console.log(await result.getText());
await mcp.close();
Auth is supplied once and reused for discovery and every call:
// Static bearer token
auth: { kind: 'bearer', token }
// Arbitrary headers
auth: { kind: 'headers', headers: { 'X-API-Key': key } }
// Pluggable OAuth (you own token refresh/storage)
auth: { kind: 'oauth', provider }
Prefer an OAuthClientProvider over caching static tokens — the transport refreshes through it
automatically.
Persist a snapshot and rebuild later without a listTools() round-trip:
import { createMCPTools, rehydrateMCPTools } from '@openrouter/agent/mcp';
const mcp = await createMCPTools({ url, auth, cacheCredentials: true });
const snapshot = await mcp.serialize(); // plain JSON — store anywhere
await mcp.close();
const mcp2 = await rehydrateMCPTools({ snapshot, auth });
Or let a store manage it (rehydrate on hit, connect + write on miss):
import { InMemoryMCPCacheStore } from '@openrouter/agent/mcp';
const store = new InMemoryMCPCacheStore(); // or your own Redis/DB-backed MCPCacheStore
const mcp = await createMCPTools({
url,
auth,
cache: { store, key: `mcp:${userId}` },
staleness: { maxAgeMs: 60 * 60 * 1000 },
});
Security:
cacheCredentialsisfalseby default. When enabled, snapshots contain bearer tokens/headers — treat the store as a secret store and namespace cache keys by principal in multi-tenant setups.
const [github, linear] = await Promise.all([
createMCPTools({ url: githubUrl, auth: gh, toolNamePrefix: 'github_' }),
createMCPTools({ url: linearUrl, auth: ln, toolNamePrefix: 'linear_' }),
]);
const result = callModel(client, {
model,
input: 'Find the Linear issue linked to GitHub PR #42.',
tools: [...github.tools, ...linear.tools],
});
| Option | Description |
|---|---|
url | Remote MCP server endpoint. |
transport | 'streamableHttp' (default, falls back to SSE) or 'sse'. |
auth | Bearer token, headers, or an OAuthClientProvider. |
toolNamePrefix | Prefix every wrapped tool name. |
includeTools / excludeTools | Allow/deny lists by MCP tool name. |
onUnconvertibleSchema | 'looseLeaf' (default) or 'throw' for exotic JSON Schema. |
cache / cacheCredentials / staleness | Caching controls. |
resources | Expose synthetic list_resources / read_resource tools (default on). |
emitProgress | Stream MCP progress as generator-tool events (default on). |
autoRefreshOnListChanged | Re-list on tools/list_changed (default on). |
onElicitation | Handle server elicitation requests; auto-declines when omitted. |
signal | Abort signal threaded into every tool call. |
Apache-2.0
FAQs
Expose remote MCP server tools (Streamable HTTP / SSE) as tools for @openrouter/agent's callModel, with serializable caching and pluggable auth.
We found that @openrouter/mcp demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 9 open source maintainers collaborating on the project.

Security News
It has been one year since Shai-Hulud made its first appearance on npm.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.

Security News
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.