@dobbyai/mcp-external 1.1.0 → 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.
Files changed (289) hide show
  1. package/README.md +44 -14
  2. package/dist/__tests__/agent-mail-tools.test.js +19 -26
  3. package/dist/__tests__/agent-mail-tools.test.js.map +1 -1
  4. package/dist/__tests__/auth.test.js +50 -5
  5. package/dist/__tests__/auth.test.js.map +1 -1
  6. package/dist/__tests__/doctor.test.d.ts +16 -0
  7. package/dist/__tests__/doctor.test.d.ts.map +1 -0
  8. package/dist/__tests__/doctor.test.js +258 -0
  9. package/dist/__tests__/doctor.test.js.map +1 -0
  10. package/dist/__tests__/external-agents-tools.test.d.ts +11 -0
  11. package/dist/__tests__/external-agents-tools.test.d.ts.map +1 -0
  12. package/dist/__tests__/external-agents-tools.test.js +619 -0
  13. package/dist/__tests__/external-agents-tools.test.js.map +1 -0
  14. package/dist/__tests__/gateway-bearer.test.d.ts +12 -0
  15. package/dist/__tests__/gateway-bearer.test.d.ts.map +1 -0
  16. package/dist/__tests__/gateway-bearer.test.js +112 -0
  17. package/dist/__tests__/gateway-bearer.test.js.map +1 -0
  18. package/dist/__tests__/gateway-key-resolver.test.d.ts +10 -0
  19. package/dist/__tests__/gateway-key-resolver.test.d.ts.map +1 -0
  20. package/dist/__tests__/gateway-key-resolver.test.js +125 -0
  21. package/dist/__tests__/gateway-key-resolver.test.js.map +1 -0
  22. package/dist/__tests__/http-concurrency.test.d.ts +20 -0
  23. package/dist/__tests__/http-concurrency.test.d.ts.map +1 -0
  24. package/dist/__tests__/http-concurrency.test.js +254 -0
  25. package/dist/__tests__/http-concurrency.test.js.map +1 -0
  26. package/dist/__tests__/integration/protocol.test.js +14 -8
  27. package/dist/__tests__/integration/protocol.test.js.map +1 -1
  28. package/dist/__tests__/mcp-integrations.test.js +20 -30
  29. package/dist/__tests__/mcp-integrations.test.js.map +1 -1
  30. package/dist/__tests__/memory-graph-tools.test.js +27 -38
  31. package/dist/__tests__/memory-graph-tools.test.js.map +1 -1
  32. package/dist/__tests__/registry-dispatch.test.d.ts +11 -0
  33. package/dist/__tests__/registry-dispatch.test.d.ts.map +1 -0
  34. package/dist/__tests__/registry-dispatch.test.js +30 -0
  35. package/dist/__tests__/registry-dispatch.test.js.map +1 -0
  36. package/dist/__tests__/registry-listing-parity.test.d.ts +2 -0
  37. package/dist/__tests__/registry-listing-parity.test.d.ts.map +1 -0
  38. package/dist/__tests__/registry-listing-parity.test.js +89 -0
  39. package/dist/__tests__/registry-listing-parity.test.js.map +1 -0
  40. package/dist/__tests__/role-cap.test.d.ts +2 -0
  41. package/dist/__tests__/role-cap.test.d.ts.map +1 -0
  42. package/dist/__tests__/role-cap.test.js +113 -0
  43. package/dist/__tests__/role-cap.test.js.map +1 -0
  44. package/dist/__tests__/schedule-tools.test.js +15 -20
  45. package/dist/__tests__/schedule-tools.test.js.map +1 -1
  46. package/dist/__tests__/server-gateway-key.test.d.ts +18 -0
  47. package/dist/__tests__/server-gateway-key.test.d.ts.map +1 -0
  48. package/dist/__tests__/server-gateway-key.test.js +148 -0
  49. package/dist/__tests__/server-gateway-key.test.js.map +1 -0
  50. package/dist/__tests__/server-user-scoped.test.d.ts +34 -0
  51. package/dist/__tests__/server-user-scoped.test.d.ts.map +1 -0
  52. package/dist/__tests__/server-user-scoped.test.js +577 -0
  53. package/dist/__tests__/server-user-scoped.test.js.map +1 -0
  54. package/dist/__tests__/task-id-pattern.test.d.ts +12 -0
  55. package/dist/__tests__/task-id-pattern.test.d.ts.map +1 -0
  56. package/dist/__tests__/task-id-pattern.test.js +43 -0
  57. package/dist/__tests__/task-id-pattern.test.js.map +1 -0
  58. package/dist/__tests__/tiers.test.js +152 -56
  59. package/dist/__tests__/tiers.test.js.map +1 -1
  60. package/dist/__tests__/tools/hosted-agents.test.d.ts +9 -0
  61. package/dist/__tests__/tools/hosted-agents.test.d.ts.map +1 -0
  62. package/dist/__tests__/tools/hosted-agents.test.js +301 -0
  63. package/dist/__tests__/tools/hosted-agents.test.js.map +1 -0
  64. package/dist/__tests__/tools/llm-providers.test.d.ts +10 -0
  65. package/dist/__tests__/tools/llm-providers.test.d.ts.map +1 -0
  66. package/dist/__tests__/tools/llm-providers.test.js +105 -0
  67. package/dist/__tests__/tools/llm-providers.test.js.map +1 -0
  68. package/dist/__tests__/tools/services.test.js +139 -98
  69. package/dist/__tests__/tools/services.test.js.map +1 -1
  70. package/dist/__tests__/tools.test.js +24 -15
  71. package/dist/__tests__/tools.test.js.map +1 -1
  72. package/dist/__tests__/transport.test.js +365 -23
  73. package/dist/__tests__/transport.test.js.map +1 -1
  74. package/dist/__tests__/validate-credentials.test.d.ts +9 -0
  75. package/dist/__tests__/validate-credentials.test.d.ts.map +1 -0
  76. package/dist/__tests__/validate-credentials.test.js +172 -0
  77. package/dist/__tests__/validate-credentials.test.js.map +1 -0
  78. package/dist/__tests__/web-eval-tools.test.js +21 -32
  79. package/dist/__tests__/web-eval-tools.test.js.map +1 -1
  80. package/dist/__tests__/whoami.test.d.ts +11 -0
  81. package/dist/__tests__/whoami.test.d.ts.map +1 -0
  82. package/dist/__tests__/whoami.test.js +194 -0
  83. package/dist/__tests__/whoami.test.js.map +1 -0
  84. package/dist/__tests__/workflow-tools.test.js +20 -27
  85. package/dist/__tests__/workflow-tools.test.js.map +1 -1
  86. package/dist/__tests__/workloads.test.d.ts +9 -0
  87. package/dist/__tests__/workloads.test.d.ts.map +1 -0
  88. package/dist/__tests__/workloads.test.js +169 -0
  89. package/dist/__tests__/workloads.test.js.map +1 -0
  90. package/dist/auth/token-verifier.d.ts +11 -6
  91. package/dist/auth/token-verifier.d.ts.map +1 -1
  92. package/dist/auth/token-verifier.js +41 -19
  93. package/dist/auth/token-verifier.js.map +1 -1
  94. package/dist/connectors/claude-desktop.d.ts.map +1 -1
  95. package/dist/connectors/claude-desktop.js +3 -2
  96. package/dist/connectors/claude-desktop.js.map +1 -1
  97. package/dist/connectors/cursor.d.ts.map +1 -1
  98. package/dist/connectors/cursor.js +3 -2
  99. package/dist/connectors/cursor.js.map +1 -1
  100. package/dist/connectors/setup.d.ts.map +1 -1
  101. package/dist/connectors/setup.js +2 -1
  102. package/dist/connectors/setup.js.map +1 -1
  103. package/dist/connectors/vscode.d.ts.map +1 -1
  104. package/dist/connectors/vscode.js +3 -2
  105. package/dist/connectors/vscode.js.map +1 -1
  106. package/dist/connectors/windsurf.d.ts.map +1 -1
  107. package/dist/connectors/windsurf.js +3 -2
  108. package/dist/connectors/windsurf.js.map +1 -1
  109. package/dist/doctor.d.ts +34 -0
  110. package/dist/doctor.d.ts.map +1 -0
  111. package/dist/doctor.js +134 -0
  112. package/dist/doctor.js.map +1 -0
  113. package/dist/http-server.d.ts +24 -3
  114. package/dist/http-server.d.ts.map +1 -1
  115. package/dist/http-server.js +342 -62
  116. package/dist/http-server.js.map +1 -1
  117. package/dist/index.d.ts +5 -1
  118. package/dist/index.d.ts.map +1 -1
  119. package/dist/index.js +72 -208
  120. package/dist/index.js.map +1 -1
  121. package/dist/lib/consts.d.ts +21 -0
  122. package/dist/lib/consts.d.ts.map +1 -0
  123. package/dist/lib/consts.js +30 -0
  124. package/dist/lib/consts.js.map +1 -0
  125. package/dist/lib/dobby-client.d.ts +50 -23
  126. package/dist/lib/dobby-client.d.ts.map +1 -1
  127. package/dist/lib/dobby-client.js +105 -54
  128. package/dist/lib/dobby-client.js.map +1 -1
  129. package/dist/lib/gateway-key-resolver.d.ts +38 -0
  130. package/dist/lib/gateway-key-resolver.d.ts.map +1 -0
  131. package/dist/lib/gateway-key-resolver.js +59 -0
  132. package/dist/lib/gateway-key-resolver.js.map +1 -0
  133. package/dist/lib/log.d.ts +25 -0
  134. package/dist/lib/log.d.ts.map +1 -0
  135. package/dist/lib/log.js +36 -0
  136. package/dist/lib/log.js.map +1 -0
  137. package/dist/server.d.ts +175 -0
  138. package/dist/server.d.ts.map +1 -0
  139. package/dist/server.js +1017 -0
  140. package/dist/server.js.map +1 -0
  141. package/dist/tools/agent-mail.d.ts +0 -41
  142. package/dist/tools/agent-mail.d.ts.map +1 -1
  143. package/dist/tools/agent-mail.js +0 -222
  144. package/dist/tools/agent-mail.js.map +1 -1
  145. package/dist/tools/agent-versions.d.ts +93 -0
  146. package/dist/tools/agent-versions.d.ts.map +1 -0
  147. package/dist/tools/agent-versions.js +99 -0
  148. package/dist/tools/agent-versions.js.map +1 -0
  149. package/dist/tools/approvals.d.ts +0 -34
  150. package/dist/tools/approvals.d.ts.map +1 -1
  151. package/dist/tools/approvals.js +0 -81
  152. package/dist/tools/approvals.js.map +1 -1
  153. package/dist/tools/claude-code-sync.d.ts +40 -0
  154. package/dist/tools/claude-code-sync.d.ts.map +1 -0
  155. package/dist/tools/claude-code-sync.js +52 -0
  156. package/dist/tools/claude-code-sync.js.map +1 -0
  157. package/dist/tools/control-plane.d.ts +118 -0
  158. package/dist/tools/control-plane.d.ts.map +1 -0
  159. package/dist/tools/control-plane.js +135 -0
  160. package/dist/tools/control-plane.js.map +1 -0
  161. package/dist/tools/crew-builder.d.ts +0 -66
  162. package/dist/tools/crew-builder.d.ts.map +1 -1
  163. package/dist/tools/crew-builder.js +0 -185
  164. package/dist/tools/crew-builder.js.map +1 -1
  165. package/dist/tools/crewai.d.ts +0 -63
  166. package/dist/tools/crewai.d.ts.map +1 -1
  167. package/dist/tools/crewai.js +0 -145
  168. package/dist/tools/crewai.js.map +1 -1
  169. package/dist/tools/exa.d.ts +0 -35
  170. package/dist/tools/exa.d.ts.map +1 -1
  171. package/dist/tools/exa.js +0 -103
  172. package/dist/tools/exa.js.map +1 -1
  173. package/dist/tools/external-agents.d.ts +440 -0
  174. package/dist/tools/external-agents.d.ts.map +1 -0
  175. package/dist/tools/external-agents.js +386 -0
  176. package/dist/tools/external-agents.js.map +1 -0
  177. package/dist/tools/github-mcp.d.ts +0 -75
  178. package/dist/tools/github-mcp.d.ts.map +1 -1
  179. package/dist/tools/github-mcp.js +0 -162
  180. package/dist/tools/github-mcp.js.map +1 -1
  181. package/dist/tools/governance.d.ts +162 -18
  182. package/dist/tools/governance.d.ts.map +1 -1
  183. package/dist/tools/governance.js +208 -93
  184. package/dist/tools/governance.js.map +1 -1
  185. package/dist/tools/hosted-agents.d.ts +216 -0
  186. package/dist/tools/hosted-agents.d.ts.map +1 -0
  187. package/dist/tools/hosted-agents.js +214 -0
  188. package/dist/tools/hosted-agents.js.map +1 -0
  189. package/dist/tools/index.d.ts +3933 -1219
  190. package/dist/tools/index.d.ts.map +1 -1
  191. package/dist/tools/index.js +412 -393
  192. package/dist/tools/index.js.map +1 -1
  193. package/dist/tools/jira.d.ts +0 -176
  194. package/dist/tools/jira.d.ts.map +1 -1
  195. package/dist/tools/jira.js +0 -365
  196. package/dist/tools/jira.js.map +1 -1
  197. package/dist/tools/llm-providers.d.ts +50 -0
  198. package/dist/tools/llm-providers.d.ts.map +1 -0
  199. package/dist/tools/llm-providers.js +41 -0
  200. package/dist/tools/llm-providers.js.map +1 -0
  201. package/dist/tools/mcp-metrics.d.ts +0 -15
  202. package/dist/tools/mcp-metrics.d.ts.map +1 -1
  203. package/dist/tools/mcp-metrics.js +0 -217
  204. package/dist/tools/mcp-metrics.js.map +1 -1
  205. package/dist/tools/mcp-tools.d.ts +0 -29
  206. package/dist/tools/mcp-tools.d.ts.map +1 -1
  207. package/dist/tools/mcp-tools.js +0 -131
  208. package/dist/tools/mcp-tools.js.map +1 -1
  209. package/dist/tools/mem0.d.ts +0 -41
  210. package/dist/tools/mem0.d.ts.map +1 -1
  211. package/dist/tools/mem0.js +65 -165
  212. package/dist/tools/mem0.js.map +1 -1
  213. package/dist/tools/memory-graph.d.ts +0 -46
  214. package/dist/tools/memory-graph.d.ts.map +1 -1
  215. package/dist/tools/memory-graph.js +0 -386
  216. package/dist/tools/memory-graph.js.map +1 -1
  217. package/dist/tools/memory-stores.d.ts +141 -0
  218. package/dist/tools/memory-stores.d.ts.map +1 -0
  219. package/dist/tools/memory-stores.js +147 -0
  220. package/dist/tools/memory-stores.js.map +1 -0
  221. package/dist/tools/messages.d.ts +0 -20
  222. package/dist/tools/messages.d.ts.map +1 -1
  223. package/dist/tools/messages.js +0 -49
  224. package/dist/tools/messages.js.map +1 -1
  225. package/dist/tools/moltbook.d.ts +0 -236
  226. package/dist/tools/moltbook.d.ts.map +1 -1
  227. package/dist/tools/moltbook.js +0 -458
  228. package/dist/tools/moltbook.js.map +1 -1
  229. package/dist/tools/monitoring-attribution.d.ts +71 -0
  230. package/dist/tools/monitoring-attribution.d.ts.map +1 -0
  231. package/dist/tools/monitoring-attribution.js +74 -0
  232. package/dist/tools/monitoring-attribution.js.map +1 -0
  233. package/dist/tools/ops.d.ts +0 -80
  234. package/dist/tools/ops.d.ts.map +1 -1
  235. package/dist/tools/ops.js +0 -209
  236. package/dist/tools/ops.js.map +1 -1
  237. package/dist/tools/orchestrations.d.ts +109 -0
  238. package/dist/tools/orchestrations.d.ts.map +1 -0
  239. package/dist/tools/orchestrations.js +115 -0
  240. package/dist/tools/orchestrations.js.map +1 -0
  241. package/dist/tools/outcomes.d.ts +138 -0
  242. package/dist/tools/outcomes.d.ts.map +1 -0
  243. package/dist/tools/outcomes.js +136 -0
  244. package/dist/tools/outcomes.js.map +1 -0
  245. package/dist/tools/schedules.d.ts +0 -47
  246. package/dist/tools/schedules.d.ts.map +1 -1
  247. package/dist/tools/schedules.js +0 -109
  248. package/dist/tools/schedules.js.map +1 -1
  249. package/dist/tools/services.d.ts +0 -16
  250. package/dist/tools/services.d.ts.map +1 -1
  251. package/dist/tools/services.js +0 -135
  252. package/dist/tools/services.js.map +1 -1
  253. package/dist/tools/sessions.d.ts +124 -0
  254. package/dist/tools/sessions.d.ts.map +1 -0
  255. package/dist/tools/sessions.js +130 -0
  256. package/dist/tools/sessions.js.map +1 -0
  257. package/dist/tools/setup-status.d.ts +29 -0
  258. package/dist/tools/setup-status.d.ts.map +1 -0
  259. package/dist/tools/setup-status.js +35 -0
  260. package/dist/tools/setup-status.js.map +1 -0
  261. package/dist/tools/tasks.d.ts +0 -57
  262. package/dist/tools/tasks.d.ts.map +1 -1
  263. package/dist/tools/tasks.js +8 -217
  264. package/dist/tools/tasks.js.map +1 -1
  265. package/dist/tools/tiers.d.ts +23 -7
  266. package/dist/tools/tiers.d.ts.map +1 -1
  267. package/dist/tools/tiers.js +180 -79
  268. package/dist/tools/tiers.js.map +1 -1
  269. package/dist/tools/unified-agents.d.ts +0 -19
  270. package/dist/tools/unified-agents.d.ts.map +1 -1
  271. package/dist/tools/unified-agents.js +2 -103
  272. package/dist/tools/unified-agents.js.map +1 -1
  273. package/dist/tools/web-eval.d.ts +0 -43
  274. package/dist/tools/web-eval.d.ts.map +1 -1
  275. package/dist/tools/web-eval.js +0 -211
  276. package/dist/tools/web-eval.js.map +1 -1
  277. package/dist/tools/workflow.d.ts +0 -66
  278. package/dist/tools/workflow.d.ts.map +1 -1
  279. package/dist/tools/workflow.js +2 -409
  280. package/dist/tools/workflow.js.map +1 -1
  281. package/dist/tools/workloads.d.ts +81 -0
  282. package/dist/tools/workloads.d.ts.map +1 -0
  283. package/dist/tools/workloads.js +81 -0
  284. package/dist/tools/workloads.js.map +1 -0
  285. package/package.json +7 -6
  286. package/dist/tools/knowledge-base.d.ts +0 -144
  287. package/dist/tools/knowledge-base.d.ts.map +0 -1
  288. package/dist/tools/knowledge-base.js +0 -179
  289. package/dist/tools/knowledge-base.js.map +0 -1
