stitchkit 0.38.0 → 0.39.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 (56) hide show
  1. package/README.md +1 -1
  2. package/dist/browser/client-url.d.ts +2 -0
  3. package/dist/browser/client-url.d.ts.map +1 -1
  4. package/dist/browser/client.d.ts +25 -1
  5. package/dist/browser/client.d.ts.map +1 -1
  6. package/dist/browser/http.d.ts +5 -6
  7. package/dist/browser/http.d.ts.map +1 -1
  8. package/dist/cli.js +2 -2
  9. package/dist/contract/define.d.ts +36 -12
  10. package/dist/contract/define.d.ts.map +1 -1
  11. package/dist/contract/index.d.ts +1 -1
  12. package/dist/contract/index.d.ts.map +1 -1
  13. package/dist/contract/index.js +1 -1
  14. package/dist/{index-czmqks7r.js → index-6jypn22c.js} +1 -1
  15. package/dist/{index-p3kwf73n.js → index-7rbzbnnf.js} +28 -15
  16. package/dist/{index-bgdd42pt.js → index-92gs1m5b.js} +1 -1
  17. package/dist/{index-mzx0an0s.js → index-fyfk537k.js} +50 -5
  18. package/dist/{index-x4wbc8sz.js → index-xax049k6.js} +73 -5
  19. package/dist/{index-n5t4gnfz.js → index-y5scd1cr.js} +1 -1
  20. package/dist/index.d.ts +2 -2
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +116 -17
  23. package/dist/internal/route-pattern.d.ts +7 -0
  24. package/dist/internal/route-pattern.d.ts.map +1 -0
  25. package/dist/node.js +3 -3
  26. package/dist/observability/index.js +1 -1
  27. package/dist/react/entity-cache.d.ts +56 -42
  28. package/dist/react/entity-cache.d.ts.map +1 -1
  29. package/dist/react.d.ts +1 -1
  30. package/dist/react.d.ts.map +1 -1
  31. package/dist/react.js +98 -46
  32. package/dist/server/create.d.ts.map +1 -1
  33. package/dist/server/index.js +10 -9
  34. package/dist/server/middleware/cors.d.ts.map +1 -1
  35. package/dist/server/openapi.d.ts.map +1 -1
  36. package/dist/server/router.d.ts +2 -0
  37. package/dist/server/router.d.ts.map +1 -1
  38. package/dist/server/socket-io.d.ts +1 -1
  39. package/dist/server/types.d.ts +4 -6
  40. package/dist/server/types.d.ts.map +1 -1
  41. package/dist/tools/agent.d.ts +3 -0
  42. package/dist/tools/agent.d.ts.map +1 -1
  43. package/dist/tools/invoker.d.ts +33 -0
  44. package/dist/tools/invoker.d.ts.map +1 -0
  45. package/dist/tools/mcp.d.ts.map +1 -1
  46. package/dist/tools/names.d.ts +1 -1
  47. package/dist/tools/names.d.ts.map +1 -1
  48. package/dist/tools/native-mcp.d.ts +6 -33
  49. package/dist/tools/native-mcp.d.ts.map +1 -1
  50. package/dist/tools/runtime-tool.d.ts +58 -0
  51. package/dist/tools/runtime-tool.d.ts.map +1 -0
  52. package/dist/tools.d.ts +3 -1
  53. package/dist/tools.d.ts.map +1 -1
  54. package/dist/tools.js +181 -82
  55. package/llms-full.txt +417 -89
  56. package/package.json +1 -1
package/dist/tools.d.ts CHANGED
@@ -7,6 +7,7 @@ export type { CliWaitConfig } from './tools/cli-wait';
7
7
  export { coerceJsonArgs } from './tools/coerce';
8
8
  export type { AfterToolCallOptions, BeforeToolCallOptions, ErrorHintFn, ToolCallContext, ToolCallHooks, ToolErrorOptions, ToolLifecycle, ToolOperation, ToolResult, } from './tools/execute';
9
9
  export { flattenToolJsonSchema, type ToolPresentationSchema, } from './tools/flatten';
10
+ export { createToolInvoker, type ToolInvoker, type ToolInvokerConfig, type ToolInvokerTransport, } from './tools/invoker';
10
11
  export { listToolNames, type ToolNameEntry } from './tools/list-names';
11
12
  export { buildToolManifest, type ToolManifestEntry } from './tools/manifest';
