@dobbyai/mcp-external 1.0.4 → 1.2.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/README.md +44 -14
- package/dist/__tests__/agent-mail-tools.test.d.ts +8 -0
- package/dist/__tests__/agent-mail-tools.test.d.ts.map +1 -0
- package/dist/__tests__/agent-mail-tools.test.js +255 -0
- package/dist/__tests__/agent-mail-tools.test.js.map +1 -0
- package/dist/__tests__/annotations.test.d.ts +8 -0
- package/dist/__tests__/annotations.test.d.ts.map +1 -0
- package/dist/__tests__/annotations.test.js +108 -0
- package/dist/__tests__/annotations.test.js.map +1 -0
- package/dist/__tests__/auth.test.d.ts +7 -0
- package/dist/__tests__/auth.test.d.ts.map +1 -0
- package/dist/__tests__/auth.test.js +161 -0
- package/dist/__tests__/auth.test.js.map +1 -0
- package/dist/__tests__/doctor.test.d.ts +16 -0
- package/dist/__tests__/doctor.test.d.ts.map +1 -0
- package/dist/__tests__/doctor.test.js +258 -0
- package/dist/__tests__/doctor.test.js.map +1 -0
- package/dist/__tests__/external-agents-tools.test.d.ts +11 -0
- package/dist/__tests__/external-agents-tools.test.d.ts.map +1 -0
- package/dist/__tests__/external-agents-tools.test.js +619 -0
- package/dist/__tests__/external-agents-tools.test.js.map +1 -0
- package/dist/__tests__/gateway-bearer.test.d.ts +12 -0
- package/dist/__tests__/gateway-bearer.test.d.ts.map +1 -0
- package/dist/__tests__/gateway-bearer.test.js +112 -0
- package/dist/__tests__/gateway-bearer.test.js.map +1 -0
- package/dist/__tests__/gateway-key-resolver.test.d.ts +10 -0
- package/dist/__tests__/gateway-key-resolver.test.d.ts.map +1 -0
- package/dist/__tests__/gateway-key-resolver.test.js +125 -0
- package/dist/__tests__/gateway-key-resolver.test.js.map +1 -0
- package/dist/__tests__/http-concurrency.test.d.ts +20 -0
- package/dist/__tests__/http-concurrency.test.d.ts.map +1 -0
- package/dist/__tests__/http-concurrency.test.js +254 -0
- package/dist/__tests__/http-concurrency.test.js.map +1 -0
- package/dist/__tests__/integration/protocol.test.d.ts +8 -0
- package/dist/__tests__/integration/protocol.test.d.ts.map +1 -0
- package/dist/__tests__/integration/protocol.test.js +110 -0
- package/dist/__tests__/integration/protocol.test.js.map +1 -0
- package/dist/__tests__/mcp-integrations.test.d.ts +8 -0
- package/dist/__tests__/mcp-integrations.test.d.ts.map +1 -0
- package/dist/__tests__/mcp-integrations.test.js +365 -0
- package/dist/__tests__/mcp-integrations.test.js.map +1 -0
- package/dist/__tests__/memory-graph-tools.test.d.ts +8 -0
- package/dist/__tests__/memory-graph-tools.test.d.ts.map +1 -0
- package/dist/__tests__/memory-graph-tools.test.js +254 -0
- package/dist/__tests__/memory-graph-tools.test.js.map +1 -0
- package/dist/__tests__/registry-dispatch.test.d.ts +11 -0
- package/dist/__tests__/registry-dispatch.test.d.ts.map +1 -0
- package/dist/__tests__/registry-dispatch.test.js +30 -0
- package/dist/__tests__/registry-dispatch.test.js.map +1 -0
- package/dist/__tests__/registry-listing-parity.test.d.ts +2 -0
- package/dist/__tests__/registry-listing-parity.test.d.ts.map +1 -0
- package/dist/__tests__/registry-listing-parity.test.js +89 -0
- package/dist/__tests__/registry-listing-parity.test.js.map +1 -0
- package/dist/__tests__/role-cap.test.d.ts +2 -0
- package/dist/__tests__/role-cap.test.d.ts.map +1 -0
- package/dist/__tests__/role-cap.test.js +113 -0
- package/dist/__tests__/role-cap.test.js.map +1 -0
- package/dist/__tests__/schedule-tools.test.d.ts +8 -0
- package/dist/__tests__/schedule-tools.test.d.ts.map +1 -0
- package/dist/__tests__/schedule-tools.test.js +285 -0
- package/dist/__tests__/schedule-tools.test.js.map +1 -0
- package/dist/__tests__/server-gateway-key.test.d.ts +18 -0
- package/dist/__tests__/server-gateway-key.test.d.ts.map +1 -0
- package/dist/__tests__/server-gateway-key.test.js +148 -0
- package/dist/__tests__/server-gateway-key.test.js.map +1 -0
- package/dist/__tests__/server-user-scoped.test.d.ts +34 -0
- package/dist/__tests__/server-user-scoped.test.d.ts.map +1 -0
- package/dist/__tests__/server-user-scoped.test.js +577 -0
- package/dist/__tests__/server-user-scoped.test.js.map +1 -0
- package/dist/__tests__/task-id-pattern.test.d.ts +12 -0
- package/dist/__tests__/task-id-pattern.test.d.ts.map +1 -0
- package/dist/__tests__/task-id-pattern.test.js +43 -0
- package/dist/__tests__/task-id-pattern.test.js.map +1 -0
- package/dist/__tests__/tiers.test.d.ts +7 -0
- package/dist/__tests__/tiers.test.d.ts.map +1 -0
- package/dist/__tests__/tiers.test.js +199 -0
- package/dist/__tests__/tiers.test.js.map +1 -0
- package/dist/__tests__/tools/hosted-agents.test.d.ts +9 -0
- package/dist/__tests__/tools/hosted-agents.test.d.ts.map +1 -0
- package/dist/__tests__/tools/hosted-agents.test.js +301 -0
- package/dist/__tests__/tools/hosted-agents.test.js.map +1 -0
- package/dist/__tests__/tools/llm-providers.test.d.ts +10 -0
- package/dist/__tests__/tools/llm-providers.test.d.ts.map +1 -0
- package/dist/__tests__/tools/llm-providers.test.js +105 -0
- package/dist/__tests__/tools/llm-providers.test.js.map +1 -0
- package/dist/__tests__/tools/services.test.js +139 -98
- package/dist/__tests__/tools/services.test.js.map +1 -1
- package/dist/__tests__/tools.test.d.ts +7 -0
- package/dist/__tests__/tools.test.d.ts.map +1 -0
- package/dist/__tests__/tools.test.js +152 -0
- package/dist/__tests__/tools.test.js.map +1 -0
- package/dist/__tests__/transport.test.d.ts +7 -0
- package/dist/__tests__/transport.test.d.ts.map +1 -0
- package/dist/__tests__/transport.test.js +397 -0
- package/dist/__tests__/transport.test.js.map +1 -0
- package/dist/__tests__/validate-credentials.test.d.ts +9 -0
- package/dist/__tests__/validate-credentials.test.d.ts.map +1 -0
- package/dist/__tests__/validate-credentials.test.js +172 -0
- package/dist/__tests__/validate-credentials.test.js.map +1 -0
- package/dist/__tests__/web-eval-tools.test.d.ts +8 -0
- package/dist/__tests__/web-eval-tools.test.d.ts.map +1 -0
- package/dist/__tests__/web-eval-tools.test.js +241 -0
- package/dist/__tests__/web-eval-tools.test.js.map +1 -0
- package/dist/__tests__/whoami.test.d.ts +11 -0
- package/dist/__tests__/whoami.test.d.ts.map +1 -0
- package/dist/__tests__/whoami.test.js +194 -0
- package/dist/__tests__/whoami.test.js.map +1 -0
- package/dist/__tests__/workflow-tools.test.d.ts +8 -0
- package/dist/__tests__/workflow-tools.test.d.ts.map +1 -0
- package/dist/__tests__/workflow-tools.test.js +261 -0
- package/dist/__tests__/workflow-tools.test.js.map +1 -0
- package/dist/__tests__/workloads.test.d.ts +9 -0
- package/dist/__tests__/workloads.test.d.ts.map +1 -0
- package/dist/__tests__/workloads.test.js +169 -0
- package/dist/__tests__/workloads.test.js.map +1 -0
- package/dist/auth/oauth-provider.d.ts +34 -0
- package/dist/auth/oauth-provider.d.ts.map +1 -0
- package/dist/auth/oauth-provider.js +75 -0
- package/dist/auth/oauth-provider.js.map +1 -0
- package/dist/auth/token-verifier.d.ts +45 -0
- package/dist/auth/token-verifier.d.ts.map +1 -0
- package/dist/auth/token-verifier.js +160 -0
- package/dist/auth/token-verifier.js.map +1 -0
- package/dist/connectors/claude-desktop.d.ts.map +1 -1
- package/dist/connectors/claude-desktop.js +3 -2
- package/dist/connectors/claude-desktop.js.map +1 -1
- package/dist/connectors/cursor.d.ts.map +1 -1
- package/dist/connectors/cursor.js +3 -2
- package/dist/connectors/cursor.js.map +1 -1
- package/dist/connectors/setup.d.ts.map +1 -1
- package/dist/connectors/setup.js +2 -1
- package/dist/connectors/setup.js.map +1 -1
- package/dist/connectors/vscode.d.ts.map +1 -1
- package/dist/connectors/vscode.js +3 -2
- package/dist/connectors/vscode.js.map +1 -1
- package/dist/connectors/windsurf.d.ts.map +1 -1
- package/dist/connectors/windsurf.js +3 -2
- package/dist/connectors/windsurf.js.map +1 -1
- package/dist/doctor.d.ts +34 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +134 -0
- package/dist/doctor.js.map +1 -0
- package/dist/http-server.d.ts +56 -0
- package/dist/http-server.d.ts.map +1 -0
- package/dist/http-server.js +455 -0
- package/dist/http-server.js.map +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +96 -171
- package/dist/index.js.map +1 -1
- package/dist/lib/consts.d.ts +21 -0
- package/dist/lib/consts.d.ts.map +1 -0
- package/dist/lib/consts.js +30 -0
- package/dist/lib/consts.js.map +1 -0
- package/dist/lib/dobby-client.d.ts +60 -3
- package/dist/lib/dobby-client.d.ts.map +1 -1
- package/dist/lib/dobby-client.js +145 -44
- package/dist/lib/dobby-client.js.map +1 -1
- package/dist/lib/gateway-key-resolver.d.ts +38 -0
- package/dist/lib/gateway-key-resolver.d.ts.map +1 -0
- package/dist/lib/gateway-key-resolver.js +59 -0
- package/dist/lib/gateway-key-resolver.js.map +1 -0
- package/dist/lib/log.d.ts +25 -0
- package/dist/lib/log.d.ts.map +1 -0
- package/dist/lib/log.js +36 -0
- package/dist/lib/log.js.map +1 -0
- package/dist/server.d.ts +175 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +1017 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/agent-mail.d.ts +112 -0
- package/dist/tools/agent-mail.d.ts.map +1 -0
- package/dist/tools/agent-mail.js +118 -0
- package/dist/tools/agent-mail.js.map +1 -0
- package/dist/tools/agent-versions.d.ts +93 -0
- package/dist/tools/agent-versions.d.ts.map +1 -0
- package/dist/tools/agent-versions.js +99 -0
- package/dist/tools/agent-versions.js.map +1 -0
- package/dist/tools/approvals.d.ts +24 -34
- package/dist/tools/approvals.d.ts.map +1 -1
- package/dist/tools/approvals.js +24 -81
- package/dist/tools/approvals.js.map +1 -1
- package/dist/tools/claude-code-sync.d.ts +40 -0
- package/dist/tools/claude-code-sync.d.ts.map +1 -0
- package/dist/tools/claude-code-sync.js +52 -0
- package/dist/tools/claude-code-sync.js.map +1 -0
- package/dist/tools/control-plane.d.ts +118 -0
- package/dist/tools/control-plane.d.ts.map +1 -0
- package/dist/tools/control-plane.js +135 -0
- package/dist/tools/control-plane.js.map +1 -0
- package/dist/tools/crew-builder.d.ts +24 -66
- package/dist/tools/crew-builder.d.ts.map +1 -1
- package/dist/tools/crew-builder.js +24 -185
- package/dist/tools/crew-builder.js.map +1 -1
- package/dist/tools/crewai.d.ts +24 -63
- package/dist/tools/crewai.d.ts.map +1 -1
- package/dist/tools/crewai.js +24 -145
- package/dist/tools/crewai.js.map +1 -1
- package/dist/tools/exa.d.ts +126 -0
- package/dist/tools/exa.d.ts.map +1 -0
- package/dist/tools/exa.js +125 -0
- package/dist/tools/exa.js.map +1 -0
- package/dist/tools/external-agents.d.ts +440 -0
- package/dist/tools/external-agents.d.ts.map +1 -0
- package/dist/tools/external-agents.js +386 -0
- package/dist/tools/external-agents.js.map +1 -0
- package/dist/tools/github-mcp.d.ts +228 -0
- package/dist/tools/github-mcp.d.ts.map +1 -0
- package/dist/tools/github-mcp.js +235 -0
- package/dist/tools/github-mcp.js.map +1 -0
- package/dist/tools/governance.d.ts +273 -0
- package/dist/tools/governance.d.ts.map +1 -0
- package/dist/tools/governance.js +286 -0
- package/dist/tools/governance.js.map +1 -0
- package/dist/tools/hosted-agents.d.ts +216 -0
- package/dist/tools/hosted-agents.d.ts.map +1 -0
- package/dist/tools/hosted-agents.js +214 -0
- package/dist/tools/hosted-agents.js.map +1 -0
- package/dist/tools/index.d.ts +6335 -191
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +441 -172
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/jira.d.ts +60 -176
- package/dist/tools/jira.d.ts.map +1 -1
- package/dist/tools/jira.js +60 -365
- package/dist/tools/jira.js.map +1 -1
- package/dist/tools/llm-providers.d.ts +50 -0
- package/dist/tools/llm-providers.d.ts.map +1 -0
- package/dist/tools/llm-providers.js +41 -0
- package/dist/tools/llm-providers.js.map +1 -0
- package/dist/tools/mcp-metrics.d.ts +47 -0
- package/dist/tools/mcp-metrics.d.ts.map +1 -0
- package/dist/tools/mcp-metrics.js +53 -0
- package/dist/tools/mcp-metrics.js.map +1 -0
- package/dist/tools/mcp-tools.d.ts +12 -29
- package/dist/tools/mcp-tools.d.ts.map +1 -1
- package/dist/tools/mcp-tools.js +12 -131
- package/dist/tools/mcp-tools.js.map +1 -1
- package/dist/tools/mem0.d.ts +127 -0
- package/dist/tools/mem0.d.ts.map +1 -0
- package/dist/tools/mem0.js +155 -0
- package/dist/tools/mem0.js.map +1 -0
- package/dist/tools/memory-graph.d.ts +151 -0
- package/dist/tools/memory-graph.d.ts.map +1 -0
- package/dist/tools/memory-graph.js +159 -0
- package/dist/tools/memory-graph.js.map +1 -0
- package/dist/tools/memory-stores.d.ts +141 -0
- package/dist/tools/memory-stores.d.ts.map +1 -0
- package/dist/tools/memory-stores.js +147 -0
- package/dist/tools/memory-stores.js.map +1 -0
- package/dist/tools/messages.d.ts +12 -20
- package/dist/tools/messages.d.ts.map +1 -1
- package/dist/tools/messages.js +12 -49
- package/dist/tools/messages.js.map +1 -1
- package/dist/tools/moltbook.d.ts +328 -0
- package/dist/tools/moltbook.d.ts.map +1 -0
- package/dist/tools/moltbook.js +334 -0
- package/dist/tools/moltbook.js.map +1 -0
- package/dist/tools/monitoring-attribution.d.ts +71 -0
- package/dist/tools/monitoring-attribution.d.ts.map +1 -0
- package/dist/tools/monitoring-attribution.js +74 -0
- package/dist/tools/monitoring-attribution.js.map +1 -0
- package/dist/tools/ops.d.ts +139 -0
- package/dist/tools/ops.d.ts.map +1 -0
- package/dist/tools/ops.js +151 -0
- package/dist/tools/ops.js.map +1 -0
- package/dist/tools/orchestrations.d.ts +109 -0
- package/dist/tools/orchestrations.d.ts.map +1 -0
- package/dist/tools/orchestrations.js +115 -0
- package/dist/tools/orchestrations.js.map +1 -0
- package/dist/tools/outcomes.d.ts +138 -0
- package/dist/tools/outcomes.d.ts.map +1 -0
- package/dist/tools/outcomes.js +136 -0
- package/dist/tools/outcomes.js.map +1 -0
- package/dist/tools/schedules.d.ts +149 -0
- package/dist/tools/schedules.d.ts.map +1 -0
- package/dist/tools/schedules.js +155 -0
- package/dist/tools/schedules.js.map +1 -0
- package/dist/tools/services.d.ts +6 -16
- package/dist/tools/services.d.ts.map +1 -1
- package/dist/tools/services.js +6 -135
- package/dist/tools/services.js.map +1 -1
- package/dist/tools/sessions.d.ts +124 -0
- package/dist/tools/sessions.d.ts.map +1 -0
- package/dist/tools/sessions.js +130 -0
- package/dist/tools/sessions.js.map +1 -0
- package/dist/tools/setup-status.d.ts +29 -0
- package/dist/tools/setup-status.d.ts.map +1 -0
- package/dist/tools/setup-status.js +35 -0
- package/dist/tools/setup-status.js.map +1 -0
- package/dist/tools/tasks.d.ts +44 -56
- package/dist/tools/tasks.d.ts.map +1 -1
- package/dist/tools/tasks.js +48 -212
- package/dist/tools/tasks.js.map +1 -1
- package/dist/tools/tiers.d.ts +55 -0
- package/dist/tools/tiers.d.ts.map +1 -0
- package/dist/tools/tiers.js +239 -0
- package/dist/tools/tiers.js.map +1 -0
- package/dist/tools/unified-agents.d.ts +43 -0
- package/dist/tools/unified-agents.d.ts.map +1 -0
- package/dist/tools/unified-agents.js +46 -0
- package/dist/tools/unified-agents.js.map +1 -0
- package/dist/tools/web-eval.d.ts +129 -0
- package/dist/tools/web-eval.d.ts.map +1 -0
- package/dist/tools/web-eval.js +136 -0
- package/dist/tools/web-eval.js.map +1 -0
- package/dist/tools/workflow.d.ts +105 -0
- package/dist/tools/workflow.d.ts.map +1 -0
- package/dist/tools/workflow.js +111 -0
- package/dist/tools/workflow.js.map +1 -0
- package/dist/tools/workloads.d.ts +81 -0
- package/dist/tools/workloads.d.ts.map +1 -0
- package/dist/tools/workloads.js +81 -0
- package/dist/tools/workloads.js.map +1 -0
- package/package.json +13 -7
package/dist/tools/index.js
CHANGED
|
@@ -1,25 +1,216 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MCP Tools Index
|
|
3
3
|
*
|
|
4
|
-
* Exports all tool definitions
|
|
4
|
+
* Exports all tool definitions; execution dispatches through the capability
|
|
5
|
+
* registry (@dobbyai/capability-core, ADR-019).
|
|
5
6
|
* Gateway integration: Auth check + audit logging via gateway MCP endpoint.
|
|
6
7
|
*/
|
|
7
|
-
export * from
|
|
8
|
-
export * from
|
|
9
|
-
export * from
|
|
10
|
-
export * from
|
|
11
|
-
export * from
|
|
12
|
-
export * from
|
|
13
|
-
export * from
|
|
14
|
-
export * from
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
8
|
+
export * from "./tasks.js";
|
|
9
|
+
export * from "./messages.js";
|
|
10
|
+
export * from "./approvals.js";
|
|
11
|
+
export * from "./services.js";
|
|
12
|
+
export * from "./crewai.js";
|
|
13
|
+
export * from "./crew-builder.js";
|
|
14
|
+
export * from "./mcp-tools.js";
|
|
15
|
+
export * from "./jira.js";
|
|
16
|
+
export * from "./ops.js";
|
|
17
|
+
export * from "./github-mcp.js";
|
|
18
|
+
export * from "./mem0.js";
|
|
19
|
+
export * from "./exa.js";
|
|
20
|
+
export * from "./mcp-metrics.js";
|
|
21
|
+
export * from "./workflow.js";
|
|
22
|
+
export * from "./web-eval.js";
|
|
23
|
+
export * from "./memory-graph.js";
|
|
24
|
+
export * from "./agent-mail.js";
|
|
25
|
+
export * from "./schedules.js";
|
|
26
|
+
export * from "./moltbook.js";
|
|
27
|
+
export * from "./unified-agents.js";
|
|
28
|
+
export * from "./governance.js";
|
|
29
|
+
export * from "./control-plane.js";
|
|
30
|
+
export * from "./monitoring-attribution.js";
|
|
31
|
+
export * from "./setup-status.js";
|
|
32
|
+
export * from "./claude-code-sync.js";
|
|
33
|
+
export * from "./memory-stores.js";
|
|
34
|
+
export * from "./agent-versions.js";
|
|
35
|
+
export * from "./orchestrations.js";
|
|
36
|
+
export * from "./external-agents.js";
|
|
37
|
+
export * from "./workloads.js";
|
|
38
|
+
export * from "./tiers.js";
|
|
39
|
+
import { taskTools } from "./tasks.js";
|
|
40
|
+
import { messageTools } from "./messages.js";
|
|
41
|
+
import { approvalTools } from "./approvals.js";
|
|
42
|
+
import { serviceTools } from "./services.js";
|
|
43
|
+
import { crewaiTools } from "./crewai.js";
|
|
44
|
+
import { crewBuilderTools } from "./crew-builder.js";
|
|
45
|
+
import { mcpRemoteTools } from "./mcp-tools.js";
|
|
46
|
+
import { jiraTools } from "./jira.js";
|
|
47
|
+
import { opsTools } from "./ops.js";
|
|
48
|
+
import { githubMcpTools } from "./github-mcp.js";
|
|
49
|
+
import { mem0Tools } from "./mem0.js";
|
|
50
|
+
import { exaTools } from "./exa.js";
|
|
51
|
+
import { mcpMetricsTools } from "./mcp-metrics.js";
|
|
52
|
+
import { workflowTools } from "./workflow.js";
|
|
53
|
+
import { webEvalTools } from "./web-eval.js";
|
|
54
|
+
import { memoryGraphTools } from "./memory-graph.js";
|
|
55
|
+
import { agentMailTools } from "./agent-mail.js";
|
|
56
|
+
import { scheduleTools } from "./schedules.js";
|
|
57
|
+
import { moltbookTools } from "./moltbook.js";
|
|
58
|
+
import { unifiedAgentTools } from "./unified-agents.js";
|
|
59
|
+
import { governanceTools } from "./governance.js";
|
|
60
|
+
import { controlPlaneTools } from "./control-plane.js";
|
|
61
|
+
import { monitoringAttributionTools } from "./monitoring-attribution.js";
|
|
62
|
+
import { hostedAgentsTools } from "./hosted-agents.js";
|
|
63
|
+
import { setupStatusTools } from "./setup-status.js";
|
|
64
|
+
import { claudeCodeSyncTools } from "./claude-code-sync.js";
|
|
65
|
+
import { memoryStoreTools } from "./memory-stores.js";
|
|
66
|
+
import { sessionTools } from "./sessions.js";
|
|
67
|
+
import { agentVersionTools } from "./agent-versions.js";
|
|
68
|
+
import { orchestrationTools } from "./orchestrations.js";
|
|
69
|
+
import { outcomeTools } from "./outcomes.js";
|
|
70
|
+
import { externalAgentTools } from "./external-agents.js";
|
|
71
|
+
import { llmProviderTools } from "./llm-providers.js";
|
|
72
|
+
import { workloadTools } from "./workloads.js";
|
|
73
|
+
import { TOOL_TIERS, filterToolsByTier, resolveToolTier, isReadOnlyScopes, } from "./tiers.js";
|
|
74
|
+
import { roleCapAllows, createRegistry, toMcpResult, } from "@dobbyai/capability-core";
|
|
75
|
+
// ============================================
|
|
76
|
+
// RBAC role-cap (ADR-019 Phase 2)
|
|
77
|
+
// ============================================
|
|
78
|
+
// Plan-tier ∩ role-cap: on top of the plan tier, each tool has a minimum
|
|
79
|
+
// TENANT role. Derived (not a 131-entry hand-map): admin-class tools →
|
|
80
|
+
// tenant_admin, readOnlyHint tools → viewer, everything else (mutations) →
|
|
81
|
+
// member. The role signal rides authInfo.extra.tenant_role (set by the web
|
|
82
|
+
// introspect route). GRACEFUL: a nullish role (signal absent / not-yet-emitted)
|
|
83
|
+
// skips role gating and falls back to tier-only — role-cap only bites when a
|
|
84
|
+
// concrete role is known, so this never breaks existing tier-gated callers.
|
|
85
|
+
// is_super_admin bypasses the cap entirely. Uses capability-core's roleCapAllows
|
|
86
|
+
// (the ONE shared graceful role-cap helper — the SAME rule the registry's
|
|
87
|
+
// visibleTo() applies, so listing + call gating can't drift) + TenantRole canon
|
|
88
|
+
// (rbac.ts, NOT the legacy constants/roles.ts enum).
|
|
89
|
+
const ADMIN_CLASS_TOOLS = new Set([
|
|
90
|
+
"approve_task",
|
|
91
|
+
"reject_task",
|
|
92
|
+
"request_changes",
|
|
93
|
+
"deregister_external_agent",
|
|
94
|
+
"update_external_agent",
|
|
95
|
+
"agent_version_rollback",
|
|
96
|
+
"delete_schedule",
|
|
97
|
+
"delete_agent_schedule",
|
|
98
|
+
"import_policies",
|
|
99
|
+
// Creates an Org/Tenant/Process-layer policy (capability-core minRole
|
|
100
|
+
// tenant_admin) — same admin bar as import_policies.
|
|
101
|
+
"create_policy",
|
|
102
|
+
// Edit / soft-delete a single policy (PATCH/DELETE routes enforce
|
|
103
|
+
// withTenantAuth admin) — same admin bar as create_policy. test_policy is
|
|
104
|
+
// NOT here: it's a read-only dry-run (viewer).
|
|
105
|
+
"update_policy",
|
|
106
|
+
"delete_policy",
|
|
107
|
+
// Seeds sample runs + fires real compliance scans — same admin bar as
|
|
108
|
+
// connecting a real workload (the route enforces withTenantAuth admin).
|
|
109
|
+
"try_sample_workload",
|
|
110
|
+
// Writes a tenant-wide LLM provider credential (the route enforces
|
|
111
|
+
// withTenantAuth admin) — same admin bar as connecting a real workload.
|
|
112
|
+
"connect_llm_provider",
|
|
113
|
+
// Tears down a Managed Agent (the route enforces withTenantAuth admin).
|
|
114
|
+
"delete_hosted_agent",
|
|
115
|
+
]);
|
|
116
|
+
// Managed Agents mutation tools — the underlying routes enforce
|
|
117
|
+
// guardHostedRoute(..., "developer", ...), a role this legacy function
|
|
118
|
+
// otherwise has no bucket for (it only distinguishes tenant_admin/viewer/
|
|
119
|
+
// member). Capability-core's `minRole: "developer"` is the source of truth;
|
|
120
|
+
// this set keeps the legacy computation in parity with it.
|
|
121
|
+
const DEVELOPER_CLASS_TOOLS = new Set([
|
|
122
|
+
"host_sample_agent",
|
|
123
|
+
"create_hosted_agent",
|
|
124
|
+
"deploy_hosted_agent",
|
|
125
|
+
"run_hosted_agent",
|
|
126
|
+
]);
|
|
127
|
+
// Read-only tools that still need "member" (not mere "viewer") because they
|
|
128
|
+
// compose from routes gated at member (e.g. hosted-agent executions), not
|
|
129
|
+
// just viewer-gated data.
|
|
130
|
+
const MEMBER_CLASS_READONLY_TOOLS = new Set(["get_agent_results"]);
|
|
131
|
+
export function minRoleForTool(name) {
|
|
132
|
+
if (ADMIN_CLASS_TOOLS.has(name))
|
|
133
|
+
return "tenant_admin";
|
|
134
|
+
if (DEVELOPER_CLASS_TOOLS.has(name))
|
|
135
|
+
return "developer";
|
|
136
|
+
if (MEMBER_CLASS_READONLY_TOOLS.has(name))
|
|
137
|
+
return "member";
|
|
138
|
+
const readOnly = allTools[name]?.annotations?.readOnlyHint === true;
|
|
139
|
+
return readOnly ? "viewer" : "member";
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Does the caller's role clear the tool's minimum role? Superadmin bypasses;
|
|
143
|
+
* otherwise delegates to the shared `roleCapAllows` (a nullish role skips the
|
|
144
|
+
* cap — tier-only, non-breaking; a concrete role is checked fail-closed). This
|
|
145
|
+
* is the SAME helper the registry's `visibleTo()` uses, so the two gating paths
|
|
146
|
+
* are guaranteed identical.
|
|
147
|
+
*/
|
|
148
|
+
export function passesRoleCap(name, role, isSuperAdmin) {
|
|
149
|
+
if (isSuperAdmin)
|
|
150
|
+
return true;
|
|
151
|
+
return roleCapAllows(role, minRoleForTool(name));
|
|
152
|
+
}
|
|
153
|
+
// ============================================
|
|
154
|
+
// Firewall Sidecar Interceptor
|
|
155
|
+
// ============================================
|
|
156
|
+
// Calls the Agentic Firewall sidecar (localhost:4000) before tool execution.
|
|
157
|
+
// Fail-open: if sidecar is unavailable or times out, tool executes normally.
|
|
158
|
+
// The sidecar returns: 200 (pass/redact), 403 (block), 202 (pause for approval).
|
|
159
|
+
const FIREWALL_SIDECAR_URL = process.env.FIREWALL_SIDECAR_URL || "http://localhost:4000";
|
|
160
|
+
const FIREWALL_TIMEOUT_MS = parseInt(process.env.FIREWALL_TIMEOUT_MS || "3000", 10);
|
|
161
|
+
const FIREWALL_ENABLED = process.env.FIREWALL_ENABLED !== "false"; // Default: enabled
|
|
162
|
+
async function interceptWithFirewall(toolName, args, context) {
|
|
163
|
+
if (!FIREWALL_ENABLED) {
|
|
164
|
+
return { action: "pass" };
|
|
165
|
+
}
|
|
166
|
+
const controller = new AbortController();
|
|
167
|
+
const timeout = setTimeout(() => controller.abort(), FIREWALL_TIMEOUT_MS);
|
|
168
|
+
try {
|
|
169
|
+
const response = await fetch(`${FIREWALL_SIDECAR_URL}/v1/tools/intercept`, {
|
|
170
|
+
method: "POST",
|
|
171
|
+
headers: { "Content-Type": "application/json" },
|
|
172
|
+
body: JSON.stringify({
|
|
173
|
+
tool_name: toolName,
|
|
174
|
+
tool_arguments: args,
|
|
175
|
+
org_id: context.tenantId || "unknown", // Best effort
|
|
176
|
+
tenant_id: context.tenantId || "unknown",
|
|
177
|
+
actor: {
|
|
178
|
+
actor_id: context.userId || "unknown",
|
|
179
|
+
actor_type: "ai_agent",
|
|
180
|
+
actor_name: context.userName,
|
|
181
|
+
},
|
|
182
|
+
session_id: `mcp_${Date.now()}`,
|
|
183
|
+
trace_id: `trace_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
|
|
184
|
+
}),
|
|
185
|
+
signal: controller.signal,
|
|
186
|
+
});
|
|
187
|
+
clearTimeout(timeout);
|
|
188
|
+
if (response.status === 200) {
|
|
189
|
+
const body = (await response.json());
|
|
190
|
+
return body;
|
|
191
|
+
}
|
|
192
|
+
if (response.status === 403) {
|
|
193
|
+
const body = (await response.json());
|
|
194
|
+
return { action: "block", reason: body.reason || "Blocked by firewall" };
|
|
195
|
+
}
|
|
196
|
+
if (response.status === 202) {
|
|
197
|
+
const body = (await response.json());
|
|
198
|
+
return {
|
|
199
|
+
action: "pause",
|
|
200
|
+
job_id: body.job_id,
|
|
201
|
+
poll_url: body.poll_url,
|
|
202
|
+
message: body.message,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
// Unknown status — fail-open
|
|
206
|
+
return { action: "pass" };
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
clearTimeout(timeout);
|
|
210
|
+
// Sidecar down or timeout — fail-open (don't block tools)
|
|
211
|
+
return { action: "pass" };
|
|
212
|
+
}
|
|
213
|
+
}
|
|
23
214
|
// ============================================
|
|
24
215
|
// All Tools
|
|
25
216
|
// ============================================
|
|
@@ -32,7 +223,127 @@ export const allTools = {
|
|
|
32
223
|
...crewBuilderTools,
|
|
33
224
|
...mcpRemoteTools,
|
|
34
225
|
...jiraTools,
|
|
226
|
+
...opsTools,
|
|
227
|
+
...githubMcpTools,
|
|
228
|
+
...mem0Tools,
|
|
229
|
+
...exaTools,
|
|
230
|
+
...mcpMetricsTools,
|
|
231
|
+
...workflowTools,
|
|
232
|
+
...webEvalTools,
|
|
233
|
+
...memoryGraphTools,
|
|
234
|
+
...agentMailTools,
|
|
235
|
+
...scheduleTools,
|
|
236
|
+
...moltbookTools,
|
|
237
|
+
...unifiedAgentTools,
|
|
238
|
+
...governanceTools,
|
|
239
|
+
...controlPlaneTools,
|
|
240
|
+
...monitoringAttributionTools,
|
|
241
|
+
...hostedAgentsTools,
|
|
242
|
+
...setupStatusTools,
|
|
243
|
+
...claudeCodeSyncTools,
|
|
244
|
+
...memoryStoreTools,
|
|
245
|
+
...sessionTools,
|
|
246
|
+
...agentVersionTools,
|
|
247
|
+
...orchestrationTools,
|
|
248
|
+
...outcomeTools,
|
|
249
|
+
...externalAgentTools,
|
|
250
|
+
...workloadTools,
|
|
251
|
+
...llmProviderTools,
|
|
35
252
|
};
|
|
253
|
+
// ============================================
|
|
254
|
+
// Capability Registry (ADR-019 Phase 1)
|
|
255
|
+
// ============================================
|
|
256
|
+
// The registry is the runtime source of truth for tool EXECUTION and VISIBILITY:
|
|
257
|
+
// handleToolCall dispatches every tool through capabilityRegistry.get(name).handler(...),
|
|
258
|
+
// and getToolDefinitions derives its visible set from capabilityRegistry.visibleTo()
|
|
259
|
+
// while sourcing the output shape from allTools (byte-identical listing). Built once
|
|
260
|
+
// at module load from @dobbyai/capability-core (all 131 tools; the legacy handle*
|
|
261
|
+
// bodies were deleted from src/tools/*.ts — the registry holds the only handlers).
|
|
262
|
+
// getToolAccessDenial keeps its staged denial messages on allTools + tiers.ts, with
|
|
263
|
+
// the role check flowing through the shared roleCapAllows rule.
|
|
264
|
+
const capabilityRegistry = createRegistry();
|
|
265
|
+
// ============================================
|
|
266
|
+
// Tool Definitions with Tier Filtering
|
|
267
|
+
// ============================================
|
|
268
|
+
/**
|
|
269
|
+
* Get tool definitions for ListTools response.
|
|
270
|
+
* Filters by tier and includes annotations on each tool.
|
|
271
|
+
* With `readOnly`, additionally filters to tools annotated readOnlyHint
|
|
272
|
+
* (a missing annotation counts as NOT read-only — fail closed).
|
|
273
|
+
*
|
|
274
|
+
* Usage in MCP server (HTTP mode):
|
|
275
|
+
* server.setRequestHandler(ListToolsRequestSchema, async (_req, extra) => ({
|
|
276
|
+
* tools: getToolDefinitions(resolveToolTier({ scopes }), {
|
|
277
|
+
* readOnly: isReadOnlyScopes(scopes),
|
|
278
|
+
* }),
|
|
279
|
+
* }));
|
|
280
|
+
*/
|
|
281
|
+
export function getToolDefinitions(tier = "enterprise", opts = {}) {
|
|
282
|
+
// The visible SET comes from the ONE registry (plan-tier ∩ role-cap ∩
|
|
283
|
+
// read-only, ADR-019 P1 tail); the output SHAPE stays sourced from allTools
|
|
284
|
+
// so the MCP tool definitions are byte-identical. Proven equivalent to the
|
|
285
|
+
// legacy filterToolsByTier + read-only + passesRoleCap path across every
|
|
286
|
+
// tier × role × readOnly × superadmin combo in registry-listing-parity.test.ts.
|
|
287
|
+
const visibleIds = new Set(capabilityRegistry
|
|
288
|
+
.visibleTo({
|
|
289
|
+
tier,
|
|
290
|
+
role: (opts.role ?? undefined),
|
|
291
|
+
isSuperAdmin: opts.isSuperAdmin,
|
|
292
|
+
readOnly: opts.readOnly,
|
|
293
|
+
})
|
|
294
|
+
.map((c) => c.id));
|
|
295
|
+
return Object.values(allTools)
|
|
296
|
+
.filter((tool) => visibleIds.has(tool.name))
|
|
297
|
+
.map((tool) => ({
|
|
298
|
+
name: tool.name,
|
|
299
|
+
description: tool.description,
|
|
300
|
+
inputSchema: tool.inputSchema,
|
|
301
|
+
annotations: tool.annotations || {},
|
|
302
|
+
}));
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Tier + read-only enforcement for CallTool — list filtering without call
|
|
306
|
+
* enforcement is cosmetic. Returns a human-readable denial message, or null
|
|
307
|
+
* when the call is allowed. Unknown tool names return null so the router's
|
|
308
|
+
* canonical "Unknown tool" error stays the single source for those.
|
|
309
|
+
*/
|
|
310
|
+
export function getToolAccessDenial(name, authContext) {
|
|
311
|
+
const tool = allTools[name];
|
|
312
|
+
if (!tool)
|
|
313
|
+
return null;
|
|
314
|
+
// superAdminOnly is a HARD call-time gate (defense-in-depth): the registry's
|
|
315
|
+
// visibleTo() only HIDES these from ListTools, which is cosmetic — a client
|
|
316
|
+
// can call any tool by name. Without this, a non-superadmin enterprise-tier
|
|
317
|
+
// token could invoke a superadmin-only tool (e.g. the platform ops tools) by
|
|
318
|
+
// name and reach its handler. Mirrors the registry's visibleTo() rule so the
|
|
319
|
+
// list and call paths gate identically.
|
|
320
|
+
if (capabilityRegistry.get(name)?.superAdminOnly &&
|
|
321
|
+
!authContext.isSuperAdmin) {
|
|
322
|
+
return `Tool "${name}" requires platform super-admin access.`;
|
|
323
|
+
}
|
|
324
|
+
const tier = resolveToolTier(authContext);
|
|
325
|
+
const allowed = new Set(filterToolsByTier(Object.keys(allTools), tier));
|
|
326
|
+
if (!allowed.has(name)) {
|
|
327
|
+
const requiredTier = TOOL_TIERS.pro.includes(name) ? "pro" : "enterprise";
|
|
328
|
+
return (`Tool "${name}" is not available on your current plan ` +
|
|
329
|
+
`(requires the ${requiredTier} tier; this token's tier is ${tier}). ` +
|
|
330
|
+
`Upgrade your Dobby plan at https://dobby-ai.com to unlock it.`);
|
|
331
|
+
}
|
|
332
|
+
if (isReadOnlyScopes(authContext.scopes) &&
|
|
333
|
+
allTools[name].annotations?.readOnlyHint !== true) {
|
|
334
|
+
return (`Tool "${name}" performs writes, but this token is read-only ` +
|
|
335
|
+
`(every scope ends in :read). Use a key with write scopes to call it.`);
|
|
336
|
+
}
|
|
337
|
+
// RBAC role-cap (ADR-019 Phase 2): plan-tier ∩ role. Superadmin bypasses;
|
|
338
|
+
// a nullish role skips (tier-only). Orthogonal to the read-only cap above —
|
|
339
|
+
// both must pass (stricter-wins).
|
|
340
|
+
if (!passesRoleCap(name, authContext.role, authContext.isSuperAdmin)) {
|
|
341
|
+
return (`Tool "${name}" requires the "${minRoleForTool(name)}" tenant role ` +
|
|
342
|
+
`or higher; your role is "${authContext.role ?? "none"}". ` +
|
|
343
|
+
`Ask a tenant admin/owner to grant a higher role.`);
|
|
344
|
+
}
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
36
347
|
/**
|
|
37
348
|
* Check gateway auth for an MCP tool call.
|
|
38
349
|
* Returns auth result from gateway. If no gatewayKey is configured, returns allowed.
|
|
@@ -44,11 +355,11 @@ async function checkGatewayAuth(toolName, mcpServer, context) {
|
|
|
44
355
|
}
|
|
45
356
|
try {
|
|
46
357
|
const response = await fetch(`${context.gatewayUrl}/api/v1/gateway/mcp/tools`, {
|
|
47
|
-
method:
|
|
358
|
+
method: "POST",
|
|
48
359
|
headers: {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
...(context.tenantId ? {
|
|
360
|
+
"Content-Type": "application/json",
|
|
361
|
+
Authorization: `Bearer ${context.gatewayKey}`,
|
|
362
|
+
...(context.tenantId ? { "X-Tenant-Id": context.tenantId } : {}),
|
|
52
363
|
},
|
|
53
364
|
body: JSON.stringify({
|
|
54
365
|
tool_name: toolName,
|
|
@@ -57,17 +368,19 @@ async function checkGatewayAuth(toolName, mcpServer, context) {
|
|
|
57
368
|
}),
|
|
58
369
|
});
|
|
59
370
|
if (!response.ok) {
|
|
60
|
-
const errBody = await response
|
|
371
|
+
const errBody = (await response
|
|
372
|
+
.json()
|
|
373
|
+
.catch(() => ({ error: "Gateway auth failed" })));
|
|
61
374
|
return {
|
|
62
375
|
allowed: false,
|
|
63
376
|
error: errBody.error || `Gateway returned ${response.status}`,
|
|
64
377
|
};
|
|
65
378
|
}
|
|
66
|
-
return await response.json();
|
|
379
|
+
return (await response.json());
|
|
67
380
|
}
|
|
68
381
|
catch (error) {
|
|
69
|
-
const errMsg = error instanceof Error ? error.message :
|
|
70
|
-
console.error(
|
|
382
|
+
const errMsg = error instanceof Error ? error.message : "Unknown error";
|
|
383
|
+
console.error("[MCP Gateway] Auth check failed:", errMsg);
|
|
71
384
|
// Fail open with warning if gateway is unreachable
|
|
72
385
|
return { allowed: true };
|
|
73
386
|
}
|
|
@@ -76,34 +389,34 @@ async function checkGatewayAuth(toolName, mcpServer, context) {
|
|
|
76
389
|
* Log tool call result to gateway.
|
|
77
390
|
* Non-blocking — errors are logged but don't affect tool result.
|
|
78
391
|
*/
|
|
79
|
-
async function logToolCallToGateway(toolCall, authResult, context, eventType =
|
|
392
|
+
async function logToolCallToGateway(toolCall, authResult, context, eventType = "mcp.tool.call") {
|
|
80
393
|
if (!context.gatewayKey || !context.gatewayUrl)
|
|
81
394
|
return;
|
|
82
395
|
try {
|
|
83
396
|
await fetch(`${context.gatewayUrl}/api/v1/gateway/mcp/tools`, {
|
|
84
|
-
method:
|
|
397
|
+
method: "POST",
|
|
85
398
|
headers: {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
...(context.tenantId ? {
|
|
399
|
+
"Content-Type": "application/json",
|
|
400
|
+
Authorization: `Bearer ${context.gatewayKey}`,
|
|
401
|
+
...(context.tenantId ? { "X-Tenant-Id": context.tenantId } : {}),
|
|
89
402
|
},
|
|
90
403
|
body: JSON.stringify({
|
|
91
|
-
action:
|
|
404
|
+
action: "log",
|
|
92
405
|
tool_call: toolCall,
|
|
93
406
|
event_type: eventType,
|
|
94
|
-
actor_type: authResult.actor?.actor_type ||
|
|
407
|
+
actor_type: authResult.actor?.actor_type || "human",
|
|
95
408
|
actor_id: authResult.actor?.actor_id || context.userId,
|
|
96
409
|
on_behalf_of: authResult.actor?.on_behalf_of || undefined,
|
|
97
|
-
org_id: authResult.org_id ||
|
|
410
|
+
org_id: authResult.org_id || "",
|
|
98
411
|
region: context.region,
|
|
99
412
|
}),
|
|
100
413
|
});
|
|
101
414
|
}
|
|
102
415
|
catch (error) {
|
|
103
|
-
console.error(
|
|
416
|
+
console.error("[MCP Gateway] Log failed:", error.message);
|
|
104
417
|
}
|
|
105
418
|
}
|
|
106
|
-
const MCP_SERVER_NAME =
|
|
419
|
+
const MCP_SERVER_NAME = "mcp-dobby-external";
|
|
107
420
|
export async function handleToolCall(toolName, args, context) {
|
|
108
421
|
const { client, userId, userName } = context;
|
|
109
422
|
const startTime = new Date();
|
|
@@ -112,165 +425,121 @@ export async function handleToolCall(toolName, args, context) {
|
|
|
112
425
|
if (!authResult.allowed) {
|
|
113
426
|
// Log denial to gateway (non-blocking)
|
|
114
427
|
logToolCallToGateway({
|
|
115
|
-
tenant_id: context.tenantId ||
|
|
116
|
-
agent_id:
|
|
117
|
-
task_id: args.task_id ||
|
|
428
|
+
tenant_id: context.tenantId || "",
|
|
429
|
+
agent_id: "mcp-external",
|
|
430
|
+
task_id: args.task_id || "",
|
|
431
|
+
mcp_server: MCP_SERVER_NAME,
|
|
432
|
+
tool_name: toolName,
|
|
433
|
+
tool_input: args,
|
|
434
|
+
status: "error",
|
|
435
|
+
error_message: authResult.error || "Gateway auth denied",
|
|
436
|
+
started_at: startTime.toISOString(),
|
|
437
|
+
completed_at: new Date().toISOString(),
|
|
438
|
+
}, authResult, context, "mcp.tool.denied");
|
|
439
|
+
return {
|
|
440
|
+
content: [
|
|
441
|
+
{
|
|
442
|
+
type: "text",
|
|
443
|
+
text: `Tool call denied: ${authResult.error || "Insufficient permissions"}`,
|
|
444
|
+
},
|
|
445
|
+
],
|
|
446
|
+
isError: true,
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
// 1.5. Firewall sidecar interception (if running)
|
|
450
|
+
// Calls the Agentic Firewall at localhost:4000 before tool execution.
|
|
451
|
+
// Fail-open: if sidecar is unavailable, tool executes normally.
|
|
452
|
+
const firewallResult = await interceptWithFirewall(toolName, args, context);
|
|
453
|
+
if (firewallResult.action === "block") {
|
|
454
|
+
logToolCallToGateway({
|
|
455
|
+
tenant_id: context.tenantId || "",
|
|
456
|
+
agent_id: "mcp-external",
|
|
457
|
+
task_id: args.task_id || "",
|
|
118
458
|
mcp_server: MCP_SERVER_NAME,
|
|
119
459
|
tool_name: toolName,
|
|
120
460
|
tool_input: args,
|
|
121
|
-
status:
|
|
122
|
-
error_message:
|
|
461
|
+
status: "error",
|
|
462
|
+
error_message: firewallResult.reason || "Blocked by firewall policy",
|
|
123
463
|
started_at: startTime.toISOString(),
|
|
124
464
|
completed_at: new Date().toISOString(),
|
|
125
|
-
}, authResult, context,
|
|
465
|
+
}, authResult, context, "mcp.tool.denied");
|
|
126
466
|
return {
|
|
127
467
|
content: [
|
|
128
468
|
{
|
|
129
|
-
type:
|
|
130
|
-
text: `Tool
|
|
469
|
+
type: "text",
|
|
470
|
+
text: `Tool blocked by Agentic Firewall: ${firewallResult.reason || "Policy violation"}`,
|
|
131
471
|
},
|
|
132
472
|
],
|
|
133
473
|
isError: true,
|
|
134
474
|
};
|
|
135
475
|
}
|
|
476
|
+
if (firewallResult.action === "pause") {
|
|
477
|
+
return {
|
|
478
|
+
content: [
|
|
479
|
+
{
|
|
480
|
+
type: "text",
|
|
481
|
+
text: [
|
|
482
|
+
`⏳ Action "${toolName}" requires human approval.`,
|
|
483
|
+
`Job ID: ${firewallResult.job_id}`,
|
|
484
|
+
`Poll: ${firewallResult.poll_url}`,
|
|
485
|
+
firewallResult.message || "",
|
|
486
|
+
]
|
|
487
|
+
.filter(Boolean)
|
|
488
|
+
.join("\n"),
|
|
489
|
+
},
|
|
490
|
+
],
|
|
491
|
+
isError: false,
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
// If firewall returned 'redact', use modified arguments
|
|
495
|
+
if (firewallResult.action === "redact" && firewallResult.modified_arguments) {
|
|
496
|
+
Object.assign(args, firewallResult.modified_arguments);
|
|
497
|
+
}
|
|
136
498
|
// 2. Execute tool
|
|
137
499
|
let result;
|
|
138
500
|
let toolError;
|
|
139
|
-
let toolStatus =
|
|
501
|
+
let toolStatus = "success";
|
|
140
502
|
try {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
// Approval tools
|
|
169
|
-
case 'get_pending_approvals':
|
|
170
|
-
result = await handleGetPendingApprovals(client);
|
|
171
|
-
break;
|
|
172
|
-
case 'approve_task':
|
|
173
|
-
result = await handleApproveTask(client, args);
|
|
174
|
-
break;
|
|
175
|
-
case 'reject_task':
|
|
176
|
-
result = await handleRejectTask(client, args);
|
|
177
|
-
break;
|
|
178
|
-
case 'request_changes':
|
|
179
|
-
result = await handleRequestChanges(client, args);
|
|
180
|
-
break;
|
|
181
|
-
// Service discovery tools
|
|
182
|
-
case 'list_services':
|
|
183
|
-
result = await handleListServices(client, args);
|
|
184
|
-
break;
|
|
185
|
-
// CrewAI tools (hosted platform)
|
|
186
|
-
case 'crewai_health':
|
|
187
|
-
result = await handleCrewAIHealth(client, args);
|
|
188
|
-
break;
|
|
189
|
-
case 'crewai_inputs':
|
|
190
|
-
result = await handleCrewAIInputs(client, args);
|
|
191
|
-
break;
|
|
192
|
-
case 'crewai_kickoff':
|
|
193
|
-
result = await handleCrewAIKickoff(client, args);
|
|
194
|
-
break;
|
|
195
|
-
case 'crewai_status':
|
|
196
|
-
result = await handleCrewAIStatus(client, args);
|
|
197
|
-
break;
|
|
198
|
-
// Crew Builder tools (local YAML-based crews)
|
|
199
|
-
case 'crew_validate':
|
|
200
|
-
result = await handleCrewValidate(client, args);
|
|
201
|
-
break;
|
|
202
|
-
case 'crew_kickoff':
|
|
203
|
-
result = await handleCrewKickoff(client, args);
|
|
204
|
-
break;
|
|
205
|
-
case 'crew_status':
|
|
206
|
-
result = await handleCrewStatus(client, args);
|
|
207
|
-
break;
|
|
208
|
-
case 'crew_list':
|
|
209
|
-
result = await handleCrewList(client, args);
|
|
210
|
-
break;
|
|
211
|
-
// MCP remote tools (discover and call tools on external MCP servers)
|
|
212
|
-
case 'mcp_discover_tools':
|
|
213
|
-
result = await handleMcpDiscoverTools(client, args);
|
|
214
|
-
break;
|
|
215
|
-
case 'mcp_call_tool':
|
|
216
|
-
result = await handleMcpCallTool(client, args);
|
|
217
|
-
break;
|
|
218
|
-
// Jira Cloud tools
|
|
219
|
-
case 'jira_search_issues':
|
|
220
|
-
result = await handleJiraSearchIssues(client, args);
|
|
221
|
-
break;
|
|
222
|
-
case 'jira_get_issue':
|
|
223
|
-
result = await handleJiraGetIssue(client, args);
|
|
224
|
-
break;
|
|
225
|
-
case 'jira_create_issue':
|
|
226
|
-
result = await handleJiraCreateIssue(client, args);
|
|
227
|
-
break;
|
|
228
|
-
case 'jira_update_issue':
|
|
229
|
-
result = await handleJiraUpdateIssue(client, args);
|
|
230
|
-
break;
|
|
231
|
-
case 'jira_add_comment':
|
|
232
|
-
result = await handleJiraAddComment(client, args);
|
|
233
|
-
break;
|
|
234
|
-
case 'jira_get_comments':
|
|
235
|
-
result = await handleJiraGetComments(client, args);
|
|
236
|
-
break;
|
|
237
|
-
case 'jira_get_transitions':
|
|
238
|
-
result = await handleJiraGetTransitions(client, args);
|
|
239
|
-
break;
|
|
240
|
-
case 'jira_transition_issue':
|
|
241
|
-
result = await handleJiraTransitionIssue(client, args);
|
|
242
|
-
break;
|
|
243
|
-
case 'jira_list_projects':
|
|
244
|
-
result = await handleJiraListProjects(client, args);
|
|
245
|
-
break;
|
|
246
|
-
case 'jira_assign_issue':
|
|
247
|
-
result = await handleJiraAssignIssue(client, args);
|
|
248
|
-
break;
|
|
249
|
-
default:
|
|
250
|
-
result = {
|
|
251
|
-
content: [
|
|
252
|
-
{
|
|
253
|
-
type: 'text',
|
|
254
|
-
text: `Unknown tool: ${toolName}`,
|
|
255
|
-
},
|
|
256
|
-
],
|
|
257
|
-
isError: true,
|
|
258
|
-
};
|
|
259
|
-
toolStatus = 'error';
|
|
260
|
-
toolError = `Unknown tool: ${toolName}`;
|
|
503
|
+
const cap = capabilityRegistry.get(toolName);
|
|
504
|
+
if (!cap) {
|
|
505
|
+
result = {
|
|
506
|
+
content: [{ type: "text", text: `Unknown tool: ${toolName}` }],
|
|
507
|
+
isError: true,
|
|
508
|
+
};
|
|
509
|
+
toolStatus = "error";
|
|
510
|
+
toolError = `Unknown tool: ${toolName}`;
|
|
511
|
+
}
|
|
512
|
+
else {
|
|
513
|
+
const capResult = await cap.handler({
|
|
514
|
+
client,
|
|
515
|
+
userId,
|
|
516
|
+
userName,
|
|
517
|
+
tenantId: context.tenantId,
|
|
518
|
+
gatewayKey: context.gatewayKey,
|
|
519
|
+
gatewayUrl: context.gatewayUrl,
|
|
520
|
+
region: context.region,
|
|
521
|
+
// ADR-019/020: thread identity so a handler can authorize per call.
|
|
522
|
+
// Declared at capability-core types.ts:104-107; previously dropped here.
|
|
523
|
+
orgId: context.orgId,
|
|
524
|
+
scopes: context.scopes,
|
|
525
|
+
tenantRole: context.tenantRole,
|
|
526
|
+
orgRole: context.orgRole,
|
|
527
|
+
isSuperAdmin: context.isSuperAdmin,
|
|
528
|
+
}, args);
|
|
529
|
+
result = toMcpResult(capResult);
|
|
261
530
|
}
|
|
262
531
|
if (result?.isError) {
|
|
263
|
-
toolStatus =
|
|
264
|
-
toolError = result.content?.[0]?.text ||
|
|
532
|
+
toolStatus = "error";
|
|
533
|
+
toolError = result.content?.[0]?.text || "Tool returned error";
|
|
265
534
|
}
|
|
266
535
|
}
|
|
267
536
|
catch (error) {
|
|
268
|
-
toolStatus =
|
|
537
|
+
toolStatus = "error";
|
|
269
538
|
toolError = error.message;
|
|
270
539
|
result = {
|
|
271
540
|
content: [
|
|
272
541
|
{
|
|
273
|
-
type:
|
|
542
|
+
type: "text",
|
|
274
543
|
text: `Tool error: ${error.message}`,
|
|
275
544
|
},
|
|
276
545
|
],
|
|
@@ -280,9 +549,9 @@ export async function handleToolCall(toolName, args, context) {
|
|
|
280
549
|
const endTime = new Date();
|
|
281
550
|
// 3. Log result to gateway (non-blocking)
|
|
282
551
|
logToolCallToGateway({
|
|
283
|
-
tenant_id: context.tenantId ||
|
|
284
|
-
agent_id:
|
|
285
|
-
task_id: args.task_id ||
|
|
552
|
+
tenant_id: context.tenantId || "",
|
|
553
|
+
agent_id: "mcp-external",
|
|
554
|
+
task_id: args.task_id || "",
|
|
286
555
|
mcp_server: MCP_SERVER_NAME,
|
|
287
556
|
tool_name: toolName,
|
|
288
557
|
tool_input: args,
|
|
@@ -292,7 +561,7 @@ export async function handleToolCall(toolName, args, context) {
|
|
|
292
561
|
duration_ms: endTime.getTime() - startTime.getTime(),
|
|
293
562
|
started_at: startTime.toISOString(),
|
|
294
563
|
completed_at: endTime.toISOString(),
|
|
295
|
-
}, authResult, context,
|
|
564
|
+
}, authResult, context, "mcp.tool.call");
|
|
296
565
|
return result;
|
|
297
566
|
}
|
|
298
567
|
//# sourceMappingURL=index.js.map
|