@@ -1,53 +1,216 @@
1
1
  /**
2
2
  * MCP Tools Index
3
3
  *
4
- * Exports all tool definitions and handlers.
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 './tasks.js';
8
- export * from './messages.js';
9
- export * from './approvals.js';
10
- export * from './services.js';
11
- export * from './crewai.js';
12
- export * from './crew-builder.js';
13
- export * from './mcp-tools.js';
14
- export * from './jira.js';
15
- export * from './ops.js';
16
- export * from './github-mcp.js';
17
- export * from './mem0.js';
18
- export * from './exa.js';
19
- export * from './mcp-metrics.js';
20
- export * from './workflow.js';
21
- export * from './web-eval.js';
22
- export * from './memory-graph.js';
23
- export * from './agent-mail.js';
24
- export * from './schedules.js';
25
- export * from './moltbook.js';
26
- export * from './unified-agents.js';
27
- export * from './governance.js';
28
- export * from './tiers.js';
29
- import { taskTools, handleCreateTask, handleListTasks, handleGetTask, handleUpdateTask, handleGetTaskTimeline, handleCancelTask } from './tasks.js';
30
- import { messageTools, handleGetMessages, handleSendMessage } from './messages.js';
31
- import { approvalTools, handleGetPendingApprovals, handleApproveTask, handleRejectTask, handleRequestChanges } from './approvals.js';
32
- import { serviceTools, handleListServices } from './services.js';
33
- import { crewaiTools, handleCrewAIHealth, handleCrewAIInputs, handleCrewAIKickoff, handleCrewAIStatus } from './crewai.js';
34
- import { crewBuilderTools, handleCrewValidate, handleCrewKickoff, handleCrewStatus, handleCrewList } from './crew-builder.js';
35
- import { mcpRemoteTools, handleMcpDiscoverTools, handleMcpCallTool } from './mcp-tools.js';
36
- import { jiraTools, handleJiraSearchIssues, handleJiraGetIssue, handleJiraCreateIssue, handleJiraUpdateIssue, handleJiraAddComment, handleJiraGetComments, handleJiraGetTransitions, handleJiraTransitionIssue, handleJiraListProjects, handleJiraAssignIssue } from './jira.js';
37
- import { opsTools, handleGetOpsHealthSummary, handleGetServiceStatus, handleGetActiveIssues, handleAcknowledgeOpsIssue, handleGetOpsAuditLog } from './ops.js';
38
- import { githubMcpTools, handleGithubSearchCode, handleGithubGetFile, handleGithubCreatePr, handleGithubListPrs, handleGithubListIssues, handleGithubCreateIssue, handleGithubGetWorkflowRuns } from './github-mcp.js';
39
- import { mem0Tools, handleMem0Store, handleMem0Search, handleMem0List, handleMem0Delete } from './mem0.js';
40
- import { exaTools, handleExaWebSearch, handleExaFindSimilar, handleExaGetContents } from './exa.js';
41
- import { mcpMetricsTools, handleMcpHealthCheck, handleMcpConnectionInfo } from './mcp-metrics.js';
42
- import { workflowTools, handleWorkflowClassifyTask, handleWorkflowAutoAssign, handleWorkflowAgentWorkload, handleWorkflowAssignmentRules } from './workflow.js';
43
- import { webEvalTools, handleWebEvalRunTests, handleWebEvalCheckHealth, handleWebEvalTestApiEndpoint, handleWebEvalCoverageReport } from './web-eval.js';
44
- import { memoryGraphTools, handleMemoryGraphStore, handleMemoryGraphQuery, handleMemoryGraphTimeline, handleMemoryGraphContext } from './memory-graph.js';
45
- import { agentMailTools, handleAgentMailSendNotification, handleAgentMailGetInbox, handleAgentMailGetIdentity } from './agent-mail.js';
46
- import { scheduleTools, handleCreateSchedule, handleListSchedules, handlePauseSchedule, handleDeleteSchedule } from './schedules.js';
47
- import { moltbookTools, handleMoltbookGetProfile, handleMoltbookUpdateProfile, handleMoltbookGetHomeFeed, handleMoltbookGetPosts, handleMoltbookGetPost, handleMoltbookCreatePost, handleMoltbookGetComments, handleMoltbookCreateComment, handleMoltbookUpvotePost, handleMoltbookDownvotePost, handleMoltbookSearch, handleMoltbookGetNotifications } from './moltbook.js';
48
- import { unifiedAgentTools, handleListAllAgents } from './unified-agents.js';
49
- import { governanceTools, handleExportPolicies, handleImportPolicies, handleValidatePolicies, handleApplyGuardrail } from './governance.js';
50
- import { filterToolsByTier } from './tiers.js';
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
+ }
51
214
  // ============================================
52
215
  // All Tools
53
216
  // ============================================
@@ -73,32 +236,114 @@ export const allTools = {
73
236
  ...moltbookTools,
74
237
  ...unifiedAgentTools,
75
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,
76
252
  };
77
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
+ // ============================================
78
266
  // Tool Definitions with Tier Filtering
79
267
  // ============================================
80
268
  /**
81
269
  * Get tool definitions for ListTools response.
82
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).
83
273
  *
84
- * Usage in MCP server:
85
- * server.setRequestHandler(ListToolsRequestSchema, async () => ({
86
- * tools: getToolDefinitions(resolveToolTier(authContext)),
274
+ * Usage in MCP server (HTTP mode):
275
+ * server.setRequestHandler(ListToolsRequestSchema, async (_req, extra) => ({
276
+ * tools: getToolDefinitions(resolveToolTier({ scopes }), {
277
+ * readOnly: isReadOnlyScopes(scopes),
278
+ * }),
87
279
  * }));
88
280
  */