12
13
  export { buildMcpServer, type IncompatibleSchemaPolicy, type McpMountConfig, type McpSchemaValidationConfig, type McpServerBuildConfig, mountMcp, mountMcpResource, type ValidateMcpSchemasConfig, validateMcpSchemas, } from './tools/mcp';
@@ -17,11 +18,12 @@ export { type CollectToolsConfig, collectTools, type MountableTool, type ToolExt
17
18
  export { type DownloadToolConfig, mountDownload } from './tools/mount-download';
18
19
  export { mountUpload, type UploadToolConfig } from './tools/mount-upload';
19
20
  export { mountWait, type WaitToolConfig } from './tools/mount-wait';
20
- export type { NativeMcpHandlerContext, NativeMcpOperationIdentity, NativeMcpRegistrar, NativeMcpResult, NativeMcpToolDefinition, } from './tools/native-mcp';
21
+ export type { NativeMcpRegistrar } from './tools/native-mcp';
21
22
  export { oauthProtectedResourceRoute, PROTECTED_RESOURCE_PATH, type ProtectedResourceConfig, protectedResourceMetadataUrl, wwwAuthenticateHeader, } from './tools/oauth-metadata';
22
23
  export { type ApplicationType, type AuthCodeData, type AuthRequest, type ClientMetadata, mountOAuthProvider, type OAuthProviderConfig, type RefreshData, type RegisteredClient, } from './tools/oauth-provider';
23
24
  export { findNonPortableFormats, type NonPortableFormat, PORTABLE_JSON_SCHEMA_FORMATS, } from './tools/portable-formats';
24
25
  export { type ImplementRemoteOptions, implementRemote } from './tools/remote';
26
+ export { defineRuntimeTool, type RuntimeAgentModelOutput, type RuntimeMcpPresentation, type RuntimeToolDefinition, type RuntimeToolDefinitionBase, type RuntimeToolDefinitionWithOutput, type RuntimeToolDefinitionWithoutOutput, type RuntimeToolHandlerContext, type RuntimeToolIdentity, type RuntimeToolOutput, type RuntimeToolPresenters, type RuntimeToolTransport, } from './tools/runtime-tool';
25
27
  export { createToolLogger, type ToolCallRecord, type ToolLoggerConfig, } from './tools/tool-logger';
26
28
  export { createToolkit, type Toolkit } from './tools/toolkit';
27
29
  export { summarizeTransports, type TransportCounts, type TransportSummary, } from './tools/transports';
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,gBAAgB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,KAAK,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,YAAY,EACV,oBAAoB,EACpB,qBAAqB,EACrB,WAAW,EACX,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,UAAU,GACX,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,qBAAqB,EACrB,KAAK,sBAAsB,GAC5B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,GAC1B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EACL,cAAc,EACd,KAAK,wBAAwB,EAC7B,KAAK,cAAc,EACnB,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EACzB,QAAQ,EACR,gBAAgB,EAChB,KAAK,wBAAwB,EAC7B,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,EAClB,KAAK,SAAS,EACd,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,cAAc,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EACL,KAAK,kBAAkB,EACvB,YAAY,EACZ,KAAK,aAAa,EAClB,KAAK,UAAU,GAChB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,KAAK,kBAAkB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpE,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,KAAK,uBAAuB,EAC5B,4BAA4B,EAC5B,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,kBAAkB,EAClB,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAChB,KAAK,gBAAgB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,sBAAsB,EACtB,KAAK,iBAAiB,EACtB,4BAA4B,GAC7B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,KAAK,sBAAsB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC9E,OAAO,EACL,iBAAiB,EACjB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,+BAA+B,EACpC,KAAK,kCAAkC,EACvC,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,gBAAgB,EAChB,KAAK,cAAc,EACnB,KAAK,gBAAgB,GACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,KAAK,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EACL,mBAAmB,EACnB,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,qBAAqB,EAAE,KAAK,eAAe,EAAE,MAAM,4BAA4B,CAAC;AACzF,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,aAAa,EACb,YAAY,EACZ,KAAK,eAAe,GACrB,MAAM,mBAAmB,CAAC"}
package/dist/tools.js CHANGED
@@ -2,10 +2,10 @@ import {
2
2
  inputIsQuery,
3
3
  signJwt,
4
4
  verifyPkce
5
- } from "./index-bgdd42pt.js";
5
+ } from "./index-92gs1m5b.js";
6
6
  import {
7
7
  DEFAULT_CORS_ALLOW_HEADERS
8
- } from "./index-czmqks7r.js";
8
+ } from "./index-6jypn22c.js";
9
9
  import {
10
10
  assertToolName,
11
11
  assertUniqueToolName,
@@ -24,7 +24,7 @@ import {
24
24
  readCapped,
25
25
  toolResultFromError,
26
26
  writeDownload
27
- } from "./index-n5t4gnfz.js";
27
+ } from "./index-y5scd1cr.js";
28
28
  import {
29
29
  toJsonSchema
30
30
  } from "./index-frfyw9fa.js";
