@mappies/miniwat-mcp-core 0.10.0 → 0.12.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/index.cjs CHANGED
@@ -26,6 +26,7 @@ module.exports = __toCommonJS(index_exports);
26
26
 
27
27
  // src/entities/toolDispatcher.ts
28
28
  var import_miniwat_agent_core = require("@mappies/miniwat-agent-core");
29
+ var import_crypto = require("crypto");
29
30
  var ToolDispatcher = class {
30
31
  constructor(mcp) {
31
32
  this.mcp = mcp;
@@ -45,6 +46,7 @@ var ToolDispatcher = class {
45
46
  let definition = pck[t.import];
46
47
  let tool = new import_miniwat_agent_core.Tool({
47
48
  name: definition.name,
49
+ displayName: definition.displayName,
48
50
  description: definition.description,
49
51
  schema: definition.inputSchema,
50
52
  func: pck[definition.name],
@@ -52,57 +54,57 @@ var ToolDispatcher = class {
52
54
  getInputText: pck[`${definition.name}InputText`],
53
55
  readOnly: definition.readOnly === true,
54
56
  requiresApproval: definition.requiresApproval === true,
55
- executionPolicy: this.resolveExecutionPolicy(server, definition, pck),
56
- outcomeMapper: this.resolveOutcomeMapper(server, definition, pck)
57
+ inputGuardrail: this.resolveInputGuardrail(server, definition, pck),
58
+ outputGuardrail: this.resolveOutputGuardrail(server, definition, pck)
57
59
  });
58
60
  this.tools.push(tool);
59
61
  }
60
62
  }
61
63
  }
62
- // Resolves a tool definition's named executionPolicy from the OWNING package's
63
- // EXECUTION_POLICIES factory export. Validation is loud and happens at init — never deferred to
64
- // tool invocation — so the app cannot reach agent.stream() with a partially resolved tool.
65
- resolveExecutionPolicy(server, definition, pck) {
66
- const name = definition.executionPolicy;
64
+ // Resolves a tool definition's named inputGuardrail from the OWNING package's INPUT_GUARDRAILS
65
+ // factory export. Validation is loud and happens at init — never deferred to tool invocation —
66
+ // so the app cannot reach agent.stream() with a partially resolved tool.
67
+ resolveInputGuardrail(server, definition, pck) {
68
+ const name = definition.inputGuardrail;
67
69
  if (name === void 0) return void 0;
68
- const factories = pck.EXECUTION_POLICIES;
70
+ const factories = pck.INPUT_GUARDRAILS;
69
71
  if (factories === void 0 || typeof factories !== "object") {
70
- throw new Error(`Tool '${definition.name}' on server '${server}' names executionPolicy '${name}' but its package exports no EXECUTION_POLICIES.`);
72
+ throw new Error(`Tool '${definition.name}' on server '${server}' names inputGuardrail '${name}' but its package exports no INPUT_GUARDRAILS.`);
71
73
  }
72
74
  const factory = factories[name];
73
75
  if (factory === void 0) {
74
- throw new Error(`Tool '${definition.name}' on server '${server}' names executionPolicy '${name}' not found in the package's EXECUTION_POLICIES.`);
76
+ throw new Error(`Tool '${definition.name}' on server '${server}' names inputGuardrail '${name}' not found in the package's INPUT_GUARDRAILS.`);
75
77
  }
76
78
  if (typeof factory !== "function") {
77
- throw new Error(`EXECUTION_POLICIES['${name}'] on server '${server}' is not a factory function.`);
79
+ throw new Error(`INPUT_GUARDRAILS['${name}'] on server '${server}' is not a factory function.`);
78
80
  }
79
- const policy = factory();
80
- if (policy === void 0 || typeof policy.evaluate !== "function") {
81
- throw new Error(`EXECUTION_POLICIES['${name}'] on server '${server}' did not produce a valid ExecutionPolicy.`);
81
+ const guardrail = factory();
82
+ if (guardrail === void 0 || typeof guardrail.evaluate !== "function") {
83
+ throw new Error(`INPUT_GUARDRAILS['${name}'] on server '${server}' did not produce a valid ToolInputGuardrail.`);
82
84
  }
83
- return policy;
85
+ return guardrail;
84
86
  }
85
- // Resolves a tool definition's named outcomeMapper from the OWNING package's OUTCOME_MAPPERS
86
- // factory export. Validated loudly at init, mirroring resolveExecutionPolicy.
87
- resolveOutcomeMapper(server, definition, pck) {
88
- const name = definition.outcomeMapper;
87
+ // Resolves a tool definition's named outputGuardrail from the OWNING package's OUTPUT_GUARDRAILS
88
+ // factory export. Validated loudly at init, mirroring resolveInputGuardrail.
89
+ resolveOutputGuardrail(server, definition, pck) {
90
+ const name = definition.outputGuardrail;
89
91
  if (name === void 0) return void 0;
90
- const factories = pck.OUTCOME_MAPPERS;
92
+ const factories = pck.OUTPUT_GUARDRAILS;
91
93
  if (factories === void 0 || typeof factories !== "object") {
92
- throw new Error(`Tool '${definition.name}' on server '${server}' names outcomeMapper '${name}' but its package exports no OUTCOME_MAPPERS.`);
94
+ throw new Error(`Tool '${definition.name}' on server '${server}' names outputGuardrail '${name}' but its package exports no OUTPUT_GUARDRAILS.`);
93
95
  }
94
96
  const factory = factories[name];
95
97
  if (factory === void 0) {
96
- throw new Error(`Tool '${definition.name}' on server '${server}' names outcomeMapper '${name}' not found in the package's OUTCOME_MAPPERS.`);
98
+ throw new Error(`Tool '${definition.name}' on server '${server}' names outputGuardrail '${name}' not found in the package's OUTPUT_GUARDRAILS.`);
97
99
  }
98
100
  if (typeof factory !== "function") {
99
- throw new Error(`OUTCOME_MAPPERS['${name}'] on server '${server}' is not a factory function.`);
101
+ throw new Error(`OUTPUT_GUARDRAILS['${name}'] on server '${server}' is not a factory function.`);
100
102
  }
101
- const mapper = factory();
102
- if (mapper === void 0 || typeof mapper.map !== "function") {
103
- throw new Error(`OUTCOME_MAPPERS['${name}'] on server '${server}' did not produce a valid ToolOutcomeMapper.`);
103
+ const guardrail = factory();
104
+ if (guardrail === void 0 || typeof guardrail.evaluate !== "function") {
105
+ throw new Error(`OUTPUT_GUARDRAILS['${name}'] on server '${server}' did not produce a valid ToolOutputGuardrail.`);
104
106
  }
105
- return mapper;
107
+ return guardrail;
106
108
  }
107
109
  async list() {
108
110
  await this.init();
@@ -120,7 +122,30 @@ var ToolDispatcher = class {
120
122
  const tool = await this.get(name);
121
123
  return tool?.getInputText?.(input) || "";
122
124
  }
123
- async execute(name, input) {
125
+ // Evaluates the dispatch-boundary input guardrail against the concrete invocation. Returns
126
+ // undefined when execution may proceed; a ToolAuthorizationBlock (defer/deny) when it is
127
+ // blocked. On defer the pending call is recorded via the awaited onDeferred sink BEFORE the
128
+ // deferred result is returned (persist-before-respond); if a tool can defer but no sink is
129
+ // supplied, it FAILS CLOSED (denied) — a deferral must never be reported as unrecoverable.
130
+ async authorize(name, input, tool, auth) {
131
+ if (!auth) {
132
+ return void 0;
133
+ }
134
+ const decision = auth.guardrail.evaluate({ toolName: name, arguments: input }, auth.context);
135
+ if (decision.status === "allow") {
136
+ return void 0;
137
+ }
138
+ if (decision.status === "deny") {
139
+ return { authorization: "deny", succeeded: false, text: decision.reason };
140
+ }
141
+ const pending = { id: (0, import_crypto.randomUUID)(), name, arguments: input ?? {}, status: "pending" };
142
+ if (!auth.onDeferred) {
143
+ return { authorization: "deny", succeeded: false, text: "Authorization is unavailable for this operation." };
144
+ }
145
+ await auth.onDeferred(pending);
146
+ return { authorization: "defer", succeeded: false, text: decision.reason, pending };
147
+ }
148
+ async execute(name, input, auth) {
124
149
  const tool = await this.get(name);
125
150
  if (!tool) {
126
151
  throw new Error(`Tool ${name} could not be found.`);
@@ -128,12 +153,18 @@ var ToolDispatcher = class {
128
153
  if (!tool.func) {
129
154
  throw new Error(`Tool ${name} does not have a function.`);
130
155
  }
156
+ const authorization = await this.authorize(name, input, tool, auth);
157
+ if (authorization) {
158
+ return authorization;
159
+ }
160
+ let result;
131
161
  try {
132
- let result = await tool.func(input);
133
- return result;
162
+ result = await tool.func(input);
134
163
  } catch (e) {
135
164
  throw new Error(`Failed to run ${name} tool: ${e?.message}`);
136
165
  }
166
+ const guardrail = tool.outputGuardrail ?? new import_miniwat_agent_core.DefaultOutputGuardrail();
167
+ return guardrail.evaluate(result);
137
168
  }
138
169
  };
139
170
  // Annotate the CommonJS export names for ESM import in node:
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/entities/toolDispatcher.ts"],"sourcesContent":["export { ToolDispatcher } from './entities/toolDispatcher';\nexport { McpConfig, McpServer, McpToolImport } from './interfaces/mcpConfig';","import { Tool, McpServer, ExecutionPolicy, ExecutionPolicyFactory, ToolOutcomeMapper, ToolOutcomeMapperFactory } from \"@mappies/miniwat-agent-core\";\nimport { McpConfig } from \"../interfaces/mcpConfig\";\n\nexport class ToolDispatcher\n{\n private tools:Tool[]\n private servers:McpServer[]\n\n constructor(private mcp?:McpConfig)\n {\n this.tools = []\n this.servers = []\n }\n\n async init()\n {\n if(this.tools.length !== 0) return;\n\n this.tools = [];\n\n if(this.mcp === undefined) return;\n\n for(let server of Object.keys(this.mcp.mcpServers))\n {\n let service = this.mcp.mcpServers[server]\n\n this.servers.push(new McpServer({name: server, ...service}))\n \n const pck = await import(service.package);\n for(let t of service.tools)\n {\n // Host intent: a tool explicitly disabled in config is excluded here, during\n // discovery, so the planner never sees it.\n if(t.enabled === false) continue;\n\n let definition = pck[t.import];\n let tool = new Tool({ \n name: definition.name, \n description: definition.description, \n schema: definition.inputSchema, \n func: pck[definition.name],\n service: server,\n getInputText: pck[`${definition.name}InputText`],\n readOnly: definition.readOnly === true,\n requiresApproval: definition.requiresApproval === true,\n executionPolicy: this.resolveExecutionPolicy(server, definition, pck),\n outcomeMapper: this.resolveOutcomeMapper(server, definition, pck)\n })\n \n this.tools.push(tool)\n }\n }\n }\n\n // Resolves a tool definition's named executionPolicy from the OWNING package's\n // EXECUTION_POLICIES factory export. Validation is loud and happens at init — never deferred to\n // tool invocation — so the app cannot reach agent.stream() with a partially resolved tool.\n private resolveExecutionPolicy(server:string, definition:any, pck:any): ExecutionPolicy | undefined\n {\n const name:string | undefined = definition.executionPolicy;\n\n if(name === undefined) return undefined;\n\n const factories = pck.EXECUTION_POLICIES;\n\n if(factories === undefined || typeof factories !== \"object\")\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names executionPolicy '${name}' but its package exports no EXECUTION_POLICIES.`);\n }\n\n const factory:ExecutionPolicyFactory | undefined = factories[name];\n\n if(factory === undefined)\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names executionPolicy '${name}' not found in the package's EXECUTION_POLICIES.`);\n }\n\n if(typeof factory !== \"function\")\n {\n throw new Error(`EXECUTION_POLICIES['${name}'] on server '${server}' is not a factory function.`);\n }\n\n const policy = factory();\n\n if(policy === undefined || typeof policy.evaluate !== \"function\")\n {\n throw new Error(`EXECUTION_POLICIES['${name}'] on server '${server}' did not produce a valid ExecutionPolicy.`);\n }\n\n return policy;\n }\n\n // Resolves a tool definition's named outcomeMapper from the OWNING package's OUTCOME_MAPPERS\n // factory export. Validated loudly at init, mirroring resolveExecutionPolicy.\n private resolveOutcomeMapper(server:string, definition:any, pck:any): ToolOutcomeMapper | undefined\n {\n const name:string | undefined = definition.outcomeMapper;\n\n if(name === undefined) return undefined;\n\n const factories = pck.OUTCOME_MAPPERS;\n\n if(factories === undefined || typeof factories !== \"object\")\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names outcomeMapper '${name}' but its package exports no OUTCOME_MAPPERS.`);\n }\n\n const factory:ToolOutcomeMapperFactory | undefined = factories[name];\n\n if(factory === undefined)\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names outcomeMapper '${name}' not found in the package's OUTCOME_MAPPERS.`);\n }\n\n if(typeof factory !== \"function\")\n {\n throw new Error(`OUTCOME_MAPPERS['${name}'] on server '${server}' is not a factory function.`);\n }\n\n const mapper = factory();\n\n if(mapper === undefined || typeof mapper.map !== \"function\")\n {\n throw new Error(`OUTCOME_MAPPERS['${name}'] on server '${server}' did not produce a valid ToolOutcomeMapper.`);\n }\n\n return mapper;\n }\n\n async list(): Promise<Tool[]>\n {\n await this.init()\n return this.tools;\n }\n\n async listServers(): Promise<McpServer[]>\n {\n await this.init()\n return this.servers;\n }\n\n async get(name:string): Promise<Tool|undefined>\n {\n await this.init()\n return this.tools.find(tool => tool.name === name);\n }\n\n async getInputText(name:string, input?:object): Promise<string>\n {\n const tool = await this.get(name);\n\n return tool?.getInputText?.(input) || '';\n }\n\n async execute(name:string, input?:object): Promise<string>\n {\n const tool = await this.get(name);\n \n if(!tool)\n {\n throw new Error(`Tool ${name} could not be found.`);\n }\n\n if(!tool.func)\n {\n throw new Error(`Tool ${name} does not have a function.`);\n }\n\n try\n {\n let result = await tool.func(input);\n return result;\n }\n catch(e:any)\n {\n throw new Error(`Failed to run ${name} tool: ${e?.message}`);\n }\n }\n}"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/entities/toolDispatcher.ts"],"sourcesContent":["export { ToolDispatcher } from './entities/toolDispatcher';\nexport { McpConfig } from './interfaces/mcpConfig';\nexport { McpServer } from './interfaces/mcpServer';\nexport { McpToolImport } from './interfaces/mcpToolImport';","import { Tool, McpServer, ToolInputGuardrail, ToolInputGuardrailFactory, ToolOutputGuardrail, ToolOutputGuardrailFactory, ToolOutputGuardrailResult, DefaultOutputGuardrail, ToolAuthorizationOptions, ToolAuthorizationBlock, PendingToolCall } from \"@mappies/miniwat-agent-core\";\nimport { randomUUID } from \"crypto\";\nimport { McpConfig } from \"../interfaces/mcpConfig\";\n\nexport class ToolDispatcher\n{\n private tools:Tool[]\n private servers:McpServer[]\n\n constructor(private mcp?:McpConfig)\n {\n this.tools = []\n this.servers = []\n }\n\n async init()\n {\n if(this.tools.length !== 0) return;\n\n this.tools = [];\n\n if(this.mcp === undefined) return;\n\n for(let server of Object.keys(this.mcp.mcpServers))\n {\n let service = this.mcp.mcpServers[server]\n\n this.servers.push(new McpServer({name: server, ...service}))\n \n const pck = await import(service.package);\n for(let t of service.tools)\n {\n // Host intent: a tool explicitly disabled in config is excluded here, during\n // discovery, so the planner never sees it.\n if(t.enabled === false) continue;\n\n let definition = pck[t.import];\n let tool = new Tool({ \n name: definition.name, \n displayName: definition.displayName,\n description: definition.description, \n schema: definition.inputSchema, \n func: pck[definition.name],\n service: server,\n getInputText: pck[`${definition.name}InputText`],\n readOnly: definition.readOnly === true,\n requiresApproval: definition.requiresApproval === true,\n inputGuardrail: this.resolveInputGuardrail(server, definition, pck),\n outputGuardrail: this.resolveOutputGuardrail(server, definition, pck)\n })\n \n this.tools.push(tool)\n }\n }\n }\n\n // Resolves a tool definition's named inputGuardrail from the OWNING package's INPUT_GUARDRAILS\n // factory export. Validation is loud and happens at init — never deferred to tool invocation —\n // so the app cannot reach agent.stream() with a partially resolved tool.\n private resolveInputGuardrail(server:string, definition:any, pck:any): ToolInputGuardrail | undefined\n {\n const name:string | undefined = definition.inputGuardrail;\n\n if(name === undefined) return undefined;\n\n const factories = pck.INPUT_GUARDRAILS;\n\n if(factories === undefined || typeof factories !== \"object\")\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names inputGuardrail '${name}' but its package exports no INPUT_GUARDRAILS.`);\n }\n\n const factory:ToolInputGuardrailFactory | undefined = factories[name];\n\n if(factory === undefined)\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names inputGuardrail '${name}' not found in the package's INPUT_GUARDRAILS.`);\n }\n\n if(typeof factory !== \"function\")\n {\n throw new Error(`INPUT_GUARDRAILS['${name}'] on server '${server}' is not a factory function.`);\n }\n\n const guardrail = factory();\n\n if(guardrail === undefined || typeof guardrail.evaluate !== \"function\")\n {\n throw new Error(`INPUT_GUARDRAILS['${name}'] on server '${server}' did not produce a valid ToolInputGuardrail.`);\n }\n\n return guardrail;\n }\n\n // Resolves a tool definition's named outputGuardrail from the OWNING package's OUTPUT_GUARDRAILS\n // factory export. Validated loudly at init, mirroring resolveInputGuardrail.\n private resolveOutputGuardrail(server:string, definition:any, pck:any): ToolOutputGuardrail | undefined\n {\n const name:string | undefined = definition.outputGuardrail;\n\n if(name === undefined) return undefined;\n\n const factories = pck.OUTPUT_GUARDRAILS;\n\n if(factories === undefined || typeof factories !== \"object\")\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names outputGuardrail '${name}' but its package exports no OUTPUT_GUARDRAILS.`);\n }\n\n const factory:ToolOutputGuardrailFactory | undefined = factories[name];\n\n if(factory === undefined)\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names outputGuardrail '${name}' not found in the package's OUTPUT_GUARDRAILS.`);\n }\n\n if(typeof factory !== \"function\")\n {\n throw new Error(`OUTPUT_GUARDRAILS['${name}'] on server '${server}' is not a factory function.`);\n }\n\n const guardrail = factory();\n\n if(guardrail === undefined || typeof guardrail.evaluate !== \"function\")\n {\n throw new Error(`OUTPUT_GUARDRAILS['${name}'] on server '${server}' did not produce a valid ToolOutputGuardrail.`);\n }\n\n return guardrail;\n }\n\n async list(): Promise<Tool[]>\n {\n await this.init()\n return this.tools;\n }\n\n async listServers(): Promise<McpServer[]>\n {\n await this.init()\n return this.servers;\n }\n\n async get(name:string): Promise<Tool|undefined>\n {\n await this.init()\n return this.tools.find(tool => tool.name === name);\n }\n\n async getInputText(name:string, input?:object): Promise<string>\n {\n const tool = await this.get(name);\n\n return tool?.getInputText?.(input) || '';\n }\n\n // Evaluates the dispatch-boundary input guardrail against the concrete invocation. Returns\n // undefined when execution may proceed; a ToolAuthorizationBlock (defer/deny) when it is\n // blocked. On defer the pending call is recorded via the awaited onDeferred sink BEFORE the\n // deferred result is returned (persist-before-respond); if a tool can defer but no sink is\n // supplied, it FAILS CLOSED (denied) — a deferral must never be reported as unrecoverable.\n private async authorize(name:string, input:object | undefined, tool:Tool, auth?:ToolAuthorizationOptions): Promise<ToolAuthorizationBlock | undefined>\n {\n if(!auth)\n {\n return undefined;\n }\n\n const decision = auth.guardrail.evaluate({ toolName: name, arguments: input }, auth.context);\n\n if(decision.status === \"allow\")\n {\n return undefined;\n }\n\n if(decision.status === \"deny\")\n {\n return { authorization: \"deny\", succeeded: false, text: decision.reason };\n }\n\n // defer: preserve the invocation for a later approval turn.\n const pending:PendingToolCall = { id: randomUUID(), name, arguments: (input ?? {}) as Record<string, unknown>, status: \"pending\" };\n\n if(!auth.onDeferred)\n {\n // Fail closed: a deferral we cannot durably record must not surface as a usable\n // approval-required result.\n return { authorization: \"deny\", succeeded: false, text: \"Authorization is unavailable for this operation.\" };\n }\n\n // Persist-before-respond: the pending call is durably recorded before the deferred result\n // (and the approval request derived from it) can reach the user. A rejection propagates.\n await auth.onDeferred(pending);\n\n return { authorization: \"defer\", succeeded: false, text: decision.reason, pending };\n }\n\n async execute(name:string, input?:object, auth?:ToolAuthorizationOptions): Promise<ToolOutputGuardrailResult | ToolAuthorizationBlock>\n {\n const tool = await this.get(name);\n \n if(!tool)\n {\n throw new Error(`Tool ${name} could not be found.`);\n }\n\n if(!tool.func)\n {\n throw new Error(`Tool ${name} does not have a function.`);\n }\n\n // Dispatch-boundary authorization runs BEFORE the tool, so an unauthorized side effect never\n // executes — regardless of which planner (or no planner) proposed it. The guardrail is the\n // existing allow/defer/deny input guardrail evaluated against the CONCRETE invocation.\n const authorization = await this.authorize(name, input, tool, auth);\n\n if(authorization)\n {\n return authorization;\n }\n\n let result;\n\n try\n {\n result = await tool.func(input);\n }\n catch(e:any)\n {\n throw new Error(`Failed to run ${name} tool: ${e?.message}`);\n }\n\n // The output guardrail is the SINGLE post-execution authority. It runs here, at the\n // provider-agnostic chokepoint, so the real result is classified BEFORE any provider relays\n // it. Its verdict carries both the user-facing text and the semantic status to the caller;\n // a `blocked` verdict withholds the real result in favor of a replacement. A tool without an\n // explicit guardrail gets the framework default (a normal return is a success).\n const guardrail = tool.outputGuardrail ?? new DefaultOutputGuardrail();\n\n return guardrail.evaluate(result);\n }\n}"],"mappings":"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","names":[]}
package/dist/index.d.cts CHANGED
@@ -1,17 +1,19 @@
1
- import { Tool, McpServer as McpServer$1 } from '@mappies/miniwat-agent-core';
1
+ import { Tool, McpServer as McpServer$1, ToolAuthorizationOptions, ToolOutputGuardrailResult, ToolAuthorizationBlock } from '@mappies/miniwat-agent-core';
2
2
 
3
- interface McpConfig {
4
- mcpServers: Record<string, McpServer>;
3
+ interface McpToolImport {
4
+ import: string;
5
+ enabled?: boolean;
5
6
  }
7
+
6
8
  interface McpServer {
7
9
  package: string;
8
10
  description?: string;
9
11
  secrets?: string[];
10
12
  tools: McpToolImport[];
11
13
  }
12
- interface McpToolImport {
13
- import: string;
14
- enabled?: boolean;
14
+
15
+ interface McpConfig {
16
+ mcpServers: Record<string, McpServer>;
15
17
  }
16
18
 
17
19
  declare class ToolDispatcher {
@@ -20,13 +22,14 @@ declare class ToolDispatcher {
20
22
  private servers;
21
23
  constructor(mcp?: McpConfig | undefined);
22
24
  init(): Promise<void>;
23
- private resolveExecutionPolicy;
24
- private resolveOutcomeMapper;
25
+ private resolveInputGuardrail;
26
+ private resolveOutputGuardrail;
25
27
  list(): Promise<Tool[]>;
26
28
  listServers(): Promise<McpServer$1[]>;
27
29
  get(name: string): Promise<Tool | undefined>;
28
30
  getInputText(name: string, input?: object): Promise<string>;
29
- execute(name: string, input?: object): Promise<string>;
31
+ private authorize;
32
+ execute(name: string, input?: object, auth?: ToolAuthorizationOptions): Promise<ToolOutputGuardrailResult | ToolAuthorizationBlock>;
30
33
  }
31
34
 
32
35
  export { type McpConfig, type McpServer, type McpToolImport, ToolDispatcher };
package/dist/index.d.ts CHANGED
@@ -1,17 +1,19 @@
1
- import { Tool, McpServer as McpServer$1 } from '@mappies/miniwat-agent-core';
1
+ import { Tool, McpServer as McpServer$1, ToolAuthorizationOptions, ToolOutputGuardrailResult, ToolAuthorizationBlock } from '@mappies/miniwat-agent-core';
2
2
 
3
- interface McpConfig {
4
- mcpServers: Record<string, McpServer>;
3
+ interface McpToolImport {
4
+ import: string;
5
+ enabled?: boolean;
5
6
  }
7
+
6
8
  interface McpServer {
7
9
  package: string;
8
10
  description?: string;
9
11
  secrets?: string[];
10
12
  tools: McpToolImport[];
11
13
  }
12
- interface McpToolImport {
13
- import: string;
14
- enabled?: boolean;
14
+
15
+ interface McpConfig {
16
+ mcpServers: Record<string, McpServer>;
15
17
  }
16
18
 
17
19
  declare class ToolDispatcher {
@@ -20,13 +22,14 @@ declare class ToolDispatcher {
20
22
  private servers;
21
23
  constructor(mcp?: McpConfig | undefined);
22
24
  init(): Promise<void>;
23
- private resolveExecutionPolicy;
24
- private resolveOutcomeMapper;
25
+ private resolveInputGuardrail;
26
+ private resolveOutputGuardrail;
25
27
  list(): Promise<Tool[]>;
26
28
  listServers(): Promise<McpServer$1[]>;
27
29
  get(name: string): Promise<Tool | undefined>;
28
30
  getInputText(name: string, input?: object): Promise<string>;
29
- execute(name: string, input?: object): Promise<string>;
31
+ private authorize;
32
+ execute(name: string, input?: object, auth?: ToolAuthorizationOptions): Promise<ToolOutputGuardrailResult | ToolAuthorizationBlock>;
30
33
  }
31
34
 
32
35
  export { type McpConfig, type McpServer, type McpToolImport, ToolDispatcher };
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // src/entities/toolDispatcher.ts
2
- import { Tool, McpServer } from "@mappies/miniwat-agent-core";
2
+ import { Tool, McpServer, DefaultOutputGuardrail } from "@mappies/miniwat-agent-core";
3
+ import { randomUUID } from "crypto";
3
4
  var ToolDispatcher = class {
4
5
  constructor(mcp) {
5
6
  this.mcp = mcp;
@@ -19,6 +20,7 @@ var ToolDispatcher = class {
19
20
  let definition = pck[t.import];
20
21
  let tool = new Tool({
21
22
  name: definition.name,
23
+ displayName: definition.displayName,
22
24
  description: definition.description,
23
25
  schema: definition.inputSchema,
24
26
  func: pck[definition.name],
@@ -26,57 +28,57 @@ var ToolDispatcher = class {
26
28
  getInputText: pck[`${definition.name}InputText`],
27
29
  readOnly: definition.readOnly === true,
28
30
  requiresApproval: definition.requiresApproval === true,
29
- executionPolicy: this.resolveExecutionPolicy(server, definition, pck),
30
- outcomeMapper: this.resolveOutcomeMapper(server, definition, pck)
31
+ inputGuardrail: this.resolveInputGuardrail(server, definition, pck),
32
+ outputGuardrail: this.resolveOutputGuardrail(server, definition, pck)
31
33
  });
32
34
  this.tools.push(tool);
33
35
  }
34
36
  }
35
37
  }
36
- // Resolves a tool definition's named executionPolicy from the OWNING package's
37
- // EXECUTION_POLICIES factory export. Validation is loud and happens at init — never deferred to
38
- // tool invocation — so the app cannot reach agent.stream() with a partially resolved tool.
39
- resolveExecutionPolicy(server, definition, pck) {
40
- const name = definition.executionPolicy;
38
+ // Resolves a tool definition's named inputGuardrail from the OWNING package's INPUT_GUARDRAILS
39
+ // factory export. Validation is loud and happens at init — never deferred to tool invocation —
40
+ // so the app cannot reach agent.stream() with a partially resolved tool.
41
+ resolveInputGuardrail(server, definition, pck) {
42
+ const name = definition.inputGuardrail;
41
43
  if (name === void 0) return void 0;
42
- const factories = pck.EXECUTION_POLICIES;
44
+ const factories = pck.INPUT_GUARDRAILS;
43
45
  if (factories === void 0 || typeof factories !== "object") {
44
- throw new Error(`Tool '${definition.name}' on server '${server}' names executionPolicy '${name}' but its package exports no EXECUTION_POLICIES.`);
46
+ throw new Error(`Tool '${definition.name}' on server '${server}' names inputGuardrail '${name}' but its package exports no INPUT_GUARDRAILS.`);
45
47
  }
46
48
  const factory = factories[name];
47
49
  if (factory === void 0) {
48
- throw new Error(`Tool '${definition.name}' on server '${server}' names executionPolicy '${name}' not found in the package's EXECUTION_POLICIES.`);
50
+ throw new Error(`Tool '${definition.name}' on server '${server}' names inputGuardrail '${name}' not found in the package's INPUT_GUARDRAILS.`);
49
51
  }
50
52
  if (typeof factory !== "function") {
51
- throw new Error(`EXECUTION_POLICIES['${name}'] on server '${server}' is not a factory function.`);
53
+ throw new Error(`INPUT_GUARDRAILS['${name}'] on server '${server}' is not a factory function.`);
52
54
  }
53
- const policy = factory();
54
- if (policy === void 0 || typeof policy.evaluate !== "function") {
55
- throw new Error(`EXECUTION_POLICIES['${name}'] on server '${server}' did not produce a valid ExecutionPolicy.`);
55
+ const guardrail = factory();
56
+ if (guardrail === void 0 || typeof guardrail.evaluate !== "function") {
57
+ throw new Error(`INPUT_GUARDRAILS['${name}'] on server '${server}' did not produce a valid ToolInputGuardrail.`);
56
58
  }
57
- return policy;
59
+ return guardrail;
58
60
  }
59
- // Resolves a tool definition's named outcomeMapper from the OWNING package's OUTCOME_MAPPERS
60
- // factory export. Validated loudly at init, mirroring resolveExecutionPolicy.
61
- resolveOutcomeMapper(server, definition, pck) {
62
- const name = definition.outcomeMapper;
61
+ // Resolves a tool definition's named outputGuardrail from the OWNING package's OUTPUT_GUARDRAILS
62
+ // factory export. Validated loudly at init, mirroring resolveInputGuardrail.
63
+ resolveOutputGuardrail(server, definition, pck) {
64
+ const name = definition.outputGuardrail;
63
65
  if (name === void 0) return void 0;
64
- const factories = pck.OUTCOME_MAPPERS;
66
+ const factories = pck.OUTPUT_GUARDRAILS;
65
67
  if (factories === void 0 || typeof factories !== "object") {
66
- throw new Error(`Tool '${definition.name}' on server '${server}' names outcomeMapper '${name}' but its package exports no OUTCOME_MAPPERS.`);
68
+ throw new Error(`Tool '${definition.name}' on server '${server}' names outputGuardrail '${name}' but its package exports no OUTPUT_GUARDRAILS.`);
67
69
  }
68
70
  const factory = factories[name];
69
71
  if (factory === void 0) {
70
- throw new Error(`Tool '${definition.name}' on server '${server}' names outcomeMapper '${name}' not found in the package's OUTCOME_MAPPERS.`);
72
+ throw new Error(`Tool '${definition.name}' on server '${server}' names outputGuardrail '${name}' not found in the package's OUTPUT_GUARDRAILS.`);
71
73
  }
72
74
  if (typeof factory !== "function") {
73
- throw new Error(`OUTCOME_MAPPERS['${name}'] on server '${server}' is not a factory function.`);
75
+ throw new Error(`OUTPUT_GUARDRAILS['${name}'] on server '${server}' is not a factory function.`);
74
76
  }
75
- const mapper = factory();
76
- if (mapper === void 0 || typeof mapper.map !== "function") {
77
- throw new Error(`OUTCOME_MAPPERS['${name}'] on server '${server}' did not produce a valid ToolOutcomeMapper.`);
77
+ const guardrail = factory();
78
+ if (guardrail === void 0 || typeof guardrail.evaluate !== "function") {
79
+ throw new Error(`OUTPUT_GUARDRAILS['${name}'] on server '${server}' did not produce a valid ToolOutputGuardrail.`);
78
80
  }
79
- return mapper;
81
+ return guardrail;
80
82
  }
81
83
  async list() {
82
84
  await this.init();
@@ -94,7 +96,30 @@ var ToolDispatcher = class {
94
96
  const tool = await this.get(name);
95
97
  return tool?.getInputText?.(input) || "";
96
98
  }
97
- async execute(name, input) {
99
+ // Evaluates the dispatch-boundary input guardrail against the concrete invocation. Returns
100
+ // undefined when execution may proceed; a ToolAuthorizationBlock (defer/deny) when it is
101
+ // blocked. On defer the pending call is recorded via the awaited onDeferred sink BEFORE the
102
+ // deferred result is returned (persist-before-respond); if a tool can defer but no sink is
103
+ // supplied, it FAILS CLOSED (denied) — a deferral must never be reported as unrecoverable.
104
+ async authorize(name, input, tool, auth) {
105
+ if (!auth) {
106
+ return void 0;
107
+ }
108
+ const decision = auth.guardrail.evaluate({ toolName: name, arguments: input }, auth.context);
109
+ if (decision.status === "allow") {
110
+ return void 0;
111
+ }
112
+ if (decision.status === "deny") {
113
+ return { authorization: "deny", succeeded: false, text: decision.reason };
114
+ }
115
+ const pending = { id: randomUUID(), name, arguments: input ?? {}, status: "pending" };
116
+ if (!auth.onDeferred) {
117
+ return { authorization: "deny", succeeded: false, text: "Authorization is unavailable for this operation." };
118
+ }
119
+ await auth.onDeferred(pending);
120
+ return { authorization: "defer", succeeded: false, text: decision.reason, pending };
121
+ }
122
+ async execute(name, input, auth) {
98
123
  const tool = await this.get(name);
99
124
  if (!tool) {
100
125
  throw new Error(`Tool ${name} could not be found.`);
@@ -102,12 +127,18 @@ var ToolDispatcher = class {
102
127
  if (!tool.func) {
103
128
  throw new Error(`Tool ${name} does not have a function.`);
104
129
  }
130
+ const authorization = await this.authorize(name, input, tool, auth);
131
+ if (authorization) {
132
+ return authorization;
133
+ }
134
+ let result;
105
135
  try {
106
- let result = await tool.func(input);
107
- return result;
136
+ result = await tool.func(input);
108
137
  } catch (e) {
109
138
  throw new Error(`Failed to run ${name} tool: ${e?.message}`);
110
139
  }
140
+ const guardrail = tool.outputGuardrail ?? new DefaultOutputGuardrail();
141
+ return guardrail.evaluate(result);
111
142
  }
112
143
  };
113
144
  export {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/entities/toolDispatcher.ts"],"sourcesContent":["import { Tool, McpServer, ExecutionPolicy, ExecutionPolicyFactory, ToolOutcomeMapper, ToolOutcomeMapperFactory } from \"@mappies/miniwat-agent-core\";\nimport { McpConfig } from \"../interfaces/mcpConfig\";\n\nexport class ToolDispatcher\n{\n private tools:Tool[]\n private servers:McpServer[]\n\n constructor(private mcp?:McpConfig)\n {\n this.tools = []\n this.servers = []\n }\n\n async init()\n {\n if(this.tools.length !== 0) return;\n\n this.tools = [];\n\n if(this.mcp === undefined) return;\n\n for(let server of Object.keys(this.mcp.mcpServers))\n {\n let service = this.mcp.mcpServers[server]\n\n this.servers.push(new McpServer({name: server, ...service}))\n \n const pck = await import(service.package);\n for(let t of service.tools)\n {\n // Host intent: a tool explicitly disabled in config is excluded here, during\n // discovery, so the planner never sees it.\n if(t.enabled === false) continue;\n\n let definition = pck[t.import];\n let tool = new Tool({ \n name: definition.name, \n description: definition.description, \n schema: definition.inputSchema, \n func: pck[definition.name],\n service: server,\n getInputText: pck[`${definition.name}InputText`],\n readOnly: definition.readOnly === true,\n requiresApproval: definition.requiresApproval === true,\n executionPolicy: this.resolveExecutionPolicy(server, definition, pck),\n outcomeMapper: this.resolveOutcomeMapper(server, definition, pck)\n })\n \n this.tools.push(tool)\n }\n }\n }\n\n // Resolves a tool definition's named executionPolicy from the OWNING package's\n // EXECUTION_POLICIES factory export. Validation is loud and happens at init — never deferred to\n // tool invocation — so the app cannot reach agent.stream() with a partially resolved tool.\n private resolveExecutionPolicy(server:string, definition:any, pck:any): ExecutionPolicy | undefined\n {\n const name:string | undefined = definition.executionPolicy;\n\n if(name === undefined) return undefined;\n\n const factories = pck.EXECUTION_POLICIES;\n\n if(factories === undefined || typeof factories !== \"object\")\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names executionPolicy '${name}' but its package exports no EXECUTION_POLICIES.`);\n }\n\n const factory:ExecutionPolicyFactory | undefined = factories[name];\n\n if(factory === undefined)\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names executionPolicy '${name}' not found in the package's EXECUTION_POLICIES.`);\n }\n\n if(typeof factory !== \"function\")\n {\n throw new Error(`EXECUTION_POLICIES['${name}'] on server '${server}' is not a factory function.`);\n }\n\n const policy = factory();\n\n if(policy === undefined || typeof policy.evaluate !== \"function\")\n {\n throw new Error(`EXECUTION_POLICIES['${name}'] on server '${server}' did not produce a valid ExecutionPolicy.`);\n }\n\n return policy;\n }\n\n // Resolves a tool definition's named outcomeMapper from the OWNING package's OUTCOME_MAPPERS\n // factory export. Validated loudly at init, mirroring resolveExecutionPolicy.\n private resolveOutcomeMapper(server:string, definition:any, pck:any): ToolOutcomeMapper | undefined\n {\n const name:string | undefined = definition.outcomeMapper;\n\n if(name === undefined) return undefined;\n\n const factories = pck.OUTCOME_MAPPERS;\n\n if(factories === undefined || typeof factories !== \"object\")\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names outcomeMapper '${name}' but its package exports no OUTCOME_MAPPERS.`);\n }\n\n const factory:ToolOutcomeMapperFactory | undefined = factories[name];\n\n if(factory === undefined)\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names outcomeMapper '${name}' not found in the package's OUTCOME_MAPPERS.`);\n }\n\n if(typeof factory !== \"function\")\n {\n throw new Error(`OUTCOME_MAPPERS['${name}'] on server '${server}' is not a factory function.`);\n }\n\n const mapper = factory();\n\n if(mapper === undefined || typeof mapper.map !== \"function\")\n {\n throw new Error(`OUTCOME_MAPPERS['${name}'] on server '${server}' did not produce a valid ToolOutcomeMapper.`);\n }\n\n return mapper;\n }\n\n async list(): Promise<Tool[]>\n {\n await this.init()\n return this.tools;\n }\n\n async listServers(): Promise<McpServer[]>\n {\n await this.init()\n return this.servers;\n }\n\n async get(name:string): Promise<Tool|undefined>\n {\n await this.init()\n return this.tools.find(tool => tool.name === name);\n }\n\n async getInputText(name:string, input?:object): Promise<string>\n {\n const tool = await this.get(name);\n\n return tool?.getInputText?.(input) || '';\n }\n\n async execute(name:string, input?:object): Promise<string>\n {\n const tool = await this.get(name);\n \n if(!tool)\n {\n throw new Error(`Tool ${name} could not be found.`);\n }\n\n if(!tool.func)\n {\n throw new Error(`Tool ${name} does not have a function.`);\n }\n\n try\n {\n let result = await tool.func(input);\n return result;\n }\n catch(e:any)\n {\n throw new Error(`Failed to run ${name} tool: ${e?.message}`);\n }\n }\n}"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/entities/toolDispatcher.ts"],"sourcesContent":["import { Tool, McpServer, ToolInputGuardrail, ToolInputGuardrailFactory, ToolOutputGuardrail, ToolOutputGuardrailFactory, ToolOutputGuardrailResult, DefaultOutputGuardrail, ToolAuthorizationOptions, ToolAuthorizationBlock, PendingToolCall } from \"@mappies/miniwat-agent-core\";\nimport { randomUUID } from \"crypto\";\nimport { McpConfig } from \"../interfaces/mcpConfig\";\n\nexport class ToolDispatcher\n{\n private tools:Tool[]\n private servers:McpServer[]\n\n constructor(private mcp?:McpConfig)\n {\n this.tools = []\n this.servers = []\n }\n\n async init()\n {\n if(this.tools.length !== 0) return;\n\n this.tools = [];\n\n if(this.mcp === undefined) return;\n\n for(let server of Object.keys(this.mcp.mcpServers))\n {\n let service = this.mcp.mcpServers[server]\n\n this.servers.push(new McpServer({name: server, ...service}))\n \n const pck = await import(service.package);\n for(let t of service.tools)\n {\n // Host intent: a tool explicitly disabled in config is excluded here, during\n // discovery, so the planner never sees it.\n if(t.enabled === false) continue;\n\n let definition = pck[t.import];\n let tool = new Tool({ \n name: definition.name, \n displayName: definition.displayName,\n description: definition.description, \n schema: definition.inputSchema, \n func: pck[definition.name],\n service: server,\n getInputText: pck[`${definition.name}InputText`],\n readOnly: definition.readOnly === true,\n requiresApproval: definition.requiresApproval === true,\n inputGuardrail: this.resolveInputGuardrail(server, definition, pck),\n outputGuardrail: this.resolveOutputGuardrail(server, definition, pck)\n })\n \n this.tools.push(tool)\n }\n }\n }\n\n // Resolves a tool definition's named inputGuardrail from the OWNING package's INPUT_GUARDRAILS\n // factory export. Validation is loud and happens at init — never deferred to tool invocation —\n // so the app cannot reach agent.stream() with a partially resolved tool.\n private resolveInputGuardrail(server:string, definition:any, pck:any): ToolInputGuardrail | undefined\n {\n const name:string | undefined = definition.inputGuardrail;\n\n if(name === undefined) return undefined;\n\n const factories = pck.INPUT_GUARDRAILS;\n\n if(factories === undefined || typeof factories !== \"object\")\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names inputGuardrail '${name}' but its package exports no INPUT_GUARDRAILS.`);\n }\n\n const factory:ToolInputGuardrailFactory | undefined = factories[name];\n\n if(factory === undefined)\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names inputGuardrail '${name}' not found in the package's INPUT_GUARDRAILS.`);\n }\n\n if(typeof factory !== \"function\")\n {\n throw new Error(`INPUT_GUARDRAILS['${name}'] on server '${server}' is not a factory function.`);\n }\n\n const guardrail = factory();\n\n if(guardrail === undefined || typeof guardrail.evaluate !== \"function\")\n {\n throw new Error(`INPUT_GUARDRAILS['${name}'] on server '${server}' did not produce a valid ToolInputGuardrail.`);\n }\n\n return guardrail;\n }\n\n // Resolves a tool definition's named outputGuardrail from the OWNING package's OUTPUT_GUARDRAILS\n // factory export. Validated loudly at init, mirroring resolveInputGuardrail.\n private resolveOutputGuardrail(server:string, definition:any, pck:any): ToolOutputGuardrail | undefined\n {\n const name:string | undefined = definition.outputGuardrail;\n\n if(name === undefined) return undefined;\n\n const factories = pck.OUTPUT_GUARDRAILS;\n\n if(factories === undefined || typeof factories !== \"object\")\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names outputGuardrail '${name}' but its package exports no OUTPUT_GUARDRAILS.`);\n }\n\n const factory:ToolOutputGuardrailFactory | undefined = factories[name];\n\n if(factory === undefined)\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names outputGuardrail '${name}' not found in the package's OUTPUT_GUARDRAILS.`);\n }\n\n if(typeof factory !== \"function\")\n {\n throw new Error(`OUTPUT_GUARDRAILS['${name}'] on server '${server}' is not a factory function.`);\n }\n\n const guardrail = factory();\n\n if(guardrail === undefined || typeof guardrail.evaluate !== \"function\")\n {\n throw new Error(`OUTPUT_GUARDRAILS['${name}'] on server '${server}' did not produce a valid ToolOutputGuardrail.`);\n }\n\n return guardrail;\n }\n\n async list(): Promise<Tool[]>\n {\n await this.init()\n return this.tools;\n }\n\n async listServers(): Promise<McpServer[]>\n {\n await this.init()\n return this.servers;\n }\n\n async get(name:string): Promise<Tool|undefined>\n {\n await this.init()\n return this.tools.find(tool => tool.name === name);\n }\n\n async getInputText(name:string, input?:object): Promise<string>\n {\n const tool = await this.get(name);\n\n return tool?.getInputText?.(input) || '';\n }\n\n // Evaluates the dispatch-boundary input guardrail against the concrete invocation. Returns\n // undefined when execution may proceed; a ToolAuthorizationBlock (defer/deny) when it is\n // blocked. On defer the pending call is recorded via the awaited onDeferred sink BEFORE the\n // deferred result is returned (persist-before-respond); if a tool can defer but no sink is\n // supplied, it FAILS CLOSED (denied) — a deferral must never be reported as unrecoverable.\n private async authorize(name:string, input:object | undefined, tool:Tool, auth?:ToolAuthorizationOptions): Promise<ToolAuthorizationBlock | undefined>\n {\n if(!auth)\n {\n return undefined;\n }\n\n const decision = auth.guardrail.evaluate({ toolName: name, arguments: input }, auth.context);\n\n if(decision.status === \"allow\")\n {\n return undefined;\n }\n\n if(decision.status === \"deny\")\n {\n return { authorization: \"deny\", succeeded: false, text: decision.reason };\n }\n\n // defer: preserve the invocation for a later approval turn.\n const pending:PendingToolCall = { id: randomUUID(), name, arguments: (input ?? {}) as Record<string, unknown>, status: \"pending\" };\n\n if(!auth.onDeferred)\n {\n // Fail closed: a deferral we cannot durably record must not surface as a usable\n // approval-required result.\n return { authorization: \"deny\", succeeded: false, text: \"Authorization is unavailable for this operation.\" };\n }\n\n // Persist-before-respond: the pending call is durably recorded before the deferred result\n // (and the approval request derived from it) can reach the user. A rejection propagates.\n await auth.onDeferred(pending);\n\n return { authorization: \"defer\", succeeded: false, text: decision.reason, pending };\n }\n\n async execute(name:string, input?:object, auth?:ToolAuthorizationOptions): Promise<ToolOutputGuardrailResult | ToolAuthorizationBlock>\n {\n const tool = await this.get(name);\n \n if(!tool)\n {\n throw new Error(`Tool ${name} could not be found.`);\n }\n\n if(!tool.func)\n {\n throw new Error(`Tool ${name} does not have a function.`);\n }\n\n // Dispatch-boundary authorization runs BEFORE the tool, so an unauthorized side effect never\n // executes — regardless of which planner (or no planner) proposed it. The guardrail is the\n // existing allow/defer/deny input guardrail evaluated against the CONCRETE invocation.\n const authorization = await this.authorize(name, input, tool, auth);\n\n if(authorization)\n {\n return authorization;\n }\n\n let result;\n\n try\n {\n result = await tool.func(input);\n }\n catch(e:any)\n {\n throw new Error(`Failed to run ${name} tool: ${e?.message}`);\n }\n\n // The output guardrail is the SINGLE post-execution authority. It runs here, at the\n // provider-agnostic chokepoint, so the real result is classified BEFORE any provider relays\n // it. Its verdict carries both the user-facing text and the semantic status to the caller;\n // a `blocked` verdict withholds the real result in favor of a replacement. A tool without an\n // explicit guardrail gets the framework default (a normal return is a success).\n const guardrail = tool.outputGuardrail ?? new DefaultOutputGuardrail();\n\n return guardrail.evaluate(result);\n }\n}"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mappies/miniwat-mcp-core",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "Shared entities and executor for Miniwat MCP",
5
5
  "homepage": "https://gitlab.com/mappies/miniwat-mcp-core#readme",
6
6
  "bugs": {
@@ -43,6 +43,6 @@
43
43
  "vitest": "^5.0.0"
44
44
  },
45
45
  "dependencies": {
46
- "@mappies/miniwat-agent-core": "^0.20.0"
46
+ "@mappies/miniwat-agent-core": "^0.22.0"
47
47
  }
48
48
  }