89
- export function getToolDefinitions(tier = 'enterprise') {
90
- const allToolNames = Object.keys(allTools);
91
- const allowedNames = filterToolsByTier(allToolNames, tier);
92
- const allowedSet = new Set(allowedNames);
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));
93
295
  return Object.values(allTools)
94
- .filter(tool => allowedSet.has(tool.name))
95
- .map(tool => ({
296
+ .filter((tool) => visibleIds.has(tool.name))
297
+ .map((tool) => ({
96
298
  name: tool.name,
97
299
  description: tool.description,
98
300
  inputSchema: tool.inputSchema,
99
301
  annotations: tool.annotations || {},
100
302
  }));
101
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
+ }
102
347
  /**
103
348
  * Check gateway auth for an MCP tool call.
104
349
  * Returns auth result from gateway. If no gatewayKey is configured, returns allowed.
@@ -110,11 +355,11 @@ async function checkGatewayAuth(toolName, mcpServer, context) {
110
355
  }
111
356
  try {
112
357
  const response = await fetch(`${context.gatewayUrl}/api/v1/gateway/mcp/tools`, {
113
- method: 'POST',
358
+ method: "POST",
114
359
  headers: {
115
- 'Content-Type': 'application/json',
116
- 'Authorization': `Bearer ${context.gatewayKey}`,
117
- ...(context.tenantId ? { 'X-Tenant-Id': context.tenantId } : {}),
360
+ "Content-Type": "application/json",
361
+ Authorization: `Bearer ${context.gatewayKey}`,
362
+ ...(context.tenantId ? { "X-Tenant-Id": context.tenantId } : {}),
118
363
  },
119
364
  body: JSON.stringify({
120
365
  tool_name: toolName,
@@ -123,17 +368,19 @@ async function checkGatewayAuth(toolName, mcpServer, context) {
123
368
  }),
124
369
  });
125
370
  if (!response.ok) {
126
- const errBody = await response.json().catch(() => ({ error: 'Gateway auth failed' }));
371
+ const errBody = (await response
372
+ .json()
373
+ .catch(() => ({ error: "Gateway auth failed" })));
127
374
  return {
128
375
  allowed: false,
129
376
  error: errBody.error || `Gateway returned ${response.status}`,
130
377
  };
131
378
  }
132
- return await response.json();
379
+ return (await response.json());
133
380
  }
134
381
  catch (error) {
135
- const errMsg = error instanceof Error ? error.message : 'Unknown error';
136
- console.error('[MCP Gateway] Auth check failed:', errMsg);
382
+ const errMsg = error instanceof Error ? error.message : "Unknown error";
383
+ console.error("[MCP Gateway] Auth check failed:", errMsg);
137
384
  // Fail open with warning if gateway is unreachable
138
385
  return { allowed: true };
139
386
  }
@@ -142,34 +389,34 @@ async function checkGatewayAuth(toolName, mcpServer, context) {
142
389
  * Log tool call result to gateway.
143
390
  * Non-blocking — errors are logged but don't affect tool result.
144
391
  */
145
- async function logToolCallToGateway(toolCall, authResult, context, eventType = 'mcp.tool.call') {
392
+ async function logToolCallToGateway(toolCall, authResult, context, eventType = "mcp.tool.call") {
146
393
  if (!context.gatewayKey || !context.gatewayUrl)
147
394
  return;
148
395
  try {
149
396
  await fetch(`${context.gatewayUrl}/api/v1/gateway/mcp/tools`, {
150
- method: 'POST',
397
+ method: "POST",
151
398
  headers: {
152
- 'Content-Type': 'application/json',
153
- 'Authorization': `Bearer ${context.gatewayKey}`,
154
- ...(context.tenantId ? { 'X-Tenant-Id': context.tenantId } : {}),
399
+ "Content-Type": "application/json",
400
+ Authorization: `Bearer ${context.gatewayKey}`,
401
+ ...(context.tenantId ? { "X-Tenant-Id": context.tenantId } : {}),
155
402
  },
156
403
  body: JSON.stringify({
157
- action: 'log',
404
+ action: "log",
158
405
  tool_call: toolCall,
159
406
  event_type: eventType,
160
- actor_type: authResult.actor?.actor_type || 'human',
407
+ actor_type: authResult.actor?.actor_type || "human",
161
408
  actor_id: authResult.actor?.actor_id || context.userId,
162
409
  on_behalf_of: authResult.actor?.on_behalf_of || undefined,
163
- org_id: authResult.org_id || '',
410
+ org_id: authResult.org_id || "",
164
411
  region: context.region,
165
412
  }),
166
413
  });
167
414
  }
168
415
  catch (error) {
169
- console.error('[MCP Gateway] Log failed:', error.message);
416
+ console.error("[MCP Gateway] Log failed:", error.message);
170
417
  }
171
418
  }
172
- const MCP_SERVER_NAME = 'mcp-dobby-external';
419
+ const MCP_SERVER_NAME = "mcp-dobby-external";
173
420
  export async function handleToolCall(toolName, args, context) {
174
421
  const { client, userId, userName } = context;
175
422
  const startTime = new Date();
@@ -178,349 +425,121 @@ export async function handleToolCall(toolName, args, context) {
178
425
  if (!authResult.allowed) {
179
426
  // Log denial to gateway (non-blocking)
180
427
  logToolCallToGateway({
181
- tenant_id: context.tenantId || '',
182
- agent_id: 'mcp-external',
183
- task_id: args.task_id || '',
428
+ tenant_id: context.tenantId || "",
429
+ agent_id: "mcp-external",
430
+ task_id: args.task_id || "",
184
431
  mcp_server: MCP_SERVER_NAME,
185
432
  tool_name: toolName,
186
433
  tool_input: args,
187
- status: 'error',
188
- error_message: authResult.error || 'Gateway auth denied',
434
+ status: "error",
435
+ error_message: authResult.error || "Gateway auth denied",
189
436
  started_at: startTime.toISOString(),
190
437
  completed_at: new Date().toISOString(),
191
- }, authResult, context, 'mcp.tool.denied');
438
+ }, authResult, context, "mcp.tool.denied");
192
439
  return {
193
440
  content: [
194
441
  {
195
- type: 'text',
196
- text: `Tool call denied: ${authResult.error || 'Insufficient permissions'}`,
442
+ type: "text",
443
+ text: `Tool call denied: ${authResult.error || "Insufficient permissions"}`,
197
444
  },
198
445
  ],
199
446
  isError: true,
200
447
  };
201
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 || "",
458
+ mcp_server: MCP_SERVER_NAME,
459
+ tool_name: toolName,
460
+ tool_input: args,
461
+ status: "error",
462
+ error_message: firewallResult.reason || "Blocked by firewall policy",
463
+ started_at: startTime.toISOString(),
464
+ completed_at: new Date().toISOString(),
465
+ }, authResult, context, "mcp.tool.denied");
466
+ return {
467
+ content: [
468
+ {
469
+ type: "text",
470
+ text: `Tool blocked by Agentic Firewall: ${firewallResult.reason || "Policy violation"}`,
471
+ },
472
+ ],
473
+ isError: true,
474
+ };
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
+ }
202
498
  // 2. Execute tool
203
499
  let result;
204
500
  let toolError;
205
- let toolStatus = 'success';
501
+ let toolStatus = "success";
206
502
  try {
207
- switch (toolName) {
208
- // Task tools
209
- case 'create_task':
210
- result = await handleCreateTask(client, args);
211
- break;
212
- case 'list_tasks':
213
- result = await handleListTasks(client, args);
214
- break;
215
- case 'get_task':
216
- result = await handleGetTask(client, args);
217
- break;
218
- case 'update_task':
219
- result = await handleUpdateTask(client, args);
220
- break;
221
- case 'get_task_timeline':
222
- result = await handleGetTaskTimeline(client, args);
223
- break;
224
- case 'cancel_task':
225
- result = await handleCancelTask(client, args);
226
- break;
227
- // Message tools
228
- case 'get_messages':
229
- result = await handleGetMessages(client, args, userId);
230
- break;
231
- case 'send_message':
232
- result = await handleSendMessage(client, args, userId, userName);
233
- break;
234
- // Approval tools
235
- case 'get_pending_approvals':
236
- result = await handleGetPendingApprovals(client);
237
- break;
238
- case 'approve_task':
239
- result = await handleApproveTask(client, args);
240
- break;
241
- case 'reject_task':
242
- result = await handleRejectTask(client, args);
243
- break;
244
- case 'request_changes':
245
- result = await handleRequestChanges(client, args);
246
- break;
247
- // Service discovery tools
248
- case 'list_services':
249
- result = await handleListServices(client, args);
250
- break;
251
- // CrewAI tools (hosted platform)
252
- case 'crewai_health':
253
- result = await handleCrewAIHealth(client, args);
254
- break;
255
- case 'crewai_inputs':
256
- result = await handleCrewAIInputs(client, args);
257
- break;
258
- case 'crewai_kickoff':
259
- result = await handleCrewAIKickoff(client, args);
260
- break;
261
- case 'crewai_status':
262
- result = await handleCrewAIStatus(client, args);
263
- break;
264
- // Crew Builder tools (local YAML-based crews)
265
- case 'crew_validate':
266
- result = await handleCrewValidate(client, args);
267
- break;
268
- case 'crew_kickoff':
269
- result = await handleCrewKickoff(client, args);
270
- break;
271
- case 'crew_status':
272
- result = await handleCrewStatus(client, args);
273
- break;
274
- case 'crew_list':
275
- result = await handleCrewList(client, args);
276
- break;
277
- // MCP remote tools (discover and call tools on external MCP servers)
278
- case 'mcp_discover_tools':
279
- result = await handleMcpDiscoverTools(client, args);
280
- break;
281
- case 'mcp_call_tool':
282
- result = await handleMcpCallTool(client, args);
283
- break;
284
- // Ops Layer tools (internal platform monitoring)
285
- case 'get_ops_health_summary':
286
- result = await handleGetOpsHealthSummary(client);
287
- break;
288
- case 'get_service_status':
289
- result = await handleGetServiceStatus(client, args);
290
- break;
291
- case 'get_active_issues':
292
- result = await handleGetActiveIssues(client, args);
293
- break;
294
- case 'acknowledge_ops_issue':
295
- result = await handleAcknowledgeOpsIssue(client, args);
296
- break;
297
- case 'get_ops_audit_log':
298
- result = await handleGetOpsAuditLog(client, args);
299
- break;
300
- // GitHub MCP tools (Phase 1, Task 1.1)
301
- case 'github_search_code':
302
- result = await handleGithubSearchCode(client, args);
303
- break;
304
- case 'github_get_file':
305
- result = await handleGithubGetFile(client, args);
306
- break;
307
- case 'github_create_pr':
308
- result = await handleGithubCreatePr(client, args);
309
- break;
310
- case 'github_list_prs':
311
- result = await handleGithubListPrs(client, args);
312
- break;
313
- case 'github_list_issues':
314
- result = await handleGithubListIssues(client, args);
315
- break;
316
- case 'github_create_issue':
317
- result = await handleGithubCreateIssue(client, args);
318
- break;
319
- case 'github_get_workflow_runs':
320
- result = await handleGithubGetWorkflowRuns(client, args);
321
- break;
322
- // Mem0 Memory tools (Phase 1, Task 1.2)
323
- case 'mem0_store':
324
- result = await handleMem0Store(client, args);
325
- break;
326
- case 'mem0_search':
327
- result = await handleMem0Search(client, args);
328
- break;
329
- case 'mem0_list':
330
- result = await handleMem0List(client, args);
331
- break;
332
- case 'mem0_delete':
333
- result = await handleMem0Delete(client, args);
334
- break;
335
- // Exa Semantic Search tools (Phase 1, Task 1.3)
336
- case 'exa_web_search':
337
- result = await handleExaWebSearch(client, args);
338
- break;
339
- case 'exa_find_similar':
340
- result = await handleExaFindSimilar(client, args);
341
- break;
342
- case 'exa_get_contents':
343
- result = await handleExaGetContents(client, args);
344
- break;
345
- // MCP Metrics & Health tools (Phase 1, Task 1.5)
346
- case 'mcp_health_check':
347
- result = await handleMcpHealthCheck(client, args);
348
- break;
349
- case 'mcp_connection_info':
350
- result = await handleMcpConnectionInfo(client, args);
351
- break;
352
- // Workflow Automation tools (Phase 2)
353
- case 'workflow_classify_task':
354
- result = await handleWorkflowClassifyTask(client, args);
355
- break;
356
- case 'workflow_auto_assign':
357
- result = await handleWorkflowAutoAssign(client, args);
358
- break;
359
- case 'workflow_agent_workload':
360
- result = await handleWorkflowAgentWorkload(client, args);
361
- break;
362
- case 'workflow_assignment_rules':
363
- result = await handleWorkflowAssignmentRules(client, args);
364
- break;
365
- // Web Eval Agent tools (Phase 3)
366
- case 'webeval_run_tests':
367
- result = await handleWebEvalRunTests(client, args);
368
- break;
369
- case 'webeval_check_health':
370
- result = await handleWebEvalCheckHealth(client, args);
371
- break;
372
- case 'webeval_test_api_endpoint':
373
- result = await handleWebEvalTestApiEndpoint(client, args);
374
- break;
375
- case 'webeval_coverage_report':
376
- result = await handleWebEvalCoverageReport(client, args);
377
- break;
378
- // Memory Graph tools (Phase 4)
379
- case 'memory_graph_store':
380
- result = await handleMemoryGraphStore(client, args);
381
- break;
382
- case 'memory_graph_query':
383
- result = await handleMemoryGraphQuery(client, args);
384
- break;
385
- case 'memory_graph_timeline':
386
- result = await handleMemoryGraphTimeline(client, args);
387
- break;
388
- case 'memory_graph_context':
389
- result = await handleMemoryGraphContext(client, args);
390
- break;
391
- // AgentMail tools (Phase 5)
392
- case 'agentmail_send_notification':
393
- result = await handleAgentMailSendNotification(client, args);
394
- break;
395
- case 'agentmail_get_inbox':
396
- result = await handleAgentMailGetInbox(client, args);
397
- break;
398
- case 'agentmail_get_identity':
399
- result = await handleAgentMailGetIdentity(client, args);
400
- break;
401
- // Schedule tools
402
- case 'create_schedule':
403
- result = await handleCreateSchedule(client, args);
404
- break;
405
- case 'list_schedules':
406
- result = await handleListSchedules(client, args);
407
- break;
408
- case 'pause_schedule':
409
- result = await handlePauseSchedule(client, args);
410
- break;
411
- case 'delete_schedule':
412
- result = await handleDeleteSchedule(client, args);
413
- break;
414
- // Jira Cloud tools
415
- case 'jira_search_issues':
416
- result = await handleJiraSearchIssues(client, args);
417
- break;
418
- case 'jira_get_issue':
419
- result = await handleJiraGetIssue(client, args);
420
- break;
421
- case 'jira_create_issue':
422
- result = await handleJiraCreateIssue(client, args);
423
- break;
424
- case 'jira_update_issue':
425
- result = await handleJiraUpdateIssue(client, args);
426
- break;
427
- case 'jira_add_comment':
428
- result = await handleJiraAddComment(client, args);
429
- break;
430
- case 'jira_get_comments':
431
- result = await handleJiraGetComments(client, args);
432
- break;
433
- case 'jira_get_transitions':
434
- result = await handleJiraGetTransitions(client, args);
435
- break;
436
- case 'jira_transition_issue':
437
- result = await handleJiraTransitionIssue(client, args);
438
- break;
439
- case 'jira_list_projects':
440
- result = await handleJiraListProjects(client, args);
441
- break;
442
- case 'jira_assign_issue':
443
- result = await handleJiraAssignIssue(client, args);
444
- break;
445
- // Moltbook tools (social network for AI agents)
446
- case 'moltbook_get_profile':
447
- result = await handleMoltbookGetProfile(client, args);
448
- break;
449
- case 'moltbook_update_profile':
450
- result = await handleMoltbookUpdateProfile(client, args);
451
- break;
452
- case 'moltbook_get_home_feed':
453
- result = await handleMoltbookGetHomeFeed(client, args);
454
- break;
455
- case 'moltbook_get_posts':
456
- result = await handleMoltbookGetPosts(client, args);
457
- break;
458
- case 'moltbook_get_post':
459
- result = await handleMoltbookGetPost(client, args);
460
- break;
461
- case 'moltbook_create_post':
462
- result = await handleMoltbookCreatePost(client, args);
463
- break;
464
- case 'moltbook_get_comments':
465
- result = await handleMoltbookGetComments(client, args);
466
- break;
467
- case 'moltbook_create_comment':
468
- result = await handleMoltbookCreateComment(client, args);
469
- break;
470
- case 'moltbook_upvote_post':
471
- result = await handleMoltbookUpvotePost(client, args);
472
- break;
473
- case 'moltbook_downvote_post':
474
- result = await handleMoltbookDownvotePost(client, args);
475
- break;
476
- case 'moltbook_search':
477
- result = await handleMoltbookSearch(client, args);
478
- break;
479
- case 'moltbook_get_notifications':
480
- result = await handleMoltbookGetNotifications(client, args);
481
- break;
482
- // Unified Agent Identity
483
- case 'list_all_agents':
484
- result = await handleListAllAgents(client, args);
485
- break;
486
- // Governance tools (Policy-as-Code)
487
- case 'export_policies':
488
- result = { content: [{ type: 'text', text: await handleExportPolicies(args, client) }] };
489
- break;
490
- case 'import_policies':
491
- result = { content: [{ type: 'text', text: await handleImportPolicies(args, client) }] };
492
- break;
493
- case 'validate_policies':
494
- result = { content: [{ type: 'text', text: await handleValidatePolicies(args, client) }] };
495
- break;
496
- case 'apply_guardrail':
497
- result = { content: [{ type: 'text', text: await handleApplyGuardrail(args, client) }] };
498
- break;
499
- default:
500
- result = {
501
- content: [
502
- {
503
- type: 'text',
504
- text: `Unknown tool: ${toolName}`,
505
- },
506
- ],
507
- isError: true,
508
- };
509
- toolStatus = 'error';
510
- 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);
511
530
  }
512
531
  if (result?.isError) {
513
- toolStatus = 'error';
514
- toolError = result.content?.[0]?.text || 'Tool returned error';
532
+ toolStatus = "error";
533
+ toolError = result.content?.[0]?.text || "Tool returned error";
515
534
  }
516
535
  }
