@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.
Files changed (315) hide show
  1. package/README.md +44 -14
  2. package/dist/__tests__/agent-mail-tools.test.d.ts +8 -0
  3. package/dist/__tests__/agent-mail-tools.test.d.ts.map +1 -0
  4. package/dist/__tests__/agent-mail-tools.test.js +255 -0
  5. package/dist/__tests__/agent-mail-tools.test.js.map +1 -0
  6. package/dist/__tests__/annotations.test.d.ts +8 -0
  7. package/dist/__tests__/annotations.test.d.ts.map +1 -0
  8. package/dist/__tests__/annotations.test.js +108 -0
  9. package/dist/__tests__/annotations.test.js.map +1 -0
  10. package/dist/__tests__/auth.test.d.ts +7 -0
  11. package/dist/__tests__/auth.test.d.ts.map +1 -0
  12. package/dist/__tests__/auth.test.js +161 -0
  13. package/dist/__tests__/auth.test.js.map +1 -0
  14. package/dist/__tests__/doctor.test.d.ts +16 -0
  15. package/dist/__tests__/doctor.test.d.ts.map +1 -0
  16. package/dist/__tests__/doctor.test.js +258 -0
  17. package/dist/__tests__/doctor.test.js.map +1 -0
  18. package/dist/__tests__/external-agents-tools.test.d.ts +11 -0
  19. package/dist/__tests__/external-agents-tools.test.d.ts.map +1 -0
  20. package/dist/__tests__/external-agents-tools.test.js +619 -0
  21. package/dist/__tests__/external-agents-tools.test.js.map +1 -0
  22. package/dist/__tests__/gateway-bearer.test.d.ts +12 -0
  23. package/dist/__tests__/gateway-bearer.test.d.ts.map +1 -0
  24. package/dist/__tests__/gateway-bearer.test.js +112 -0
  25. package/dist/__tests__/gateway-bearer.test.js.map +1 -0
  26. package/dist/__tests__/gateway-key-resolver.test.d.ts +10 -0
  27. package/dist/__tests__/gateway-key-resolver.test.d.ts.map +1 -0
  28. package/dist/__tests__/gateway-key-resolver.test.js +125 -0
  29. package/dist/__tests__/gateway-key-resolver.test.js.map +1 -0
  30. package/dist/__tests__/http-concurrency.test.d.ts +20 -0
  31. package/dist/__tests__/http-concurrency.test.d.ts.map +1 -0
  32. package/dist/__tests__/http-concurrency.test.js +254 -0
  33. package/dist/__tests__/http-concurrency.test.js.map +1 -0
  34. package/dist/__tests__/integration/protocol.test.d.ts +8 -0
  35. package/dist/__tests__/integration/protocol.test.d.ts.map +1 -0
  36. package/dist/__tests__/integration/protocol.test.js +110 -0
  37. package/dist/__tests__/integration/protocol.test.js.map +1 -0
  38. package/dist/__tests__/mcp-integrations.test.d.ts +8 -0
  39. package/dist/__tests__/mcp-integrations.test.d.ts.map +1 -0
  40. package/dist/__tests__/mcp-integrations.test.js +365 -0
  41. package/dist/__tests__/mcp-integrations.test.js.map +1 -0
  42. package/dist/__tests__/memory-graph-tools.test.d.ts +8 -0
  43. package/dist/__tests__/memory-graph-tools.test.d.ts.map +1 -0
  44. package/dist/__tests__/memory-graph-tools.test.js +254 -0
  45. package/dist/__tests__/memory-graph-tools.test.js.map +1 -0
  46. package/dist/__tests__/registry-dispatch.test.d.ts +11 -0
  47. package/dist/__tests__/registry-dispatch.test.d.ts.map +1 -0
  48. package/dist/__tests__/registry-dispatch.test.js +30 -0
  49. package/dist/__tests__/registry-dispatch.test.js.map +1 -0
  50. package/dist/__tests__/registry-listing-parity.test.d.ts +2 -0
  51. package/dist/__tests__/registry-listing-parity.test.d.ts.map +1 -0
  52. package/dist/__tests__/registry-listing-parity.test.js +89 -0
  53. package/dist/__tests__/registry-listing-parity.test.js.map +1 -0
  54. package/dist/__tests__/role-cap.test.d.ts +2 -0
  55. package/dist/__tests__/role-cap.test.d.ts.map +1 -0
  56. package/dist/__tests__/role-cap.test.js +113 -0
  57. package/dist/__tests__/role-cap.test.js.map +1 -0
  58. package/dist/__tests__/schedule-tools.test.d.ts +8 -0
  59. package/dist/__tests__/schedule-tools.test.d.ts.map +1 -0
  60. package/dist/__tests__/schedule-tools.test.js +285 -0
  61. package/dist/__tests__/schedule-tools.test.js.map +1 -0
  62. package/dist/__tests__/server-gateway-key.test.d.ts +18 -0
  63. package/dist/__tests__/server-gateway-key.test.d.ts.map +1 -0
  64. package/dist/__tests__/server-gateway-key.test.js +148 -0
  65. package/dist/__tests__/server-gateway-key.test.js.map +1 -0
  66. package/dist/__tests__/server-user-scoped.test.d.ts +34 -0
  67. package/dist/__tests__/server-user-scoped.test.d.ts.map +1 -0
  68. package/dist/__tests__/server-user-scoped.test.js +577 -0
  69. package/dist/__tests__/server-user-scoped.test.js.map +1 -0
  70. package/dist/__tests__/task-id-pattern.test.d.ts +12 -0
  71. package/dist/__tests__/task-id-pattern.test.d.ts.map +1 -0
  72. package/dist/__tests__/task-id-pattern.test.js +43 -0
  73. package/dist/__tests__/task-id-pattern.test.js.map +1 -0
  74. package/dist/__tests__/tiers.test.d.ts +7 -0
  75. package/dist/__tests__/tiers.test.d.ts.map +1 -0
  76. package/dist/__tests__/tiers.test.js +199 -0
  77. package/dist/__tests__/tiers.test.js.map +1 -0
  78. package/dist/__tests__/tools/hosted-agents.test.d.ts +9 -0
  79. package/dist/__tests__/tools/hosted-agents.test.d.ts.map +1 -0
  80. package/dist/__tests__/tools/hosted-agents.test.js +301 -0
  81. package/dist/__tests__/tools/hosted-agents.test.js.map +1 -0
  82. package/dist/__tests__/tools/llm-providers.test.d.ts +10 -0
  83. package/dist/__tests__/tools/llm-providers.test.d.ts.map +1 -0
  84. package/dist/__tests__/tools/llm-providers.test.js +105 -0
  85. package/dist/__tests__/tools/llm-providers.test.js.map +1 -0
  86. package/dist/__tests__/tools/services.test.js +139 -98
  87. package/dist/__tests__/tools/services.test.js.map +1 -1
  88. package/dist/__tests__/tools.test.d.ts +7 -0
  89. package/dist/__tests__/tools.test.d.ts.map +1 -0
  90. package/dist/__tests__/tools.test.js +152 -0
  91. package/dist/__tests__/tools.test.js.map +1 -0
  92. package/dist/__tests__/transport.test.d.ts +7 -0
  93. package/dist/__tests__/transport.test.d.ts.map +1 -0
  94. package/dist/__tests__/transport.test.js +397 -0
  95. package/dist/__tests__/transport.test.js.map +1 -0
  96. package/dist/__tests__/validate-credentials.test.d.ts +9 -0
  97. package/dist/__tests__/validate-credentials.test.d.ts.map +1 -0
  98. package/dist/__tests__/validate-credentials.test.js +172 -0
  99. package/dist/__tests__/validate-credentials.test.js.map +1 -0
  100. package/dist/__tests__/web-eval-tools.test.d.ts +8 -0
  101. package/dist/__tests__/web-eval-tools.test.d.ts.map +1 -0
  102. package/dist/__tests__/web-eval-tools.test.js +241 -0
  103. package/dist/__tests__/web-eval-tools.test.js.map +1 -0
  104. package/dist/__tests__/whoami.test.d.ts +11 -0
  105. package/dist/__tests__/whoami.test.d.ts.map +1 -0
  106. package/dist/__tests__/whoami.test.js +194 -0
  107. package/dist/__tests__/whoami.test.js.map +1 -0
  108. package/dist/__tests__/workflow-tools.test.d.ts +8 -0
  109. package/dist/__tests__/workflow-tools.test.d.ts.map +1 -0
  110. package/dist/__tests__/workflow-tools.test.js +261 -0
  111. package/dist/__tests__/workflow-tools.test.js.map +1 -0
  112. package/dist/__tests__/workloads.test.d.ts +9 -0
  113. package/dist/__tests__/workloads.test.d.ts.map +1 -0
  114. package/dist/__tests__/workloads.test.js +169 -0
  115. package/dist/__tests__/workloads.test.js.map +1 -0
  116. package/dist/auth/oauth-provider.d.ts +34 -0
  117. package/dist/auth/oauth-provider.d.ts.map +1 -0
  118. package/dist/auth/oauth-provider.js +75 -0
  119. package/dist/auth/oauth-provider.js.map +1 -0
  120. package/dist/auth/token-verifier.d.ts +45 -0
  121. package/dist/auth/token-verifier.d.ts.map +1 -0
  122. package/dist/auth/token-verifier.js +160 -0
  123. package/dist/auth/token-verifier.js.map +1 -0
  124. package/dist/connectors/claude-desktop.d.ts.map +1 -1
  125. package/dist/connectors/claude-desktop.js +3 -2
  126. package/dist/connectors/claude-desktop.js.map +1 -1
  127. package/dist/connectors/cursor.d.ts.map +1 -1
  128. package/dist/connectors/cursor.js +3 -2
  129. package/dist/connectors/cursor.js.map +1 -1
  130. package/dist/connectors/setup.d.ts.map +1 -1
  131. package/dist/connectors/setup.js +2 -1
  132. package/dist/connectors/setup.js.map +1 -1
  133. package/dist/connectors/vscode.d.ts.map +1 -1
  134. package/dist/connectors/vscode.js +3 -2
  135. package/dist/connectors/vscode.js.map +1 -1
  136. package/dist/connectors/windsurf.d.ts.map +1 -1
  137. package/dist/connectors/windsurf.js +3 -2
  138. package/dist/connectors/windsurf.js.map +1 -1
  139. package/dist/doctor.d.ts +34 -0
  140. package/dist/doctor.d.ts.map +1 -0
  141. package/dist/doctor.js +134 -0
  142. package/dist/doctor.js.map +1 -0
  143. package/dist/http-server.d.ts +56 -0
  144. package/dist/http-server.d.ts.map +1 -0
  145. package/dist/http-server.js +455 -0
  146. package/dist/http-server.js.map +1 -0
  147. package/dist/index.d.ts +5 -1
  148. package/dist/index.d.ts.map +1 -1
  149. package/dist/index.js +96 -171
  150. package/dist/index.js.map +1 -1
  151. package/dist/lib/consts.d.ts +21 -0
  152. package/dist/lib/consts.d.ts.map +1 -0
  153. package/dist/lib/consts.js +30 -0
  154. package/dist/lib/consts.js.map +1 -0
  155. package/dist/lib/dobby-client.d.ts +60 -3
  156. package/dist/lib/dobby-client.d.ts.map +1 -1
  157. package/dist/lib/dobby-client.js +145 -44
  158. package/dist/lib/dobby-client.js.map +1 -1
  159. package/dist/lib/gateway-key-resolver.d.ts +38 -0
  160. package/dist/lib/gateway-key-resolver.d.ts.map +1 -0
  161. package/dist/lib/gateway-key-resolver.js +59 -0
  162. package/dist/lib/gateway-key-resolver.js.map +1 -0
  163. package/dist/lib/log.d.ts +25 -0
  164. package/dist/lib/log.d.ts.map +1 -0
  165. package/dist/lib/log.js +36 -0
  166. package/dist/lib/log.js.map +1 -0
  167. package/dist/server.d.ts +175 -0
  168. package/dist/server.d.ts.map +1 -0
  169. package/dist/server.js +1017 -0
  170. package/dist/server.js.map +1 -0
  171. package/dist/tools/agent-mail.d.ts +112 -0
  172. package/dist/tools/agent-mail.d.ts.map +1 -0
  173. package/dist/tools/agent-mail.js +118 -0
  174. package/dist/tools/agent-mail.js.map +1 -0
  175. package/dist/tools/agent-versions.d.ts +93 -0
  176. package/dist/tools/agent-versions.d.ts.map +1 -0
  177. package/dist/tools/agent-versions.js +99 -0
  178. package/dist/tools/agent-versions.js.map +1 -0
  179. package/dist/tools/approvals.d.ts +24 -34
  180. package/dist/tools/approvals.d.ts.map +1 -1
  181. package/dist/tools/approvals.js +24 -81
  182. package/dist/tools/approvals.js.map +1 -1
  183. package/dist/tools/claude-code-sync.d.ts +40 -0
  184. package/dist/tools/claude-code-sync.d.ts.map +1 -0
  185. package/dist/tools/claude-code-sync.js +52 -0
  186. package/dist/tools/claude-code-sync.js.map +1 -0
  187. package/dist/tools/control-plane.d.ts +118 -0
  188. package/dist/tools/control-plane.d.ts.map +1 -0
  189. package/dist/tools/control-plane.js +135 -0
  190. package/dist/tools/control-plane.js.map +1 -0
  191. package/dist/tools/crew-builder.d.ts +24 -66
  192. package/dist/tools/crew-builder.d.ts.map +1 -1
  193. package/dist/tools/crew-builder.js +24 -185
  194. package/dist/tools/crew-builder.js.map +1 -1
  195. package/dist/tools/crewai.d.ts +24 -63
  196. package/dist/tools/crewai.d.ts.map +1 -1
  197. package/dist/tools/crewai.js +24 -145
  198. package/dist/tools/crewai.js.map +1 -1
  199. package/dist/tools/exa.d.ts +126 -0
  200. package/dist/tools/exa.d.ts.map +1 -0
  201. package/dist/tools/exa.js +125 -0
  202. package/dist/tools/exa.js.map +1 -0
  203. package/dist/tools/external-agents.d.ts +440 -0
  204. package/dist/tools/external-agents.d.ts.map +1 -0
  205. package/dist/tools/external-agents.js +386 -0
  206. package/dist/tools/external-agents.js.map +1 -0
  207. package/dist/tools/github-mcp.d.ts +228 -0
  208. package/dist/tools/github-mcp.d.ts.map +1 -0
  209. package/dist/tools/github-mcp.js +235 -0
  210. package/dist/tools/github-mcp.js.map +1 -0
  211. package/dist/tools/governance.d.ts +273 -0
  212. package/dist/tools/governance.d.ts.map +1 -0
  213. package/dist/tools/governance.js +286 -0
  214. package/dist/tools/governance.js.map +1 -0
  215. package/dist/tools/hosted-agents.d.ts +216 -0
  216. package/dist/tools/hosted-agents.d.ts.map +1 -0
  217. package/dist/tools/hosted-agents.js +214 -0
  218. package/dist/tools/hosted-agents.js.map +1 -0
  219. package/dist/tools/index.d.ts +6335 -191
  220. package/dist/tools/index.d.ts.map +1 -1
  221. package/dist/tools/index.js +441 -172
  222. package/dist/tools/index.js.map +1 -1
  223. package/dist/tools/jira.d.ts +60 -176
  224. package/dist/tools/jira.d.ts.map +1 -1
  225. package/dist/tools/jira.js +60 -365
  226. package/dist/tools/jira.js.map +1 -1
  227. package/dist/tools/llm-providers.d.ts +50 -0
  228. package/dist/tools/llm-providers.d.ts.map +1 -0
  229. package/dist/tools/llm-providers.js +41 -0
  230. package/dist/tools/llm-providers.js.map +1 -0
  231. package/dist/tools/mcp-metrics.d.ts +47 -0
  232. package/dist/tools/mcp-metrics.d.ts.map +1 -0
  233. package/dist/tools/mcp-metrics.js +53 -0
  234. package/dist/tools/mcp-metrics.js.map +1 -0
  235. package/dist/tools/mcp-tools.d.ts +12 -29
  236. package/dist/tools/mcp-tools.d.ts.map +1 -1
  237. package/dist/tools/mcp-tools.js +12 -131
  238. package/dist/tools/mcp-tools.js.map +1 -1
  239. package/dist/tools/mem0.d.ts +127 -0
  240. package/dist/tools/mem0.d.ts.map +1 -0
  241. package/dist/tools/mem0.js +155 -0
  242. package/dist/tools/mem0.js.map +1 -0
  243. package/dist/tools/memory-graph.d.ts +151 -0
  244. package/dist/tools/memory-graph.d.ts.map +1 -0
  245. package/dist/tools/memory-graph.js +159 -0
  246. package/dist/tools/memory-graph.js.map +1 -0
  247. package/dist/tools/memory-stores.d.ts +141 -0
  248. package/dist/tools/memory-stores.d.ts.map +1 -0
  249. package/dist/tools/memory-stores.js +147 -0
  250. package/dist/tools/memory-stores.js.map +1 -0
  251. package/dist/tools/messages.d.ts +12 -20
  252. package/dist/tools/messages.d.ts.map +1 -1
  253. package/dist/tools/messages.js +12 -49
  254. package/dist/tools/messages.js.map +1 -1
  255. package/dist/tools/moltbook.d.ts +328 -0
  256. package/dist/tools/moltbook.d.ts.map +1 -0
  257. package/dist/tools/moltbook.js +334 -0
  258. package/dist/tools/moltbook.js.map +1 -0
  259. package/dist/tools/monitoring-attribution.d.ts +71 -0
  260. package/dist/tools/monitoring-attribution.d.ts.map +1 -0
  261. package/dist/tools/monitoring-attribution.js +74 -0
  262. package/dist/tools/monitoring-attribution.js.map +1 -0
  263. package/dist/tools/ops.d.ts +139 -0
  264. package/dist/tools/ops.d.ts.map +1 -0
  265. package/dist/tools/ops.js +151 -0
  266. package/dist/tools/ops.js.map +1 -0
  267. package/dist/tools/orchestrations.d.ts +109 -0
  268. package/dist/tools/orchestrations.d.ts.map +1 -0
  269. package/dist/tools/orchestrations.js +115 -0
  270. package/dist/tools/orchestrations.js.map +1 -0
  271. package/dist/tools/outcomes.d.ts +138 -0
  272. package/dist/tools/outcomes.d.ts.map +1 -0
  273. package/dist/tools/outcomes.js +136 -0
  274. package/dist/tools/outcomes.js.map +1 -0
  275. package/dist/tools/schedules.d.ts +149 -0
  276. package/dist/tools/schedules.d.ts.map +1 -0
  277. package/dist/tools/schedules.js +155 -0
  278. package/dist/tools/schedules.js.map +1 -0
  279. package/dist/tools/services.d.ts +6 -16
  280. package/dist/tools/services.d.ts.map +1 -1
  281. package/dist/tools/services.js +6 -135
  282. package/dist/tools/services.js.map +1 -1
  283. package/dist/tools/sessions.d.ts +124 -0
  284. package/dist/tools/sessions.d.ts.map +1 -0
  285. package/dist/tools/sessions.js +130 -0
  286. package/dist/tools/sessions.js.map +1 -0
  287. package/dist/tools/setup-status.d.ts +29 -0
  288. package/dist/tools/setup-status.d.ts.map +1 -0
  289. package/dist/tools/setup-status.js +35 -0
  290. package/dist/tools/setup-status.js.map +1 -0
  291. package/dist/tools/tasks.d.ts +44 -56
  292. package/dist/tools/tasks.d.ts.map +1 -1
  293. package/dist/tools/tasks.js +48 -212
  294. package/dist/tools/tasks.js.map +1 -1
  295. package/dist/tools/tiers.d.ts +55 -0
  296. package/dist/tools/tiers.d.ts.map +1 -0
  297. package/dist/tools/tiers.js +239 -0
  298. package/dist/tools/tiers.js.map +1 -0
  299. package/dist/tools/unified-agents.d.ts +43 -0
  300. package/dist/tools/unified-agents.d.ts.map +1 -0
  301. package/dist/tools/unified-agents.js +46 -0
  302. package/dist/tools/unified-agents.js.map +1 -0
  303. package/dist/tools/web-eval.d.ts +129 -0
  304. package/dist/tools/web-eval.d.ts.map +1 -0
  305. package/dist/tools/web-eval.js +136 -0
  306. package/dist/tools/web-eval.js.map +1 -0
  307. package/dist/tools/workflow.d.ts +105 -0
  308. package/dist/tools/workflow.d.ts.map +1 -0
  309. package/dist/tools/workflow.js +111 -0
  310. package/dist/tools/workflow.js.map +1 -0
  311. package/dist/tools/workloads.d.ts +81 -0
  312. package/dist/tools/workloads.d.ts.map +1 -0
  313. package/dist/tools/workloads.js +81 -0
  314. package/dist/tools/workloads.js.map +1 -0
  315. package/package.json +13 -7