@@ -33,15 +33,63 @@ import {
33
33
  } from "./index-x3fcszf8.js";
34
34
  import {
35
35
  AppError,
36
- formatZodError,
37
36
  getTraceId,
38
37
  isRecord,
39
38
  mergeMeta,
39
+ parseTrailingWildcard,
40
40
  typedEntries
41
- } from "./index-mzx0an0s.js";
41
+ } from "./index-fyfk537k.js";
42
42
 
43
43
  // src/tools/agent.ts
44
44
  import { jsonSchema, tool } from "ai";
45
+
46
+ // src/tools/runtime-tool.ts
47
+ function defineRuntimeTool(definition) {
48
+ if (definition.transports?.length === 0) {
49
+ throw new Error(`Runtime tool "${definition.name}" must expose at least one transport`);
50
+ }
51
+ return definition;
52
+ }
53
+ function runtimeToolSupports(definition, transport) {
54
+ if (definition.transports?.length === 0) {
55
+ throw new Error(`Runtime tool "${definition.name}" must expose at least one transport`);
56
+ }
57
+ return !definition.transports || definition.transports.includes(transport);
58
+ }
59
+ function runtimeToolIdentity(definition) {
60
+ return {
61
+ method: definition.identity.method,
62
+ desc: definition.description,
63
+ serviceName: definition.identity.serviceName,
64
+ key: definition.identity.action,
65
+ toolName: definition.name,
66
+ scope: definition.identity.scope,
67
+ meta: definition.identity.meta,
68
+ annotations: definition.annotations,
69
+ ui: definition.ui
70
+ };
71
+ }
72
+ function runtimeToolMountable(definition) {
73
+ assertToolName(definition.name, definition.identity.serviceName, definition.identity.action);
74
+ const method = {
75
+ ...runtimeToolIdentity(definition),
76
+ inputSchema: definition.input,
77
+ outputSchema: definition.output,
78
+ handler: definition.handler
79
+ };
80
+ return {
81
+ method,
82
+ name: definition.name,
83
+ argumentSchema: definition.input,
84
+ presentationSchema: buildToolPresentationSchema({
85
+ inputSchema: definition.input,
86
+ unrepresentable: "any"
87
+ }),
88
+ shouldExtend: false
89
+ };
90
+ }
91
+
92
+ // src/tools/agent.ts
45
93
  function mountAgent(services, config = {}) {
46
94
  const serviceList = Array.isArray(services) ? services : [services];
47
95
  const tools = {};
@@ -80,8 +128,88 @@ function mountAgent(services, config = {}) {
80
128
  });
81
129
  }
82
130
  }
131
+ for (const definition of config.runtimeTools ?? []) {
132
+ if (!runtimeToolSupports(definition, "AGENT"))
133
+ continue;
134
+ const mountable = runtimeToolMountable(definition);
135
+ assertUniqueToolName(definition.name, Object.hasOwn(tools, definition.name), "agent tool name");
136
+ const inputSchema = jsonSchema(mountable.presentationSchema, {
137
+ validate: async (value) => isRecord(value) ? { success: true, value } : { success: false, error: new Error("Tool arguments must be an object") }
138
+ });
139
+ const execute = async (rawArgs) => {
140
+ const args = isRecord(rawArgs) ? rawArgs : {};
141
+ try {
142
+ const result = await runTool(mountable, args);
143
+ if (result.ok)
144
+ return result.data;
145
+ return formatToolError(result, mountable.name, config.errorHint);
146
+ } catch (err) {
147
+ return formatToolError(toolResultFromError(err), mountable.name, config.errorHint);
148
+ }
149
+ };
150
+ if (definition.present?.agent) {
151
+ const presenter = definition.present.agent;
152
+ const output = definition.output;
153
+ tools[definition.name] = tool({
154
+ description: definition.description,
155
+ inputSchema,
156
+ outputSchema: output,
157
+ execute,
158
+ toModelOutput: async ({ output: rawOutput }) => {
159
+ const parsed = output.safeParse(rawOutput);
160
+ if (!parsed.success) {
161
+ return { type: "text", value: JSON.stringify(rawOutput) };
162
+ }
163
+ return presenter(parsed.data);
164
+ }
165
+ });
166
+ } else {
167
+ tools[definition.name] = tool({
168
+ description: definition.description,
169
+ inputSchema,
170
+ ...definition.output && { outputSchema: definition.output },
171
+ execute
172
+ });
173
+ }
174
+ }
83
175
  return tools;
