@onlyne/mcp-gateway 3.0.0 → 3.2.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/dist/exec.js ADDED
@@ -0,0 +1,155 @@
1
+ import { OnlyneError } from '@onlyne/lib';
2
+ /** Output kept per stream: enough for one readable result line, bounded so a chatty script cannot bloat the store. */
3
+ export const OUTPUT_CAP = 4_096;
4
+ /** How long a cancelled or stopping run gets to exit before the subtree is killed outright. */
5
+ const KILL_GRACE_MS = 1_500;
6
+ const safeKill = (pid, signal) => {
7
+ // Never signal this process or init: a scheduler cancel must not take the gateway down.
8
+ if (pid <= 1 || pid === process.pid)
9
+ return;
10
+ try {
11
+ process.kill(pid, signal);
12
+ }
13
+ catch { /* the process is already gone */ }
14
+ };
15
+ /** The parent the kernel currently reports for a pid, used to prove the process is still ours. */
16
+ function parentOf(pid) {
17
+ try {
18
+ const text = Bun.spawnSync({
19
+ cmd: ['ps', '-o', 'ppid=', '-p', String(pid)], stdout: 'pipe', stderr: 'ignore',
20
+ }).stdout.toString().trim();
21
+ const parent = Number(text);
22
+ return Number.isInteger(parent) ? parent : undefined;
23
+ }
24
+ catch {
25
+ return undefined;
26
+ }
27
+ }
28
+ /**
29
+ * The live descendants of `pid`, read from `ps` once per signal so the list is the kernel's
30
+ * current view and not a stale snapshot from before the parent exited. Every pid is exact;
31
+ * nothing is matched by name.
32
+ */
33
+ async function descendantsOf(pid) {
34
+ let output;
35
+ try {
36
+ output = Bun.spawnSync({
37
+ cmd: ['ps', '-axo', 'pid=,ppid='], stdout: 'pipe', stderr: 'ignore',
38
+ }).stdout.toString();
39
+ }
40
+ catch {
41
+ return [];
42
+ }
43
+ const children = new Map();
44
+ for (const line of output.split('\n')) {
45
+ const [childText, parentText] = line.trim().split(/\s+/);
46
+ const child = Number(childText);
47
+ const parent = Number(parentText);
48
+ if (!Number.isInteger(child) || !Number.isInteger(parent))
49
+ continue;
50
+ const list = children.get(parent) ?? [];
51
+ list.push(child);
52
+ children.set(parent, list);
53
+ }
54
+ const found = [];
55
+ const queue = [...(children.get(pid) ?? [])];
56
+ while (queue.length > 0) {
57
+ const next = queue.shift();
58
+ if (next === process.pid || found.includes(next))
59
+ continue;
60
+ found.push(next);
61
+ queue.push(...(children.get(next) ?? []));
62
+ }
63
+ return found;
64
+ }
65
+ /** Signals the process group the scheduler built: the exact child first, then its verified descendants. */
66
+ export async function signalTree(child, signal) {
67
+ const pid = child.pid;
68
+ if (pid === undefined)
69
+ return;
70
+ // A pid that no longer descends from this process has exited and its number may now belong to
71
+ // an unrelated process: drop the handle instead of signalling whatever took the slot.
72
+ if (parentOf(pid) !== process.pid) {
73
+ child.pid = undefined;
74
+ return;
75
+ }
76
+ const descendants = await descendantsOf(pid);
77
+ for (const descendant of descendants.reverse())
78
+ safeKill(descendant, signal);
79
+ safeKill(pid, signal);
80
+ }
81
+ /**
82
+ * Stops one run: SIGTERM for a clean exit, then SIGKILL of the same subtree while its root is
83
+ * still alive after the grace period. The escalation is not awaited by the caller, so a cancel
84
+ * answers as soon as the signal is sent; the run settles when its process actually exits.
85
+ */
86
+ export function stopChild(child) {
87
+ if (child.cancelled)
88
+ return;
89
+ child.cancelled = true;
90
+ const pid = child.pid;
91
+ if (pid === undefined)
92
+ return;
93
+ void signalTree(child, 'SIGTERM');
94
+ const timer = setTimeout(() => {
95
+ // Re-derive from the live root: a dead root's pid may already belong to another process,
96
+ // and a reused pid must never receive this run's signal.
97
+ if (child.pid === pid)
98
+ void signalTree(child, 'SIGKILL');
99
+ }, KILL_GRACE_MS);
100
+ timer.unref?.();
101
+ }
102
+ async function drain(stream, cap) {
103
+ const decoder = new TextDecoder();
104
+ let text = '';
105
+ let bytes = 0;
106
+ for await (const chunk of stream) {
107
+ bytes += chunk.byteLength;
108
+ text += decoder.decode(chunk, { stream: true });
109
+ if (text.length > cap)
110
+ text = text.slice(-cap);
111
+ }
112
+ text += decoder.decode();
113
+ if (text.length > cap)
114
+ text = text.slice(-cap);
115
+ return { text, bytes };
116
+ }
117
+ /**
118
+ * Runs one allowlisted executable with argv directly, never through a shell: no quoting, no
119
+ * metacharacters, no remote string ever reaches `/bin/sh`. The child's pid is recorded before
120
+ * any output is read so a cancel that arrives first still has a handle to signal.
121
+ */
122
+ export async function runCommand(target, child) {
123
+ let proc;
124
+ try {
125
+ proc = Bun.spawn({
126
+ cmd: [target.command, ...(target.args ?? [])],
127
+ cwd: target.cwd ?? process.cwd(),
128
+ env: process.env,
129
+ stdio: ['ignore', 'pipe', 'pipe'],
130
+ });
131
+ }
132
+ catch (error) {
133
+ throw new OnlyneError('invalid_request', `The command ${target.command} could not be started: ${error instanceof Error ? error.message : String(error)}`);
134
+ }
135
+ child.pid = proc.pid;
136
+ try {
137
+ const [stdout, stderr] = await Promise.all([
138
+ drain(proc.stdout, OUTPUT_CAP),
139
+ drain(proc.stderr, OUTPUT_CAP),
140
+ proc.exited,
141
+ ]);
142
+ return {
143
+ exit_code: proc.exitCode ?? null,
144
+ stdout: stdout.text,
145
+ stderr: stderr.text,
146
+ output_bytes: stdout.bytes + stderr.bytes,
147
+ };
148
+ }
149
+ finally {
150
+ // The child is gone; releasing the handle keeps a late cancel from signalling a reused pid.
151
+ if (proc.exitCode !== null)
152
+ child.pid = undefined;
153
+ }
154
+ }
155
+ //# sourceMappingURL=exec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.js","sourceRoot":"","sources":["../src/exec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ declare const en: {
2
+ readonly 'cli.usage': "usage: onlyne-mcp-gateway <config.json>";
3
+ readonly 'startup.pending': "The gateway is starting.";
4
+ readonly 'config.unreadable': "The configuration file is unreadable: {path}";
5
+ readonly 'config.object': "The configuration needs {field} as an object.";
6
+ readonly 'config.string': "The configuration field {field} is a non-empty string.";
7
+ readonly 'config.servers': "The configuration needs servers as an array.";
8
+ readonly 'config.duplicateName': "Two servers share the name {name}.";
9
+ readonly 'config.language': "The configuration language is en or zh-CN, not {value}.";
10
+ readonly 'config.stringList': "The configuration field {field} needs a list of non-empty strings.";
11
+ readonly 'config.reservedName': "The server name {name} uses the reserved resource prefix {prefix}.";
12
+ readonly 'config.mountsControllers': "mounts.controllers needs at least one node id.";
13
+ readonly 'config.mountsOwner': "The node owner {owner} cannot be its own mount controller.";
14
+ readonly 'config.mountsCommands': "mounts.commands needs an array.";
15
+ readonly 'config.mountsTools': "mounts.tools needs an array.";
16
+ readonly 'config.mountsToolServer': "mounts.tools names the server {server}, which is not configured.";
17
+ readonly 'config.mountsDuplicate': "Two mounts entries share the {kind} {id}.";
18
+ readonly 'config.mountTick': "mounts.tick_ms is an integer from 100 to 60000.";
19
+ readonly 'error.claimIdentity': "HTTP callers cannot claim the gateway identity.";
20
+ readonly 'error.decide': "The gateway forwards tool calls; it decides nothing.";
21
+ readonly 'error.noContext': "The gateway consumes no model context.";
22
+ };
23
+ export type GatewayTextKey = keyof typeof en;
24
+ export declare const t: (key: "cli.usage" | "startup.pending" | "config.unreadable" | "config.object" | "config.string" | "config.servers" | "config.duplicateName" | "config.language" | "config.stringList" | "config.reservedName" | "config.mountsControllers" | "config.mountsOwner" | "config.mountsCommands" | "config.mountsTools" | "config.mountsToolServer" | "config.mountsDuplicate" | "config.mountTick" | "error.claimIdentity" | "error.decide" | "error.noContext", vars?: Record<string, string | number>) => string;
25
+ export {};
26
+ //# sourceMappingURL=gateway-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-text.d.ts","sourceRoot":"","sources":["../src/gateway-text.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;CAqBE,CAAC;AAyBX,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,EAAE,CAAC;AAE7C,eAAO,MAAM,CAAC,gfAAwC,CAAC"}
@@ -0,0 +1,47 @@
1
+ import { createTranslator } from '@onlyne/node-host/i18n';
2
+ const en = {
3
+ 'cli.usage': 'usage: onlyne-mcp-gateway <config.json>',
4
+ 'startup.pending': 'The gateway is starting.',
5
+ 'config.unreadable': 'The configuration file is unreadable: {path}',
6
+ 'config.object': 'The configuration needs {field} as an object.',
7
+ 'config.string': 'The configuration field {field} is a non-empty string.',
8
+ 'config.servers': 'The configuration needs servers as an array.',
9
+ 'config.duplicateName': 'Two servers share the name {name}.',
10
+ 'config.language': 'The configuration language is en or zh-CN, not {value}.',
11
+ 'config.stringList': 'The configuration field {field} needs a list of non-empty strings.',
12
+ 'config.reservedName': 'The server name {name} uses the reserved resource prefix {prefix}.',
13
+ 'config.mountsControllers': 'mounts.controllers needs at least one node id.',
14
+ 'config.mountsOwner': 'The node owner {owner} cannot be its own mount controller.',
15
+ 'config.mountsCommands': 'mounts.commands needs an array.',
16
+ 'config.mountsTools': 'mounts.tools needs an array.',
17
+ 'config.mountsToolServer': 'mounts.tools names the server {server}, which is not configured.',
18
+ 'config.mountsDuplicate': 'Two mounts entries share the {kind} {id}.',
19
+ 'config.mountTick': 'mounts.tick_ms is an integer from 100 to 60000.',
20
+ 'error.claimIdentity': 'HTTP callers cannot claim the gateway identity.',
21
+ 'error.decide': 'The gateway forwards tool calls; it decides nothing.',
22
+ 'error.noContext': 'The gateway consumes no model context.',
23
+ };
24
+ const zh = {
25
+ 'cli.usage': '用法:onlyne-mcp-gateway <config.json>',
26
+ 'startup.pending': '网关正在启动。',
27
+ 'config.unreadable': '配置文件无法读取:{path}',
28
+ 'config.object': '配置项 {field} 需要是一个对象。',
29
+ 'config.string': '配置项 {field} 需要是非空字符串。',
30
+ 'config.servers': '配置项 servers 需要是一个数组。',
31
+ 'config.duplicateName': '有两个服务器共用了名称 {name}。',
32
+ 'config.language': '配置项 language 只能是 en 或 zh-CN,而不是 {value}。',
33
+ 'config.stringList': '配置项 {field} 需要是非空字符串列表。',
34
+ 'config.reservedName': '服务器名称 {name} 占用了保留的资源前缀 {prefix}。',
35
+ 'config.mountsControllers': 'mounts.controllers 至少需要一个节点标识。',
36
+ 'config.mountsOwner': '节点自身 {owner} 不能作为自己的挂载控制者。',
37
+ 'config.mountsCommands': 'mounts.commands 需要是一个数组。',
38
+ 'config.mountsTools': 'mounts.tools 需要是一个数组。',
39
+ 'config.mountsToolServer': 'mounts.tools 指向的服务器 {server} 并未配置。',
40
+ 'config.mountsDuplicate': '有两个挂载配置项共用了 {kind} {id}。',
41
+ 'config.mountTick': 'mounts.tick_ms 是 100 到 60000 之间的整数。',
42
+ 'error.claimIdentity': 'HTTP 调用方不能冒用网关身份。',
43
+ 'error.decide': '网关只转发工具调用,不做任何决策。',
44
+ 'error.noContext': '网关不消费模型上下文。',
45
+ };
46
+ export const t = createTranslator({ en, 'zh-CN': zh });
47
+ //# sourceMappingURL=gateway-text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-text.js","sourceRoot":"","sources":["../src/gateway-text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,MAAM,EAAE,GAAG;IACT,WAAW,EAAE,yCAAyC;IACtD,iBAAiB,EAAE,0BAA0B;IAC7C,mBAAmB,EAAE,8CAA8C;IACnE,eAAe,EAAE,+CAA+C;IAChE,eAAe,EAAE,wDAAwD;IACzE,gBAAgB,EAAE,8CAA8C;IAChE,sBAAsB,EAAE,oCAAoC;IAC5D,iBAAiB,EAAE,yDAAyD;IAC5E,mBAAmB,EAAE,oEAAoE;IACzF,qBAAqB,EAAE,oEAAoE;IAC3F,0BAA0B,EAAE,gDAAgD;IAC5E,oBAAoB,EAAE,4DAA4D;IAClF,uBAAuB,EAAE,iCAAiC;IAC1D,oBAAoB,EAAE,8BAA8B;IACpD,yBAAyB,EAAE,kEAAkE;IAC7F,wBAAwB,EAAE,2CAA2C;IACrE,kBAAkB,EAAE,iDAAiD;IACrE,qBAAqB,EAAE,iDAAiD;IACxE,cAAc,EAAE,sDAAsD;IACtE,iBAAiB,EAAE,wCAAwC;CACnD,CAAC;AAEX,MAAM,EAAE,GAAoC;IAC1C,WAAW,EAAE,qCAAqC;IAClD,iBAAiB,EAAE,SAAS;IAC5B,mBAAmB,EAAE,iBAAiB;IACtC,eAAe,EAAE,sBAAsB;IACvC,eAAe,EAAE,uBAAuB;IACxC,gBAAgB,EAAE,sBAAsB;IACxC,sBAAsB,EAAE,qBAAqB;IAC7C,iBAAiB,EAAE,0CAA0C;IAC7D,mBAAmB,EAAE,yBAAyB;IAC9C,qBAAqB,EAAE,mCAAmC;IAC1D,0BAA0B,EAAE,gCAAgC;IAC5D,oBAAoB,EAAE,4BAA4B;IAClD,uBAAuB,EAAE,0BAA0B;IACnD,oBAAoB,EAAE,uBAAuB;IAC7C,yBAAyB,EAAE,oCAAoC;IAC/D,wBAAwB,EAAE,0BAA0B;IACpD,kBAAkB,EAAE,qCAAqC;IACzD,qBAAqB,EAAE,mBAAmB;IAC1C,cAAc,EAAE,mBAAmB;IACnC,iBAAiB,EAAE,aAAa;CACjC,CAAC;AAIF,MAAM,CAAC,MAAM,CAAC,GAAG,gBAAgB,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { OnlyneNode, type KeyHook, type MaintenanceClock } from '@onlyne/lib';
2
+ import { McpConnection, type McpBridge } from '@onlyne/mcp-core';
3
+ import type { GatewayConfig } from './config.js';
4
+ import { type MountService } from './mounts.js';
5
+ export type { GatewayConfig, ServerConfig } from './config.js';
6
+ export type { McpBridge, McpResourceInfo, McpResourcePage } from '@onlyne/mcp-core';
7
+ export type { MountService } from './mounts.js';
8
+ export interface McpGateway {
9
+ readonly node: OnlyneNode;
10
+ readonly config: GatewayConfig;
11
+ /** The MCP connections, one per configured server, keyed by resource id. */
12
+ readonly connections: Map<string, McpConnection>;
13
+ /** The resource driver plus the read-only MCP resource primitives. */
14
+ readonly bridge: McpBridge;
15
+ /** The scheduled-mount service; its driver is part of the node's resource routing. */
16
+ readonly mounts: MountService;
17
+ /** Display lines for the node host's TUI: servers, mounts, push queue, recent results. */
18
+ status(): Promise<string[]>;
19
+ stop(): Promise<void>;
20
+ }
21
+ /** The Node-timer MaintenanceClock: one-shot timers, the lib's loop re-arms them. */
22
+ export declare function nodeClock(): MaintenanceClock;
23
+ /**
24
+ * Assembles the gateway: one session per configured MCP server, one Onlyne resource per server,
25
+ * and — when configured — one scheduler resource per mount controller. A server that cannot be
26
+ * reached at startup still registers (with its last known tools if the store has them, an empty
27
+ * list otherwise): the node stays up, and the session re-initializes and refreshes `tools/list`
28
+ * on the first operation that needs the catalog (RFC 0015 §5).
29
+ */
30
+ export interface McpGatewayOptions {
31
+ log?: (message: string, fields?: Record<string, unknown>) => void;
32
+ /**
33
+ * RFC 0017 identity key. The CLI always supplies one; a programmatic caller may omit it and
34
+ * keep the keyless loopback binding the tests use.
35
+ */
36
+ keys?: KeyHook;
37
+ }
38
+ export declare function createMcpGateway(config: GatewayConfig, options?: McpGatewayOptions): Promise<McpGateway>;
39
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAA0B,KAAK,OAAO,EAAE,KAAK,gBAAgB,EAExE,MAAM,aAAa,CAAC;AACrB,OAAO,EACwB,aAAa,EAC1C,KAAK,SAAS,EACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,aAAa,CAAC;AAG/D,OAAO,EAA8C,KAAK,YAAY,EAAuB,MAAM,aAAa,CAAC;AAGjH,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC/D,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACpF,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,4EAA4E;IAC5E,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACjD,sEAAsE;IACtE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,sFAAsF;IACtF,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,0FAA0F;IAC1F,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,qFAAqF;AACrF,wBAAgB,SAAS,IAAI,gBAAgB,CAK5C;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAClE;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AA2BD,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,UAAU,CAAC,CAwNlH"}
package/dist/index.js ADDED
@@ -0,0 +1,274 @@
1
+ import { OnlyneNode, OnlyneError, } from '@onlyne/lib';
2
+ import { createMcpBridge, resourceOf, McpConnection, } from '@onlyne/mcp-core';
3
+ import { FileStorage } from '@onlyne/im-gateway/storage';
4
+ import { neighborRows } from '@onlyne/im-gateway';
5
+ import { createMountService, MOUNTS_RESOURCE_PREFIX } from './mounts.js';
6
+ import { t } from './gateway-text.js';
7
+ /** The Node-timer MaintenanceClock: one-shot timers, the lib's loop re-arms them. */
8
+ export function nodeClock() {
9
+ return {
10
+ setTimer: (ms, run) => setTimeout(run, ms),
11
+ clearTimer: handle => clearTimeout(handle),
12
+ };
13
+ }
14
+ /** Maps the configuration's transport union onto the core connection contract. */
15
+ function serverOptionsOf(entry) {
16
+ const shared = {
17
+ name: entry.name,
18
+ ...(entry.timeout_ms === undefined ? {} : { timeoutMs: entry.timeout_ms }),
19
+ ...(entry.allowed_tools === undefined ? {} : { allowedTools: entry.allowed_tools }),
20
+ };
21
+ if (entry.transport === 'stdio') {
22
+ return {
23
+ ...shared,
24
+ transport: 'stdio',
25
+ command: entry.command,
26
+ ...(entry.args === undefined ? {} : { args: entry.args }),
27
+ ...(entry.env === undefined ? {} : { env: entry.env }),
28
+ ...(entry.cwd === undefined ? {} : { cwd: entry.cwd }),
29
+ };
30
+ }
31
+ return {
32
+ ...shared,
33
+ transport: 'http',
34
+ url: entry.url,
35
+ ...(entry.headers === undefined ? {} : { headers: entry.headers }),
36
+ };
37
+ }
38
+ export async function createMcpGateway(config, options = {}) {
39
+ const owner = config.node.id;
40
+ const storage = new FileStorage(config.storage_path);
41
+ const connections = new Map();
42
+ const serverEntries = [];
43
+ const resourcesByName = new Map();
44
+ const toolsByName = new Map();
45
+ for (const entry of config.servers) {
46
+ const server = serverOptionsOf(entry);
47
+ const connection = new McpConnection(server);
48
+ let tools = [];
49
+ let resources = [];
50
+ // The last known tool list rides in the store, so a temporarily unreachable server still
51
+ // presents its operations instead of an empty resource.
52
+ const toolsKey = `mcp/tools/${encodeURIComponent(entry.name)}`;
53
+ const resourcesKey = `mcp/resources/${encodeURIComponent(entry.name)}`;
54
+ const cached = await storage.transaction(async (tx) => tx.get(toolsKey));
55
+ const cachedResources = await storage.transaction(async (tx) => tx.get(resourcesKey));
56
+ let started = false;
57
+ try {
58
+ await connection.start();
59
+ started = true;
60
+ tools = connection.tools;
61
+ await storage.transaction(async (tx) => { await tx.put(toolsKey, { tools }); });
62
+ }
63
+ catch (err) {
64
+ // Registration proceeds with the cache; the connection connects and refreshes tools/list
65
+ // on the first operation that needs the catalog.
66
+ options.log?.('mcp.server.start.failed', { server: entry.name, error: String(err) });
67
+ tools = cached?.tools ?? [];
68
+ }
69
+ if (started) {
70
+ if (connection.canListResources) {
71
+ try {
72
+ resources = await connection.refreshResources();
73
+ await storage.transaction(async (tx) => { await tx.put(resourcesKey, { resources }); });
74
+ }
75
+ catch (err) {
76
+ options.log?.('mcp.server.resources.failed', { server: entry.name, error: String(err) });
77
+ resources = cachedResources?.resources ?? [];
78
+ }
79
+ }
80
+ else {
81
+ // The server answered and declares no resources capability: an empty catalog is the truth.
82
+ await storage.transaction(async (tx) => { await tx.put(resourcesKey, { resources: [] }); });
83
+ }
84
+ }
85
+ else {
86
+ resources = cachedResources?.resources ?? [];
87
+ }
88
+ resourcesByName.set(entry.name, resources);
89
+ toolsByName.set(entry.name, tools);
90
+ connections.set(entry.name, connection);
91
+ serverEntries.push({ server, connection });
92
+ }
93
+ const bridge = createMcpBridge(serverEntries, {
94
+ onResourceUpdated: (server, uri) => options.log?.('mcp.resource.updated', { server, uri }),
95
+ onResourceListChanged: (server, resources, error) => {
96
+ options.log?.('mcp.resource.list.changed', {
97
+ server, count: resources.length,
98
+ ...(error === undefined ? {} : { error }),
99
+ });
100
+ void cacheCatalog(server, resources);
101
+ },
102
+ onSubscriptionLost: (server, uri, reason) => options.log?.('mcp.resource.subscription.lost', { server, uri, reason }),
103
+ });
104
+ // The refreshed catalog rides in the store for the next start, when the server may be down.
105
+ async function cacheCatalog(server, resources) {
106
+ try {
107
+ await storage.transaction(async (tx) => {
108
+ await tx.put(`mcp/resources/${encodeURIComponent(server)}`, { resources });
109
+ });
110
+ }
111
+ catch (error) {
112
+ options.log?.('mcp.resources.cache.failed', { server, error: String(error) });
113
+ }
114
+ }
115
+ const base_url = `http://${config.server.bind}:${config.server.port}/onlyne/v3`;
116
+ const keys = options.keys;
117
+ const authenticate = async (request) => {
118
+ const actor = request.headers.get('Onlyne-Actor');
119
+ if (actor === null || actor.length === 0)
120
+ return null;
121
+ if (actor === owner)
122
+ throw new OnlyneError('forbidden', t('error.claimIdentity'));
123
+ return { actor };
124
+ };
125
+ const plugins = {
126
+ authenticate,
127
+ maintenanceClock: nodeClock(),
128
+ resolve: async (id) => {
129
+ // A peer's address is whatever discovery last verified; the actor header is what names
130
+ // this node on the wire, and the signing transport adds the signature over it.
131
+ const target = id === owner ? { node_id: id, base_url } : await node.discovery.resolve(id);
132
+ return { ...target, headers: { 'Onlyne-Actor': owner } };
133
+ },
134
+ decide: () => { throw new OnlyneError('decision_unavailable', t('error.decide')); },
135
+ runtime: {
136
+ // The terminal log is the gateway's only console, so every exchange stage lands in it
137
+ // with the fingerprint the operator has to repeat on `confirm`.
138
+ notify: event => {
139
+ if (event.event !== 'trust')
140
+ return;
141
+ options.log?.('onlyne.trust', {
142
+ node: event.entry.node_id, phase: event.phase, fingerprint: event.entry.fingerprint, cause: event.cause,
143
+ });
144
+ },
145
+ // The gateway stores messages but holds no model context: it can fulfill every plan
146
+ // except an await, which would need a model to answer. Its own scheduled result
147
+ // messages are admitted locally under the thread it owns, so this gate must allow
148
+ // `response: none`; refusing it would turn every run result into a delivery refusal.
149
+ supports: async (plan) => plan.response !== 'await',
150
+ inject: async () => { throw new OnlyneError('unsupported_delivery', t('error.noContext')); },
151
+ },
152
+ domainCandidates: async (domain_id) => node.discovery.candidates(domain_id),
153
+ neighbors: () => neighborRows(node, owner),
154
+ ...(keys === undefined ? {} : { keys }),
155
+ };
156
+ let node;
157
+ let mounts;
158
+ const requireMounts = () => {
159
+ if (mounts === undefined)
160
+ throw new OnlyneError('unsupported_delivery', 'The scheduler is not assembled yet.');
161
+ return mounts;
162
+ };
163
+ // One driver routes a resource by id: the scheduler owns `mounts:<controller>`, every other id
164
+ // belongs to the configured MCP server of that name (config rejects a server on the prefix).
165
+ const resources = {
166
+ validate: (resource, operation, data) => (resource.resource_ref.id.startsWith(MOUNTS_RESOURCE_PREFIX)
167
+ ? requireMounts().driver.validate(resource, operation, data)
168
+ : bridge.validate(resource, operation, data)),
169
+ execute: (resource, request, signal) => (resource.resource_ref.id.startsWith(MOUNTS_RESOURCE_PREFIX)
170
+ ? requireMounts().driver.execute(resource, request, signal)
171
+ : bridge.execute(resource, request, signal)),
172
+ };
173
+ node = new OnlyneNode({
174
+ node_id: owner,
175
+ base_url,
176
+ // RFC 0017 §1: a keyed node advertises the scheme it authenticates with. The keyless
177
+ // binding stays for programmatic callers on loopback.
178
+ authentication: keys === undefined ? ['none'] : ['signature'],
179
+ plugins: { ...plugins, storage, resources },
180
+ now: () => Date.now(),
181
+ id: () => crypto.randomUUID(),
182
+ });
183
+ const transport = {
184
+ // One thread per task: the first mount creates it, a restart recovers the same id, and the
185
+ // result messages land in one readable conversation instead of one thread per run.
186
+ ensureThread: async (threadId, title) => {
187
+ try {
188
+ await node.threads.create(node.auth, {
189
+ id: threadId, title,
190
+ idempotency_key: crypto.randomUUID(),
191
+ retry_until: new Date(Date.now() + 86_400_000).toISOString(),
192
+ });
193
+ }
194
+ catch (error) {
195
+ if (!(error instanceof OnlyneError) || error.error.code !== 'id_conflict')
196
+ throw error;
197
+ }
198
+ },
199
+ // A target this node cannot name yet is a queue condition, not a peer refusal: the run's
200
+ // result stays pending until discovery finds the controller.
201
+ resolveTarget: async (id) => { await node.discovery.resolve(id); },
202
+ send: (controller, message) => node.client.send(controller, message, { response: 'none', execution: 'existing' }),
203
+ };
204
+ mounts = createMountService({
205
+ owner, config: config.mounts, servers: config.servers, storage,
206
+ connections, transport,
207
+ ...(options.log === undefined ? {} : { log: options.log }),
208
+ });
209
+ await mounts.start();
210
+ const mountService = mounts;
211
+ const gatewayAuth = { actor: owner };
212
+ for (const [index, entry] of config.servers.entries()) {
213
+ const controllers = Array.from(new Set([owner, ...(entry.controllers ?? [])]));
214
+ const connection = serverEntries[index].connection;
215
+ const capabilities = connection.capabilities;
216
+ // The effective catalog: live tools when the start succeeded, the cached ones when it did
217
+ // not, so a down server still advertises the operations a later call can refresh.
218
+ const definition = resourceOf(owner, serverEntries[index].server, toolsByName.get(entry.name) ?? [], controllers, {
219
+ resources: resourcesByName.get(entry.name) ?? [],
220
+ ...(capabilities === undefined ? {} : { capabilities }),
221
+ });
222
+ // RFC 0006 §3: one handler operates a resource, so the first configured controller holds
223
+ // the control right; every other controller keeps read access through the log reader list.
224
+ const resource = {
225
+ resource_ref: definition.resource_ref,
226
+ kind: 'mcp',
227
+ operations: definition.operations,
228
+ binding: { handler: entry.controllers?.[0] ?? owner, cursor: '0' },
229
+ log_readers: definition.log_readers,
230
+ revision: 'rev-1',
231
+ event_seq: '0',
232
+ retention_ms: 0,
233
+ data: definition.data,
234
+ };
235
+ await registerResource(node, gatewayAuth, resource);
236
+ }
237
+ for (const { resource } of mountService.resources()) {
238
+ await registerResource(node, gatewayAuth, resource);
239
+ }
240
+ // The node is the resource endpoint, so it subscribes locally to every listed resource when
241
+ // the server declares `resources.subscribe` (RFC 0015 §4). A server without that capability
242
+ // holds no subscriptions; a failure here is logged and does not take the gateway down.
243
+ for (const entry of serverEntries) {
244
+ try {
245
+ await bridge.syncSubscriptions(entry.server.name);
246
+ }
247
+ catch (error) {
248
+ options.log?.('mcp.resources.subscribe.failed', { server: entry.server.name, error: String(error) });
249
+ }
250
+ }
251
+ return {
252
+ node, config, connections, bridge, mounts: mountService,
253
+ status: () => mountService.status(),
254
+ async stop() {
255
+ await mountService.stop();
256
+ node.client.stopMaintenance();
257
+ await bridge.close();
258
+ for (const connection of connections.values())
259
+ await connection.close();
260
+ },
261
+ };
262
+ }
263
+ /** Registration is idempotent for the same definition; a changed definition is a real conflict. */
264
+ async function registerResource(node, auth, resource) {
265
+ try {
266
+ await node.resources.describe(auth, resource.resource_ref);
267
+ }
268
+ catch (error) {
269
+ if (!(error instanceof OnlyneError) || error.error.code !== 'not_found')
270
+ throw error;
271
+ await node.resources.register(auth, resource);
272
+ }
273
+ }
274
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/main.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bun
2
+ export {};
3
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":""}