@@ -1,25 +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
- import { taskTools, handleCreateTask, handleListTasks, handleGetTask, handleUpdateTask, handleGetTaskTimeline, handleCancelTask } from './tasks.js';
16
- import { messageTools, handleGetMessages, handleSendMessage } from './messages.js';
17
- import { approvalTools, handleGetPendingApprovals, handleApproveTask, handleRejectTask, handleRequestChanges } from './approvals.js';
18
- import { serviceTools, handleListServices } from './services.js';
19
- import { crewaiTools, handleCrewAIHealth, handleCrewAIInputs, handleCrewAIKickoff, handleCrewAIStatus } from './crewai.js';
20
- import { crewBuilderTools, handleCrewValidate, handleCrewKickoff, handleCrewStatus, handleCrewList } from './crew-builder.js';
21
- import { mcpRemoteTools, handleMcpDiscoverTools, handleMcpCallTool } from './mcp-tools.js';
22
- import { jiraTools, handleJiraSearchIssues, handleJiraGetIssue, handleJiraCreateIssue, handleJiraUpdateIssue, handleJiraAddComment, handleJiraGetComments, handleJiraGetTransitions, handleJiraTransitionIssue, handleJiraListProjects, handleJiraAssignIssue } from './jira.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
+ }
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: 'POST',
358
+ method: "POST",
48
359
  headers: {
49
- 'Content-Type': 'application/json',
50
- 'Authorization': `Bearer ${context.gatewayKey}`,
51
- ...(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 } : {}),
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.json().catch(() => ({ error: 'Gateway auth failed' }));
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 : 'Unknown error';
70
- 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);
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 = 'mcp.tool.call') {
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: 'POST',
397
+ method: "POST",
85
398
  headers: {
86
- 'Content-Type': 'application/json',
87
- 'Authorization': `Bearer ${context.gatewayKey}`,
88
- ...(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 } : {}),
89
402
  },
