@winstonsayno/mcp-gateway 2.5.0 → 2.6.0
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.
- package/CHANGELOG.md +15 -0
- package/README.md +9 -0
- package/dist/edge/adapters.d.ts +38 -0
- package/dist/edge/adapters.d.ts.map +1 -0
- package/dist/edge/adapters.js +97 -0
- package/dist/edge/adapters.js.map +1 -0
- package/dist/edge/entry.d.ts +8 -0
- package/dist/edge/entry.d.ts.map +1 -0
- package/dist/edge/entry.js +7 -0
- package/dist/edge/entry.js.map +1 -0
- package/dist/edge/index.d.ts +73 -0
- package/dist/edge/index.d.ts.map +1 -0
- package/dist/edge/index.js +341 -0
- package/dist/edge/index.js.map +1 -0
- package/package.json +5 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
## [2.6.0] - 2026-10-07
|
|
13
|
+
|
|
14
|
+
Edge runtimes: Cloudflare Workers, Deno and Bun adapters for the HTTP transport.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- **`@winstonsayno/mcp-gateway/edge`** (new package export): a dependency-free Fetch-API gateway —
|
|
18
|
+
`createEdgeGateway({ servers, apiKeys, toolNaming, corsOrigins })` → `fetch(request)`. Fronts remote Streamable
|
|
19
|
+
HTTP upstreams (sessions, JSON and SSE replies, paging, re-initialize on `404`), aggregates tools (collision or
|
|
20
|
+
always-prefixed names, per-server allow / deny), serves `/mcp` (initialize, ping, tools/list, tools/call, batches;
|
|
21
|
+
stateless JSON) and `GET /api/v1/health`, `GET /api/v1/tools`, `POST /api/v1/tools/call`. API keys plain or
|
|
22
|
+
`sha256:` (Web Crypto), constant-time compare, CORS.
|
|
23
|
+
- **Adapters**: `workersHandler()` (Cloudflare Workers module syntax, config from bindings), `serveDeno()`,
|
|
24
|
+
`serveBun()`, `serveNode()`; `configFromEnv()`. Examples in `examples/edge` (worker + `wrangler.toml`, Deno, Bun).
|
|
25
|
+
- Docs: [Edge runtimes](docs/guides/edge.md).
|
|
26
|
+
|
|
12
27
|
## [2.5.0] - 2026-10-07
|
|
13
28
|
|
|
14
29
|
Usage quotas and metering export.
|
package/README.md
CHANGED
|
@@ -579,6 +579,15 @@ await gateway.start();
|
|
|
579
579
|
process.on('SIGTERM', () => gateway.stop());
|
|
580
580
|
```
|
|
581
581
|
|
|
582
|
+
## What's New in v2.6
|
|
583
|
+
|
|
584
|
+
| Feature | Description |
|
|
585
|
+
|---------|-------------|
|
|
586
|
+
| **Edge gateway** | `@winstonsayno/mcp-gateway/edge`: Fetch-API gateway for remote MCP servers, no Node dependencies |
|
|
587
|
+
| **Runtime adapters** | Cloudflare Workers, Deno, Bun (and Node) — [guide](docs/guides/edge.md) |
|
|
588
|
+
|
|
589
|
+
Details: [CHANGELOG](CHANGELOG.md).
|
|
590
|
+
|
|
582
591
|
## What's New in v2.5
|
|
583
592
|
|
|
584
593
|
| Feature | Description |
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime adapters for the edge gateway (`createEdgeGateway`).
|
|
3
|
+
*
|
|
4
|
+
* - Cloudflare Workers: `export default workersHandler((env) => config)`
|
|
5
|
+
* - Deno: `serveDeno(config, { port: 8000 })`
|
|
6
|
+
* - Bun: `serveBun(config, { port: 3000 })`
|
|
7
|
+
* - Node: `serveNode(config, { port })` (uses `node:http` through a dynamic import)
|
|
8
|
+
*
|
|
9
|
+
* Config can also come from environment variables with `configFromEnv(env)`:
|
|
10
|
+
* `MCP_GATEWAY_SERVERS` (JSON array of `{ id, url, headers?, tools? }`),
|
|
11
|
+
* `MCP_GATEWAY_API_KEYS` (comma separated), `MCP_GATEWAY_TOOL_NAMING`,
|
|
12
|
+
* `MCP_GATEWAY_CORS_ORIGINS`.
|
|
13
|
+
*
|
|
14
|
+
* @module edge/adapters
|
|
15
|
+
*/
|
|
16
|
+
import { type EdgeConfig } from './index.js';
|
|
17
|
+
type Env = Record<string, unknown>;
|
|
18
|
+
/** Edge config from environment variables / Worker bindings. */
|
|
19
|
+
export declare function configFromEnv(env: Env): EdgeConfig;
|
|
20
|
+
/** Cloudflare Workers module handler. The gateway (and its upstream sessions) is reused per isolate. */
|
|
21
|
+
export declare function workersHandler(build?: (env: Env) => EdgeConfig): {
|
|
22
|
+
fetch(request: Request, env?: Env): Promise<Response>;
|
|
23
|
+
};
|
|
24
|
+
interface ServeOptions {
|
|
25
|
+
port?: number;
|
|
26
|
+
hostname?: string;
|
|
27
|
+
}
|
|
28
|
+
/** Deno: `Deno.serve`. */
|
|
29
|
+
export declare function serveDeno(config: EdgeConfig, opts?: ServeOptions): unknown;
|
|
30
|
+
/** Bun: `Bun.serve`. */
|
|
31
|
+
export declare function serveBun(config: EdgeConfig, opts?: ServeOptions): unknown;
|
|
32
|
+
/** Node: serve the edge handler with `node:http` (handy for local testing of an edge deployment). */
|
|
33
|
+
export declare function serveNode(config: EdgeConfig, opts?: ServeOptions): Promise<{
|
|
34
|
+
port: number;
|
|
35
|
+
close: () => Promise<void>;
|
|
36
|
+
}>;
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=adapters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../../src/edge/adapters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAqB,KAAK,UAAU,EAAoB,MAAM,YAAY,CAAC;AAElF,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnC,gEAAgE;AAChE,wBAAgB,aAAa,CAAC,GAAG,EAAE,GAAG,GAAG,UAAU,CAgBlD;AAED,wGAAwG;AACxG,wBAAgB,cAAc,CAAC,KAAK,GAAE,CAAC,GAAG,EAAE,GAAG,KAAK,UAA0B;mBAI3D,OAAO,QAAO,GAAG,GAAQ,OAAO,CAAC,QAAQ,CAAC;EAQ5D;AAED,UAAU,YAAY;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,0BAA0B;AAC1B,wBAAgB,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,GAAE,YAAiB,GAAG,OAAO,CAK9E;AAED,wBAAwB;AACxB,wBAAgB,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,GAAE,YAAiB,GAAG,OAAO,CAK7E;AAED,qGAAqG;AACrG,wBAAsB,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAyBlI"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime adapters for the edge gateway (`createEdgeGateway`).
|
|
3
|
+
*
|
|
4
|
+
* - Cloudflare Workers: `export default workersHandler((env) => config)`
|
|
5
|
+
* - Deno: `serveDeno(config, { port: 8000 })`
|
|
6
|
+
* - Bun: `serveBun(config, { port: 3000 })`
|
|
7
|
+
* - Node: `serveNode(config, { port })` (uses `node:http` through a dynamic import)
|
|
8
|
+
*
|
|
9
|
+
* Config can also come from environment variables with `configFromEnv(env)`:
|
|
10
|
+
* `MCP_GATEWAY_SERVERS` (JSON array of `{ id, url, headers?, tools? }`),
|
|
11
|
+
* `MCP_GATEWAY_API_KEYS` (comma separated), `MCP_GATEWAY_TOOL_NAMING`,
|
|
12
|
+
* `MCP_GATEWAY_CORS_ORIGINS`.
|
|
13
|
+
*
|
|
14
|
+
* @module edge/adapters
|
|
15
|
+
*/
|
|
16
|
+
import { createEdgeGateway } from './index.js';
|
|
17
|
+
/** Edge config from environment variables / Worker bindings. */
|
|
18
|
+
export function configFromEnv(env) {
|
|
19
|
+
const str = (k) => (typeof env[k] === 'string' ? env[k] : undefined);
|
|
20
|
+
let servers = [];
|
|
21
|
+
const raw = str('MCP_GATEWAY_SERVERS');
|
|
22
|
+
if (raw) {
|
|
23
|
+
const parsed = JSON.parse(raw);
|
|
24
|
+
if (!Array.isArray(parsed))
|
|
25
|
+
throw new Error('MCP_GATEWAY_SERVERS must be a JSON array');
|
|
26
|
+
servers = parsed;
|
|
27
|
+
}
|
|
28
|
+
const naming = str('MCP_GATEWAY_TOOL_NAMING');
|
|
29
|
+
return {
|
|
30
|
+
servers,
|
|
31
|
+
apiKeys: str('MCP_GATEWAY_API_KEYS')?.split(',').map((k) => k.trim()).filter(Boolean),
|
|
32
|
+
toolNaming: naming === 'prefix' ? 'prefix' : 'auto',
|
|
33
|
+
corsOrigins: str('MCP_GATEWAY_CORS_ORIGINS')?.split(',').map((o) => o.trim()).filter(Boolean),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** Cloudflare Workers module handler. The gateway (and its upstream sessions) is reused per isolate. */
|
|
37
|
+
export function workersHandler(build = configFromEnv) {
|
|
38
|
+
let gw;
|
|
39
|
+
let built;
|
|
40
|
+
return {
|
|
41
|
+
fetch(request, env = {}) {
|
|
42
|
+
if (!gw || built !== env) {
|
|
43
|
+
gw = createEdgeGateway(build(env));
|
|
44
|
+
built = env;
|
|
45
|
+
}
|
|
46
|
+
return gw.fetch(request);
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/** Deno: `Deno.serve`. */
|
|
51
|
+
export function serveDeno(config, opts = {}) {
|
|
52
|
+
const Deno = globalThis.Deno;
|
|
53
|
+
if (!Deno)
|
|
54
|
+
throw new Error('serveDeno() needs the Deno runtime');
|
|
55
|
+
const gw = createEdgeGateway(config);
|
|
56
|
+
return Deno.serve({ port: opts.port ?? 8000, hostname: opts.hostname ?? '0.0.0.0' }, (r) => gw.fetch(r));
|
|
57
|
+
}
|
|
58
|
+
/** Bun: `Bun.serve`. */
|
|
59
|
+
export function serveBun(config, opts = {}) {
|
|
60
|
+
const Bun = globalThis.Bun;
|
|
61
|
+
if (!Bun)
|
|
62
|
+
throw new Error('serveBun() needs the Bun runtime');
|
|
63
|
+
const gw = createEdgeGateway(config);
|
|
64
|
+
return Bun.serve({ port: opts.port ?? 3000, hostname: opts.hostname ?? '0.0.0.0', fetch: (r) => gw.fetch(r) });
|
|
65
|
+
}
|
|
66
|
+
/** Node: serve the edge handler with `node:http` (handy for local testing of an edge deployment). */
|
|
67
|
+
export async function serveNode(config, opts = {}) {
|
|
68
|
+
const http = await import('node:http');
|
|
69
|
+
const gw = createEdgeGateway(config);
|
|
70
|
+
const server = http.createServer(async (req, res) => {
|
|
71
|
+
try {
|
|
72
|
+
const chunks = [];
|
|
73
|
+
for await (const c of req)
|
|
74
|
+
chunks.push(c);
|
|
75
|
+
const body = chunks.length ? Buffer.concat(chunks) : undefined;
|
|
76
|
+
const headers = new Headers();
|
|
77
|
+
for (const [k, v] of Object.entries(req.headers))
|
|
78
|
+
if (typeof v === 'string')
|
|
79
|
+
headers.set(k, v);
|
|
80
|
+
const url = `http://${req.headers.host ?? 'localhost'}${req.url ?? '/'}`;
|
|
81
|
+
const r = await gw.fetch(new Request(url, { method: req.method, headers, body: body && req.method !== 'GET' && req.method !== 'HEAD' ? body : undefined }));
|
|
82
|
+
res.writeHead(r.status, Object.fromEntries(r.headers.entries()));
|
|
83
|
+
res.end(Buffer.from(await r.arrayBuffer()));
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
res.writeHead(500, { 'content-type': 'application/json' });
|
|
87
|
+
res.end(JSON.stringify({ error: 'Internal Server Error', message: err instanceof Error ? err.message : String(err) }));
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
await new Promise((resolveListen) => server.listen(opts.port ?? 0, opts.hostname ?? '127.0.0.1', resolveListen));
|
|
91
|
+
const addr = server.address();
|
|
92
|
+
return {
|
|
93
|
+
port: typeof addr === 'object' && addr ? addr.port : 0,
|
|
94
|
+
close: () => new Promise((r) => server.close(() => r())),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=adapters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.js","sourceRoot":"","sources":["../../src/edge/adapters.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@winstonsayno/mcp-gateway/edge` — Fetch-API gateway for Cloudflare Workers, Deno and Bun.
|
|
3
|
+
* Imports nothing from Node (except `serveNode`, which loads `node:http` lazily).
|
|
4
|
+
*/
|
|
5
|
+
export { createEdgeGateway, EdgeUpstream, readRpcReply, EDGE_PROTOCOL_VERSION } from './index.js';
|
|
6
|
+
export type { EdgeConfig, EdgeServerConfig, EdgeGateway } from './index.js';
|
|
7
|
+
export { workersHandler, serveDeno, serveBun, serveNode, configFromEnv } from './adapters.js';
|
|
8
|
+
//# sourceMappingURL=entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../../src/edge/entry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAClG,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@winstonsayno/mcp-gateway/edge` — Fetch-API gateway for Cloudflare Workers, Deno and Bun.
|
|
3
|
+
* Imports nothing from Node (except `serveNode`, which loads `node:http` lazily).
|
|
4
|
+
*/
|
|
5
|
+
export { createEdgeGateway, EdgeUpstream, readRpcReply, EDGE_PROTOCOL_VERSION } from './index.js';
|
|
6
|
+
export { workersHandler, serveDeno, serveBun, serveNode, configFromEnv } from './adapters.js';
|
|
7
|
+
//# sourceMappingURL=entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../src/edge/entry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAElG,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge gateway: a dependency-free, Fetch-API implementation of the gateway's
|
|
3
|
+
* HTTP surface for runtimes without Node's `http` / `child_process` —
|
|
4
|
+
* Cloudflare Workers, Deno, Bun (and Node via `serveNode`).
|
|
5
|
+
*
|
|
6
|
+
* Scope: remote upstreams over Streamable HTTP only (no stdio / WebSocket),
|
|
7
|
+
* API-key auth (plain or `sha256:` keys), per-server tool filters, the `/mcp`
|
|
8
|
+
* endpoint (stateless JSON responses: initialize, ping, tools/list,
|
|
9
|
+
* tools/call) and the REST subset `GET /api/v1/health`, `GET /api/v1/tools`,
|
|
10
|
+
* `POST /api/v1/tools/call`. Everything else stays in the full Node gateway.
|
|
11
|
+
*
|
|
12
|
+
* This module must not import Node built-ins.
|
|
13
|
+
*
|
|
14
|
+
* @module edge
|
|
15
|
+
*/
|
|
16
|
+
import type { ToolFilterConfig } from '../utils/types.js';
|
|
17
|
+
export declare const EDGE_PROTOCOL_VERSION = "2025-06-18";
|
|
18
|
+
export interface EdgeServerConfig {
|
|
19
|
+
id: string;
|
|
20
|
+
name?: string;
|
|
21
|
+
/** Streamable HTTP endpoint of the upstream MCP server. */
|
|
22
|
+
url: string;
|
|
23
|
+
headers?: Record<string, string>;
|
|
24
|
+
tools?: ToolFilterConfig;
|
|
25
|
+
timeoutMs?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface EdgeConfig {
|
|
28
|
+
servers: EdgeServerConfig[];
|
|
29
|
+
/** Accepted API keys (plain, or `sha256:<hex>`). Empty / absent = no auth. */
|
|
30
|
+
apiKeys?: string[];
|
|
31
|
+
/** Downstream MCP path (default `/mcp`). */
|
|
32
|
+
mcpPath?: string;
|
|
33
|
+
/** `prefix` always names tools `<server>__<tool>`; `auto` (default) only on collisions. */
|
|
34
|
+
toolNaming?: 'auto' | 'prefix';
|
|
35
|
+
/** CORS allowed origins (default none). */
|
|
36
|
+
corsOrigins?: string[];
|
|
37
|
+
/** fetch implementation (tests, custom agents). */
|
|
38
|
+
fetch?: typeof fetch;
|
|
39
|
+
name?: string;
|
|
40
|
+
version?: string;
|
|
41
|
+
}
|
|
42
|
+
interface UpstreamTool {
|
|
43
|
+
name: string;
|
|
44
|
+
description?: string;
|
|
45
|
+
inputSchema?: unknown;
|
|
46
|
+
title?: string;
|
|
47
|
+
annotations?: unknown;
|
|
48
|
+
outputSchema?: unknown;
|
|
49
|
+
}
|
|
50
|
+
type Json = Record<string, unknown>;
|
|
51
|
+
/** Parse a JSON or SSE MCP reply and return the JSON-RPC message with `id`. */
|
|
52
|
+
export declare function readRpcReply(res: Response, id: number | string): Promise<Json>;
|
|
53
|
+
/** Minimal Streamable HTTP MCP client for one upstream. */
|
|
54
|
+
export declare class EdgeUpstream {
|
|
55
|
+
readonly cfg: EdgeServerConfig;
|
|
56
|
+
private readonly fetchImpl;
|
|
57
|
+
private session?;
|
|
58
|
+
private seq;
|
|
59
|
+
private toolsCache?;
|
|
60
|
+
constructor(cfg: EdgeServerConfig, fetchImpl: typeof fetch);
|
|
61
|
+
private post;
|
|
62
|
+
private init;
|
|
63
|
+
request(method: string, params?: Json, retried?: boolean): Promise<unknown>;
|
|
64
|
+
tools(maxAgeMs?: number): Promise<UpstreamTool[]>;
|
|
65
|
+
}
|
|
66
|
+
export interface EdgeGateway {
|
|
67
|
+
fetch(request: Request): Promise<Response>;
|
|
68
|
+
upstreams: ReadonlyMap<string, EdgeUpstream>;
|
|
69
|
+
}
|
|
70
|
+
/** Build the edge gateway's Fetch handler. */
|
|
71
|
+
export declare function createEdgeGateway(config: EdgeConfig): EdgeGateway;
|
|
72
|
+
export {};
|
|
73
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/edge/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,eAAO,MAAM,qBAAqB,eAAe,CAAC;AAGlD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2FAA2F;IAC3F,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC/B,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,mDAAmD;IACnD,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAQD,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAsBpC,+EAA+E;AAC/E,wBAAsB,YAAY,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BpF;AAYD,2DAA2D;AAC3D,qBAAa,YAAY;IAMrB,QAAQ,CAAC,GAAG,EAAE,gBAAgB;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAN5B,OAAO,CAAC,OAAO,CAAC,CAAU;IAC1B,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,UAAU,CAAC,CAAwC;gBAGhD,GAAG,EAAE,gBAAgB,EACb,SAAS,EAAE,OAAO,KAAK;YAG5B,IAAI;YAgBJ,IAAI;IA4BZ,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,UAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAezE,KAAK,CAAC,QAAQ,SAAS,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAcxD;AAQD,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3C,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CAC9C;AAED,8CAA8C;AAC9C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,CAgKjE"}
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge gateway: a dependency-free, Fetch-API implementation of the gateway's
|
|
3
|
+
* HTTP surface for runtimes without Node's `http` / `child_process` —
|
|
4
|
+
* Cloudflare Workers, Deno, Bun (and Node via `serveNode`).
|
|
5
|
+
*
|
|
6
|
+
* Scope: remote upstreams over Streamable HTTP only (no stdio / WebSocket),
|
|
7
|
+
* API-key auth (plain or `sha256:` keys), per-server tool filters, the `/mcp`
|
|
8
|
+
* endpoint (stateless JSON responses: initialize, ping, tools/list,
|
|
9
|
+
* tools/call) and the REST subset `GET /api/v1/health`, `GET /api/v1/tools`,
|
|
10
|
+
* `POST /api/v1/tools/call`. Everything else stays in the full Node gateway.
|
|
11
|
+
*
|
|
12
|
+
* This module must not import Node built-ins.
|
|
13
|
+
*
|
|
14
|
+
* @module edge
|
|
15
|
+
*/
|
|
16
|
+
import { globToRegExp } from '../utils/tool-filter.js';
|
|
17
|
+
export const EDGE_PROTOCOL_VERSION = '2025-06-18';
|
|
18
|
+
const SUPPORTED_VERSIONS = ['2025-06-18', '2025-03-26', '2024-11-05'];
|
|
19
|
+
const isObj = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
20
|
+
function allowed(name, f) {
|
|
21
|
+
if (!f)
|
|
22
|
+
return true;
|
|
23
|
+
if (f.allow && !f.allow.some((p) => globToRegExp(p).test(name)))
|
|
24
|
+
return false;
|
|
25
|
+
if (f.deny && f.deny.some((p) => globToRegExp(p).test(name)))
|
|
26
|
+
return false;
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
async function sha256Hex(s) {
|
|
30
|
+
const d = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(s));
|
|
31
|
+
return [...new Uint8Array(d)].map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
32
|
+
}
|
|
33
|
+
function safeEqual(a, b) {
|
|
34
|
+
let diff = a.length ^ b.length;
|
|
35
|
+
for (let i = 0; i < Math.max(a.length, b.length); i++)
|
|
36
|
+
diff |= (a.charCodeAt(i) || 0) ^ (b.charCodeAt(i) || 0);
|
|
37
|
+
return diff === 0;
|
|
38
|
+
}
|
|
39
|
+
/** Parse a JSON or SSE MCP reply and return the JSON-RPC message with `id`. */
|
|
40
|
+
export async function readRpcReply(res, id) {
|
|
41
|
+
const type = res.headers.get('content-type') ?? '';
|
|
42
|
+
const text = await res.text();
|
|
43
|
+
if (type.includes('text/event-stream')) {
|
|
44
|
+
for (const block of text.split(/\r?\n\r?\n/)) {
|
|
45
|
+
const data = block
|
|
46
|
+
.split(/\r?\n/)
|
|
47
|
+
.filter((l) => l.startsWith('data:'))
|
|
48
|
+
.map((l) => l.slice(5).replace(/^ /, ''))
|
|
49
|
+
.join('\n');
|
|
50
|
+
if (!data)
|
|
51
|
+
continue;
|
|
52
|
+
try {
|
|
53
|
+
const msg = JSON.parse(data);
|
|
54
|
+
const list = Array.isArray(msg) ? msg : [msg];
|
|
55
|
+
const hit = list.find((m) => isObj(m) && m.id === id && ('result' in m || 'error' in m));
|
|
56
|
+
if (hit)
|
|
57
|
+
return hit;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
/* keep scanning */
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
throw new Error('No response in event stream');
|
|
64
|
+
}
|
|
65
|
+
const msg = JSON.parse(text);
|
|
66
|
+
const list = Array.isArray(msg) ? msg : [msg];
|
|
67
|
+
const hit = list.find((m) => isObj(m) && m.id === id);
|
|
68
|
+
if (!hit)
|
|
69
|
+
throw new Error('No matching JSON-RPC response');
|
|
70
|
+
return hit;
|
|
71
|
+
}
|
|
72
|
+
class RpcError extends Error {
|
|
73
|
+
code;
|
|
74
|
+
data;
|
|
75
|
+
constructor(code, message, data) {
|
|
76
|
+
super(message);
|
|
77
|
+
this.code = code;
|
|
78
|
+
this.data = data;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/** Minimal Streamable HTTP MCP client for one upstream. */
|
|
82
|
+
export class EdgeUpstream {
|
|
83
|
+
cfg;
|
|
84
|
+
fetchImpl;
|
|
85
|
+
session;
|
|
86
|
+
seq = 0;
|
|
87
|
+
toolsCache;
|
|
88
|
+
constructor(cfg, fetchImpl) {
|
|
89
|
+
this.cfg = cfg;
|
|
90
|
+
this.fetchImpl = fetchImpl;
|
|
91
|
+
}
|
|
92
|
+
async post(body, sessionId, version = EDGE_PROTOCOL_VERSION) {
|
|
93
|
+
const headers = {
|
|
94
|
+
'content-type': 'application/json',
|
|
95
|
+
accept: 'application/json, text/event-stream',
|
|
96
|
+
'mcp-protocol-version': version,
|
|
97
|
+
...(this.cfg.headers ?? {}),
|
|
98
|
+
};
|
|
99
|
+
if (sessionId)
|
|
100
|
+
headers['mcp-session-id'] = sessionId;
|
|
101
|
+
return this.fetchImpl(this.cfg.url, {
|
|
102
|
+
method: 'POST',
|
|
103
|
+
headers,
|
|
104
|
+
body: JSON.stringify(body),
|
|
105
|
+
signal: AbortSignal.timeout(this.cfg.timeoutMs ?? 30_000),
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
async init() {
|
|
109
|
+
if (this.session?.ready) {
|
|
110
|
+
await this.session.ready;
|
|
111
|
+
return this.session;
|
|
112
|
+
}
|
|
113
|
+
const s = { version: EDGE_PROTOCOL_VERSION };
|
|
114
|
+
this.session = s;
|
|
115
|
+
s.ready = (async () => {
|
|
116
|
+
const id = ++this.seq;
|
|
117
|
+
const res = await this.post({ jsonrpc: '2.0', id, method: 'initialize', params: { protocolVersion: EDGE_PROTOCOL_VERSION, capabilities: {}, clientInfo: { name: 'mcp-gateway-edge', version: '1' } } });
|
|
118
|
+
if (!res.ok)
|
|
119
|
+
throw new Error(`initialize failed: HTTP ${res.status}`);
|
|
120
|
+
s.id = res.headers.get('mcp-session-id') ?? undefined;
|
|
121
|
+
const reply = await readRpcReply(res, id);
|
|
122
|
+
if (reply.error)
|
|
123
|
+
throw new Error(`initialize failed: ${JSON.stringify(reply.error)}`);
|
|
124
|
+
const v = isObj(reply.result) && typeof reply.result.protocolVersion === 'string' ? reply.result.protocolVersion : EDGE_PROTOCOL_VERSION;
|
|
125
|
+
s.version = v;
|
|
126
|
+
const n = await this.post({ jsonrpc: '2.0', method: 'notifications/initialized' }, s.id, v);
|
|
127
|
+
await n.body?.cancel().catch(() => undefined);
|
|
128
|
+
})();
|
|
129
|
+
try {
|
|
130
|
+
await s.ready;
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
this.session = undefined;
|
|
134
|
+
throw err;
|
|
135
|
+
}
|
|
136
|
+
return s;
|
|
137
|
+
}
|
|
138
|
+
async request(method, params, retried = false) {
|
|
139
|
+
const s = await this.init();
|
|
140
|
+
const id = ++this.seq;
|
|
141
|
+
const res = await this.post({ jsonrpc: '2.0', id, method, ...(params ? { params } : {}) }, s.id, s.version);
|
|
142
|
+
if (res.status === 404 && s.id && !retried) {
|
|
143
|
+
// Session expired upstream: start a new one once.
|
|
144
|
+
this.session = undefined;
|
|
145
|
+
return this.request(method, params, true);
|
|
146
|
+
}
|
|
147
|
+
if (!res.ok)
|
|
148
|
+
throw new RpcError(-32000, `Upstream "${this.cfg.id}" HTTP ${res.status}`);
|
|
149
|
+
const reply = await readRpcReply(res, id);
|
|
150
|
+
if (isObj(reply.error))
|
|
151
|
+
throw new RpcError(Number(reply.error.code ?? -32603), String(reply.error.message ?? 'error'), reply.error.data);
|
|
152
|
+
return reply.result;
|
|
153
|
+
}
|
|
154
|
+
async tools(maxAgeMs = 30_000) {
|
|
155
|
+
if (this.toolsCache && Date.now() - this.toolsCache.at < maxAgeMs)
|
|
156
|
+
return this.toolsCache.tools;
|
|
157
|
+
const all = [];
|
|
158
|
+
let cursor;
|
|
159
|
+
for (let page = 0; page < 50; page++) {
|
|
160
|
+
const r = (await this.request('tools/list', cursor ? { cursor } : undefined));
|
|
161
|
+
all.push(...(r?.tools ?? []));
|
|
162
|
+
cursor = r?.nextCursor;
|
|
163
|
+
if (!cursor)
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
const tools = all.filter((t) => allowed(t.name, this.cfg.tools));
|
|
167
|
+
this.toolsCache = { at: Date.now(), tools };
|
|
168
|
+
return tools;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/** Build the edge gateway's Fetch handler. */
|
|
172
|
+
export function createEdgeGateway(config) {
|
|
173
|
+
const fetchImpl = config.fetch ?? ((...a) => fetch(...a));
|
|
174
|
+
const upstreams = new Map(config.servers.map((s) => [s.id, new EdgeUpstream(s, fetchImpl)]));
|
|
175
|
+
const mcpPath = config.mcpPath ?? '/mcp';
|
|
176
|
+
const keys = (config.apiKeys ?? []).filter(Boolean);
|
|
177
|
+
const json = (status, body, extra = {}) => new Response(JSON.stringify(body), { status, headers: { 'content-type': 'application/json', ...extra } });
|
|
178
|
+
async function authorized(req) {
|
|
179
|
+
if (keys.length === 0)
|
|
180
|
+
return true;
|
|
181
|
+
const h = req.headers.get('authorization') ?? '';
|
|
182
|
+
const token = /^Bearer\s+(.+)$/i.exec(h)?.[1]?.trim() ?? req.headers.get('x-api-key') ?? '';
|
|
183
|
+
if (!token)
|
|
184
|
+
return false;
|
|
185
|
+
const digest = keys.some((k) => k.startsWith('sha256:')) ? await sha256Hex(token) : '';
|
|
186
|
+
return keys.some((k) => (k.startsWith('sha256:') ? safeEqual(`sha256:${digest}`, k.toLowerCase()) : safeEqual(token, k)));
|
|
187
|
+
}
|
|
188
|
+
async function index() {
|
|
189
|
+
const errors = {};
|
|
190
|
+
const per = await Promise.all([...upstreams.values()].map(async (u) => {
|
|
191
|
+
try {
|
|
192
|
+
return (await u.tools()).map((tool) => ({ serverId: u.cfg.id, tool }));
|
|
193
|
+
}
|
|
194
|
+
catch (err) {
|
|
195
|
+
errors[u.cfg.id] = err instanceof Error ? err.message : String(err);
|
|
196
|
+
return [];
|
|
197
|
+
}
|
|
198
|
+
}));
|
|
199
|
+
const flat = per.flat();
|
|
200
|
+
const count = new Map();
|
|
201
|
+
for (const t of flat)
|
|
202
|
+
count.set(t.tool.name, (count.get(t.tool.name) ?? 0) + 1);
|
|
203
|
+
const list = flat.map((t) => ({
|
|
204
|
+
...t,
|
|
205
|
+
exposed: config.toolNaming === 'prefix' || (count.get(t.tool.name) ?? 0) > 1 ? `${t.serverId}__${t.tool.name}` : t.tool.name,
|
|
206
|
+
}));
|
|
207
|
+
return { list, errors };
|
|
208
|
+
}
|
|
209
|
+
async function callTool(name, args, server) {
|
|
210
|
+
const { list } = await index();
|
|
211
|
+
const hit = server ? list.find((t) => t.serverId === server && t.tool.name === name) : list.find((t) => t.exposed === name) ?? list.find((t) => t.tool.name === name);
|
|
212
|
+
if (!hit)
|
|
213
|
+
throw new RpcError(-32602, `Unknown tool: ${name}`);
|
|
214
|
+
const result = await upstreams.get(hit.serverId).request('tools/call', { name: hit.tool.name, arguments: args });
|
|
215
|
+
return { serverId: hit.serverId, result };
|
|
216
|
+
}
|
|
217
|
+
function cors(req, res) {
|
|
218
|
+
const origin = req.headers.get('origin');
|
|
219
|
+
const allowedOrigins = config.corsOrigins ?? [];
|
|
220
|
+
if (origin && (allowedOrigins.includes('*') || allowedOrigins.includes(origin))) {
|
|
221
|
+
res.headers.set('access-control-allow-origin', allowedOrigins.includes('*') ? '*' : origin);
|
|
222
|
+
res.headers.set('access-control-allow-headers', 'authorization, content-type, mcp-session-id, mcp-protocol-version, x-api-key');
|
|
223
|
+
res.headers.set('access-control-allow-methods', 'GET, POST, DELETE, OPTIONS');
|
|
224
|
+
res.headers.set('access-control-expose-headers', 'mcp-session-id');
|
|
225
|
+
res.headers.append('vary', 'Origin');
|
|
226
|
+
}
|
|
227
|
+
return res;
|
|
228
|
+
}
|
|
229
|
+
async function handleRpc(msg) {
|
|
230
|
+
const id = msg.id;
|
|
231
|
+
const method = typeof msg.method === 'string' ? msg.method : '';
|
|
232
|
+
if (id === undefined)
|
|
233
|
+
return undefined; // notification
|
|
234
|
+
const ok = (result) => ({ jsonrpc: '2.0', id, result });
|
|
235
|
+
try {
|
|
236
|
+
switch (method) {
|
|
237
|
+
case 'initialize': {
|
|
238
|
+
const asked = isObj(msg.params) && typeof msg.params.protocolVersion === 'string' ? msg.params.protocolVersion : EDGE_PROTOCOL_VERSION;
|
|
239
|
+
return ok({
|
|
240
|
+
protocolVersion: SUPPORTED_VERSIONS.includes(asked) ? asked : EDGE_PROTOCOL_VERSION,
|
|
241
|
+
capabilities: { tools: { listChanged: false } },
|
|
242
|
+
serverInfo: { name: config.name ?? 'mcp-gateway-edge', version: config.version ?? '1' },
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
case 'ping':
|
|
246
|
+
return ok({});
|
|
247
|
+
case 'tools/list': {
|
|
248
|
+
const { list } = await index();
|
|
249
|
+
return ok({ tools: list.map((t) => ({ ...t.tool, name: t.exposed })) });
|
|
250
|
+
}
|
|
251
|
+
case 'tools/call': {
|
|
252
|
+
const p = isObj(msg.params) ? msg.params : {};
|
|
253
|
+
if (typeof p.name !== 'string')
|
|
254
|
+
throw new RpcError(-32602, 'params.name is required');
|
|
255
|
+
const r = await callTool(p.name, isObj(p.arguments) ? p.arguments : {});
|
|
256
|
+
return ok(r.result);
|
|
257
|
+
}
|
|
258
|
+
default:
|
|
259
|
+
throw new RpcError(-32601, `Method not supported by the edge gateway: ${method}`);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
catch (err) {
|
|
263
|
+
const e = err instanceof RpcError ? err : new RpcError(-32603, err instanceof Error ? err.message : String(err));
|
|
264
|
+
return { jsonrpc: '2.0', id, error: { code: e.code, message: e.message, ...(e.data !== undefined ? { data: e.data } : {}) } };
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
async function route(req) {
|
|
268
|
+
const url = new URL(req.url);
|
|
269
|
+
const path = url.pathname.replace(/\/+$/, '') || '/';
|
|
270
|
+
if (req.method === 'OPTIONS')
|
|
271
|
+
return new Response(null, { status: 204 });
|
|
272
|
+
if (path === '/' && req.method === 'GET')
|
|
273
|
+
return json(200, { name: 'mcp-gateway (edge)', mcp: mcpPath, servers: upstreams.size });
|
|
274
|
+
if (path === '/api/v1/health/live')
|
|
275
|
+
return json(200, { status: 'ok' });
|
|
276
|
+
if (!(await authorized(req)))
|
|
277
|
+
return json(401, { error: 'Unauthorized', message: 'missing or invalid API key' }, { 'www-authenticate': 'Bearer' });
|
|
278
|
+
if (path === mcpPath) {
|
|
279
|
+
if (req.method === 'GET')
|
|
280
|
+
return json(405, { error: 'Method Not Allowed', message: 'The edge gateway does not offer a server-to-client stream' }, { allow: 'POST, DELETE' });
|
|
281
|
+
if (req.method === 'DELETE')
|
|
282
|
+
return new Response(null, { status: 204 });
|
|
283
|
+
if (req.method !== 'POST')
|
|
284
|
+
return json(405, { error: 'Method Not Allowed' }, { allow: 'POST, DELETE' });
|
|
285
|
+
let body;
|
|
286
|
+
try {
|
|
287
|
+
body = await req.json();
|
|
288
|
+
}
|
|
289
|
+
catch {
|
|
290
|
+
return json(400, { jsonrpc: '2.0', id: null, error: { code: -32700, message: 'Parse error' } });
|
|
291
|
+
}
|
|
292
|
+
const batch = Array.isArray(body);
|
|
293
|
+
const msgs = (batch ? body : [body]);
|
|
294
|
+
if (msgs.length === 0 || !msgs.every(isObj))
|
|
295
|
+
return json(400, { jsonrpc: '2.0', id: null, error: { code: -32600, message: 'Invalid Request' } });
|
|
296
|
+
const out = (await Promise.all(msgs.map((m) => handleRpc(m)))).filter((m) => m !== undefined);
|
|
297
|
+
if (out.length === 0)
|
|
298
|
+
return new Response(null, { status: 202 });
|
|
299
|
+
return json(200, batch ? out : out[0]);
|
|
300
|
+
}
|
|
301
|
+
if (path === '/api/v1/health' && req.method === 'GET') {
|
|
302
|
+
const { list, errors } = await index();
|
|
303
|
+
const down = Object.keys(errors).length;
|
|
304
|
+
return json(down === 0 ? 200 : 207, { status: down === 0 ? 'healthy' : down === upstreams.size ? 'unhealthy' : 'degraded', runtime: 'edge', servers: { total: upstreams.size, online: upstreams.size - down, offline: down, totalTools: list.length }, errors });
|
|
305
|
+
}
|
|
306
|
+
if (path === '/api/v1/tools' && req.method === 'GET') {
|
|
307
|
+
const { list } = await index();
|
|
308
|
+
const server = url.searchParams.get('server');
|
|
309
|
+
const tools = list.filter((t) => !server || t.serverId === server).map((t) => ({ ...t.tool, serverId: t.serverId, serverName: upstreams.get(t.serverId).cfg.name ?? t.serverId, exposedName: t.exposed }));
|
|
310
|
+
return json(200, { tools, total: tools.length });
|
|
311
|
+
}
|
|
312
|
+
if (path === '/api/v1/tools/call' && req.method === 'POST') {
|
|
313
|
+
let b;
|
|
314
|
+
try {
|
|
315
|
+
b = await req.json();
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
return json(400, { error: 'Bad Request', message: 'Invalid JSON body' });
|
|
319
|
+
}
|
|
320
|
+
if (!isObj(b) || typeof b.tool !== 'string')
|
|
321
|
+
return json(400, { error: 'Bad Request', message: '"tool" is required' });
|
|
322
|
+
const started = Date.now();
|
|
323
|
+
try {
|
|
324
|
+
const r = await callTool(b.tool, isObj(b.arguments) ? b.arguments : {}, typeof b.server === 'string' ? b.server : undefined);
|
|
325
|
+
return json(200, { result: r.result, server: r.serverId, tool: b.tool, durationMs: Date.now() - started });
|
|
326
|
+
}
|
|
327
|
+
catch (err) {
|
|
328
|
+
const e = err instanceof RpcError ? err : new RpcError(-32603, err instanceof Error ? err.message : String(err));
|
|
329
|
+
return json(e.code === -32602 ? 404 : 502, { error: e.code === -32602 ? 'Not Found' : 'Bad Gateway', message: e.message, code: e.code });
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return json(404, { error: 'Not Found' });
|
|
333
|
+
}
|
|
334
|
+
return {
|
|
335
|
+
upstreams,
|
|
336
|
+
async fetch(request) {
|
|
337
|
+
return cors(request, await route(request));
|
|
338
|
+
},
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/edge/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@winstonsayno/mcp-gateway",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "A lightweight, open-source gateway for managing, routing, and monitoring multiple MCP (Model Context Protocol) servers.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -73,6 +73,10 @@
|
|
|
73
73
|
".": {
|
|
74
74
|
"types": "./dist/index.d.ts",
|
|
75
75
|
"import": "./dist/index.js"
|
|
76
|
+
},
|
|
77
|
+
"./edge": {
|
|
78
|
+
"types": "./dist/edge/entry.d.ts",
|
|
79
|
+
"import": "./dist/edge/entry.js"
|
|
76
80
|
}
|
|
77
81
|
},
|
|
78
82
|
"publishConfig": {
|