@kavo/mcp 0.7.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.
@@ -0,0 +1,36 @@
1
+ import type { ClassRef, EntityId } from "@kavo/core";
2
+ import type { BoundKavoService, KavoMcpToolBinding } from "./tools.js";
3
+ /** The minimum a host framework needs to hand this package about one `@Kavo` entity. */
4
+ export interface KavoEntityRef {
5
+ readonly entity: ClassRef;
6
+ }
7
+ /**
8
+ * The host-agnostic half of "collect every entity's standard toolset into
9
+ * one process-wide MCP toolset." One thing stays deliberately outside this
10
+ * package, supplied by the caller instead — the same split
11
+ * `@kavo/graphql`'s `resolveKavoGraphQLSchema` uses for its own "how to
12
+ * resolve a service" half:
13
+ *
14
+ * - **How to resolve a bound service for one entity** — `@kavo/nest`'s
15
+ * `ModuleRef` + `getKavoServiceToken`, a plain `Map`, or whatever DI
16
+ * container that host uses.
17
+ *
18
+ * Every entity in `entities` gets the full standard toolset unconditionally
19
+ * (`crudTools`, no per-entity opt-in) — the list of entities to expose is
20
+ * controlled entirely by what the caller passes in (e.g. `@kavo/nest`'s
21
+ * `getKavoEntities()`, every `@Kavo`-decorated class), not by a second,
22
+ * MCP-specific registry.
23
+ *
24
+ * This function only ever touches `@kavo/core` shapes — never a host
25
+ * framework — so the same call works from a Nest MCP controller today and
26
+ * from a future `@kavo/express`/`@kavo/fastify`/`@kavo/nextjs` binding
27
+ * without either package importing the other (ADR-0016's `protocols/*`
28
+ * shape).
29
+ *
30
+ * Unlike `mergeKavoGraphQLSchemas` (which must fail fast on an empty
31
+ * `Query` type — GraphQL has no such thing as a schema with zero fields),
32
+ * an empty tool list is a perfectly valid MCP `ListToolsResult`, so an
33
+ * empty `entities` list is not treated as an error here.
34
+ */
35
+ export declare function resolveKavoMcpTools(entities: readonly KavoEntityRef[], resolveService: (entity: ClassRef) => BoundKavoService<object, EntityId, unknown, unknown, unknown>): readonly KavoMcpToolBinding[];
36
+ //# sourceMappingURL=discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGvE,wFAAwF;AACxF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,cAAc,EAAE,CAAC,MAAM,EAAE,QAAQ,KAAK,gBAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,GAClG,SAAS,kBAAkB,EAAE,CAQ/B"}
@@ -0,0 +1,37 @@
1
+ import { crudTools } from "./tools.js";
2
+ /**
3
+ * The host-agnostic half of "collect every entity's standard toolset into
4
+ * one process-wide MCP toolset." One thing stays deliberately outside this
5
+ * package, supplied by the caller instead — the same split
6
+ * `@kavo/graphql`'s `resolveKavoGraphQLSchema` uses for its own "how to
7
+ * resolve a service" half:
8
+ *
9
+ * - **How to resolve a bound service for one entity** — `@kavo/nest`'s
10
+ * `ModuleRef` + `getKavoServiceToken`, a plain `Map`, or whatever DI
11
+ * container that host uses.
12
+ *
13
+ * Every entity in `entities` gets the full standard toolset unconditionally
14
+ * (`crudTools`, no per-entity opt-in) — the list of entities to expose is
15
+ * controlled entirely by what the caller passes in (e.g. `@kavo/nest`'s
16
+ * `getKavoEntities()`, every `@Kavo`-decorated class), not by a second,
17
+ * MCP-specific registry.
18
+ *
19
+ * This function only ever touches `@kavo/core` shapes — never a host
20
+ * framework — so the same call works from a Nest MCP controller today and
21
+ * from a future `@kavo/express`/`@kavo/fastify`/`@kavo/nextjs` binding
22
+ * without either package importing the other (ADR-0016's `protocols/*`
23
+ * shape).
24
+ *
25
+ * Unlike `mergeKavoGraphQLSchemas` (which must fail fast on an empty
26
+ * `Query` type — GraphQL has no such thing as a schema with zero fields),
27
+ * an empty tool list is a perfectly valid MCP `ListToolsResult`, so an
28
+ * empty `entities` list is not treated as an error here.
29
+ */
30
+ export function resolveKavoMcpTools(entities, resolveService) {
31
+ const bindings = [];
32
+ for (const { entity } of entities) {
33
+ bindings.push(...crudTools({ name: entity.name, service: resolveService(entity) }));
34
+ }
35
+ return bindings;
36
+ }
37
+ //# sourceMappingURL=discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAOvC;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAAkC,EAClC,cAAmG;IAEnG,MAAM,QAAQ,GAAyB,EAAE,CAAC;IAE1C,KAAK,MAAM,EAAE,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;QAClC,QAAQ,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IACtF,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { crudTools, type KavoMcpToolsOptions, type KavoMcpToolBinding, type BoundKavoService } from "./tools.js";
2
+ export { resolveKavoMcpTools, type KavoEntityRef } from "./discovery.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACjH,OAAO,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { crudTools } from "./tools.js";
2
+ export { resolveKavoMcpTools } from "./discovery.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAA4E,MAAM,YAAY,CAAC;AACjH,OAAO,EAAE,mBAAmB,EAAsB,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { CallToolResult, Tool } from "@modelcontextprotocol/sdk/types.js";
2
+ import type { DefaultKavoService, EntityId } from "@kavo/core";
3
+ /**
4
+ * What a tool handler in this binding actually calls — the same
5
+ * transport-agnostic programmatic surface `createCrud` returns that
6
+ * `@kavo/graphql`'s `BoundKavoService` binds to. Kept as its own structural
7
+ * type for the same reason: a caller only has to satisfy the operations a
8
+ * toolset actually wires up.
9
+ */
10
+ export type BoundKavoService<Entity extends object, Id extends EntityId, CreateDto, UpdateDto, PatchDto> = Pick<DefaultKavoService<Entity, Id, CreateDto, UpdateDto, PatchDto, unknown, unknown, unknown>, "findOne" | "findMany" | "createOne" | "updateOne" | "patchOne" | "deleteOne" | "restoreOne" | "purgeOne">;
11
+ /** One entity's MCP tool binding: a `Tool` definition plus the handler that runs it — `crudTools`'s unit of work. */
12
+ export interface KavoMcpToolBinding {
13
+ readonly tool: Tool;
14
+ readonly handler: (args: Record<string, unknown>) => Promise<CallToolResult>;
15
+ }
16
+ /** One entity's MCP binding options. */
17
+ export interface KavoMcpToolsOptions<Entity extends object, Id extends EntityId, CreateDto, UpdateDto, PatchDto> {
18
+ /** Singular, capitalized entity name — becomes the `<lowerName>.<operation>` tool name prefix. */
19
+ readonly name: string;
20
+ readonly service: BoundKavoService<Entity, Id, CreateDto, UpdateDto, PatchDto>;
21
+ }
22
+ /**
23
+ * Every standard operation, for one entity — unconditional. There is no
24
+ * per-entity opt-in or hand-authored input schema (there used to be; see
25
+ * git history / the issue this simplified) — every `@Kavo` entity handed
26
+ * to `resolveKavoMcpTools` gets the full 8-tool set, the same way `@Kavo`
27
+ * itself enables every standard operation by default. An operation that
28
+ * doesn't actually apply — `restoreOne` on a non-soft-deletable entity, or
29
+ * any operation an entity's own `@Kavo` config disabled — still produces a
30
+ * tool, and calling it surfaces `OperationDisabledException` as a normal
31
+ * `isError` result (`guarded`), exactly like calling the disabled REST
32
+ * route would.
33
+ */
34
+ export declare function crudTools<Entity extends object, Id extends EntityId, CreateDto, UpdateDto, PatchDto>(options: KavoMcpToolsOptions<Entity, Id, CreateDto, UpdateDto, PatchDto>): readonly KavoMcpToolBinding[];
35
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,KAAK,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAiB/D;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,CAAC,MAAM,SAAS,MAAM,EAAE,EAAE,SAAS,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,IAAI,IAAI,CAC7G,kBAAkB,CAAC,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EACzF,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,WAAW,GAAG,UAAU,GAAG,WAAW,GAAG,YAAY,GAAG,UAAU,CAC1G,CAAC;AAyCF,qHAAqH;AACrH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;CAC9E;AAED,wCAAwC;AACxC,MAAM,WAAW,mBAAmB,CAAC,MAAM,SAAS,MAAM,EAAE,EAAE,SAAS,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ;IAC7G,kGAAkG;IAClG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;CAChF;AAyDD;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,MAAM,SAAS,MAAM,EAAE,EAAE,SAAS,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAClG,OAAO,EAAE,mBAAmB,CAAC,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,GACvE,SAAS,kBAAkB,EAAE,CAyF/B"}
package/dist/tools.js ADDED
@@ -0,0 +1,189 @@
1
+ import { ConfigurationException, KavoException } from "@kavo/core";
2
+ /**
3
+ * `sort: ["-createdAt", "name"]` → `[{ field: "createdAt", direction: "desc" }, { field: "name", direction: "asc" }]`
4
+ * — same convention (and same reasoning) as `@kavo/graphql`'s `parseSortArg`: this binding calls the programmatic
5
+ * `QueryContext` surface directly, never REST's wire-string parser.
6
+ */
7
+ function parseSortArg(tokens) {
8
+ if (tokens === undefined)
9
+ return [];
10
+ return tokens.map((token) => token.startsWith("-")
11
+ ? { field: token.slice(1), direction: "desc" }
12
+ : { field: token, direction: "asc" });
13
+ }
14
+ /**
15
+ * Refuse to bind an entity this protocol cannot page (ADR-0021 §7, extended
16
+ * to `since` by ADR-0022).
17
+ *
18
+ * `<name>.findMany` accepts `limit`/`offset` only, and `QueryNormalizer`
19
+ * ignores `offset` under both keyset strategies — so a model calling
20
+ * `todo.findMany({ limit: 20, offset: 40 })` against a cursor- or
21
+ * since-configured entity gets rows 1–20 (or everything from the beginning)
22
+ * back with no error and no way to tell, and the `nextCursor`/`nextSince` it
23
+ * would need is not in the tool's result shape. Name-gated on
24
+ * `"cursor"`/`"since"` rather than structural, the same limitation
25
+ * ADR-0021 §7 already records. Failing at bootstrap beats answering wrongly.
26
+ * `@kavo/graphql` carries the identical guard; the two packages may not
27
+ * import each other, so it is duplicated rather than shared.
28
+ */
29
+ /**
30
+ * The bound entity's configured `pagination.strategy`, read structurally —
31
+ * for the same reason `@kavo/graphql` reads it that way: putting `engine` in
32
+ * `BoundKavoService`'s `Pick` would drag the entity-typed
33
+ * `ResolvedEntityConfig` into an invariant position and break every erased
34
+ * `BoundKavoService<object, …>` call site.
35
+ */
36
+ function paginationStrategyOf(service) {
37
+ const engine = service.engine;
38
+ return engine?.config?.settings?.pagination?.strategy;
39
+ }
40
+ function requireOffsetPageable(entityName, strategy) {
41
+ if (strategy !== "cursor" && strategy !== "since")
42
+ return;
43
+ throw new ConfigurationException(entityName, "pagination.strategy", `'${strategy}' is not supported by the MCP binding: '<entity>.findMany' exposes 'limit'/'offset' only, ` +
44
+ `and a keyset page ignores 'offset' — a paged call would silently return the first page (or everything ` +
45
+ `from the beginning) every time. Either page this entity over REST, or give it an entity-scope ` +
46
+ `'pagination.strategy' of 'offset'/'page'`);
47
+ }
48
+ function lowerFirst(value) {
49
+ return value.charAt(0).toLowerCase() + value.slice(1);
50
+ }
51
+ function textResult(value) {
52
+ return { content: [{ type: "text", text: JSON.stringify(value) }] };
53
+ }
54
+ /**
55
+ * Runs a handler and turns a `KavoException` into a normal (`isError:
56
+ * true`) tool result instead of letting it propagate — the MCP protocol's
57
+ * own convention for an expected domain failure (bad id, disabled
58
+ * operation, conflict): the *call* succeeded, the *operation* didn't. An
59
+ * error the engine did not itself raise (a bug, an unmapped adapter
60
+ * failure) still propagates, so it surfaces as a protocol-level error
61
+ * rather than being silently reframed as routine tool output.
62
+ *
63
+ * This is also how a mutation tool that doesn't apply to a given entity —
64
+ * `restoreOne`/`purgeOne` on one that never declared soft delete —
65
+ * degrades: every entity gets the full standard toolset unconditionally
66
+ * (§ below), and the engine's own `OperationDisabledException` for a
67
+ * disabled operation lands here as a normal `isError` result, exactly the
68
+ * way calling the equivalent disabled REST route would.
69
+ */
70
+ async function guarded(fn) {
71
+ try {
72
+ return textResult(await fn());
73
+ }
74
+ catch (error) {
75
+ if (error instanceof KavoException) {
76
+ return { isError: true, content: [{ type: "text", text: `${error.code}: ${error.detail}` }] };
77
+ }
78
+ throw error;
79
+ }
80
+ }
81
+ const idSchema = { type: ["string", "number"] };
82
+ function objectSchema(properties, required) {
83
+ return { type: "object", properties, required: [...required] };
84
+ }
85
+ const idOnlySchema = objectSchema({ id: idSchema }, ["id"]);
86
+ /**
87
+ * `{ id }` required, with any other property left unconstrained — JSON
88
+ * Schema permits additional properties by default (no `additionalProperties:
89
+ * false` here), so this doubles as `updateOne`/`patchOne`'s input schema: a
90
+ * caller fills in `id` plus whatever DTO fields it wants, with no
91
+ * per-entity schema to author or keep in sync.
92
+ */
93
+ const idAndFreeformSchema = objectSchema({ id: idSchema }, ["id"]);
94
+ /** No constraints at all — every field an entity's `create` DTO accepts, forwarded straight through. */
95
+ const freeformObjectSchema = { type: "object" };
96
+ /**
97
+ * Every standard operation, for one entity — unconditional. There is no
98
+ * per-entity opt-in or hand-authored input schema (there used to be; see
99
+ * git history / the issue this simplified) — every `@Kavo` entity handed
100
+ * to `resolveKavoMcpTools` gets the full 8-tool set, the same way `@Kavo`
101
+ * itself enables every standard operation by default. An operation that
102
+ * doesn't actually apply — `restoreOne` on a non-soft-deletable entity, or
103
+ * any operation an entity's own `@Kavo` config disabled — still produces a
104
+ * tool, and calling it surfaces `OperationDisabledException` as a normal
105
+ * `isError` result (`guarded`), exactly like calling the disabled REST
106
+ * route would.
107
+ */
108
+ export function crudTools(options) {
109
+ const { name, service } = options;
110
+ requireOffsetPageable(name, paginationStrategyOf(service));
111
+ const prefix = lowerFirst(name);
112
+ return [
113
+ {
114
+ tool: { name: `${prefix}.findOne`, description: `Find one ${name} by id.`, inputSchema: idOnlySchema },
115
+ handler: (args) => guarded(() => service.findOne(args["id"])),
116
+ },
117
+ {
118
+ tool: {
119
+ name: `${prefix}.findMany`,
120
+ description: `List ${name} records, with optional pagination, sort, and filter.`,
121
+ inputSchema: objectSchema({
122
+ limit: { type: "integer" },
123
+ offset: { type: "integer" },
124
+ sort: { type: "array", items: { type: "string" } },
125
+ filter: { type: "object" },
126
+ }, []),
127
+ },
128
+ handler: (args) => guarded(() => service.findMany({
129
+ limit: args["limit"],
130
+ offset: args["offset"],
131
+ sort: parseSortArg(args["sort"]),
132
+ filter: args["filter"] ?? null,
133
+ })),
134
+ },
135
+ {
136
+ tool: { name: `${prefix}.createOne`, description: `Create a new ${name}.`, inputSchema: freeformObjectSchema },
137
+ handler: (args) => guarded(() => service.createOne(args)),
138
+ },
139
+ {
140
+ tool: {
141
+ name: `${prefix}.updateOne`,
142
+ description: `Replace an existing ${name} by id.`,
143
+ inputSchema: idAndFreeformSchema,
144
+ },
145
+ handler: (args) => {
146
+ const { id, ...input } = args;
147
+ return guarded(() => service.updateOne(id, input));
148
+ },
149
+ },
150
+ {
151
+ tool: {
152
+ name: `${prefix}.patchOne`,
153
+ description: `Partially update an existing ${name} by id.`,
154
+ inputSchema: idAndFreeformSchema,
155
+ },
156
+ handler: (args) => {
157
+ const { id, ...input } = args;
158
+ return guarded(() => service.patchOne(id, input));
159
+ },
160
+ },
161
+ {
162
+ tool: { name: `${prefix}.deleteOne`, description: `Delete a ${name} by id.`, inputSchema: idOnlySchema },
163
+ handler: (args) => guarded(async () => {
164
+ await service.deleteOne(args["id"]);
165
+ return { deleted: true };
166
+ }),
167
+ },
168
+ {
169
+ tool: {
170
+ name: `${prefix}.restoreOne`,
171
+ description: `Restore a soft-deleted ${name} by id.`,
172
+ inputSchema: idOnlySchema,
173
+ },
174
+ handler: (args) => guarded(() => service.restoreOne(args["id"])),
175
+ },
176
+ {
177
+ tool: {
178
+ name: `${prefix}.purgeOne`,
179
+ description: `Permanently delete a soft-deleted ${name} by id.`,
180
+ inputSchema: idOnlySchema,
181
+ },
182
+ handler: (args) => guarded(async () => {
183
+ await service.purgeOne(args["id"]);
184
+ return { purged: true };
185
+ }),
186
+ },
187
+ ];
188
+ }
189
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@kavo/mcp",
3
+ "version": "0.7.0",
4
+ "description": "Kavo MCP binding — exposes a createCrud service's standard operations as MCP tools, delegating every call to the same engine REST uses.",
5
+ "license": "Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/kavo-labs/kavo.git",
9
+ "directory": "packages/protocols/mcp"
10
+ },
11
+ "homepage": "https://github.com/kavo-labs/kavo/tree/main/packages/protocols/mcp#readme",
12
+ "type": "module",
13
+ "sideEffects": false,
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "default": "./dist/index.js"
21
+ }
22
+ },
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "scripts": {
27
+ "build": "tsc -b"
28
+ },
29
+ "dependencies": {
30
+ "@kavo/core": "workspace:^"
31
+ },
32
+ "peerDependencies": {
33
+ "@modelcontextprotocol/sdk": "^1.0.0"
34
+ },
35
+ "devDependencies": {
36
+ "@modelcontextprotocol/sdk": "^1.0.0"
37
+ }
38
+ }