90
403
  body: JSON.stringify({
91
- action: 'log',
404
+ action: "log",
92
405
  tool_call: toolCall,
93
406
  event_type: eventType,
94
- actor_type: authResult.actor?.actor_type || 'human',
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('[MCP Gateway] Log failed:', error.message);
416
+ console.error("[MCP Gateway] Log failed:", error.message);
104
417
  }
105
418
  }
106
- const MCP_SERVER_NAME = 'mcp-dobby-external';
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: 'mcp-external',
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: 'error',
122
- error_message: authResult.error || 'Gateway auth denied',
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, 'mcp.tool.denied');
465
+ }, authResult, context, "mcp.tool.denied");
126
466
  return {
127
467
  content: [
128
468
  {
129
- type: 'text',
130
- text: `Tool call denied: ${authResult.error || 'Insufficient permissions'}`,
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 = 'success';
501
+ let toolStatus = "success";
140
502
  try {
141
- switch (toolName) {
142
- // Task tools
143
- case 'create_task':
144
- result = await handleCreateTask(client, args);
145
- break;
146
- case 'list_tasks':
147
- result = await handleListTasks(client, args);
148
- break;
149
- case 'get_task':
150
- result = await handleGetTask(client, args);
151
- break;
152
- case 'update_task':
153
- result = await handleUpdateTask(client, args);
154
- break;
155
- case 'get_task_timeline':
156
- result = await handleGetTaskTimeline(client, args);
157
- break;
158
- case 'cancel_task':
159
- result = await handleCancelTask(client, args);
160
- break;
161
- // Message tools
162
- case 'get_messages':
163
- result = await handleGetMessages(client, args, userId);
164
- break;
165
- case 'send_message':
166
- result = await handleSendMessage(client, args, userId, userName);
167
- break;
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 = 'error';
264
- toolError = result.content?.[0]?.text || 'Tool returned error';
532
+ toolStatus = "error";
533
+ toolError = result.content?.[0]?.text || "Tool returned error";
265
534
  }
266
535
  }
267
536
  catch (error) {
268
- toolStatus = 'error';
537
+ toolStatus = "error";
269
538
  toolError = error.message;
270
539
  result = {
271
540
  content: [
272
541
  {
273
- type: 'text',
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: 'mcp-external',
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, 'mcp.tool.call');
564
+ }, authResult, context, "mcp.tool.call");
296
565
  return result;
297
566
  }
298
567
  //# sourceMappingURL=index.js.map