84
176
  }
177
+ // src/tools/invoker.ts
178
+ function createToolInvoker(services, config) {
179
+ const serviceList = Array.isArray(services) ? services : [services];
180
+ const tools = new Map;
181
+ for (const service of serviceList) {
182
+ for (const tool2 of collectTools(service, config.transport, {
183
+ extend: config.extend,
184
+ flattenUnionInput: config.flattenUnionInput
185
+ })) {
186
+ assertUniqueToolName(tool2.name, tools.has(tool2.name), "in-process tool name");
187
+ tools.set(tool2.name, tool2);
188
+ }
189
+ }
190
+ const names = Object.freeze([...tools.keys()].sort());
191
+ const runTool = createToolRunner({
192
+ source: config.source ?? "internal",
193
+ context: config.context,
194
+ hooks: config.hooks,
195
+ lifecycle: config.lifecycle,
196
+ extend: config.extend,
197
+ coerceJsonArgs: config.coerceJsonArgs,
198
+ onOutputStrip: config.onOutputStrip
199
+ });
200
+ return Object.freeze({
201
+ names,
202
+ invoke(name, args) {
203
+ const tool2 = tools.get(name);
204
+ if (!tool2) {
205
+ throw new AppError("NOT_FOUND", `Unknown tool: ${name}`, 404, {
206
+ available: names
207
+ });
208
+ }
209
+ return runTool(tool2, args);
210
+ }
211
+ });
212
+ }
85
213
  // src/tools/list-names.ts
86
214
  var TOOL_TRANSPORTS = ["MCP", "AGENT", "CLI"];
