@konneal/engine 0.2.137 → 0.2.138
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/mcp-proto.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
export declare const PROTOCOL_VERSION = "2025-06-18";
|
|
2
|
+
/** Registry tool name → the MCP-presented name. */
|
|
3
|
+
export declare function mcpName(registryName: string): string;
|
|
4
|
+
/** MCP-presented name → the name the handlers dispatch on. Raw
|
|
5
|
+
* registry names pass through (transition tolerance for early
|
|
6
|
+
* consumers of the unprefixed surface). */
|
|
7
|
+
export declare function registryName(presented: string): string;
|
|
2
8
|
export interface McpTool {
|
|
3
9
|
name: string;
|
|
4
10
|
description: string;
|
|
@@ -961,9 +961,30 @@ async function deleteAttachment(deps, sub, id) {
|
|
|
961
961
|
|
|
962
962
|
// workers/worker_public/src/mcp-proto.ts
|
|
963
963
|
var PROTOCOL_VERSION = "2025-06-18";
|
|
964
|
+
var mcpPrefix = () => `${P().publisher.id}_`;
|
|
965
|
+
var MCP_NAME_OVERRIDES = {
|
|
966
|
+
retrieve: `${P().publisher.id}_search`,
|
|
967
|
+
// the published retrieval contract
|
|
968
|
+
"documents.family": `${P().publisher.id}_documents`
|
|
969
|
+
// the published registry contract
|
|
970
|
+
};
|
|
971
|
+
function mcpName(registryName2) {
|
|
972
|
+
return MCP_NAME_OVERRIDES[registryName2] ?? `${mcpPrefix()}${registryName2.replace(/\./g, "_")}`;
|
|
973
|
+
}
|
|
974
|
+
function registryName(presented) {
|
|
975
|
+
const pid = P().publisher.id;
|
|
976
|
+
if (presented === `${pid}_ask`) return "ask";
|
|
977
|
+
for (const [reg, mc] of Object.entries(MCP_NAME_OVERRIDES)) if (mc === presented) return reg;
|
|
978
|
+
if (presented.startsWith(`${pid}_`)) {
|
|
979
|
+
const rest = presented.slice(pid.length + 1);
|
|
980
|
+
const hit = TOOLS_REGISTRY.find((t) => t.audiences.includes("mcp") && t.name.replace(/\./g, "_") === rest);
|
|
981
|
+
if (hit) return hit.name;
|
|
982
|
+
}
|
|
983
|
+
return presented;
|
|
984
|
+
}
|
|
964
985
|
var TOOLS = [
|
|
965
986
|
{
|
|
966
|
-
name: "ask",
|
|
987
|
+
name: mcpName("ask"),
|
|
967
988
|
description: "Ask the corpus a question; returns a citation-grounded answer with the passages it rests on.",
|
|
968
989
|
inputSchema: {
|
|
969
990
|
type: "object",
|
|
@@ -975,7 +996,7 @@ var TOOLS = [
|
|
|
975
996
|
}
|
|
976
997
|
},
|
|
977
998
|
{
|
|
978
|
-
name: "retrieve",
|
|
999
|
+
name: mcpName("retrieve"),
|
|
979
1000
|
description: "Retrieve the top passages for a query (hybrid dense + metadata steering, reranked).",
|
|
980
1001
|
inputSchema: {
|
|
981
1002
|
type: "object",
|
|
@@ -987,7 +1008,7 @@ var TOOLS = [
|
|
|
987
1008
|
}
|
|
988
1009
|
},
|
|
989
1010
|
...TOOLS_REGISTRY.filter((t) => t.audiences.includes("mcp")).map((t) => ({
|
|
990
|
-
name: t.name,
|
|
1011
|
+
name: mcpName(t.name),
|
|
991
1012
|
description: t.description,
|
|
992
1013
|
inputSchema: {
|
|
993
1014
|
type: "object",
|
|
@@ -1010,7 +1031,7 @@ function dispatch(method, params, callTool) {
|
|
|
1010
1031
|
if (!TOOLS.some((t) => t.name === name)) {
|
|
1011
1032
|
return Promise.resolve({ ok: false, code: -32602, message: `unknown tool: ${name}` });
|
|
1012
1033
|
}
|
|
1013
|
-
return callTool(name, params?.arguments ?? {}).then(
|
|
1034
|
+
return callTool(registryName(name), params?.arguments ?? {}).then(
|
|
1014
1035
|
(payload) => ({ ok: true, result: { content: [{ type: "text", text: JSON.stringify(payload) }] } })
|
|
1015
1036
|
);
|
|
1016
1037
|
}
|
package/package.json
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"playwright": "^1.62.1",
|
|
28
28
|
"yaml": "^2.9.1"
|
|
29
29
|
},
|
|
30
|
-
"version": "0.2.
|
|
30
|
+
"version": "0.2.138",
|
|
31
31
|
"description": "The Konneal engine: the publisher-agnostic build pipeline and API plane for standards intelligence (retrieval, answer contract, verdicts, evaluation).",
|
|
32
32
|
"license": "BSD-3-Clause",
|
|
33
33
|
"type": "module",
|
|
@@ -2,8 +2,40 @@
|
|
|
2
2
|
// dependency-free so plain node can load it for unit tests — the
|
|
3
3
|
// route adapter (mcp.ts) owns the handler wiring.
|
|
4
4
|
import { TOOLS_REGISTRY } from "./tools.ts";
|
|
5
|
+
import { P } from "./profile.ts";
|
|
5
6
|
export const PROTOCOL_VERSION = "2025-06-18";
|
|
6
7
|
|
|
8
|
+
// The MCP naming convention (2026-10-12): every tool the publisher
|
|
9
|
+
// exposes over MCP carries the publisher prefix — MCP clients render
|
|
10
|
+
// tool names in a SHARED namespace, so generic names ("ask") collide
|
|
11
|
+
// across servers. The three names docs/MCP.md already publishes keep
|
|
12
|
+
// their exact spelling; the mechanical transform covers the rest.
|
|
13
|
+
const mcpPrefix = () => `${P().publisher.id}_`;
|
|
14
|
+
const MCP_NAME_OVERRIDES: Record<string, string> = {
|
|
15
|
+
retrieve: `${P().publisher.id}_search`, // the published retrieval contract
|
|
16
|
+
"documents.family": `${P().publisher.id}_documents`, // the published registry contract
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/** Registry tool name → the MCP-presented name. */
|
|
20
|
+
export function mcpName(registryName: string): string {
|
|
21
|
+
return MCP_NAME_OVERRIDES[registryName] ?? `${mcpPrefix()}${registryName.replace(/\./g, "_")}`;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** MCP-presented name → the name the handlers dispatch on. Raw
|
|
25
|
+
* registry names pass through (transition tolerance for early
|
|
26
|
+
* consumers of the unprefixed surface). */
|
|
27
|
+
export function registryName(presented: string): string {
|
|
28
|
+
const pid = P().publisher.id;
|
|
29
|
+
if (presented === `${pid}_ask`) return "ask";
|
|
30
|
+
for (const [reg, mc] of Object.entries(MCP_NAME_OVERRIDES)) if (mc === presented) return reg;
|
|
31
|
+
if (presented.startsWith(`${pid}_`)) {
|
|
32
|
+
const rest = presented.slice(pid.length + 1);
|
|
33
|
+
const hit = TOOLS_REGISTRY.find((t) => t.audiences.includes("mcp") && t.name.replace(/\./g, "_") === rest);
|
|
34
|
+
if (hit) return hit.name;
|
|
35
|
+
}
|
|
36
|
+
return presented;
|
|
37
|
+
}
|
|
38
|
+
|
|
7
39
|
export interface McpTool {
|
|
8
40
|
name: string;
|
|
9
41
|
description: string;
|
|
@@ -14,7 +46,7 @@ export interface McpTool {
|
|
|
14
46
|
// tool registers it; this list is never hand-extended for them)
|
|
15
47
|
export const TOOLS: McpTool[] = [
|
|
16
48
|
{
|
|
17
|
-
name: "ask",
|
|
49
|
+
name: mcpName("ask"),
|
|
18
50
|
description: "Ask the corpus a question; returns a citation-grounded answer with the passages it rests on.",
|
|
19
51
|
inputSchema: {
|
|
20
52
|
type: "object",
|
|
@@ -26,7 +58,7 @@ export const TOOLS: McpTool[] = [
|
|
|
26
58
|
},
|
|
27
59
|
},
|
|
28
60
|
{
|
|
29
|
-
name: "retrieve",
|
|
61
|
+
name: mcpName("retrieve"),
|
|
30
62
|
description: "Retrieve the top passages for a query (hybrid dense + metadata steering, reranked).",
|
|
31
63
|
inputSchema: {
|
|
32
64
|
type: "object",
|
|
@@ -40,7 +72,7 @@ export const TOOLS: McpTool[] = [
|
|
|
40
72
|
...TOOLS_REGISTRY
|
|
41
73
|
.filter((t) => t.audiences.includes("mcp"))
|
|
42
74
|
.map((t): McpTool => ({
|
|
43
|
-
name: t.name,
|
|
75
|
+
name: mcpName(t.name),
|
|
44
76
|
description: t.description,
|
|
45
77
|
inputSchema: {
|
|
46
78
|
type: "object",
|
|
@@ -75,7 +107,7 @@ export function dispatch(
|
|
|
75
107
|
if (!TOOLS.some((t) => t.name === name)) {
|
|
76
108
|
return Promise.resolve({ ok: false, code: -32602, message: `unknown tool: ${name}` });
|
|
77
109
|
}
|
|
78
|
-
return callTool(name, params?.arguments ?? {}).then(
|
|
110
|
+
return callTool(registryName(name), params?.arguments ?? {}).then(
|
|
79
111
|
(payload) => ({ ok: true, result: { content: [{ type: "text", text: JSON.stringify(payload) }] } }) as McpResult,
|
|
80
112
|
);
|
|
81
113
|
}
|