517
536
  catch (error) {
518
- toolStatus = 'error';
537
+ toolStatus = "error";
519
538
  toolError = error.message;
520
539
  result = {
521
540
  content: [
522
541
  {
523
- type: 'text',
542
+ type: "text",
524
543
  text: `Tool error: ${error.message}`,
525
544
  },
526
545
  ],
@@ -530,9 +549,9 @@ export async function handleToolCall(toolName, args, context) {
530
549
  const endTime = new Date();
531
550
  // 3. Log result to gateway (non-blocking)
532
551
  logToolCallToGateway({
533
- tenant_id: context.tenantId || '',
534
- agent_id: 'mcp-external',
535
- task_id: args.task_id || '',
552
+ tenant_id: context.tenantId || "",
553
+ agent_id: "mcp-external",
554
+ task_id: args.task_id || "",
536
555
  mcp_server: MCP_SERVER_NAME,
537
556
  tool_name: toolName,
538
557
  tool_input: args,
@@ -542,7 +561,7 @@ export async function handleToolCall(toolName, args, context) {
542
561
  duration_ms: endTime.getTime() - startTime.getTime(),
543
562
  started_at: startTime.toISOString(),
544
563
  completed_at: endTime.toISOString(),
545
- }, authResult, context, 'mcp.tool.call');
564
+ }, authResult, context, "mcp.tool.call");
546
565
  return result;
547
566
  }
548
567
  //# sourceMappingURL=index.js.map