@procedures/mcp 0.0.0-stage → 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.
Files changed (54) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/LICENSE +21 -0
  3. package/README.md +359 -2
  4. package/dist/.tsbuildinfo +1 -0
  5. package/dist/context/index.d.ts +5 -0
  6. package/dist/context/index.d.ts.map +1 -0
  7. package/dist/context/index.js +5 -0
  8. package/dist/context/index.js.map +1 -0
  9. package/dist/context/mcp-context.d.ts +57 -0
  10. package/dist/context/mcp-context.d.ts.map +1 -0
  11. package/dist/context/mcp-context.js +40 -0
  12. package/dist/context/mcp-context.js.map +1 -0
  13. package/dist/index.d.ts +13 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +15 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/mapping/index.d.ts +6 -0
  18. package/dist/mapping/index.d.ts.map +1 -0
  19. package/dist/mapping/index.js +6 -0
  20. package/dist/mapping/index.js.map +1 -0
  21. package/dist/mapping/path-encoder.d.ts +72 -0
  22. package/dist/mapping/path-encoder.d.ts.map +1 -0
  23. package/dist/mapping/path-encoder.js +93 -0
  24. package/dist/mapping/path-encoder.js.map +1 -0
  25. package/dist/mapping/procedure-to-tool.d.ts +47 -0
  26. package/dist/mapping/procedure-to-tool.d.ts.map +1 -0
  27. package/dist/mapping/procedure-to-tool.js +163 -0
  28. package/dist/mapping/procedure-to-tool.js.map +1 -0
  29. package/dist/schema/index.d.ts +5 -0
  30. package/dist/schema/index.d.ts.map +1 -0
  31. package/dist/schema/index.js +5 -0
  32. package/dist/schema/index.js.map +1 -0
  33. package/dist/schema/tool-schema.d.ts +77 -0
  34. package/dist/schema/tool-schema.d.ts.map +1 -0
  35. package/dist/schema/tool-schema.js +103 -0
  36. package/dist/schema/tool-schema.js.map +1 -0
  37. package/dist/schema/zod-to-json-schema.d.ts +58 -0
  38. package/dist/schema/zod-to-json-schema.d.ts.map +1 -0
  39. package/dist/schema/zod-to-json-schema.js +79 -0
  40. package/dist/schema/zod-to-json-schema.js.map +1 -0
  41. package/dist/types.d.ts +99 -0
  42. package/dist/types.d.ts.map +1 -0
  43. package/dist/types.js +8 -0
  44. package/dist/types.js.map +1 -0
  45. package/package.json +63 -3
  46. package/src/context/index.ts +10 -0
  47. package/src/context/mcp-context.ts +80 -0
  48. package/src/index.ts +56 -0
  49. package/src/mapping/index.ts +20 -0
  50. package/src/mapping/path-encoder.ts +103 -0
  51. package/src/mapping/procedure-to-tool.ts +208 -0
  52. package/src/schema/index.ts +15 -0
  53. package/src/schema/tool-schema.ts +135 -0
  54. package/src/types.ts +107 -0
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Zod to JSON Schema Converter
3
+ *
4
+ * Converts Zod schemas to JSON Schema format for MCP tool inputSchema.
5
+ * Uses zod-to-json-schema with caching for performance.
6
+ */
7
+ import { zodToJsonSchema as zodConvert } from "zod-to-json-schema";
8
+ /**
9
+ * Convert a schema to JSON Schema.
10
+ *
11
+ * Uses zod-to-json-schema library for actual Zod schemas,
12
+ * with safe fallbacks for non-Zod implementations.
13
+ *
14
+ * @param schema - Schema to convert (Zod or ZodLike)
15
+ * @param options - Conversion options
16
+ * @returns JSON Schema representation
17
+ */
18
+ export function zodToJsonSchema(schema, options) {
19
+ // Check if it's actually a Zod schema (has _def property)
20
+ if (schema && typeof schema === "object" && "_def" in schema) {
21
+ try {
22
+ const result = zodConvert(schema, {
23
+ name: options?.name,
24
+ $refStrategy: "none", // Inline all refs for MCP compatibility
25
+ errorMessages: false,
26
+ });
27
+ // The library returns { $schema, ...rest } or just the schema
28
+ // We want to strip $schema for MCP
29
+ if (typeof result === "object" && result !== null) {
30
+ const { $schema: _, ...rest } = result;
31
+ return rest;
32
+ }
33
+ return result;
34
+ }
35
+ catch {
36
+ // Fallback to permissive schema on conversion error
37
+ return { type: "object", additionalProperties: true };
38
+ }
39
+ }
40
+ // For non-Zod schemas (our ZodLike interface), return permissive schema
41
+ return { type: "object", additionalProperties: true };
42
+ }
43
+ // Schema cache for performance, keyed by the schema object: a procedure that is registered
44
+ // again with a different schema gets the new JSON Schema (BUGS-2026-07 L30: the cache was keyed
45
+ // by the procedure path and returned the old schema)
46
+ const schemaCache = new Map();
47
+ /**
48
+ * Convert a schema to JSON Schema with caching.
49
+ *
50
+ * @param schema - Schema to convert (Zod or ZodLike)
51
+ * @param _cacheKey - Not used any more (kept for compatibility): the schema object is the key
52
+ * @returns Cached or freshly converted JSON Schema
53
+ */
54
+ export function cachedZodToJsonSchema(schema, _cacheKey) {
55
+ if (!schema || typeof schema !== "object") {
56
+ return zodToJsonSchema(schema);
57
+ }
58
+ const cached = schemaCache.get(schema);
59
+ if (cached) {
60
+ return cached;
61
+ }
62
+ const jsonSchema = zodToJsonSchema(schema);
63
+ schemaCache.set(schema, jsonSchema);
64
+ return jsonSchema;
65
+ }
66
+ /**
67
+ * Clear the schema cache.
68
+ * Useful when procedures are re-registered with different schemas.
69
+ */
70
+ export function clearSchemaCache() {
71
+ schemaCache.clear();
72
+ }
73
+ /**
74
+ * Get the current schema cache size.
75
+ */
76
+ export function getSchemaCacheSize() {
77
+ return schemaCache.size;
78
+ }
79
+ //# sourceMappingURL=zod-to-json-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod-to-json-schema.js","sourceRoot":"","sources":["../../src/schema/zod-to-json-schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,IAAI,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAuBnE;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAC7B,MAA4B,EAC5B,OAAgC;IAEhC,0DAA0D;IAC1D,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;QAC7D,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,UAAU,CAAC,MAA0C,EAAE;gBACpE,IAAI,EAAE,OAAO,EAAE,IAAI;gBACnB,YAAY,EAAE,MAAM,EAAE,wCAAwC;gBAC9D,aAAa,EAAE,KAAK;aACrB,CAAC,CAAC;YAEH,8DAA8D;YAC9D,mCAAmC;YACnC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBAClD,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,MAAiC,CAAC;gBAClE,OAAO,IAAkB,CAAC;YAC5B,CAAC;YAED,OAAO,MAAoB,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,oDAAoD;YACpD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC;QACxD,CAAC;IACH,CAAC;IAED,wEAAwE;IACxE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC;AACxD,CAAC;AAED,2FAA2F;AAC3F,gGAAgG;AAChG,qDAAqD;AACrD,MAAM,WAAW,GAAG,IAAI,GAAG,EAAsB,CAAC;AAElD;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAA4B,EAC5B,SAAkB;IAElB,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1C,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAED,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACvC,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,UAAU,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAC3C,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACpC,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC9B,WAAW,CAAC,KAAK,EAAE,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,WAAW,CAAC,IAAI,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * MCP Core Types
3
+ *
4
+ * Types for MCP (Model Context Protocol) integration with the procedure system.
5
+ * Extends MCP SDK types with procedure-specific metadata.
6
+ */
7
+ import type { ProcedurePath } from "@procedures/client";
8
+ /**
9
+ * JSON Schema type for MCP tool inputSchema.
10
+ * Simplified representation of JSON Schema 7.
11
+ */
12
+ export interface JsonSchema {
13
+ type?: string | string[];
14
+ properties?: Record<string, JsonSchema>;
15
+ items?: JsonSchema | JsonSchema[];
16
+ required?: string[];
17
+ additionalProperties?: boolean | JsonSchema;
18
+ description?: string;
19
+ default?: unknown;
20
+ enum?: unknown[];
21
+ const?: unknown;
22
+ oneOf?: JsonSchema[];
23
+ anyOf?: JsonSchema[];
24
+ allOf?: JsonSchema[];
25
+ $ref?: string;
26
+ definitions?: Record<string, JsonSchema>;
27
+ [key: string]: unknown;
28
+ }
29
+ /**
30
+ * MCP Tool definition as used in ListToolsRequest response.
31
+ */
32
+ export interface McpToolDefinition {
33
+ /** Tool name (procedure path joined with dots) */
34
+ name: string;
35
+ /** Human-readable description */
36
+ description?: string;
37
+ /** JSON Schema for tool input */
38
+ inputSchema: JsonSchema;
39
+ /**
40
+ * JSON Schema of the result (MCP 2025-06-18 structured output). Only a tool whose output is
41
+ * an object has it: then each successful result also has `structuredContent`.
42
+ */
43
+ outputSchema?: JsonSchema;
44
+ }
45
+ /**
46
+ * Extended MCP Tool with procedure metadata.
47
+ * Used internally for mapping and introspection.
48
+ */
49
+ export interface McpTool extends McpToolDefinition {
50
+ /** Original procedure path */
51
+ procedurePath: ProcedurePath;
52
+ /** Whether the procedure supports streaming output */
53
+ streaming?: boolean;
54
+ /** Procedure tags for filtering */
55
+ tags?: string[];
56
+ }
57
+ /**
58
+ * MCP tool call result content item.
59
+ */
60
+ export interface McpContentItem {
61
+ type: "text" | "image" | "resource";
62
+ text?: string;
63
+ data?: string;
64
+ mimeType?: string;
65
+ }
66
+ /**
67
+ * MCP tool call result.
68
+ */
69
+ export interface McpToolResult {
70
+ content: McpContentItem[];
71
+ isError?: boolean;
72
+ }
73
+ /**
74
+ * MCP transport types.
75
+ */
76
+ export type McpTransportType = "stdio" | "sse";
77
+ /**
78
+ * MCP server information.
79
+ */
80
+ export interface McpServerInfo {
81
+ name: string;
82
+ version: string;
83
+ }
84
+ /**
85
+ * MCP tool filter options.
86
+ */
87
+ export interface McpToolFilter {
88
+ /** Only include procedures with these tags */
89
+ includeTags?: string[];
90
+ /** Exclude procedures with these tags */
91
+ excludeTags?: string[];
92
+ /** Exclude procedures marked as internal */
93
+ excludeInternal?: boolean;
94
+ /** Only include procedures under this path prefix */
95
+ pathPrefix?: ProcedurePath;
96
+ /** Only include the procedures for which this function gives true */
97
+ include?: (path: ProcedurePath) => boolean;
98
+ }
99
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACxC,KAAK,CAAC,EAAE,UAAU,GAAG,UAAU,EAAE,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,oBAAoB,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,WAAW,EAAE,UAAU,CAAC;IACxB;;;OAGG;IACH,YAAY,CAAC,EAAE,UAAU,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,OAAQ,SAAQ,iBAAiB;IAChD,8BAA8B;IAC9B,aAAa,EAAE,aAAa,CAAC;IAC7B,sDAAsD;IACtD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,mCAAmC;IACnC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,KAAK,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,yCAAyC;IACzC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,4CAA4C;IAC5C,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qDAAqD;IACrD,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,qEAAqE;IACrE,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC;CAC5C"}
package/dist/types.js ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * MCP Core Types
3
+ *
4
+ * Types for MCP (Model Context Protocol) integration with the procedure system.
5
+ * Extends MCP SDK types with procedure-specific metadata.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
package/package.json CHANGED
@@ -1,6 +1,66 @@
1
1
  {
2
+ "$schema": "https://json.schemastore.org/package",
2
3
  "name": "@procedures/mcp",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
4
+ "version": "0.1.0",
5
+ "description": "Map typed procedures to MCP tools: JSON Schema from Zod, tool names, and input and result conversion for Model Context Protocol servers.",
6
+ "keywords": [
7
+ "mcp",
8
+ "model-context-protocol",
9
+ "json-schema",
10
+ "zod",
11
+ "tools"
12
+ ],
13
+ "homepage": "https://mark1russell7.github.io/client/",
14
+ "bugs": {
15
+ "url": "https://github.com/mark1russell7/client/issues"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/mark1russell7/client.git",
20
+ "directory": "packages/mcp"
21
+ },
22
+ "license": "MIT",
23
+ "author": "Mark Russell (https://github.com/mark1russell7)",
24
+ "type": "module",
25
+ "main": "./dist/index.js",
26
+ "types": "./dist/index.d.ts",
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.js"
31
+ }
32
+ },
33
+ "files": [
34
+ "dist",
35
+ "src",
36
+ "!src/**/*.test.ts",
37
+ "!src/**/*.test.tsx",
38
+ "!src/**/__tests__",
39
+ "CHANGELOG.md"
40
+ ],
41
+ "sideEffects": false,
42
+ "engines": {
43
+ "node": ">=22"
44
+ },
45
+ "publishConfig": {
46
+ "access": "public",
47
+ "provenance": true
48
+ },
49
+ "peerDependencies": {
50
+ "@procedures/client": "^0.1.0"
51
+ },
52
+ "devDependencies": {
53
+ "typescript": "^7.0.2",
54
+ "@types/node": "^22.0.0",
55
+ "@mark1russell7/cue": "^1.0.0",
56
+ "vitest": "^5.0.3",
57
+ "@procedures/client": "0.1.0"
58
+ },
59
+ "scripts": {
60
+ "build": "tsc -b",
61
+ "typecheck": "tsc --noEmit",
62
+ "clean": "rm -rf dist .tsbuildinfo",
63
+ "test": "vitest run --passWithNoTests",
64
+ "test:watch": "vitest"
65
+ }
6
66
  }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Context exports.
