@cmssy/mcp-server 0.68.0 → 0.69.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/__tests__/tool-catalogue.test.d.ts +2 -0
- package/dist/__tests__/tool-catalogue.test.d.ts.map +1 -0
- package/dist/__tests__/tool-catalogue.test.js +110 -0
- package/dist/__tests__/tool-catalogue.test.js.map +1 -0
- package/dist/ai-tools-binder.d.ts +1 -0
- package/dist/ai-tools-binder.d.ts.map +1 -1
- package/dist/ai-tools-binder.js +7 -0
- package/dist/ai-tools-binder.js.map +1 -1
- package/dist/tool-catalogue.d.ts +20 -0
- package/dist/tool-catalogue.d.ts.map +1 -0
- package/dist/tool-catalogue.js +67 -0
- package/dist/tool-catalogue.js.map +1 -0
- package/package.json +3 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-catalogue.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/tool-catalogue.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from "vitest";
|
|
2
|
+
import { boundTools, buildCatalogue, catalogueOfServer, catalogueDrift, catalogueFrom, } from "../tool-catalogue.js";
|
|
3
|
+
import { boundDeclarations } from "../ai-tools-binder.js";
|
|
4
|
+
import { createServer } from "../server.js";
|
|
5
|
+
const client = { query: vi.fn() };
|
|
6
|
+
describe("catalogueFrom", () => {
|
|
7
|
+
it("publishes one row per bound tool, ordered by name", () => {
|
|
8
|
+
const rows = catalogueFrom({ publish_page: {}, add_block_to_page: {} }, [
|
|
9
|
+
{ name: "publish_page", requiredPermissions: ["pages:publish"] },
|
|
10
|
+
{ name: "add_block_to_page", requiredPermissions: ["pages:edit"] },
|
|
11
|
+
]);
|
|
12
|
+
expect(rows).toEqual([
|
|
13
|
+
{
|
|
14
|
+
name: "add_block_to_page",
|
|
15
|
+
permission: "pages:edit",
|
|
16
|
+
description: "",
|
|
17
|
+
},
|
|
18
|
+
{ name: "publish_page", permission: "pages:publish", description: "" },
|
|
19
|
+
]);
|
|
20
|
+
});
|
|
21
|
+
it("joins every permission a tool needs", () => {
|
|
22
|
+
const rows = catalogueFrom({ edit_order: {} }, [
|
|
23
|
+
{
|
|
24
|
+
name: "edit_order",
|
|
25
|
+
requiredPermissions: ["orders:manage", "models:edit"],
|
|
26
|
+
},
|
|
27
|
+
]);
|
|
28
|
+
expect(rows[0]?.permission).toBe("orders:manage, models:edit");
|
|
29
|
+
});
|
|
30
|
+
it("leaves the permission empty for a tool that needs none", () => {
|
|
31
|
+
const rows = catalogueFrom({ get_workspace_info: {} }, [
|
|
32
|
+
{ name: "get_workspace_info", requiredPermissions: [] },
|
|
33
|
+
]);
|
|
34
|
+
expect(rows[0]?.permission).toBe("");
|
|
35
|
+
});
|
|
36
|
+
it("collapses the whitespace a multi-line description carries", () => {
|
|
37
|
+
const rows = catalogueFrom({ get_page: { description: " One\n two. " } }, [{ name: "get_page", requiredPermissions: ["pages:view"] }]);
|
|
38
|
+
expect(rows[0]?.description).toBe("One two.");
|
|
39
|
+
});
|
|
40
|
+
it("falls back to the declared description when the binding carries none", () => {
|
|
41
|
+
const rows = catalogueFrom({ get_page: {} }, [
|
|
42
|
+
{ name: "get_page", description: "Reads a page." },
|
|
43
|
+
]);
|
|
44
|
+
expect(rows[0]?.description).toBe("Reads a page.");
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
describe("boundTools", () => {
|
|
48
|
+
it("refuses to publish an empty catalogue", () => {
|
|
49
|
+
expect(() => boundTools({})).toThrow(/no tools/);
|
|
50
|
+
expect(() => boundTools({ _registeredTools: {} })).toThrow(/no tools/);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
describe("buildCatalogue", () => {
|
|
54
|
+
const rows = buildCatalogue();
|
|
55
|
+
it("lists every tool the server binds, and no more", () => {
|
|
56
|
+
const server = createServer(client);
|
|
57
|
+
const registered = Object.keys(boundTools(server)).sort();
|
|
58
|
+
expect(rows.map((row) => row.name)).toEqual(registered);
|
|
59
|
+
expect(rows.length).toBeGreaterThan(50);
|
|
60
|
+
});
|
|
61
|
+
it("has a declaration behind every binding, so no permission is guessed", () => {
|
|
62
|
+
const server = createServer(client);
|
|
63
|
+
expect(Object.keys(boundTools(server)).filter((name) => !boundDeclarations(server).has(name))).toEqual([]);
|
|
64
|
+
});
|
|
65
|
+
it("describes every tool it publishes", () => {
|
|
66
|
+
expect(rows.filter((row) => row.description === "")).toEqual([]);
|
|
67
|
+
});
|
|
68
|
+
it("refuses a tool bound past the binder, whose permissions it cannot know", () => {
|
|
69
|
+
const rogue = {
|
|
70
|
+
_registeredTools: { sneak_in: { description: "bound directly" } },
|
|
71
|
+
};
|
|
72
|
+
expect(() => catalogueOfServer(rogue)).toThrow(/sneak_in/);
|
|
73
|
+
});
|
|
74
|
+
it("names a write tool's permission, not none", () => {
|
|
75
|
+
const write = rows.find((row) => row.name === "update_region_settings");
|
|
76
|
+
expect(write?.permission).toBe("pages:edit");
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
describe("catalogueDrift", () => {
|
|
80
|
+
const built = [
|
|
81
|
+
{ name: "get_page", permission: "pages:view", description: "Reads." },
|
|
82
|
+
];
|
|
83
|
+
it("stays quiet when the page lists exactly what the server exposes", () => {
|
|
84
|
+
expect(catalogueDrift(built, [...built])).toEqual([]);
|
|
85
|
+
});
|
|
86
|
+
it("reports a tool the page never got", () => {
|
|
87
|
+
expect(catalogueDrift(built, [])).toEqual(["get_page is not on the page"]);
|
|
88
|
+
});
|
|
89
|
+
it("reports a tool the page kept after the server dropped it", () => {
|
|
90
|
+
expect(catalogueDrift(built, [
|
|
91
|
+
...built,
|
|
92
|
+
{ name: "old_tool", permission: "", description: "" },
|
|
93
|
+
])).toEqual(["old_tool is on the page but the server does not expose it"]);
|
|
94
|
+
});
|
|
95
|
+
it("reports a row the page lists twice, which a lookup would swallow", () => {
|
|
96
|
+
expect(catalogueDrift(built, [...built, ...built])).toEqual([
|
|
97
|
+
"get_page is listed twice on the page",
|
|
98
|
+
]);
|
|
99
|
+
});
|
|
100
|
+
it("reports a permission and a description that moved", () => {
|
|
101
|
+
const drift = catalogueDrift(built, [
|
|
102
|
+
{ name: "get_page", permission: "pages:edit", description: "Writes." },
|
|
103
|
+
]);
|
|
104
|
+
expect(drift).toEqual([
|
|
105
|
+
"get_page requires pages:view, the page says pages:edit",
|
|
106
|
+
"get_page is described differently on the page",
|
|
107
|
+
]);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
//# sourceMappingURL=tool-catalogue.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-catalogue.test.js","sourceRoot":"","sources":["../../src/__tests__/tool-catalogue.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import type { AiTool, WorkspaceOps } from "@cmssy/ai-tools";
|
|
3
|
+
export declare function boundDeclarations(server: McpServer): Map<string, AiTool>;
|
|
3
4
|
export declare function bindSharedTool(server: McpServer, tool: AiTool, ops: WorkspaceOps): void;
|
|
4
5
|
//# sourceMappingURL=ai-tools-binder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-tools-binder.d.ts","sourceRoot":"","sources":["../src/ai-tools-binder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"ai-tools-binder.d.ts","sourceRoot":"","sources":["../src/ai-tools-binder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAc5D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAExE;AAED,wBAAgB,cAAc,CAC5B,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,YAAY,GAChB,IAAI,CAkCN"}
|
package/dist/ai-tools-binder.js
CHANGED
|
@@ -10,7 +10,14 @@ const jsonPreprocess = (val) => {
|
|
|
10
10
|
return val;
|
|
11
11
|
}
|
|
12
12
|
};
|
|
13
|
+
const declarations = new WeakMap();
|
|
14
|
+
export function boundDeclarations(server) {
|
|
15
|
+
return declarations.get(server) ?? new Map();
|
|
16
|
+
}
|
|
13
17
|
export function bindSharedTool(server, tool, ops) {
|
|
18
|
+
const declared = declarations.get(server) ?? new Map();
|
|
19
|
+
declared.set(tool.name, tool);
|
|
20
|
+
declarations.set(server, declared);
|
|
14
21
|
const shape = tool.inputSchema
|
|
15
22
|
.shape;
|
|
16
23
|
const mcpShape = Object.fromEntries(Object.entries(shape).map(([key, schema]) => [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-tools-binder.js","sourceRoot":"","sources":["../src/ai-tools-binder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,cAAc,GAAG,CAAC,GAAY,EAAE,EAAE;IACtC,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IACxC,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,OAAO,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;IACtE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,UAAU,cAAc,CAC5B,MAAiB,EACjB,IAAY,EACZ,GAAiB;IAEjB,MAAM,KAAK,GAAI,IAAI,CAAC,WAAqD;SACtE,KAAK,CAAC;IACT,MAAM,QAAQ,GAAkB,MAAM,CAAC,WAAW,CAChD,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;QAC3C,GAAG;QACH,CAAC,CAAC,UAAU,CAAC,cAAc,EAAE,MAAsB,CAAC;KACrD,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAc,EAAE,EAAE;QAC1E,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC9C,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBACjE;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;qBACvD;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
1
|
+
{"version":3,"file":"ai-tools-binder.js","sourceRoot":"","sources":["../src/ai-tools-binder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,cAAc,GAAG,CAAC,GAAY,EAAE,EAAE;IACtC,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IACxC,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,OAAO,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;IACtE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,IAAI,OAAO,EAAkC,CAAC;AAEnE,MAAM,UAAU,iBAAiB,CAAC,MAAiB;IACjD,OAAO,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,MAAiB,EACjB,IAAY,EACZ,GAAiB;IAEjB,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,GAAG,EAAkB,CAAC;IACvE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC9B,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAEnC,MAAM,KAAK,GAAI,IAAI,CAAC,WAAqD;SACtE,KAAK,CAAC;IACT,MAAM,QAAQ,GAAkB,MAAM,CAAC,WAAW,CAChD,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;QAC3C,GAAG;QACH,CAAC,CAAC,UAAU,CAAC,cAAc,EAAE,MAAsB,CAAC;KACrD,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAc,EAAE,EAAE;QAC1E,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC9C,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBACjE;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;qBACvD;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
export interface CatalogueRow {
|
|
3
|
+
name: string;
|
|
4
|
+
permission: string;
|
|
5
|
+
description: string;
|
|
6
|
+
}
|
|
7
|
+
export interface BoundTool {
|
|
8
|
+
description?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface DeclaredTool {
|
|
11
|
+
name: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
requiredPermissions?: readonly string[];
|
|
14
|
+
}
|
|
15
|
+
export declare function catalogueFrom(bound: Record<string, BoundTool>, declared: readonly DeclaredTool[]): CatalogueRow[];
|
|
16
|
+
export declare function boundTools(server: unknown): Record<string, BoundTool>;
|
|
17
|
+
export declare function catalogueOfServer(server: McpServer): CatalogueRow[];
|
|
18
|
+
export declare function buildCatalogue(): CatalogueRow[];
|
|
19
|
+
export declare function catalogueDrift(built: readonly CatalogueRow[], published: readonly CatalogueRow[]): string[];
|
|
20
|
+
//# sourceMappingURL=tool-catalogue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-catalogue.d.ts","sourceRoot":"","sources":["../src/tool-catalogue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAChC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAChC,YAAY,EAAE,CAahB;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAUrE;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,YAAY,EAAE,CAcnE;AAED,wBAAgB,cAAc,IAAI,YAAY,EAAE,CAE/C;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,SAAS,YAAY,EAAE,EAC9B,SAAS,EAAE,SAAS,YAAY,EAAE,GACjC,MAAM,EAAE,CAqCV"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { createServer } from "./server.js";
|
|
2
|
+
import { boundDeclarations } from "./ai-tools-binder.js";
|
|
3
|
+
export function catalogueFrom(bound, declared) {
|
|
4
|
+
const byName = new Map(declared.map((tool) => [tool.name, tool]));
|
|
5
|
+
return Object.entries(bound)
|
|
6
|
+
.map(([name, tool]) => {
|
|
7
|
+
const declaration = byName.get(name);
|
|
8
|
+
const description = tool.description ?? declaration?.description ?? "";
|
|
9
|
+
return {
|
|
10
|
+
name,
|
|
11
|
+
permission: (declaration?.requiredPermissions ?? []).join(", "),
|
|
12
|
+
description: description.replace(/\s+/g, " ").trim(),
|
|
13
|
+
};
|
|
14
|
+
})
|
|
15
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
16
|
+
}
|
|
17
|
+
export function boundTools(server) {
|
|
18
|
+
const registered = server._registeredTools;
|
|
19
|
+
if (!registered || Object.keys(registered).length === 0) {
|
|
20
|
+
throw new Error("the server exposes no tools - the MCP SDK no longer keeps them on _registeredTools");
|
|
21
|
+
}
|
|
22
|
+
return registered;
|
|
23
|
+
}
|
|
24
|
+
export function catalogueOfServer(server) {
|
|
25
|
+
const registered = boundTools(server);
|
|
26
|
+
const declared = boundDeclarations(server);
|
|
27
|
+
const undeclared = Object.keys(registered).filter((name) => !declared.has(name));
|
|
28
|
+
if (undeclared.length > 0) {
|
|
29
|
+
throw new Error(`bound without a declaration, so their permissions cannot be published: ${undeclared.join(", ")}`);
|
|
30
|
+
}
|
|
31
|
+
return catalogueFrom(registered, [...declared.values()]);
|
|
32
|
+
}
|
|
33
|
+
export function buildCatalogue() {
|
|
34
|
+
return catalogueOfServer(createServer({}));
|
|
35
|
+
}
|
|
36
|
+
export function catalogueDrift(built, published) {
|
|
37
|
+
const drift = [];
|
|
38
|
+
const live = new Map();
|
|
39
|
+
for (const row of published) {
|
|
40
|
+
if (live.has(row.name)) {
|
|
41
|
+
drift.push(`${row.name} is listed twice on the page`);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
live.set(row.name, row);
|
|
45
|
+
}
|
|
46
|
+
for (const row of built) {
|
|
47
|
+
const onPage = live.get(row.name);
|
|
48
|
+
if (!onPage) {
|
|
49
|
+
drift.push(`${row.name} is not on the page`);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (onPage.permission !== row.permission) {
|
|
53
|
+
drift.push(`${row.name} requires ${row.permission || "no permission"}, the page says ${onPage.permission || "none"}`);
|
|
54
|
+
}
|
|
55
|
+
if (onPage.description !== row.description) {
|
|
56
|
+
drift.push(`${row.name} is described differently on the page`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const exposed = new Set(built.map((row) => row.name));
|
|
60
|
+
for (const row of published) {
|
|
61
|
+
if (!exposed.has(row.name)) {
|
|
62
|
+
drift.push(`${row.name} is on the page but the server does not expose it`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return drift;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=tool-catalogue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-catalogue.js","sourceRoot":"","sources":["../src/tool-catalogue.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cmssy/mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.69.0",
|
|
4
4
|
"description": "MCP server for Cmssy CMS \u2014 enables AI-driven page creation and management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
"sync-schema": "node scripts/sync-schema.mjs",
|
|
13
13
|
"fetch-prod-schema": "node scripts/fetch-prod-schema.mjs",
|
|
14
14
|
"check-schema-drift": "node scripts/check-schema-drift.mjs",
|
|
15
|
+
"catalogue": "pnpm build && node scripts/publish-tool-catalogue.mjs",
|
|
16
|
+
"catalogue:check": "pnpm build && node scripts/publish-tool-catalogue.mjs --check",
|
|
15
17
|
"dev": "tsx src/index.ts",
|
|
16
18
|
"typecheck": "tsc --noEmit",
|
|
17
19
|
"test": "vitest run"
|