@openrouter/mcp 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +127 -0
  2. package/esm/auth/auth-resolver.d.ts +14 -0
  3. package/esm/auth/auth-resolver.d.ts.map +1 -0
  4. package/esm/auth/auth-resolver.js +27 -0
  5. package/esm/auth/auth-resolver.js.map +1 -0
  6. package/esm/auth/auth-types.d.ts +25 -0
  7. package/esm/auth/auth-types.d.ts.map +1 -0
  8. package/esm/auth/auth-types.js +4 -0
  9. package/esm/auth/auth-types.js.map +1 -0
  10. package/esm/build-tools.d.ts +27 -0
  11. package/esm/build-tools.d.ts.map +1 -0
  12. package/esm/build-tools.js +77 -0
  13. package/esm/build-tools.js.map +1 -0
  14. package/esm/cache/cache-store.d.ts +24 -0
  15. package/esm/cache/cache-store.d.ts.map +1 -0
  16. package/esm/cache/cache-store.js +20 -0
  17. package/esm/cache/cache-store.js.map +1 -0
  18. package/esm/cache/cache-types.d.ts +54 -0
  19. package/esm/cache/cache-types.d.ts.map +1 -0
  20. package/esm/cache/cache-types.js +41 -0
  21. package/esm/cache/cache-types.js.map +1 -0
  22. package/esm/cache/serialize.d.ts +25 -0
  23. package/esm/cache/serialize.d.ts.map +1 -0
  24. package/esm/cache/serialize.js +85 -0
  25. package/esm/cache/serialize.js.map +1 -0
  26. package/esm/create-mcp-tools.d.ts +13 -0
  27. package/esm/create-mcp-tools.d.ts.map +1 -0
  28. package/esm/create-mcp-tools.js +75 -0
  29. package/esm/create-mcp-tools.js.map +1 -0
  30. package/esm/elicitation.d.ts +11 -0
  31. package/esm/elicitation.d.ts.map +1 -0
  32. package/esm/elicitation.js +51 -0
  33. package/esm/elicitation.js.map +1 -0
  34. package/esm/errors.d.ts +35 -0
  35. package/esm/errors.d.ts.map +1 -0
  36. package/esm/errors.js +39 -0
  37. package/esm/errors.js.map +1 -0
  38. package/esm/handle.d.ts +41 -0
  39. package/esm/handle.d.ts.map +1 -0
  40. package/esm/handle.js +221 -0
  41. package/esm/handle.js.map +1 -0
  42. package/esm/index.d.ts +13 -0
  43. package/esm/index.d.ts.map +1 -0
  44. package/esm/index.js +11 -0
  45. package/esm/index.js.map +1 -0
  46. package/esm/mcp-connection.d.ts +35 -0
  47. package/esm/mcp-connection.d.ts.map +1 -0
  48. package/esm/mcp-connection.js +147 -0
  49. package/esm/mcp-connection.js.map +1 -0
  50. package/esm/rehydrate.d.ts +41 -0
  51. package/esm/rehydrate.d.ts.map +1 -0
  52. package/esm/rehydrate.js +173 -0
  53. package/esm/rehydrate.js.map +1 -0
  54. package/esm/resource-tools.d.ts +17 -0
  55. package/esm/resource-tools.d.ts.map +1 -0
  56. package/esm/resource-tools.js +133 -0
  57. package/esm/resource-tools.js.map +1 -0
  58. package/esm/result-mapper.d.ts +19 -0
  59. package/esm/result-mapper.d.ts.map +1 -0
  60. package/esm/result-mapper.js +40 -0
  61. package/esm/result-mapper.js.map +1 -0
  62. package/esm/schema/json-schema-guards.d.ts +14 -0
  63. package/esm/schema/json-schema-guards.d.ts.map +1 -0
  64. package/esm/schema/json-schema-guards.js +19 -0
  65. package/esm/schema/json-schema-guards.js.map +1 -0
  66. package/esm/schema/json-schema-to-zod.d.ts +20 -0
  67. package/esm/schema/json-schema-to-zod.d.ts.map +1 -0
  68. package/esm/schema/json-schema-to-zod.js +72 -0
  69. package/esm/schema/json-schema-to-zod.js.map +1 -0
  70. package/esm/tool-wrapper.d.ts +26 -0
  71. package/esm/tool-wrapper.d.ts.map +1 -0
  72. package/esm/tool-wrapper.js +118 -0
  73. package/esm/tool-wrapper.js.map +1 -0
  74. package/esm/transport-types.d.ts +3 -0
  75. package/esm/transport-types.d.ts.map +1 -0
  76. package/esm/transport-types.js +2 -0
  77. package/esm/transport-types.js.map +1 -0
  78. package/esm/types.d.ts +104 -0
  79. package/esm/types.d.ts.map +1 -0
  80. package/esm/types.js +2 -0
  81. package/esm/types.js.map +1 -0
  82. package/package.json +72 -0
