@jini-ai/mcp 0.1.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/LICENSE +201 -0
- package/dist/agent-install/index.d.ts +9 -0
- package/dist/agent-install/index.d.ts.map +1 -0
- package/dist/agent-install/index.js +9 -0
- package/dist/agent-install/index.js.map +1 -0
- package/dist/agent-install/install.d.ts +97 -0
- package/dist/agent-install/install.d.ts.map +1 -0
- package/dist/agent-install/install.js +410 -0
- package/dist/agent-install/install.js.map +1 -0
- package/dist/bin/serve.d.ts +75 -0
- package/dist/bin/serve.d.ts.map +1 -0
- package/dist/bin/serve.js +79 -0
- package/dist/bin/serve.js.map +1 -0
- package/dist/client/client.d.ts +48 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +242 -0
- package/dist/client/client.js.map +1 -0
- package/dist/client/index.d.ts +8 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +8 -0
- package/dist/client/index.js.map +1 -0
- package/dist/core/config.d.ts +157 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +475 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/index.d.ts +14 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +14 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/install-info.d.ts +69 -0
- package/dist/core/install-info.d.ts.map +1 -0
- package/dist/core/install-info.js +79 -0
- package/dist/core/install-info.js.map +1 -0
- package/dist/core/oauth.d.ts +274 -0
- package/dist/core/oauth.d.ts.map +1 -0
- package/dist/core/oauth.js +667 -0
- package/dist/core/oauth.js.map +1 -0
- package/dist/core/secure-write.d.ts +17 -0
- package/dist/core/secure-write.d.ts.map +1 -0
- package/dist/core/secure-write.js +72 -0
- package/dist/core/secure-write.js.map +1 -0
- package/dist/core/tokens.d.ts +72 -0
- package/dist/core/tokens.d.ts.map +1 -0
- package/dist/core/tokens.js +197 -0
- package/dist/core/tokens.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/server/daemon-client.d.ts +21 -0
- package/dist/server/daemon-client.d.ts.map +1 -0
- package/dist/server/daemon-client.js +176 -0
- package/dist/server/daemon-client.js.map +1 -0
- package/dist/server/index.d.ts +18 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +18 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/resource-protocol.d.ts +38 -0
- package/dist/server/resource-protocol.d.ts.map +1 -0
- package/dist/server/resource-protocol.js +68 -0
- package/dist/server/resource-protocol.js.map +1 -0
- package/dist/server/resources/active-resource.d.ts +12 -0
- package/dist/server/resources/active-resource.d.ts.map +1 -0
- package/dist/server/resources/active-resource.js +46 -0
- package/dist/server/resources/active-resource.js.map +1 -0
- package/dist/server/tool-protocol.d.ts +45 -0
- package/dist/server/tool-protocol.d.ts.map +1 -0
- package/dist/server/tool-protocol.js +74 -0
- package/dist/server/tool-protocol.js.map +1 -0
- package/dist/server/tool-server.d.ts +105 -0
- package/dist/server/tool-server.d.ts.map +1 -0
- package/dist/server/tool-server.js +96 -0
- package/dist/server/tool-server.js.map +1 -0
- package/dist/server/tools/delegated-tool.d.ts +15 -0
- package/dist/server/tools/delegated-tool.d.ts.map +1 -0
- package/dist/server/tools/delegated-tool.js +90 -0
- package/dist/server/tools/delegated-tool.js.map +1 -0
- package/dist/server/tools/run-tools.d.ts +14 -0
- package/dist/server/tools/run-tools.d.ts.map +1 -0
- package/dist/server/tools/run-tools.js +142 -0
- package/dist/server/tools/run-tools.js.map +1 -0
- package/dist/server/tools/tool-catalog-tools.d.ts +8 -0
- package/dist/server/tools/tool-catalog-tools.d.ts.map +1 -0
- package/dist/server/tools/tool-catalog-tools.js +66 -0
- package/dist/server/tools/tool-catalog-tools.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @jini-ai/mcp/server/tool-server
|
|
3
|
+
*
|
|
4
|
+
* `createMcpToolServer` — the generic stdio MCP server hosting mechanism.
|
|
5
|
+
* Ported from the *mechanism* of OD's `apps/daemon/src/mcp.ts` `runMcpStdio`
|
|
6
|
+
* (idle-exit lifecycle, `Server` + `StdioServerTransport` wiring, holding the
|
|
7
|
+
* process open until stdin closes) with the OD-specific parts — the
|
|
8
|
+
* hardcoded 18-tool `TOOL_DEFS`, the `od://` resource scheme, the
|
|
9
|
+
* project/skill/plugin `instructions` prose — replaced by a caller-supplied,
|
|
10
|
+
* bounded, explicit `tools: readonly McpToolDef[]` list. A caller is the
|
|
11
|
+
* *first* user of this mechanism, not the only one it will ever support (see
|
|
12
|
+
* `source-map.md`'s 2026-07-21 addition for the full design-decision note).
|
|
13
|
+
*
|
|
14
|
+
* `tools` capability is always advertised (`capabilities: {tools: {}}`).
|
|
15
|
+
* `resources` capability (`ListResourcesRequestSchema`/
|
|
16
|
+
* `ReadResourceRequestSchema`, mirroring the tools wiring one section down)
|
|
17
|
+
* is advertised only when the caller supplies at least one entry in the
|
|
18
|
+
* optional `resources` option — a 2026-07-21 addition once this package
|
|
19
|
+
* shipped its first genuinely portable resource (`../resources/
|
|
20
|
+
* active-resource.js`'s `jini://active`, see that file's module doc and
|
|
21
|
+
* `source-map.md`'s 2026-07-21 addition for why the *rest* of OD's resource
|
|
22
|
+
* surface — `od://skills/...`, `od://design-systems/...` — still has no
|
|
23
|
+
* kernel equivalent and stays unported). A caller passing no `resources`
|
|
24
|
+
* gets the exact same `capabilities: {tools: {}}`-only server this module
|
|
25
|
+
* always produced.
|
|
26
|
+
*/
|
|
27
|
+
import type { Readable, Writable } from 'node:stream';
|
|
28
|
+
import type { ServerOptions } from '@modelcontextprotocol/sdk/server/index.js';
|
|
29
|
+
import { CallToolRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
30
|
+
import type { CallToolResult, Implementation, ListResourcesResult, ListToolsResult, ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';
|
|
31
|
+
import { type McpResourceDef } from './resource-protocol.js';
|
|
32
|
+
import { type McpToolDef } from './tool-protocol.js';
|
|
33
|
+
/**
|
|
34
|
+
* The minimal surface this module needs from an MCP `Server` instance. A real
|
|
35
|
+
* `@modelcontextprotocol/sdk` `Server` satisfies this structurally (its own `setRequestHandler`
|
|
36
|
+
* is more general — one generic method covering every request schema — and TS accepts the
|
|
37
|
+
* narrowing); a test can substitute a lightweight fake without spinning up a real transport.
|
|
38
|
+
* Method-shorthand syntax (not arrow-typed properties) is deliberate: it keeps parameter checking
|
|
39
|
+
* bivariant, so a handler typed against a *specific* request shape (as the two internal handlers
|
|
40
|
+
* below are) is still assignable here even under `strict`.
|
|
41
|
+
*/
|
|
42
|
+
export interface McpServerLike {
|
|
43
|
+
setRequestHandler(schema: typeof ListToolsRequestSchema, handler: () => Promise<ListToolsResult>): void;
|
|
44
|
+
setRequestHandler(schema: typeof CallToolRequestSchema, handler: (request: {
|
|
45
|
+
params: {
|
|
46
|
+
name: string;
|
|
47
|
+
arguments?: Record<string, unknown>;
|
|
48
|
+
};
|
|
49
|
+
}) => Promise<CallToolResult>): void;
|
|
50
|
+
setRequestHandler(schema: typeof ListResourcesRequestSchema, handler: () => Promise<ListResourcesResult>): void;
|
|
51
|
+
setRequestHandler(schema: typeof ReadResourceRequestSchema, handler: (request: {
|
|
52
|
+
params: {
|
|
53
|
+
uri: string;
|
|
54
|
+
};
|
|
55
|
+
}) => Promise<ReadResourceResult>): void;
|
|
56
|
+
connect(transport: McpTransportLike): Promise<void>;
|
|
57
|
+
}
|
|
58
|
+
/** The minimal surface this module needs from an MCP transport. A real `StdioServerTransport` satisfies this structurally. */
|
|
59
|
+
export interface McpTransportLike {
|
|
60
|
+
onmessage?: ((message: unknown) => void) | undefined;
|
|
61
|
+
onclose?: (() => void) | undefined;
|
|
62
|
+
close(): Promise<void>;
|
|
63
|
+
}
|
|
64
|
+
export interface McpToolServerOptions {
|
|
65
|
+
/** Advertised to the MCP client during initialization. */
|
|
66
|
+
readonly name: string;
|
|
67
|
+
readonly version: string;
|
|
68
|
+
/** The bounded, explicit tool list this server hosts. Duplicate names throw at construction time. */
|
|
69
|
+
readonly tools: readonly McpToolDef[];
|
|
70
|
+
/** The bounded, explicit read-only resource list this server hosts. Duplicate uris throw at construction time. Omit (or pass an empty array) for a tools-only server — `capabilities.resources` is only advertised when this is non-empty. */
|
|
71
|
+
readonly resources?: readonly McpResourceDef[];
|
|
72
|
+
/** Resolves the daemon HTTP base URL once, at the start of {@link McpToolServerHandle.run}. May be sync or async (e.g. wraps `@jini-ai/cli`'s `resolveDaemonUrl`). */
|
|
73
|
+
readonly resolveBaseUrl: () => Promise<string> | string;
|
|
74
|
+
/** Free-text guidance surfaced to the MCP client alongside the tool list. Optional — omit for a caller with nothing to add beyond each tool's own `description`. */
|
|
75
|
+
readonly instructions?: string;
|
|
76
|
+
/** Idle-exit window in ms. Defaults to {@link DEFAULT_IDLE_MS}. */
|
|
77
|
+
readonly idleMs?: number;
|
|
78
|
+
/** Defaults to the global `fetch`; threaded into every tool call's {@link McpToolContext}. */
|
|
79
|
+
readonly fetchImpl?: typeof fetch;
|
|
80
|
+
/** Defaults to `process.stdin`; inject for tests (or an alternate stdio pair). */
|
|
81
|
+
readonly stdin?: Readable;
|
|
82
|
+
/** Defaults to `process.stdout`; inject for tests. */
|
|
83
|
+
readonly stdout?: Writable;
|
|
84
|
+
/** Test/embedding seam: builds the underlying `Server`. Defaults to the real `@modelcontextprotocol/sdk` `Server`. */
|
|
85
|
+
readonly createServer?: (info: Implementation, options: ServerOptions) => McpServerLike;
|
|
86
|
+
/** Test/embedding seam: builds the underlying transport. Defaults to the real `StdioServerTransport`. */
|
|
87
|
+
readonly createTransport?: (stdin?: Readable, stdout?: Writable) => McpTransportLike;
|
|
88
|
+
}
|
|
89
|
+
export interface McpToolServerHandle {
|
|
90
|
+
/**
|
|
91
|
+
* Resolves the daemon base URL, connects the MCP server to its transport, and holds the process
|
|
92
|
+
* open until the client disconnects (stdin EOF) or the idle-exit window elapses. Resolves once
|
|
93
|
+
* the transport has closed.
|
|
94
|
+
*/
|
|
95
|
+
run(): Promise<void>;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Builds a stdio MCP server hosting `options.tools` (and, optionally, `options.resources`).
|
|
99
|
+
* Construction is synchronous and cheap (validates tool-name uniqueness via
|
|
100
|
+
* {@link buildToolIndex} and resource-uri uniqueness via {@link buildResourceIndex}); all I/O —
|
|
101
|
+
* resolving the daemon URL, connecting the transport, serving requests — happens in the returned
|
|
102
|
+
* handle's `run()`.
|
|
103
|
+
*/
|
|
104
|
+
export declare function createMcpToolServer(options: McpToolServerOptions): McpToolServerHandle;
|
|
105
|
+
//# sourceMappingURL=tool-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-server.d.ts","sourceRoot":"","sources":["../../src/server/tool-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { CallToolRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
4
|
+
import { createMcpIdleExitController } from '../client/client.js';
|
|
5
|
+
import { buildResourceIndex, handleResourceRead, resourcesToList } from './resource-protocol.js';
|
|
6
|
+
import { buildToolIndex, handleToolCall, toolsToList } from './tool-protocol.js';
|
|
7
|
+
/** Auto-exit an idle server after this long with no tool activity — same ceiling the OD origin used for its own stdio MCP server. */
|
|
8
|
+
const DEFAULT_IDLE_MS = 30 * 60 * 1000;
|
|
9
|
+
function defaultCreateServer(info, options) {
|
|
10
|
+
return new Server(info, options);
|
|
11
|
+
}
|
|
12
|
+
function defaultCreateTransport(stdin, stdout) {
|
|
13
|
+
return new StdioServerTransport(stdin, stdout);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Builds a stdio MCP server hosting `options.tools` (and, optionally, `options.resources`).
|
|
17
|
+
* Construction is synchronous and cheap (validates tool-name uniqueness via
|
|
18
|
+
* {@link buildToolIndex} and resource-uri uniqueness via {@link buildResourceIndex}); all I/O —
|
|
19
|
+
* resolving the daemon URL, connecting the transport, serving requests — happens in the returned
|
|
20
|
+
* handle's `run()`.
|
|
21
|
+
*/
|
|
22
|
+
export function createMcpToolServer(options) {
|
|
23
|
+
const toolIndex = buildToolIndex(options.tools);
|
|
24
|
+
const resources = options.resources ?? [];
|
|
25
|
+
const resourceIndex = buildResourceIndex(resources);
|
|
26
|
+
const createServer = options.createServer ?? defaultCreateServer;
|
|
27
|
+
const createTransport = options.createTransport ?? defaultCreateTransport;
|
|
28
|
+
return {
|
|
29
|
+
async run() {
|
|
30
|
+
const resolvedBaseUrl = await options.resolveBaseUrl();
|
|
31
|
+
const ctx = {
|
|
32
|
+
baseUrl: String(resolvedBaseUrl).replace(/\/$/, ''),
|
|
33
|
+
fetchImpl: options.fetchImpl ?? fetch,
|
|
34
|
+
};
|
|
35
|
+
let closeTransportForIdle = null;
|
|
36
|
+
const idleExit = createMcpIdleExitController({
|
|
37
|
+
idleMs: options.idleMs ?? DEFAULT_IDLE_MS,
|
|
38
|
+
onIdle: () => closeTransportForIdle?.(),
|
|
39
|
+
});
|
|
40
|
+
const withActivity = (handler) => (...args) => idleExit.trackRequest(() => handler(...args));
|
|
41
|
+
const server = createServer({ name: options.name, version: options.version }, {
|
|
42
|
+
capabilities: { tools: {}, ...(resources.length > 0 ? { resources: {} } : {}) },
|
|
43
|
+
...(options.instructions !== undefined ? { instructions: options.instructions } : {}),
|
|
44
|
+
});
|
|
45
|
+
server.setRequestHandler(ListToolsRequestSchema, withActivity(async () => ({ tools: toolsToList(options.tools) })));
|
|
46
|
+
server.setRequestHandler(CallToolRequestSchema, withActivity(async (request) => handleToolCall(request.params.name, request.params.arguments, toolIndex, ctx)));
|
|
47
|
+
if (resources.length > 0) {
|
|
48
|
+
server.setRequestHandler(ListResourcesRequestSchema, withActivity(async () => ({ resources: resourcesToList(resources) })));
|
|
49
|
+
server.setRequestHandler(ReadResourceRequestSchema, withActivity(async (request) => handleResourceRead(request.params.uri, resourceIndex, ctx)));
|
|
50
|
+
}
|
|
51
|
+
const transport = createTransport(options.stdin, options.stdout);
|
|
52
|
+
try {
|
|
53
|
+
closeTransportForIdle = () => {
|
|
54
|
+
void transport.close().catch(() => { });
|
|
55
|
+
};
|
|
56
|
+
await server.connect(transport);
|
|
57
|
+
// `connect()` sets `transport.onmessage` to its own protocol-dispatch handler; wrap it so
|
|
58
|
+
// every inbound message also counts as activity for the idle-exit timer, without losing
|
|
59
|
+
// the SDK's own routing.
|
|
60
|
+
const sdkOnMessage = transport.onmessage;
|
|
61
|
+
transport.onmessage = (message) => {
|
|
62
|
+
idleExit.noteActivity();
|
|
63
|
+
sdkOnMessage?.(message);
|
|
64
|
+
};
|
|
65
|
+
const stdin = options.stdin ?? process.stdin;
|
|
66
|
+
await new Promise((resolve) => {
|
|
67
|
+
const sdkOnClose = transport.onclose;
|
|
68
|
+
let finished = false;
|
|
69
|
+
const done = () => {
|
|
70
|
+
if (finished)
|
|
71
|
+
return;
|
|
72
|
+
finished = true;
|
|
73
|
+
idleExit.dispose();
|
|
74
|
+
resolve();
|
|
75
|
+
};
|
|
76
|
+
transport.onclose = () => {
|
|
77
|
+
sdkOnClose?.();
|
|
78
|
+
done();
|
|
79
|
+
};
|
|
80
|
+
const closeTransportForStdin = () => {
|
|
81
|
+
void transport.close().catch(() => done());
|
|
82
|
+
};
|
|
83
|
+
// Hold the process open until the client disconnects (stdin EOF) — `connect()` only
|
|
84
|
+
// starts the transport, it doesn't wait for the stream to close.
|
|
85
|
+
stdin.once('end', closeTransportForStdin);
|
|
86
|
+
stdin.once('close', closeTransportForStdin);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
idleExit.dispose();
|
|
91
|
+
closeTransportForIdle = null;
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=tool-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-server.js","sourceRoot":"","sources":["../../src/server/tool-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type McpToolDef } from '../tool-protocol.js';
|
|
2
|
+
export interface CreateExecuteDelegatedToolToolOptions {
|
|
3
|
+
/** The one run this MCP server process — and therefore this tool instance — is scoped to. */
|
|
4
|
+
readonly runId: string;
|
|
5
|
+
/** Generates each call's `toolUseId`. @default node:crypto randomUUID */
|
|
6
|
+
readonly generateToolUseId?: () => string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Builds the `execute_delegated_tool` tool def for one specific `runId`. A fresh MCP server
|
|
10
|
+
* process (one per spawned `claude` run, see `../../bin/serve.js`) calls this once at startup;
|
|
11
|
+
* every `tools/call` for the returned def's `name` during that process's lifetime executes
|
|
12
|
+
* against the same run.
|
|
13
|
+
*/
|
|
14
|
+
export declare function createExecuteDelegatedToolTool(options: CreateExecuteDelegatedToolToolOptions): McpToolDef;
|
|
15
|
+
//# sourceMappingURL=delegated-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delegated-tool.d.ts","sourceRoot":"","sources":["../../../src/server/tools/delegated-tool.ts"],"names":[],"mappings":"AA4BA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAOrE,MAAM,WAAW,qCAAqC;IACpD,6FAA6F;IAC7F,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,yEAAyE;IACzE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,MAAM,CAAC;CAC3C;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,qCAAqC,GAAG,UAAU,CAuDzG"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @jini-ai/mcp/server/tools/delegated-tool
|
|
3
|
+
*
|
|
4
|
+
* `execute_delegated_tool` — the MCP-callback half of gap 3's continuation transport (see
|
|
5
|
+
* `packages/daemon/source-map.md`'s "run/chat orchestration gap 3, part 1" addition and this
|
|
6
|
+
* package's own dated section in `source-map.md` for the rest of the spike). The swarm-consensus
|
|
7
|
+
* Final Recommendation asked for exactly this: "inject the already-shipped MCP host into one
|
|
8
|
+
* MCP-capable CLI's launch config, prove a tool round-trip through the existing
|
|
9
|
+
* `delegated-tool-bridge.ts`." Where `../tools/run-tools.js`'s tools proxy generic
|
|
10
|
+
* run-lifecycle HTTP endpoints, this tool proxies the new `POST /api/delegated-tool-calls`
|
|
11
|
+
* daemon route (`packages/http/src/delegated-tools.ts`), which is the one and only thing that
|
|
12
|
+
* calls into `createDelegatedToolBridge` (`packages/daemon/src/delegated-tool-bridge.ts`) — the
|
|
13
|
+
* same `ToolExecutor` deny-by-default gate every other tool-execution path in this codebase
|
|
14
|
+
* already uses. No parallel authorization mechanism is introduced anywhere on this path.
|
|
15
|
+
*
|
|
16
|
+
* Unlike every other tool this package ships (`run-tools.ts`'s five tools, plain static
|
|
17
|
+
* objects), this one is a **factory**. The MCP server subprocess a `claude` run spawns via
|
|
18
|
+
* `.mcp.json` (see `../../bin/serve.js`) is scoped to exactly one `runId` for its entire
|
|
19
|
+
* lifetime — the daemon injected that run id into the subprocess's own environment at spawn
|
|
20
|
+
* time, before the model ever said a word. `runId` is therefore closed over at construction
|
|
21
|
+
* time, not accepted as a per-call tool argument: a model has no legitimate way to pick, or
|
|
22
|
+
* need to know, which run it is currently inside, and letting it supply one would open a
|
|
23
|
+
* confused-deputy path (one run's MCP subprocess executing a tool call "as" a different run).
|
|
24
|
+
* `toolUseId` is likewise generated per call (`randomUUID` by default), not model-supplied — a
|
|
25
|
+
* model has no legitimate reason to choose its own correlation id either.
|
|
26
|
+
*/
|
|
27
|
+
import { randomUUID } from 'node:crypto';
|
|
28
|
+
import { postDaemonJson } from '../daemon-client.js';
|
|
29
|
+
import { requireString } from '../tool-protocol.js';
|
|
30
|
+
/**
|
|
31
|
+
* Builds the `execute_delegated_tool` tool def for one specific `runId`. A fresh MCP server
|
|
32
|
+
* process (one per spawned `claude` run, see `../../bin/serve.js`) calls this once at startup;
|
|
33
|
+
* every `tools/call` for the returned def's `name` during that process's lifetime executes
|
|
34
|
+
* against the same run.
|
|
35
|
+
*/
|
|
36
|
+
export function createExecuteDelegatedToolTool(options) {
|
|
37
|
+
const { runId } = options;
|
|
38
|
+
const generateToolUseId = options.generateToolUseId ?? randomUUID;
|
|
39
|
+
return {
|
|
40
|
+
name: 'execute_delegated_tool',
|
|
41
|
+
description: 'Execute a Jini-registered tool (never an agent-vendor-specific tool name) against the current run, routed through the daemon\'s ToolExecutor deny-by-default gate — the same authorization/confirmation/audit path every other tool-execution mechanism in this host uses. Returns {result}, a ToolExecutionResult: {status, output?, truncated?, error?} where status is one of completed|denied|confirmation-denied|timed-out|cancelled|failed.',
|
|
42
|
+
inputSchema: {
|
|
43
|
+
type: 'object',
|
|
44
|
+
properties: {
|
|
45
|
+
toolId: {
|
|
46
|
+
type: 'string',
|
|
47
|
+
description: 'Jini registry tool id to invoke. Required.',
|
|
48
|
+
},
|
|
49
|
+
input: {
|
|
50
|
+
// `type` is load-bearing, not decoration. Declared without one, an MCP client has no
|
|
51
|
+
// signal that this property carries structured data, and at least one real client
|
|
52
|
+
// (Claude Code, observed 2026-07-26) then delivers the model's object as a raw JSON
|
|
53
|
+
// *string* — which every Jini tool rejects, because a tool's input is a record or
|
|
54
|
+
// absent (`@jini-ai/daemon`'s `toCapabilityInput` refuses a string by name rather than
|
|
55
|
+
// coercing it). The effect was that only no-input tools were callable at all.
|
|
56
|
+
//
|
|
57
|
+
// Object-only is narrower than "arbitrary JSON" and deliberately so: it is exactly
|
|
58
|
+
// what every registered tool accepts today, it matches MCP's own convention that tool
|
|
59
|
+
// arguments are objects, and widening it later (a union type, say) is additive.
|
|
60
|
+
type: 'object',
|
|
61
|
+
additionalProperties: true,
|
|
62
|
+
description: 'JSON object of input fields for the tool. Optional; omit for a tool that takes no input. Must be an object, not a JSON-encoded string.',
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
required: ['toolId'],
|
|
66
|
+
additionalProperties: false,
|
|
67
|
+
},
|
|
68
|
+
annotations: {
|
|
69
|
+
readOnlyHint: false,
|
|
70
|
+
idempotentHint: false,
|
|
71
|
+
destructiveHint: false,
|
|
72
|
+
openWorldHint: false,
|
|
73
|
+
title: 'Execute a Jini-registered tool',
|
|
74
|
+
},
|
|
75
|
+
handler: async (args, ctx) => {
|
|
76
|
+
requireString(args.toolId, 'toolId');
|
|
77
|
+
const body = {
|
|
78
|
+
runId,
|
|
79
|
+
toolUseId: generateToolUseId(),
|
|
80
|
+
toolId: args.toolId,
|
|
81
|
+
input: args.input,
|
|
82
|
+
};
|
|
83
|
+
const data = await postDaemonJson(ctx.baseUrl, '/api/delegated-tool-calls', body, {
|
|
84
|
+
fetchImpl: ctx.fetchImpl,
|
|
85
|
+
});
|
|
86
|
+
return data.result;
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=delegated-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delegated-tool.js","sourceRoot":"","sources":["../../../src/server/tools/delegated-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAmB,MAAM,qBAAqB,CAAC;AAcrE;;;;;GAKG;AACH,MAAM,UAAU,8BAA8B,CAAC,OAA8C;IAC3F,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAC1B,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,IAAI,UAAU,CAAC;IAElE,OAAO;QACL,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EACT,mbAAmb;QACrb,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,4CAA4C;iBAC1D;gBACD,KAAK,EAAE;oBACL,qFAAqF;oBACrF,kFAAkF;oBAClF,oFAAoF;oBACpF,kFAAkF;oBAClF,uFAAuF;oBACvF,8EAA8E;oBAC9E,EAAE;oBACF,mFAAmF;oBACnF,sFAAsF;oBACtF,gFAAgF;oBAChF,IAAI,EAAE,QAAQ;oBACd,oBAAoB,EAAE,IAAI;oBAC1B,WAAW,EAAE,wIAAwI;iBACtJ;aACF;YACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;YACpB,oBAAoB,EAAE,KAAK;SAC5B;QACD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,cAAc,EAAE,KAAK;YACrB,eAAe,EAAE,KAAK;YACtB,aAAa,EAAE,KAAK;YACpB,KAAK,EAAE,gCAAgC;SACxC;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;YAC3B,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YACrC,MAAM,IAAI,GAA4B;gBACpC,KAAK;gBACL,SAAS,EAAE,iBAAiB,EAAE;gBAC9B,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;aAClB,CAAC;YACF,MAAM,IAAI,GAAG,MAAM,cAAc,CAA+B,GAAG,CAAC,OAAO,EAAE,2BAA2B,EAAE,IAAI,EAAE;gBAC9G,SAAS,EAAE,GAAG,CAAC,SAAS;aACzB,CAAC,CAAC;YACH,OAAO,IAAI,CAAC,MAAM,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type McpToolDef } from '../tool-protocol.js';
|
|
2
|
+
/** `start_run` -> `POST /api/runs` (`packages/http/src/runs.ts`'s `runStartRoute`). */
|
|
3
|
+
export declare const startRunTool: McpToolDef;
|
|
4
|
+
/** `get_run` -> `GET /api/runs/:runId` (`packages/http/src/runs.ts`'s `runStatusRoute`). */
|
|
5
|
+
export declare const getRunTool: McpToolDef;
|
|
6
|
+
/** `cancel_run` -> `POST /api/runs/:runId/cancel` (`packages/http/src/runs.ts`'s `runCancelRoute`). */
|
|
7
|
+
export declare const cancelRunTool: McpToolDef;
|
|
8
|
+
/** `get_active_context` -> `GET /api/active` (`packages/http/src/active-context.ts`'s `getActiveRoute`). */
|
|
9
|
+
export declare const getActiveContextTool: McpToolDef;
|
|
10
|
+
/** `list_agents` -> `GET /api/agents` (`packages/http/src/agents.ts`'s `agentListRoute`). */
|
|
11
|
+
export declare const listAgentsTool: McpToolDef;
|
|
12
|
+
/** The full set of kernel-run tool defs this package ships, ready to pass as `createMcpToolServer`'s `tools` option. */
|
|
13
|
+
export declare const RUN_TOOLS: readonly McpToolDef[];
|
|
14
|
+
//# sourceMappingURL=run-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-tools.d.ts","sourceRoot":"","sources":["../../../src/server/tools/run-tools.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAmBrE,uFAAuF;AACvF,eAAO,MAAM,YAAY,EAAE,UAiC1B,CAAC;AAEF,4FAA4F;AAC5F,eAAO,MAAM,UAAU,EAAE,UAgBxB,CAAC;AAEF,uGAAuG;AACvG,eAAO,MAAM,aAAa,EAAE,UAoB3B,CAAC;AAOF,4GAA4G;AAC5G,eAAO,MAAM,oBAAoB,EAAE,UAgBlC,CAAC;AAEF,6FAA6F;AAC7F,eAAO,MAAM,cAAc,EAAE,UAM5B,CAAC;AAEF,wHAAwH;AACxH,eAAO,MAAM,SAAS,EAAE,SAAS,UAAU,EAM1C,CAAC"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @jini-ai/mcp/server/tools/run-tools
|
|
3
|
+
*
|
|
4
|
+
* The first real, concrete `McpToolDef`s hosted by `createMcpToolServer`
|
|
5
|
+
* (`../tool-server.js`) — a proxy over `@jini-ai/http`'s already-gated `Run`
|
|
6
|
+
* transport (`packages/http/src/runs.ts`) plus the generic active-resource
|
|
7
|
+
* channel (`packages/http/src/active-context.ts`) and the agent-def listing
|
|
8
|
+
* (`packages/http/src/agents.ts`). Each tool's `handler` does nothing but
|
|
9
|
+
* validate its own arguments and proxy a single HTTP call via
|
|
10
|
+
* `../daemon-client.js` — no separate authorization mechanism, no caching,
|
|
11
|
+
* no state: whatever `@jini-ai/http`'s same-origin guard / bearer-auth
|
|
12
|
+
* middleware already enforces on the target route is the only gate a call
|
|
13
|
+
* here passes through (see `source-map.md`'s 2026-07-21 addition for the
|
|
14
|
+
* full origin-mapping and what was deliberately not ported).
|
|
15
|
+
*/
|
|
16
|
+
import { getDaemonJson, postDaemonJson } from '../daemon-client.js';
|
|
17
|
+
import { requireString } from '../tool-protocol.js';
|
|
18
|
+
const READ_ANNOTATIONS = {
|
|
19
|
+
readOnlyHint: true,
|
|
20
|
+
idempotentHint: true,
|
|
21
|
+
openWorldHint: false,
|
|
22
|
+
};
|
|
23
|
+
const WRITE_ANNOTATIONS = {
|
|
24
|
+
readOnlyHint: false,
|
|
25
|
+
idempotentHint: false,
|
|
26
|
+
destructiveHint: false,
|
|
27
|
+
openWorldHint: false,
|
|
28
|
+
};
|
|
29
|
+
function optionalNonEmptyString(value) {
|
|
30
|
+
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
31
|
+
}
|
|
32
|
+
/** `start_run` -> `POST /api/runs` (`packages/http/src/runs.ts`'s `runStartRoute`). */
|
|
33
|
+
export const startRunTool = {
|
|
34
|
+
name: 'start_run',
|
|
35
|
+
description: 'Start a new run against a caller-supplied contextRef (an opaque identity the run belongs to — this kernel has no project/conversation noun, just that one caller-chosen string). Returns {run, started} immediately; poll get_run(run.id) for completion.',
|
|
36
|
+
inputSchema: {
|
|
37
|
+
type: 'object',
|
|
38
|
+
properties: {
|
|
39
|
+
contextRef: {
|
|
40
|
+
type: 'string',
|
|
41
|
+
description: 'Opaque caller-supplied identity the run belongs to. Required.',
|
|
42
|
+
},
|
|
43
|
+
agentId: {
|
|
44
|
+
type: 'string',
|
|
45
|
+
description: 'Which registered agent should drive this run. Optional; the host may default this.',
|
|
46
|
+
},
|
|
47
|
+
idempotencyKey: {
|
|
48
|
+
type: 'string',
|
|
49
|
+
description: 'Starting twice with the same key returns the original run instead of starting a second one. Optional.',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
required: ['contextRef'],
|
|
53
|
+
additionalProperties: false,
|
|
54
|
+
},
|
|
55
|
+
annotations: { ...WRITE_ANNOTATIONS, title: 'Start a run' },
|
|
56
|
+
handler: async (args, ctx) => {
|
|
57
|
+
requireString(args.contextRef, 'contextRef');
|
|
58
|
+
const body = { contextRef: args.contextRef };
|
|
59
|
+
const agentId = optionalNonEmptyString(args.agentId);
|
|
60
|
+
if (agentId !== undefined)
|
|
61
|
+
body.agentId = agentId;
|
|
62
|
+
const idempotencyKey = optionalNonEmptyString(args.idempotencyKey);
|
|
63
|
+
if (idempotencyKey !== undefined)
|
|
64
|
+
body.idempotencyKey = idempotencyKey;
|
|
65
|
+
return postDaemonJson(ctx.baseUrl, '/api/runs', body, { fetchImpl: ctx.fetchImpl });
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
/** `get_run` -> `GET /api/runs/:runId` (`packages/http/src/runs.ts`'s `runStatusRoute`). */
|
|
69
|
+
export const getRunTool = {
|
|
70
|
+
name: 'get_run',
|
|
71
|
+
description: 'Poll a run started by start_run. Returns {run} with the run\'s current state (queued|running|succeeded|failed|canceled, per @jini-ai/protocol\'s RunState).',
|
|
72
|
+
inputSchema: {
|
|
73
|
+
type: 'object',
|
|
74
|
+
properties: {
|
|
75
|
+
runId: { type: 'string', description: 'Run id returned by start_run.' },
|
|
76
|
+
},
|
|
77
|
+
required: ['runId'],
|
|
78
|
+
additionalProperties: false,
|
|
79
|
+
},
|
|
80
|
+
annotations: { ...READ_ANNOTATIONS, title: 'Check a run' },
|
|
81
|
+
handler: async (args, ctx) => {
|
|
82
|
+
requireString(args.runId, 'runId');
|
|
83
|
+
return getDaemonJson(ctx.baseUrl, `/api/runs/${encodeURIComponent(args.runId)}`, { fetchImpl: ctx.fetchImpl });
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
/** `cancel_run` -> `POST /api/runs/:runId/cancel` (`packages/http/src/runs.ts`'s `runCancelRoute`). */
|
|
87
|
+
export const cancelRunTool = {
|
|
88
|
+
name: 'cancel_run',
|
|
89
|
+
description: 'Request cancellation of an in-flight run started by start_run. A no-op on an already-terminal run.',
|
|
90
|
+
inputSchema: {
|
|
91
|
+
type: 'object',
|
|
92
|
+
properties: {
|
|
93
|
+
runId: { type: 'string', description: 'Run id returned by start_run.' },
|
|
94
|
+
reason: { type: 'string', description: 'Optional human-readable cancellation reason.' },
|
|
95
|
+
},
|
|
96
|
+
required: ['runId'],
|
|
97
|
+
additionalProperties: false,
|
|
98
|
+
},
|
|
99
|
+
annotations: { ...WRITE_ANNOTATIONS, title: 'Cancel a run' },
|
|
100
|
+
handler: async (args, ctx) => {
|
|
101
|
+
requireString(args.runId, 'runId');
|
|
102
|
+
const body = {};
|
|
103
|
+
const reason = optionalNonEmptyString(args.reason);
|
|
104
|
+
if (reason !== undefined)
|
|
105
|
+
body.reason = reason;
|
|
106
|
+
return postDaemonJson(ctx.baseUrl, `/api/runs/${encodeURIComponent(args.runId)}/cancel`, body, { fetchImpl: ctx.fetchImpl });
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
/** `get_active_context` -> `GET /api/active` (`packages/http/src/active-context.ts`'s `getActiveRoute`). */
|
|
110
|
+
export const getActiveContextTool = {
|
|
111
|
+
name: 'get_active_context',
|
|
112
|
+
description: 'The resource (resourceRef) plus optional detail the caller last recorded as its current focus via POST /api/active — a generic, product-neutral pointer (this kernel has no "project" or "file" noun; a host maps resourceRef to whatever domain object it manages). Returns {active:false} once the pointer has aged past its TTL (5 minutes, see ACTIVE_CONTEXT_TTL_MS in packages/http/src/active-context.ts) or was never set.',
|
|
113
|
+
inputSchema: { type: 'object', properties: {}, additionalProperties: false },
|
|
114
|
+
annotations: { ...READ_ANNOTATIONS, title: 'What is the caller focused on?' },
|
|
115
|
+
handler: async (_args, ctx) => {
|
|
116
|
+
const data = await getDaemonJson(ctx.baseUrl, '/api/active', { fetchImpl: ctx.fetchImpl });
|
|
117
|
+
if (data.active !== true) {
|
|
118
|
+
return {
|
|
119
|
+
active: false,
|
|
120
|
+
hint: 'No active resource is currently recorded, or the recorded one aged out (5-minute TTL). Pass an explicit resource reference to other tools instead of relying on this fallback.',
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return data;
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
/** `list_agents` -> `GET /api/agents` (`packages/http/src/agents.ts`'s `agentListRoute`). */
|
|
127
|
+
export const listAgentsTool = {
|
|
128
|
+
name: 'list_agents',
|
|
129
|
+
description: 'List every agent def registered with this host\'s @jini-ai/agent-runtime — {id, name} pairs suitable for start_run\'s optional agentId argument. Static registration data only: this does not probe which agent binaries are actually installed on the host machine.',
|
|
130
|
+
inputSchema: { type: 'object', properties: {}, additionalProperties: false },
|
|
131
|
+
annotations: { ...READ_ANNOTATIONS, title: 'List registered agents' },
|
|
132
|
+
handler: async (_args, ctx) => getDaemonJson(ctx.baseUrl, '/api/agents', { fetchImpl: ctx.fetchImpl }),
|
|
133
|
+
};
|
|
134
|
+
/** The full set of kernel-run tool defs this package ships, ready to pass as `createMcpToolServer`'s `tools` option. */
|
|
135
|
+
export const RUN_TOOLS = [
|
|
136
|
+
startRunTool,
|
|
137
|
+
getRunTool,
|
|
138
|
+
cancelRunTool,
|
|
139
|
+
getActiveContextTool,
|
|
140
|
+
listAgentsTool,
|
|
141
|
+
];
|
|
142
|
+
//# sourceMappingURL=run-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-tools.js","sourceRoot":"","sources":["../../../src/server/tools/run-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type McpToolDef } from '../tool-protocol.js';
|
|
2
|
+
/** `search_tools` -> `GET /api/tools/search` (`packages/http/src/tool-catalog.ts`'s `toolCatalogSearchRoute`). */
|
|
3
|
+
export declare const searchToolsTool: McpToolDef;
|
|
4
|
+
/** `describe_tool` -> `GET /api/tools/:id` (`packages/http/src/tool-catalog.ts`'s `toolCatalogDescribeRoute`). */
|
|
5
|
+
export declare const describeToolTool: McpToolDef;
|
|
6
|
+
/** Both tool-catalog discovery tools, ready to pass as `createMcpToolServer`'s `tools` option. */
|
|
7
|
+
export declare const TOOL_CATALOG_TOOLS: readonly McpToolDef[];
|
|
8
|
+
//# sourceMappingURL=tool-catalog-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-catalog-tools.d.ts","sourceRoot":"","sources":["../../../src/server/tools/tool-catalog-tools.ts"],"names":[],"mappings":"AAcA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAiBrE,kHAAkH;AAClH,eAAO,MAAM,eAAe,EAAE,UAuB7B,CAAC;AAEF,kHAAkH;AAClH,eAAO,MAAM,gBAAgB,EAAE,UAiB9B,CAAC;AAEF,kGAAkG;AAClG,eAAO,MAAM,kBAAkB,EAAE,SAAS,UAAU,EAAwC,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @jini-ai/mcp/server/tools/tool-catalog-tools
|
|
3
|
+
*
|
|
4
|
+
* `search_tools` / `describe_tool` — the discovery half of `ai-control-plane.md` §29 /
|
|
5
|
+
* `PROP-tool-catalog-discovery-2026-07-26.md` §6.1, proxying `@jini-ai/http`'s
|
|
6
|
+
* `GET /api/tools/search` / `GET /api/tools/:id` exactly as `run-tools.ts`'s tools proxy
|
|
7
|
+
* `runs.ts` — no separate authorization mechanism, no caching, no state.
|
|
8
|
+
*
|
|
9
|
+
* v0 scope: no principal scoping, no versioning, no schema narrowing. Execution is unchanged —
|
|
10
|
+
* a caller still runs a discovered id through `execute_delegated_tool`
|
|
11
|
+
* (`../tools/delegated-tool.js`), which is the only thing that ever reaches `ToolExecutor`.
|
|
12
|
+
* Finding a tool id here grants nothing (`PROP` §6.3).
|
|
13
|
+
*/
|
|
14
|
+
import { getDaemonJson } from '../daemon-client.js';
|
|
15
|
+
import { requireString } from '../tool-protocol.js';
|
|
16
|
+
const READ_ANNOTATIONS = {
|
|
17
|
+
readOnlyHint: true,
|
|
18
|
+
idempotentHint: true,
|
|
19
|
+
openWorldHint: false,
|
|
20
|
+
};
|
|
21
|
+
/** `search_tools` -> `GET /api/tools/search` (`packages/http/src/tool-catalog.ts`'s `toolCatalogSearchRoute`). */
|
|
22
|
+
export const searchToolsTool = {
|
|
23
|
+
name: 'search_tools',
|
|
24
|
+
description: 'Search the durable tool catalog by keyword. Returns ranked {id, description, source, score} candidates only — no input schemas, so this stays cheap to call broadly. Call describe_tool on the 1-3 candidates that look right before calling execute_delegated_tool.',
|
|
25
|
+
inputSchema: {
|
|
26
|
+
type: 'object',
|
|
27
|
+
properties: {
|
|
28
|
+
query: { type: 'string', description: 'Keywords to search for, e.g. "navigate page" or "fill form". Required.' },
|
|
29
|
+
limit: { type: 'number', description: 'Max hits to return (1-25). Optional, defaults to 10.' },
|
|
30
|
+
},
|
|
31
|
+
required: ['query'],
|
|
32
|
+
additionalProperties: false,
|
|
33
|
+
},
|
|
34
|
+
annotations: { ...READ_ANNOTATIONS, title: 'Search the tool catalog' },
|
|
35
|
+
handler: async (args, ctx) => {
|
|
36
|
+
requireString(args.query, 'query');
|
|
37
|
+
const params = new URLSearchParams({ q: args.query });
|
|
38
|
+
if (typeof args.limit === 'number')
|
|
39
|
+
params.set('limit', String(args.limit));
|
|
40
|
+
const data = await getDaemonJson(ctx.baseUrl, `/api/tools/search?${params.toString()}`, {
|
|
41
|
+
fetchImpl: ctx.fetchImpl,
|
|
42
|
+
});
|
|
43
|
+
return data.hits;
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
/** `describe_tool` -> `GET /api/tools/:id` (`packages/http/src/tool-catalog.ts`'s `toolCatalogDescribeRoute`). */
|
|
47
|
+
export const describeToolTool = {
|
|
48
|
+
name: 'describe_tool',
|
|
49
|
+
description: 'Get the full descriptor for one tool id found via search_tools — description and input schema. Paid for only on the candidates that survive search, per the tool catalog\'s staged-discovery design.',
|
|
50
|
+
inputSchema: {
|
|
51
|
+
type: 'object',
|
|
52
|
+
properties: {
|
|
53
|
+
id: { type: 'string', description: 'Tool id returned by search_tools. Required.' },
|
|
54
|
+
},
|
|
55
|
+
required: ['id'],
|
|
56
|
+
additionalProperties: false,
|
|
57
|
+
},
|
|
58
|
+
annotations: { ...READ_ANNOTATIONS, title: 'Describe a tool' },
|
|
59
|
+
handler: async (args, ctx) => {
|
|
60
|
+
requireString(args.id, 'id');
|
|
61
|
+
return getDaemonJson(ctx.baseUrl, `/api/tools/${encodeURIComponent(args.id)}`, { fetchImpl: ctx.fetchImpl });
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
/** Both tool-catalog discovery tools, ready to pass as `createMcpToolServer`'s `tools` option. */
|
|
65
|
+
export const TOOL_CATALOG_TOOLS = [searchToolsTool, describeToolTool];
|
|
66
|
+
//# sourceMappingURL=tool-catalog-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-catalog-tools.js","sourceRoot":"","sources":["../../../src/server/tools/tool-catalog-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAmB,MAAM,qBAAqB,CAAC;AAErE,MAAM,gBAAgB,GAAG;IACvB,YAAY,EAAE,IAAI;IAClB,cAAc,EAAE,IAAI;IACpB,aAAa,EAAE,KAAK;CACZ,CAAC;AAWX,kHAAkH;AAClH,MAAM,CAAC,MAAM,eAAe,GAAe;IACzC,IAAI,EAAE,cAAc;IACpB,WAAW,EACT,sQAAsQ;IACxQ,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,wEAAwE,EAAE;YAChH,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sDAAsD,EAAE;SAC/F;QACD,QAAQ,EAAE,CAAC,OAAO,CAAC;QACnB,oBAAoB,EAAE,KAAK;KAC5B;IACD,WAAW,EAAE,EAAE,GAAG,gBAAgB,EAAE,KAAK,EAAE,yBAAyB,EAAE;IACtE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAC3B,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACtD,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ;YAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5E,MAAM,IAAI,GAAG,MAAM,aAAa,CAA4B,GAAG,CAAC,OAAO,EAAE,qBAAqB,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE;YACjH,SAAS,EAAE,GAAG,CAAC,SAAS;SACzB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;CACF,CAAC;AAEF,kHAAkH;AAClH,MAAM,CAAC,MAAM,gBAAgB,GAAe;IAC1C,IAAI,EAAE,eAAe;IACrB,WAAW,EACT,sMAAsM;IACxM,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6CAA6C,EAAE;SACnF;QACD,QAAQ,EAAE,CAAC,IAAI,CAAC;QAChB,oBAAoB,EAAE,KAAK;KAC5B;IACD,WAAW,EAAE,EAAE,GAAG,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,EAAE;IAC9D,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAC3B,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC7B,OAAO,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,cAAc,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;IAC/G,CAAC;CACF,CAAC;AAEF,kGAAkG;AAClG,MAAM,CAAC,MAAM,kBAAkB,GAA0B,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC"}
|