3
+ */
4
+
5
+ export {
6
+ isMcpContext,
7
+ getMcpContext,
8
+ type McpCallContext,
9
+ type McpProcedureContext,
10
+ } from "./mcp-context.js";
@@ -0,0 +1,80 @@
1
+ /**
2
+ * MCP Context Types
3
+ *
4
+ * Extended procedure context types when called via MCP transport.
5
+ */
6
+
7
+ import type { ProcedureContext } from "@procedures/client";
8
+ import type { McpTransportType } from "../types.js";
9
+
10
+ /**
11
+ * MCP-specific context data available when a procedure is called via MCP.
12
+ */
13
+ export interface McpCallContext {
14
+ /** MCP request ID */
15
+ requestId: string;
16
+
17
+ /** Transport type used (stdio or sse) */
18
+ transport: McpTransportType;
19
+
20
+ /** Client information from MCP connection (if available) */
21
+ clientInfo?: {
22
+ name?: string;
23
+ version?: string;
24
+ };
25
+
26
+ /** Raw MCP metadata */
27
+ rawMetadata?: Record<string, unknown>;
28
+ }
29
+
30
+ /**
31
+ * Extended procedure context when called via MCP transport.
32
+ *
33
+ * Provides access to MCP-specific metadata through the `mcp` property.
34
+ */
35
+ export interface McpProcedureContext extends ProcedureContext {
36
+ /** MCP-specific context data */
37
+ mcp: McpCallContext;
38
+ }
39
+
40
+ /**
41
+ * Type guard to check if context is from MCP transport.
42
+ *
43
+ * @param context - Procedure context to check
44
+ * @returns True if context has MCP metadata
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * handler: async (input, ctx) => {
49
+ * if (isMcpContext(ctx)) {
50
+ * console.log(`Called via MCP: ${ctx.mcp.transport}`);
51
+ * }
52
+ * // ... handle request
53
+ * }
54
+ * ```
55
+ */
56
+ export function isMcpContext(
57
+ context: ProcedureContext
58
+ ): context is McpProcedureContext {
59
+ return (
60
+ context !== undefined &&
61
+ typeof context === "object" &&
62
+ "mcp" in context &&
63
+ context.mcp !== undefined
64
+ );
65
+ }
66
+
67
+ /**
68
+ * Get MCP context if available, undefined otherwise.
69
+ *
70
+ * @param context - Procedure context to check
71
+ * @returns MCP context data or undefined
72
+ */
73
+ export function getMcpContext(
74
+ context: ProcedureContext
75
+ ): McpCallContext | undefined {
76
+ if (isMcpContext(context)) {
77
+ return context.mcp;
78
+ }
79
+ return undefined;
80
+ }
package/src/index.ts ADDED
@@ -0,0 +1,56 @@
1
+ /**
2
+ * MCP Core Package
3
+ *
4
+ * Core types and utilities for MCP (Model Context Protocol) integration
5
+ * with the procedure system.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+
10
+ // Types
11
+ export type {
12
+ JsonSchema,
13
+ McpToolDefinition,
14
+ McpTool,
15
+ McpContentItem,
16
+ McpToolResult,
17
+ McpTransportType,
18
+ McpServerInfo,
19
+ McpToolFilter,
20
+ } from "./types.js";
21
+
22
+ // Schema utilities
23
+ export {
24
+ toolInputSchema,
25
+ cachedToolInputSchema,
26
+ toolOutputSchema,
27
+ cachedToolOutputSchema,
28
+ zodToJsonSchema,
29
+ cachedZodToJsonSchema,
30
+ clearSchemaCache,
31
+ getSchemaCacheSize,
32
+ type ZodToJsonSchemaOptions,
33
+ } from "./schema/index.js";
34
+
35
+ // Mapping utilities
36
+ export {
37
+ encodePath,
38
+ decodePath,
39
+ isValidPathSegment,
40
+ isValidPath,
41
+ sanitizePathSegment,
42
+ sanitizePath,
43
+ procedureToMcpTool,
44
+ proceduresToMcpTools,
45
+ toToolDefinition,
46
+ createToolMap,
47
+ findToolByPath,
48
+ } from "./mapping/index.js";
49
+
50
+ // Context utilities
51
+ export {
52
+ isMcpContext,
53
+ getMcpContext,
54
+ type McpCallContext,
55
+ type McpProcedureContext,
56
+ } from "./context/index.js";
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Mapping utilities exports.
3
+ */
4
+
5
+ export {
6
+ encodePath,
7
+ decodePath,
8
+ isValidPathSegment,
9
+ isValidPath,
10
+ sanitizePathSegment,
11
+ sanitizePath,
12
+ } from "./path-encoder.js";
13
+
14
+ export {
15
+ procedureToMcpTool,
16
+ proceduresToMcpTools,
17
+ toToolDefinition,
18
+ createToolMap,
19
+ findToolByPath,
20
+ } from "./procedure-to-tool.js";
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Path Encoder
3
+ *
4
+ * Converts procedure paths to/from MCP tool names.
5
+ * MCP tool names should be valid identifiers (alphanumeric with dots/underscores).
6
+ */
7
+
8
+ import type { ProcedurePath } from "@procedures/client";
9
+
10
+ /**
11
+ * Encode a procedure path to an MCP tool name.
12
+ *
13
+ * Strategy: Join path segments with dots.
14
+ * Most procedure paths are already MCP-compatible (lowercase, alphanumeric).
15
+ *
16
+ * @param path - Procedure path array
17
+ * @returns MCP tool name string
18
+ *
19
+ * @example
20
+ * encodePath(["fs", "read"]) // "fs.read"
21
+ * encodePath(["mongo", "collections", "list"]) // "mongo.collections.list"
22
+ */
23
+ export function encodePath(path: ProcedurePath): string {
24
+ return path.join(".");
25
+ }
26
+
27
+ /**
28
+ * Decode an MCP tool name back to procedure path.
29
+ *
30
+ * @param toolName - MCP tool name string
31
+ * @returns Procedure path array
32
+ *
33
+ * @example
34
+ * decodePath("fs.read") // ["fs", "read"]
35
+ * decodePath("mongo.collections.list") // ["mongo", "collections", "list"]
36
+ */
37
+ export function decodePath(toolName: string): ProcedurePath {
38
+ return toolName.split(".");
39
+ }
40
+
41
+ /**
42
+ * Validate that a path segment is MCP-compatible.
43
+ *
44
+ * Valid segments:
45
+ * - Start with letter or underscore
46
+ * - Contain only letters, numbers, underscores, hyphens
47
+ *
48
+ * @param segment - Path segment to validate
49
+ * @returns True if segment is valid for MCP tool names
50
+ */
51
+ export function isValidPathSegment(segment: string): boolean {
52
+ return /^[a-zA-Z_][a-zA-Z0-9_-]*$/.test(segment);
53
+ }
54
+
55
+ /**
56
+ * Validate that an entire path is MCP-compatible.
57
+ *
58
+ * @param path - Procedure path to validate
59
+ * @returns True if all segments are valid
60
+ */
61
+ export function isValidPath(path: ProcedurePath): boolean {
62
+ return path.length > 0 && path.every(isValidPathSegment);
63
+ }
64
+
65
+ /**
66
+ * Sanitize a path segment for MCP compatibility.
67
+ *
68
+ * Replaces invalid characters with underscores.
69
+ *
70
+ * @param segment - Path segment to sanitize
71
+ * @returns Sanitized segment
72
+ *
73
+ * @example
74
+ * sanitizePathSegment("my-func") // "my-func" (valid)
75
+ * sanitizePathSegment("123abc") // "_123abc" (prefix if starts with number)
76
+ * sanitizePathSegment("my.func") // "my_func" (replace dots)
77
+ */
78
+ export function sanitizePathSegment(segment: string): string {
79
+ // Replace invalid chars with underscores
80
+ let sanitized = segment.replace(/[^a-zA-Z0-9_-]/g, "_");
81
+
82
+ // Prefix if starts with number
83
+ if (/^[0-9]/.test(sanitized)) {
84
+ sanitized = "_" + sanitized;
85
+ }
86
+
87
+ // Ensure not empty
88
+ if (!sanitized) {
89
+ sanitized = "_";
90
+ }
91
+
92
+ return sanitized;
93
+ }
94
+
95
+ /**
96
+ * Sanitize an entire path for MCP compatibility.
97
+ *
98
+ * @param path - Procedure path to sanitize
99
+ * @returns Sanitized path
100
+ */
101
+ export function sanitizePath(path: ProcedurePath): ProcedurePath {
102
+ return path.map(sanitizePathSegment);
103
+ }