package/README.md ADDED
@@ -0,0 +1,127 @@
1
+ # @openrouter/mcp
2
+
3
+ Expose the tools of a remote [Model Context Protocol](https://modelcontextprotocol.io) server
4
+ (Streamable HTTP or SSE) as tools you can pass straight into
5
+ [`@openrouter/agent`](https://www.npmjs.com/package/@openrouter/agent)'s `callModel`.
6
+
7
+ - Connect to a non-stdio MCP server, authenticate **once**, and reuse that auth for tool
8
+ discovery and every tool call.
9
+ - Faithful JSON Schema → Zod conversion so the model sees real parameters.
10
+ - Serializable, rehydratable cache so you can skip re-listing (and, opt-in, re-authenticating).
11
+ - Progress streaming, `tools/list_changed` auto-refresh, cancellation, resources, and elicitation.
12
+
13
+ > stdio servers are intentionally out of scope.
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ pnpm add @openrouter/mcp @openrouter/agent
19
+ ```
20
+
21
+ ## Quick start
22
+
23
+ ```ts
24
+ import { OpenRouter } from '@openrouter/agent';
25
+ import { callModel } from '@openrouter/agent/call-model';
26
+ import { createMCPTools } from '@openrouter/mcp';
27
+
28
+ const client = new OpenRouter({ apiKey: process.env.OPENROUTER_API_KEY });
29
+
30
+ const mcp = await createMCPTools({
31
+ url: 'https://mcp.example.com/mcp',
32
+ auth: { kind: 'bearer', token: process.env.MCP_TOKEN },
33
+ });
34
+
35
+ const result = callModel(client, {
36
+ model: 'anthropic/claude-opus-4-8',
37
+ input: 'What are my three most recently updated issues?',
38
+ tools: mcp.tools,
39
+ });
40
+
41
+ console.log(await result.getText());
42
+ await mcp.close();
43
+ ```
44
+
45
+ ## Authentication
46
+
47
+ Auth is supplied once and reused for discovery and every call:
48
+
49
+ ```ts
50
+ // Static bearer token
51
+ auth: { kind: 'bearer', token }
52
+ // Arbitrary headers
53
+ auth: { kind: 'headers', headers: { 'X-API-Key': key } }
54
+ // Pluggable OAuth (you own token refresh/storage)
55
+ auth: { kind: 'oauth', provider }
56
+ ```
57
+
58
+ Prefer an `OAuthClientProvider` over caching static tokens — the transport refreshes through it
59
+ automatically.
60
+
61
+ ## Caching & rehydration
62
+
63
+ Persist a snapshot and rebuild later without a `listTools()` round-trip:
64
+
65
+ ```ts
66
+ import { createMCPTools, rehydrateMCPTools } from '@openrouter/mcp';
67
+
68
+ const mcp = await createMCPTools({ url, auth, cacheCredentials: true });
69
+ const snapshot = await mcp.serialize(); // plain JSON — store anywhere
70
+ await mcp.close();
71
+
72
+ const mcp2 = await rehydrateMCPTools({ snapshot, auth });
73
+ ```
74
+
75
+ Or let a store manage it (rehydrate on hit, connect + write on miss):
76
+
77
+ ```ts
78
+ import { InMemoryMCPCacheStore } from '@openrouter/mcp';
79
+
80
+ const store = new InMemoryMCPCacheStore(); // or your own Redis/DB-backed MCPCacheStore
81
+ const mcp = await createMCPTools({
82
+ url,
83
+ auth,
84
+ cache: { store, key: `mcp:${userId}` },
85
+ staleness: { maxAgeMs: 60 * 60 * 1000 },
86
+ });
87
+ ```
88
+
89
+ > **Security:** `cacheCredentials` is `false` by default. When enabled, snapshots contain bearer
90
+ > tokens/headers — treat the store as a secret store and namespace cache keys by principal in
91
+ > multi-tenant setups.
92
+
93
+ ## Multiple servers
94
+
95
+ ```ts
96
+ const [github, linear] = await Promise.all([
97
+ createMCPTools({ url: githubUrl, auth: gh, toolNamePrefix: 'github_' }),
98
+ createMCPTools({ url: linearUrl, auth: ln, toolNamePrefix: 'linear_' }),
99
+ ]);
100
+
101
+ const result = callModel(client, {
102
+ model,
103
+ input: 'Find the Linear issue linked to GitHub PR #42.',
104
+ tools: [...github.tools, ...linear.tools],
105
+ });
106
+ ```
107
+
108
+ ## Options
109
+
110
+ | Option | Description |
111
+ | --- | --- |
112
+ | `url` | Remote MCP server endpoint. |
113
+ | `transport` | `'streamableHttp'` (default, falls back to SSE) or `'sse'`. |
114
+ | `auth` | Bearer token, headers, or an `OAuthClientProvider`. |
115
+ | `toolNamePrefix` | Prefix every wrapped tool name. |
116
+ | `includeTools` / `excludeTools` | Allow/deny lists by MCP tool name. |
117
+ | `onUnconvertibleSchema` | `'looseLeaf'` (default) or `'throw'` for exotic JSON Schema. |
118
+ | `cache` / `cacheCredentials` / `staleness` | Caching controls. |
119
+ | `resources` | Expose synthetic `list_resources` / `read_resource` tools (default on). |
120
+ | `emitProgress` | Stream MCP progress as generator-tool events (default on). |
121
+ | `autoRefreshOnListChanged` | Re-list on `tools/list_changed` (default on). |
122
+ | `onElicitation` | Handle server elicitation requests; auto-declines when omitted. |
123
+ | `signal` | Abort signal threaded into every tool call. |
124
+
125
+ ## License
126
+
127
+ Apache-2.0
@@ -0,0 +1,14 @@
1
+ import type { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js';
2
+ import type { MCPAuth } from './auth-types.js';
3
+ /**
4
+ * The transport-level pieces derived from an {@link MCPAuth}: static headers to
5
+ * merge into `requestInit`, and/or an OAuth provider to hand to the transport.
6
+ * Both flow into the same connected client, so discovery and tool calls share
7
+ * one authenticated session.
8
+ */
9
+ export interface ResolvedAuth {
10
+ headers: Record<string, string>;
11
+ authProvider?: OAuthClientProvider;
12
+ }
13
+ export declare function resolveAuth(auth: MCPAuth | undefined): ResolvedAuth;
14
+ //# sourceMappingURL=auth-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-resolver.d.ts","sourceRoot":"","sources":["../../src/auth/auth-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AACpF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,YAAY,CAyBnE"}
@@ -0,0 +1,27 @@
1
+ export function resolveAuth(auth) {
2
+ if (auth === undefined) {
3
+ return {
4
+ headers: {},
5
+ };
6
+ }
7
+ switch (auth.kind) {
8
+ case 'bearer':
9
+ return {
10
+ headers: {
11
+ Authorization: `Bearer ${auth.token}`,
12
+ },
13
+ };
14
+ case 'headers':
15
+ return {
16
+ headers: {
17
+ ...auth.headers,
18
+ },
19
+ };
20
+ case 'oauth':
21
+ return {
22
+ headers: {},
23
+ authProvider: auth.provider,
24
+ };
25
+ }
26
+ }
27
+ //# sourceMappingURL=auth-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-resolver.js","sourceRoot":"","sources":["../../src/auth/auth-resolver.ts"],"names":[],"mappings":"AAcA,MAAM,UAAU,WAAW,CAAC,IAAyB;IACnD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO;YACL,OAAO,EAAE,EAAE;SACZ,CAAC;IACJ,CAAC;IACD,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,QAAQ;YACX,OAAO;gBACL,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;iBACtC;aACF,CAAC;QACJ,KAAK,SAAS;YACZ,OAAO;gBACL,OAAO,EAAE;oBACP,GAAG,IAAI,CAAC,OAAO;iBAChB;aACF,CAAC;QACJ,KAAK,OAAO;YACV,OAAO;gBACL,OAAO,EAAE,EAAE;gBACX,YAAY,EAAE,IAAI,CAAC,QAAQ;aAC5B,CAAC;IACN,CAAC;AACH,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js';
2
+ /**
3
+ * Authentication for a remote MCP server. Supplied once and reused by the
4
+ * connected client for tool discovery and every subsequent tool call.
5
+ *
6
+ * - `bearer`: a static bearer token sent as `Authorization: Bearer <token>`.
7
+ * - `headers`: arbitrary static headers (e.g. API keys, custom auth schemes).
8
+ * - `oauth`: a user-supplied {@link OAuthClientProvider} that owns token
9
+ * acquisition/refresh. Preferred over caching static tokens.
10
+ */
11
+ export type MCPAuth = {
12
+ kind: 'bearer';
13
+ token: string;
14
+ } | {
15
+ kind: 'headers';
16
+ headers: Readonly<Record<string, string>>;
17
+ } | {
18
+ kind: 'oauth';
19
+ provider: OAuthClientProvider;
20
+ };
21
+ export declare function isOAuthAuth(auth: MCPAuth | undefined): auth is {
22
+ kind: 'oauth';
23
+ provider: OAuthClientProvider;
24
+ };
25
+ //# sourceMappingURL=auth-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-types.d.ts","sourceRoot":"","sources":["../../src/auth/auth-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAEpF;;;;;;;;GAQG;AACH,MAAM,MAAM,OAAO,GACf;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,GACD;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC3C,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,mBAAmB,CAAC;CAC/B,CAAC;AAEN,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,IAAI;IAC9D,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,mBAAmB,CAAC;CAC/B,CAEA"}
@@ -0,0 +1,4 @@
1
+ export function isOAuthAuth(auth) {
2
+ return auth?.kind === 'oauth';
3
+ }
4
+ //# sourceMappingURL=auth-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-types.js","sourceRoot":"","sources":["../../src/auth/auth-types.ts"],"names":[],"mappings":"AAyBA,MAAM,UAAU,WAAW,CAAC,IAAyB;IAInD,OAAO,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC;AAChC,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
+ import type { Tool } from '@openrouter/agent/tool-types';
3
+ import type { UnconvertibleSchemaMode } from './schema/json-schema-to-zod.js';
4
+ import type { McpToolDef } from './tool-wrapper.js';
5
+ import type { ResourcesOption } from './types.js';
6
+ export interface BuildToolsOptions {
7
+ client: Client;
8
+ toolDefs: readonly McpToolDef[];
9
+ namePrefix?: string;
10
+ includeTools?: readonly string[];
11
+ excludeTools?: readonly string[];
12
+ schemaMode?: UnconvertibleSchemaMode;
13
+ emitProgress?: boolean;
14
+ signal?: AbortSignal;
15
+ resources?: ResourcesOption;
16
+ /** Whether the server advertised the resources capability. */
17
+ serverHasResources: boolean;
18
+ }
19
+ /** Apply allow/deny filters to discovered MCP tool definitions. */
20
+ export declare function filterToolDefs(defs: readonly McpToolDef[], includeTools?: readonly string[], excludeTools?: readonly string[]): McpToolDef[];
21
+ /**
22
+ * Build the full ordered tool list for a handle: filtered + wrapped MCP tools,
23
+ * plus synthetic resource tools when enabled. Throws on a name collision so two
24
+ * tools never silently shadow each other in `callModel`.
25
+ */
26
+ export declare function buildTools(options: BuildToolsOptions): Tool[];
27
+ //# sourceMappingURL=build-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-tools.d.ts","sourceRoot":"","sources":["../src/build-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAGzD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,UAAU,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,UAAU,CAAC,EAAE,uBAAuB,CAAC;IACrC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,8DAA8D;IAC9D,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AASD,mEAAmE;AACnE,wBAAgB,cAAc,CAC5B,IAAI,EAAE,SAAS,UAAU,EAAE,EAC3B,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,EAChC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,GAC/B,UAAU,EAAE,CASd;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,EAAE,CAqC7D"}
@@ -0,0 +1,77 @@
1
+ import { MCPError } from './errors.js';
2
+ import { buildResourceTools } from './resource-tools.js';
3
+ import { wrapMcpTool } from './tool-wrapper.js';
4
+ function resourcesEnabled(option) {
5
+ if (option === undefined) {
6
+ return true;
7
+ }
8
+ return option === true || (typeof option === 'object' && option !== null);
9
+ }
10
+ /** Apply allow/deny filters to discovered MCP tool definitions. */
11
+ export function filterToolDefs(defs, includeTools, excludeTools) {
12
+ const include = includeTools !== undefined ? new Set(includeTools) : undefined;
13
+ const exclude = new Set(excludeTools ?? []);
14
+ return defs.filter((def) => {
15
+ if (include !== undefined && !include.has(def.name)) {
16
+ return false;
17
+ }
18
+ return !exclude.has(def.name);
19
+ });
20
+ }
21
+ /**
22
+ * Build the full ordered tool list for a handle: filtered + wrapped MCP tools,
23
+ * plus synthetic resource tools when enabled. Throws on a name collision so two
24
+ * tools never silently shadow each other in `callModel`.
25
+ */
26
+ export function buildTools(options) {
27
+ const filtered = filterToolDefs(options.toolDefs, options.includeTools, options.excludeTools);
28
+ const wrapOptions = {
29
+ client: options.client,
30
+ ...(options.namePrefix !== undefined && {
31
+ namePrefix: options.namePrefix,
32
+ }),
33
+ ...(options.schemaMode !== undefined && {
34
+ schemaMode: options.schemaMode,
35
+ }),
36
+ ...(options.emitProgress !== undefined && {
37
+ emitProgress: options.emitProgress,
38
+ }),
39
+ ...(options.signal !== undefined && {
40
+ signal: options.signal,
41
+ }),
42
+ };
43
+ const tools = filtered.map((def) => wrapMcpTool(def, wrapOptions));
44
+ if (options.serverHasResources && resourcesEnabled(options.resources)) {
45
+ tools.push(...buildResourceTools({
46
+ client: options.client,
47
+ ...(options.namePrefix !== undefined && {
48
+ namePrefix: options.namePrefix,
49
+ }),
50
+ ...(options.signal !== undefined && {
51
+ signal: options.signal,
52
+ }),
53
+ }));
54
+ }
55
+ assertNoDuplicateNames(tools);
56
+ return tools;
57
+ }
58
+ function toolName(tool) {
59
+ if ('function' in tool && typeof tool.function.name === 'string') {
60
+ return tool.function.name;
61
+ }
62
+ return undefined;
63
+ }
64
+ function assertNoDuplicateNames(tools) {
65
+ const seen = new Set();
66
+ for (const tool of tools) {
67
+ const name = toolName(tool);
68
+ if (name === undefined) {
69
+ continue;
70
+ }
71
+ if (seen.has(name)) {
72
+ throw new MCPError(`Duplicate tool name "${name}". Use toolNamePrefix or excludeTools to disambiguate.`);
73
+ }
74
+ seen.add(name);
75
+ }
76
+ }
77
+ //# sourceMappingURL=build-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-tools.js","sourceRoot":"","sources":["../src/build-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { SerializedMCPServer } from './cache-types.js';
2
+ /**
3
+ * Pluggable cache for MCP server snapshots. Implement this to back the cache
4
+ * with Redis, a database, or the filesystem. All methods may be async.
5
+ *
6
+ * SECURITY: when `cacheCredentials` is enabled, stored snapshots contain bearer
7
+ * tokens/headers — treat the store as a secret store (encrypt at rest, scope
8
+ * access) and namespace keys by principal in multi-tenant setups.
9
+ */
10
+ export interface MCPCacheStore {
11
+ get(key: string): Promise<SerializedMCPServer | null> | SerializedMCPServer | null;
12
+ set(key: string, value: SerializedMCPServer): Promise<void> | void;
13
+ delete?(key: string): Promise<void> | void;
14
+ }
15
+ /** Default in-process cache backed by a `Map`. Not shared across processes. */
16
+ export declare class InMemoryMCPCacheStore implements MCPCacheStore {
17
+ private readonly entries;
18
+ get(key: string): SerializedMCPServer | null;
19
+ set(key: string, value: SerializedMCPServer): void;
20
+ delete(key: string): void;
21
+ }
22
+ /** Default cache key for a server URL. Override via `cache.key` for multi-tenant. */
23
+ export declare function defaultCacheKey(url: string): string;
24
+ //# sourceMappingURL=cache-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-store.d.ts","sourceRoot":"","sources":["../../src/cache/cache-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE5D;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,GAAG,mBAAmB,GAAG,IAAI,CAAC;IACnF,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACnE,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC5C;AAED,+EAA+E;AAC/E,qBAAa,qBAAsB,YAAW,aAAa;IACzD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0C;IAElE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI;IAI5C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,IAAI;IAIlD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAG1B;AAED,qFAAqF;AACrF,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEnD"}
@@ -0,0 +1,20 @@
1
+ /** Default in-process cache backed by a `Map`. Not shared across processes. */
2
+ export class InMemoryMCPCacheStore {
3
+ constructor() {
4
+ this.entries = new Map();
5
+ }
6
+ get(key) {
7
+ return this.entries.get(key) ?? null;
8
+ }
9
+ set(key, value) {
10
+ this.entries.set(key, value);
11
+ }
12
+ delete(key) {
13
+ this.entries.delete(key);
14
+ }
15
+ }
16
+ /** Default cache key for a server URL. Override via `cache.key` for multi-tenant. */
17
+ export function defaultCacheKey(url) {
18
+ return `openrouter-mcp:${url}`;
19
+ }
20
+ //# sourceMappingURL=cache-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-store.js","sourceRoot":"","sources":["../../src/cache/cache-store.ts"],"names":[],"mappings":"AAgBA,+EAA+E;AAC/E,MAAM,OAAO,qBAAqB;IAAlC;QACmB,YAAO,GAAG,IAAI,GAAG,EAA+B,CAAC;IAapE,CAAC;IAXC,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;IACvC,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,KAA0B;QACzC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;CACF;AAED,qFAAqF;AACrF,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,OAAO,kBAAkB,GAAG,EAAE,CAAC;AACjC,CAAC"}
@@ -0,0 +1,54 @@
1
+ import type { MCPTransportKind } from '../transport-types.js';
2
+ /** A discovered tool definition as stored in a cache snapshot. */
3
+ export interface SerializedMCPToolDef {
4
+ name: string;
5
+ description?: string;
6
+ inputSchema: Readonly<Record<string, unknown>>;
7
+ outputSchema?: Readonly<Record<string, unknown>>;
8
+ }
9
+ /** OAuth/bearer token material, persisted only when `cacheCredentials` is on. */
10
+ export interface SerializedTokenSet {
11
+ accessToken: string;
12
+ tokenType?: string;
13
+ refreshToken?: string;
14
+ /** Epoch ms; absence means unknown/no declared expiry. */
15
+ expiresAt?: number;
16
+ scope?: string;
17
+ }
18
+ /**
19
+ * Serializable snapshot of a connected MCP server: enough to rebuild the tool
20
+ * set (and, opt-in, reconnect with cached credentials) without re-listing or
21
+ * re-authenticating.
22
+ */
23
+ export interface SerializedMCPServer {
24
+ version: 1;
25
+ url: string;
26
+ transport: MCPTransportKind;
27
+ serverInfo?: {
28
+ name?: string;
29
+ version?: string;
30
+ };
31
+ capabilities?: Readonly<Record<string, unknown>>;
32
+ sessionId?: string;
33
+ tools: SerializedMCPToolDef[];
34
+ auth?: {
35
+ headers?: Readonly<Record<string, string>>;
36
+ tokens?: SerializedTokenSet;
37
+ };
38
+ cachedAt: number;
39
+ }
40
+ /**
41
+ * The shared "valid `cachedAt`" rule: a finite, non-negative epoch (ms).
42
+ * Consumed by both the read-side snapshot validator and the write-side
43
+ * serializer so the two can't drift. Rejecting negatives keeps the invariant
44
+ * honest at the boundary rather than relying on downstream maxAge arithmetic to
45
+ * fail-safe on a clock-skewed or garbage value.
46
+ */
47
+ export declare function isFiniteEpoch(value: unknown): value is number;
48
+ /**
49
+ * Validate an untrusted value as a {@link SerializedMCPServer}. Cache stores may
50
+ * be backed by a DB or another org member's data, so snapshots are checked
51
+ * structurally before use — never trusted by shape alone.
52
+ */
53
+ export declare function isSerializedMCPServer(value: unknown): value is SerializedMCPServer;
54
+ //# sourceMappingURL=cache-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-types.d.ts","sourceRoot":"","sources":["../../src/cache/cache-types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,kEAAkE;AAClE,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/C,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAClD;AAED,iFAAiF;AACjF,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,CAAC,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,gBAAgB,CAAC;IAC5B,UAAU,CAAC,EAAE;QACX,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,oBAAoB,EAAE,CAAC;IAC9B,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,EAAE,kBAAkB,CAAC;KAC7B,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;CAClB;AAMD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE7D;AAUD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CAelF"}
@@ -0,0 +1,41 @@
1
+ import { isJsonSchemaObject } from '../schema/json-schema-guards.js';
2
+ function isTransportKind(value) {
3
+ return value === 'streamableHttp' || value === 'sse';
4
+ }
5
+ /**
6
+ * The shared "valid `cachedAt`" rule: a finite, non-negative epoch (ms).
7
+ * Consumed by both the read-side snapshot validator and the write-side
8
+ * serializer so the two can't drift. Rejecting negatives keeps the invariant
9
+ * honest at the boundary rather than relying on downstream maxAge arithmetic to
10
+ * fail-safe on a clock-skewed or garbage value.
11
+ */
12
+ export function isFiniteEpoch(value) {
13
+ return typeof value === 'number' && Number.isFinite(value) && value >= 0;
14
+ }
15
+ function isSerializedToolDef(value) {
16
+ return (isJsonSchemaObject(value) &&
17
+ typeof value['name'] === 'string' &&
18
+ isJsonSchemaObject(value['inputSchema']));
19
+ }
20
+ /**
21
+ * Validate an untrusted value as a {@link SerializedMCPServer}. Cache stores may
22
+ * be backed by a DB or another org member's data, so snapshots are checked
23
+ * structurally before use — never trusted by shape alone.
24
+ */
25
+ export function isSerializedMCPServer(value) {
26
+ if (!isJsonSchemaObject(value)) {
27
+ return false;
28
+ }
29
+ if (value['version'] !== 1) {
30
+ return false;
31
+ }
32
+ if (typeof value['url'] !== 'string' || !isTransportKind(value['transport'])) {
33
+ return false;
34
+ }
35
+ if (!isFiniteEpoch(value['cachedAt'])) {
36
+ return false;
37
+ }
38
+ const { tools } = value;
39
+ return Array.isArray(tools) && tools.every(isSerializedToolDef);
40
+ }
41
+ //# sourceMappingURL=cache-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-types.js","sourceRoot":"","sources":["../../src/cache/cache-types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AA4CrE,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,KAAK,KAAK,gBAAgB,IAAI,KAAK,KAAK,KAAK,CAAC;AACvD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAc;IACzC,OAAO,CACL,kBAAkB,CAAC,KAAK,CAAC;QACzB,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,QAAQ;QACjC,kBAAkB,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CACzC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,QAAQ,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC;QAC7E,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IACxB,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;AAClE,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { MCPAuth } from '../auth/auth-types.js';
2
+ import type { McpToolDef } from '../tool-wrapper.js';
3
+ import type { MCPTransportKind } from '../types.js';
4
+ import type { SerializedMCPServer } from './cache-types.js';
5
+ export interface SerializeInput {
6
+ url: string;
7
+ transport: MCPTransportKind;
8
+ toolDefs: readonly McpToolDef[];
9
+ serverInfo?: {
10
+ name?: string;
11
+ version?: string;
12
+ };
13
+ capabilities?: Readonly<Record<string, unknown>>;
14
+ sessionId?: string;
15
+ auth?: MCPAuth;
16
+ cacheCredentials: boolean;
17
+ cachedAt: number;
18
+ }
19
+ /**
20
+ * Build a serializable snapshot. Credentials (tokens/headers, session id) are
21
+ * included only when `cacheCredentials` is true; otherwise the snapshot holds
22
+ * just the structural data needed to rebuild the tool set after a fresh auth.
23
+ */
24
+ export declare function serializeServer(input: SerializeInput): Promise<SerializedMCPServer>;
25
+ //# sourceMappingURL=serialize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../src/cache/serialize.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,mBAAmB,EAAsB,MAAM,kBAAkB,CAAC;AAGhF,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,gBAAgB,CAAC;IAC5B,QAAQ,EAAE,SAAS,UAAU,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE;QACX,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAgDD;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAqCzF"}
@@ -0,0 +1,85 @@
1
+ import { resolveAuth } from '../auth/auth-resolver.js';
2
+ import { isFiniteEpoch } from './cache-types.js';
3
+ /** Pull a serializable token set from an OAuth provider, if it has tokens. */
4
+ async function tokensFromProvider(provider) {
5
+ const tokens = await provider.tokens();
6
+ if (tokens === undefined) {
7
+ return undefined;
8
+ }
9
+ const expiresInMs = typeof tokens.expires_in === 'number' ? tokens.expires_in * 1000 : undefined;
10
+ return {
11
+ accessToken: tokens.access_token,
12
+ ...(typeof tokens.token_type === 'string' && {
13
+ tokenType: tokens.token_type,
14
+ }),
15
+ ...(typeof tokens.refresh_token === 'string' && {
16
+ refreshToken: tokens.refresh_token,
17
+ }),
18
+ ...(typeof tokens.scope === 'string' && {
19
+ scope: tokens.scope,
20
+ }),
21
+ ...(expiresInMs !== undefined && {
22
+ expiresAt: Date.now() + expiresInMs,
23
+ }),
24
+ };
25
+ }
26
+ async function buildAuthBlock(auth) {
27
+ if (auth === undefined) {
28
+ return undefined;
29
+ }
30
+ if (auth.kind === 'oauth') {
31
+ const tokens = await tokensFromProvider(auth.provider);
32
+ return tokens !== undefined
33
+ ? {
34
+ tokens,
35
+ }
36
+ : undefined;
37
+ }
38
+ const { headers } = resolveAuth(auth);
39
+ return Object.keys(headers).length > 0
40
+ ? {
41
+ headers,
42
+ }
43
+ : undefined;
44
+ }
45
+ /**
46
+ * Build a serializable snapshot. Credentials (tokens/headers, session id) are
47
+ * included only when `cacheCredentials` is true; otherwise the snapshot holds
48
+ * just the structural data needed to rebuild the tool set after a fresh auth.
49
+ */
50
+ export async function serializeServer(input) {
51
+ const tools = input.toolDefs.map((def) => ({
52
+ name: def.name,
53
+ ...(def.description !== undefined && {
54
+ description: def.description,
55
+ }),
56
+ inputSchema: def.inputSchema,
57
+ ...(def.outputSchema !== undefined && {
58
+ outputSchema: def.outputSchema,
59
+ }),
60
+ }));
61
+ const snapshot = {
62
+ version: 1,
63
+ url: input.url,
64
+ transport: input.transport,
65
+ ...(input.serverInfo !== undefined && {
66
+ serverInfo: input.serverInfo,
67
+ }),
68
+ ...(input.capabilities !== undefined && {
69
+ capabilities: input.capabilities,
70
+ }),
71
+ tools,
72
+ cachedAt: isFiniteEpoch(input.cachedAt) ? input.cachedAt : Date.now(),
73
+ };
74
+ if (input.cacheCredentials) {
75
+ const auth = await buildAuthBlock(input.auth);
76
+ if (auth !== undefined) {
77
+ snapshot.auth = auth;
78
+ }
79
+ if (input.sessionId !== undefined) {
80
+ snapshot.sessionId = input.sessionId;
81
+ }
82
+ }
83
+ return snapshot;
84
+ }
85
+ //# sourceMappingURL=serialize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialize.js","sourceRoot":"","sources":["../../src/cache/serialize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { SerializedMCPServer } from './cache/cache-types.js';
2
+ import type { CreateMCPToolsOptions, MCPToolsHandle } from './types.js';
3
+ /**
4
+ * Connect to a remote MCP server, discover its tools, and return a handle whose
5
+ * `.tools` can be passed straight into `callModel({ tools })`. Auth is supplied
6
+ * once and reused for discovery and every subsequent tool call.
7
+ *
8
+ * When `cache` is provided, a valid non-stale snapshot is rehydrated instead of
9
+ * re-listing; otherwise the fresh result is written back to the cache.
10
+ */
11
+ export declare function createMCPTools(options: CreateMCPToolsOptions): Promise<MCPToolsHandle>;
12
+ export type { SerializedMCPServer };
13
+ //# sourceMappingURL=create-mcp-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-mcp-tools.d.ts","sourceRoot":"","sources":["../src/create-mcp-tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAKlE,OAAO,KAAK,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAExE;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,CAAC,CAY5F;AA8DD,YAAY,EAAE,mBAAmB,EAAE,CAAC"}