87
215
  function listToolNames(services) {
@@ -142,72 +270,21 @@ function inlineMcpAppBundle(html) {
142
270
  // src/tools/native-mcp.ts
143
271
  import { CallToolResultSchema } from "@modelcontextprotocol/sdk/types.js";
144
272
  import { z } from "zod";
145
- function operationIdentity(definition) {
146
- return {
147
- method: definition.identity.method,
148
- desc: definition.description,
149
- serviceName: definition.identity.serviceName,
150
- key: definition.identity.action,
151
- toolName: definition.name,
152
- scope: definition.identity.scope,
153
- meta: definition.identity.meta,
154
- annotations: definition.annotations,
155
- ui: definition.ui
156
- };
157
- }
158
273
  function isCallToolResult(value) {
159
274
  return CallToolResultSchema.safeParse(value).success;
160
275
  }
161
- function nativeResultSchema(output) {
162
- const envelope = z.custom(isCallToolResult, {
163
- error: "Native MCP handler must return a valid CallToolResult"
164
- });
165
- if (!output)
166
- return envelope;
167
- return envelope.transform((result, context) => {
168
- const parsed = output.safeParse(result.structuredContent);
169
- if (!parsed.success) {
170
- context.addIssue({
171
- code: "custom",
172
- message: `Invalid structuredContent: ${formatZodError(parsed.error)}`
173
- });
174
- return z.NEVER;
175
- }
176
- return { ...result, structuredContent: parsed.data };
177
- });
178
- }
179
276
  function createNativeMcpRegistrar(server, config) {
180
277
  return {
181
278
  rawServer: server,
182
279
  registerTool: (definition) => {
183
- const identity = operationIdentity(definition);
184
- const advertisedOperation = {
185
- ...identity,
186
- inputSchema: definition.input,
187
- outputSchema: definition.output,
188
- handler: () => {
189
- return;
190
- }
191
- };
192
- const mountable = {
193
- method: advertisedOperation,
194
- name: definition.name,
195
- argumentSchema: definition.input,
196
- presentationSchema: buildToolPresentationSchema({
197
- inputSchema: definition.input,
198
- unrepresentable: "any"
199
- }),
200
- shouldExtend: false
201
- };
280
+ if (!runtimeToolSupports(definition, "MCP"))
281
+ return;
282
+ assertUniqueToolName(definition.name, config.takenNames.has(definition.name), "MCP tool name");
283
+ config.takenNames.add(definition.name);
284
+ const mountable = runtimeToolMountable(definition);
202
285
  const [prepared] = config.prepare(mountable);
203
286
  if (!prepared)
204
287
  return;
205
- const executionOperation = {
206
- ...identity,
207
- inputSchema: definition.input,
208
- outputSchema: nativeResultSchema(definition.output),
209
- handler: definition.handler
210
- };
211
288
  const toolConfig = {
212
289
  description: definition.description,
213
290
  inputSchema: z.looseObject({}).meta(presentationMetadata(prepared.inputSchema))
@@ -224,16 +301,32 @@ function createNativeMcpRegistrar(server, config) {
224
301
  }
225
302
  server.registerTool(definition.name, toolConfig, async (rawArgs) => {
226
303
  const args = isRecord(rawArgs) ? rawArgs : {};
227
- const result = await executeToolMethod(executionOperation, definition.name, args, { ...config.context, source: "mcp" }, config.hooks, config.lifecycle, config.coerceJsonArgs ?? true, config.onOutputStrip ? (paths) => config.onOutputStrip?.(definition.name, paths) : undefined);
228
- if (!result.ok)
229
- return config.formatError(result, definition.name);
230
- if (isCallToolResult(result.data))
231
- return result.data;
232
- return config.formatError({
304
+ const result = await executeToolMethod(mountable.method, definition.name, args, { ...config.context, source: "mcp" }, config.hooks, config.lifecycle, config.coerceJsonArgs ?? true, config.onOutputStrip ? (paths) => config.onOutputStrip?.(definition.name, paths) : undefined);
305
+ if (!result.ok || !definition.present?.mcp) {
306
+ return config.formatResult(result, prepared.outputMode, definition.name);
307
+ }
308
+ const presented = await definition.present.mcp(result.data);
309
+ if ("structuredContent" in presented || "isError" in presented) {
310
+ return config.formatResult({
311
+ ok: false,
312
+ code: "INTERNAL_SERVER_ERROR",
313
+ details: {
314
+ message: "Runtime MCP presenter cannot set framework-owned structuredContent or isError"
315
+ }
316
+ }, "none", definition.name);
317
+ }
318
+ const structured = config.formatResult(result, prepared.outputMode, definition.name).structuredContent;
319
+ const response = {
320
+ ...presented,
321
+ ...structured && { structuredContent: structured }
322
+ };
323
+ if (isCallToolResult(response))
324
+ return response;
325
+ return config.formatResult({
233
326
  ok: false,
234
327
  code: "INTERNAL_SERVER_ERROR",
235
- details: { message: "Native MCP handler returned an invalid result" }
236
- }, definition.name);
328
+ details: { message: "Runtime MCP presenter returned an invalid CallToolResult" }
329
+ }, "none", definition.name);
237
330
  });
238
331
  }
239
332
  };
@@ -606,17 +699,19 @@ function buildMcpServerFromPrepared(config, auth, prepared) {
606
699
  onOutputStrip: config.onOutputStrip
607
700
  });
608
701
  if (config.nativeTools) {
702
+ const takenNames = new Set(prepared.map((tool2) => tool2.mountable.name));
609
703
  const registrar = createNativeMcpRegistrar(server, {
610
704
  context,
611
705
  hooks: config.hooks,
612
706
  lifecycle: config.lifecycle,
613
707
  coerceJsonArgs: config.coerceJsonArgs,
614
708
  onOutputStrip: config.onOutputStrip,
709
+ takenNames,
615
710
  prepare: (tool2) => prepareMcpTools([tool2], {
616
711
  schemaValidation: config.schemaValidation,
617
712
  logger: config.logger
618
713
  }),
619
- formatError: (result, toolName) => formatMcpResult(result, "none", toolName, config.errorHint)
714
+ formatResult: (result, mode, toolName) => formatMcpResult(result, mode, toolName, config.errorHint)
620
715
  });
621
716
  config.nativeTools(registrar, auth);
622
717
  }
@@ -1277,11 +1372,13 @@ function resolvePathPrefix(config, args) {
1277
1372
  function extractParamNames(path) {
1278
1373
  const matches = path.match(/:(\w+)/g);
1279
1374
  const names = matches ? matches.map((match) => match.slice(1)) : [];
1280
- if (path.endsWith("/*"))
1281
- names.push("*");
1375
+ const wildcard = parseTrailingWildcard(path);
1376
+ if (wildcard)
1377
+ names.push(wildcard.name);
1282
1378
  return names;
1283
1379
  }
1284
1380
  function fillPathParams(path, args) {
1381
+ const wildcard = parseTrailingWildcard(path);
1285
1382
  let filled = path.replace(/:(\w+)/g, (_, key) => {
1286
1383
  const value = args[key];
1287
1384
  if (value === undefined || value === null) {
@@ -1289,14 +1386,14 @@ function fillPathParams(path, args) {
1289
1386
  }
1290
1387
  return encodeURIComponent(String(value));
1291
1388
  });
1292
- if (!filled.endsWith("/*"))
1389
+ if (!wildcard)
1293
1390
  return filled;
1294
- const wildcard = args["*"];
1295
- if (wildcard === undefined || wildcard === null) {
1296
- throw new Error("Missing path param: *");
1391
+ const wildcardValue = args[wildcard.name];
1392
+ if (wildcardValue === undefined || wildcardValue === null) {
1393
+ throw new Error(`Missing path param: ${wildcard.name}`);
1297
1394
  }
1298
- const remainder = String(wildcard).split("/").map((segment) => encodeURIComponent(segment)).join("/");
1299
- filled = `${filled.slice(0, -1)}${remainder}`;
1395
+ const remainder = String(wildcardValue).split("/").map((segment) => encodeURIComponent(segment)).join("/");
1396
+ filled = `${filled.slice(0, -(wildcard.name.length + 1))}${remainder}`;
1300
1397
  return filled;
1301
1398
  }
1302
1399
  function stripConsumedArgs(args, path, scopeKeys) {
@@ -1422,7 +1519,7 @@ function createHttpMethod(endpoint, prefix, client, config) {
1422
1519
  if (!isMultipartFile(file)) {
1423
1520
  throw new Error(`Missing multipart file field: ${endpoint.multipart}`);
1424
1521
  }
1425
- if (httpMethod === "get" || httpMethod === "delete") {
1522
+ if (httpMethod === "get" || httpMethod === "head" || httpMethod === "delete") {
1426
1523
  throw new Error(`Multipart endpoint ${endpoint.method} ${endpoint.path} must be POST / PUT / PATCH`);
1427
1524
  }
1428
1525
  const formData = new FormData;
@@ -1430,8 +1527,8 @@ function createHttpMethod(endpoint, prefix, client, config) {
1430
1527
  appendFormFields(formData, plan.remainingArgs, new Set([endpoint.multipart]));
1431
1528
  return withOutput(endpoint, client[httpMethod](plan.relativeUrl, formData, withTimeout(undefined, endpoint)));
1432
1529
  }
1433
- if (httpMethod === "get") {
1434
- return withOutput(endpoint, client.get(plan.relativeUrl, withTimeout(undefined, endpoint)));
1530
+ if (httpMethod === "get" || httpMethod === "head") {
1531
+ return withOutput(endpoint, client[httpMethod](plan.relativeUrl, withTimeout(undefined, endpoint)));
1435
1532
  }
1436
1533
  if (httpMethod === "delete") {
1437
1534
  return withOutput(endpoint, client.delete(plan.relativeUrl, withTimeout(undefined, endpoint)));
@@ -1448,7 +1545,7 @@ function createFetchMethod(endpoint, prefix, config, contractConfig) {
1448
1545
  ...typeof config.headers === "function" ? config.headers() : config.headers
1449
1546
  };
1450
1547
  const signal = endpoint.timeout !== undefined ? AbortSignal.timeout(endpoint.timeout) : undefined;
1451
- const hasBody = endpoint.method !== "GET" && endpoint.method !== "DELETE" && !endpoint.multipart && endpoint.input && args;
1548
+ const hasBody = endpoint.method !== "GET" && endpoint.method !== "HEAD" && endpoint.method !== "DELETE" && !endpoint.multipart && endpoint.input && args;
1452
1549
  if (hasBody)
1453
1550
  headers["Content-Type"] = "application/json";
1454
1551
  if (endpoint.multipart && args) {
@@ -1765,8 +1862,10 @@ export {
1765
1862
  flattenToolJsonSchema,
1766
1863
  findUntypedProperties,
1767
1864
  findNonPortableFormats,
1865
+ defineRuntimeTool,
1768
1866
  createToolkit,
1769
1867
  createToolLogger,
1868
+ createToolInvoker,
1770
1869
  createStdioMcpServer,
1771
1870
  createMcpHandler,
1772
1871
  createCli,