@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
@@ -0,0 +1,12 @@
1
+ /**
2
+ * DobbyClient.gatewayBearer Tests
3
+ *
4
+ * gatewayBearer() picks the credential for GATEWAY-scoped endpoints (routes
5
+ * guarded by authenticateGatewayRequest hard-require a gk_* key):
6
+ * lazy provider (HTTP mode) > static gatewayKey (STDIO) > apiKey (legacy).
7
+ *
8
+ * Also proves at the helper level that a gateway fetch helper sends the
9
+ * RESOLVED key — not the OAuth session token — when a provider is present.
10
+ */
11
+ export {};
12
+ //# sourceMappingURL=gateway-bearer.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-bearer.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/gateway-bearer.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * DobbyClient.gatewayBearer Tests
3
+ *
4
+ * gatewayBearer() picks the credential for GATEWAY-scoped endpoints (routes
5
+ * guarded by authenticateGatewayRequest hard-require a gk_* key):
6
+ * lazy provider (HTTP mode) > static gatewayKey (STDIO) > apiKey (legacy).
7
+ *
8
+ * Also proves at the helper level that a gateway fetch helper sends the
9
+ * RESOLVED key — not the OAuth session token — when a provider is present.
10
+ */
11
+ import { describe, it, expect, vi, afterEach } from 'vitest';
12
+ import { createRegistry, toMcpResult } from '@dobbyai/capability-core';
13
+ import { DobbyClient } from '../lib/dobby-client.js';
14
+ // ADR-019: the legacy handleCrewAIHealth is gone — dispatch goes through the
15
+ // 'crewai_health' registry capability. Its handler is a verbatim copy (same
16
+ // callGatewayProxy → gatewayBearer() path), so the same real DobbyClient is
17
+ // passed through ctx and the outgoing-header assertions stay unchanged.
18
+ const registry = createRegistry();
19
+ describe('DobbyClient.gatewayBearer', () => {
20
+ const base = {
21
+ apiUrl: 'https://api.test',
22
+ apiKey: 'sk_live_api_key',
23
+ tenantId: 'tenant_1',
24
+ };
25
+ it('prefers the lazy provider over static gatewayKey and apiKey', async () => {
26
+ const client = new DobbyClient({
27
+ ...base,
28
+ gatewayKey: 'gk_static_key',
29
+ getGatewayKey: async () => 'gk_tmp_provider_key',
30
+ });
31
+ expect(await client.gatewayBearer()).toBe('gk_tmp_provider_key');
32
+ });
33
+ it('falls back to the static gatewayKey when the provider resolves undefined', async () => {
34
+ const client = new DobbyClient({
35
+ ...base,
36
+ gatewayKey: 'gk_static_key',
37
+ getGatewayKey: async () => undefined,
38
+ });
39
+ expect(await client.gatewayBearer()).toBe('gk_static_key');
40
+ });
41
+ it('uses the static gatewayKey when no provider is configured (STDIO)', async () => {
42
+ const client = new DobbyClient({ ...base, gatewayKey: 'gk_static_key' });
43
+ expect(await client.gatewayBearer()).toBe('gk_static_key');
44
+ });
45
+ it('falls back to apiKey when neither provider nor static key is configured', async () => {
46
+ const client = new DobbyClient(base);
47
+ expect(await client.gatewayBearer()).toBe('sk_live_api_key');
48
+ });
49
+ it('invokes a memoized provider only ONCE across two gatewayBearer calls', async () => {
50
+ // Mirrors the per-session memoization in server.ts:
51
+ // sessionGatewayKey ??= resolveSessionGatewayKey(...)
52
+ let sessionGatewayKey;
53
+ const resolve = vi.fn().mockResolvedValue('gk_tmp_once');
54
+ const client = new DobbyClient({
55
+ ...base,
56
+ getGatewayKey: () => (sessionGatewayKey ??= resolve()),
57
+ });
58
+ expect(await client.gatewayBearer()).toBe('gk_tmp_once');
59
+ expect(await client.gatewayBearer()).toBe('gk_tmp_once');
60
+ expect(resolve).toHaveBeenCalledTimes(1);
61
+ });
62
+ });
63
+ describe('gateway fetch helpers use gatewayBearer()', () => {
64
+ afterEach(() => {
65
+ vi.unstubAllGlobals();
66
+ });
67
+ it('crewai callGatewayProxy sends the RESOLVED gk_tmp_, not the OAuth session token', async () => {
68
+ const fetchMock = vi.fn().mockResolvedValue({
69
+ ok: true,
70
+ json: () => Promise.resolve({
71
+ response: { status: 'healthy' },
72
+ connection: { connection_id: 'conn_1', provider_id: 'crewai', status: 'active' },
73
+ latency_ms: 5,
74
+ }),
75
+ });
76
+ vi.stubGlobal('fetch', fetchMock);
77
+ const client = new DobbyClient({
78
+ apiUrl: 'https://api.test',
79
+ apiKey: 'dobby_at_session_token',
80
+ tenantId: 'tenant_1',
81
+ getGatewayKey: async () => 'gk_tmp_resolved',
82
+ });
83
+ const result = toMcpResult(await registry.get('crewai_health').handler({ client }, {}));
84
+ expect(result.isError).toBeUndefined();
85
+ expect(fetchMock).toHaveBeenCalledTimes(1);
86
+ const [url, init] = fetchMock.mock.calls[0];
87
+ expect(url).toBe('https://api.test/api/v1/gateway/agents/proxy');
88
+ expect(init.headers.Authorization).toBe('Bearer gk_tmp_resolved');
89
+ // The session token must NOT leak into any header of a gateway call
90
+ expect(JSON.stringify(init.headers)).not.toContain('dobby_at_session_token');
91
+ });
92
+ it('crewai callGatewayProxy keeps sending the gk_ apiKey for genuine gateway-key clients', async () => {
93
+ const fetchMock = vi.fn().mockResolvedValue({
94
+ ok: true,
95
+ json: () => Promise.resolve({
96
+ response: { status: 'healthy' },
97
+ connection: {},
98
+ latency_ms: 3,
99
+ }),
100
+ });
101
+ vi.stubGlobal('fetch', fetchMock);
102
+ const client = new DobbyClient({
103
+ apiUrl: 'https://api.test',
104
+ apiKey: 'gk_user_direct',
105
+ tenantId: 'tenant_1',
106
+ });
107
+ await registry.get('crewai_health').handler({ client }, {});
108
+ const [, init] = fetchMock.mock.calls[0];
109
+ expect(init.headers.Authorization).toBe('Bearer gk_user_direct');
110
+ });
111
+ });
112
+ //# sourceMappingURL=gateway-bearer.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-bearer.test.js","sourceRoot":"","sources":["../../src/__tests__/gateway-bearer.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Session Gateway Key Resolver Tests
3
+ *
4
+ * resolveSessionGatewayKey exchanges an MCP HTTP session token (dobby_at_* /
5
+ * sk_live_*) for a tenant+user-bound gk_tmp_* gateway key via the web app's
6
+ * internal endpoint. It must fail SOFT (return undefined) on every failure
7
+ * mode, log why exactly once, and never log the session token or the key.
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=gateway-key-resolver.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-key-resolver.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/gateway-key-resolver.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Session Gateway Key Resolver Tests
3
+ *
4
+ * resolveSessionGatewayKey exchanges an MCP HTTP session token (dobby_at_* /
5
+ * sk_live_*) for a tenant+user-bound gk_tmp_* gateway key via the web app's
6
+ * internal endpoint. It must fail SOFT (return undefined) on every failure
7
+ * mode, log why exactly once, and never log the session token or the key.
8
+ */
9
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
10
+ import { resolveSessionGatewayKey } from '../lib/gateway-key-resolver.js';
11
+ const API_URL = 'https://web.test';
12
+ const SESSION_TOKEN = 'dobby_at_secret_session_token';
13
+ const RESOLVED_KEY = 'gk_tmp_resolved_key_123';
14
+ const INTERNAL_SECRET = 'internal-secret-for-tests';
15
+ describe('resolveSessionGatewayKey', () => {
16
+ let consoleErrorSpy;
17
+ beforeEach(() => {
18
+ vi.stubEnv('INTERNAL_SERVICE_SECRET', INTERNAL_SECRET);
19
+ consoleErrorSpy = vi
20
+ .spyOn(console, 'error')
21
+ .mockImplementation(() => { });
22
+ });
23
+ afterEach(() => {
24
+ vi.unstubAllEnvs();
25
+ vi.unstubAllGlobals();
26
+ vi.restoreAllMocks();
27
+ });
28
+ it('returns data.gateway_key on 200 — POST carries the session token as Bearer + the internal secret header', async () => {
29
+ const fetchMock = vi.fn().mockResolvedValue({
30
+ ok: true,
31
+ json: () => Promise.resolve({
32
+ success: true,
33
+ data: {
34
+ gateway_key: RESOLVED_KEY,
35
+ key_id: 'key_abc',
36
+ expires_at: '2026-07-12T12:00:00Z',
37
+ scopes: ['agents:read'],
38
+ },
39
+ }),
40
+ });
41
+ vi.stubGlobal('fetch', fetchMock);
42
+ const key = await resolveSessionGatewayKey({
43
+ apiUrl: API_URL,
44
+ token: SESSION_TOKEN,
45
+ });
46
+ expect(key).toBe(RESOLVED_KEY);
47
+ expect(fetchMock).toHaveBeenCalledTimes(1);
48
+ const [url, init] = fetchMock.mock.calls[0];
49
+ expect(url).toBe(`${API_URL}/api/v1/internal/mcp/gateway-key`);
50
+ expect(init.method).toBe('POST');
51
+ expect(init.headers['x-internal-secret']).toBe(INTERNAL_SECRET);
52
+ expect(init.headers.Authorization).toBe(`Bearer ${SESSION_TOKEN}`);
53
+ expect(init.headers['Content-Type']).toBe('application/json');
54
+ expect(init.body).toBe('{}');
55
+ // Success path logs nothing
56
+ expect(consoleErrorSpy).not.toHaveBeenCalled();
57
+ });
58
+ it('returns undefined on a non-OK response — logs the HTTP status, never the token', async () => {
59
+ vi.stubGlobal('fetch', vi.fn().mockResolvedValue({
60
+ ok: false,
61
+ status: 401,
62
+ json: () => Promise.resolve({ error: 'unauthorized', message: 'bad token' }),
63
+ }));
64
+ const key = await resolveSessionGatewayKey({
65
+ apiUrl: API_URL,
66
+ token: SESSION_TOKEN,
67
+ });
68
+ expect(key).toBeUndefined();
69
+ expect(consoleErrorSpy).toHaveBeenCalledTimes(1);
70
+ const logged = consoleErrorSpy.mock.calls[0].join(' ');
71
+ expect(logged).toContain('401');
72
+ expect(logged).not.toContain(SESSION_TOKEN);
73
+ });
74
+ it('returns undefined WITHOUT calling fetch when INTERNAL_SERVICE_SECRET is missing', async () => {
75
+ vi.stubEnv('INTERNAL_SERVICE_SECRET', '');
76
+ const fetchMock = vi.fn();
77
+ vi.stubGlobal('fetch', fetchMock);
78
+ const key = await resolveSessionGatewayKey({
79
+ apiUrl: API_URL,
80
+ token: SESSION_TOKEN,
81
+ });
82
+ expect(key).toBeUndefined();
83
+ expect(fetchMock).not.toHaveBeenCalled();
84
+ expect(consoleErrorSpy).toHaveBeenCalledTimes(1);
85
+ expect(consoleErrorSpy.mock.calls[0].join(' ')).toContain('INTERNAL_SERVICE_SECRET');
86
+ });
87
+ it('returns undefined on a network error (no retries)', async () => {
88
+ const fetchMock = vi.fn().mockRejectedValue(new Error('ECONNREFUSED'));
89
+ vi.stubGlobal('fetch', fetchMock);
90
+ const key = await resolveSessionGatewayKey({
91
+ apiUrl: API_URL,
92
+ token: SESSION_TOKEN,
93
+ });
94
+ expect(key).toBeUndefined();
95
+ expect(fetchMock).toHaveBeenCalledTimes(1); // no retries
96
+ expect(consoleErrorSpy).toHaveBeenCalledTimes(1);
97
+ expect(consoleErrorSpy.mock.calls[0].join(' ')).toContain('ECONNREFUSED');
98
+ });
99
+ it('returns undefined when the 200 body has no data.gateway_key (malformed body)', async () => {
100
+ vi.stubGlobal('fetch', vi.fn().mockResolvedValue({
101
+ ok: true,
102
+ json: () => Promise.resolve({ success: true, data: {} }),
103
+ }));
104
+ const key = await resolveSessionGatewayKey({
105
+ apiUrl: API_URL,
106
+ token: SESSION_TOKEN,
107
+ });
108
+ expect(key).toBeUndefined();
109
+ expect(consoleErrorSpy).toHaveBeenCalledTimes(1);
110
+ expect(consoleErrorSpy.mock.calls[0].join(' ')).toContain('gateway_key');
111
+ });
112
+ it('returns undefined when the 200 body is not JSON at all', async () => {
113
+ vi.stubGlobal('fetch', vi.fn().mockResolvedValue({
114
+ ok: true,
115
+ json: () => Promise.reject(new Error('Unexpected token < in JSON')),
116
+ }));
117
+ const key = await resolveSessionGatewayKey({
118
+ apiUrl: API_URL,
119
+ token: SESSION_TOKEN,
120
+ });
121
+ expect(key).toBeUndefined();
122
+ expect(consoleErrorSpy).toHaveBeenCalledTimes(1);
123
+ });
124
+ });
125
+ //# sourceMappingURL=gateway-key-resolver.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-key-resolver.test.js","sourceRoot":"","sources":["../../src/__tests__/gateway-key-resolver.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Streamable-HTTP concurrency correlation tests
3
+ *
4
+ * Regression for the 2026-07-18 customer incident: a burst of concurrent tool
5
+ * calls on ONE session followed by a retry produced a CROSS-LABELED response —
6
+ * the list_services payload delivered as the get_task result. Server-side
7
+ * mechanism: the SDK correlates JSON-RPC responses to HTTP streams by the
8
+ * CLIENT-chosen request id (`_requestToStreamMapping`) and silently OVERWRITES
9
+ * the mapping when a second POST on the same session reuses an id that is
10
+ * still in flight — the first handler's late response is then written to the
11
+ * SECOND request's SSE stream with a matching id, so the client trusts a
12
+ * payload that belongs to a different tool call. http-server.ts rejects
13
+ * in-flight id reuse with an explicit 400 instead.
14
+ *
15
+ * These tests also pin the SDK-private location of the in-flight map: if an
16
+ * SDK upgrade moves `_requestToStreamMapping`, the guard silently disarms and
17
+ * the "rejected with 400" test here fails loudly.
18
+ */
19
+ export {};
20
+ //# sourceMappingURL=http-concurrency.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-concurrency.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/http-concurrency.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG"}
@@ -0,0 +1,254 @@
1
+ /**
2
+ * Streamable-HTTP concurrency correlation tests
3
+ *
4
+ * Regression for the 2026-07-18 customer incident: a burst of concurrent tool
5
+ * calls on ONE session followed by a retry produced a CROSS-LABELED response —
6
+ * the list_services payload delivered as the get_task result. Server-side
7
+ * mechanism: the SDK correlates JSON-RPC responses to HTTP streams by the
8
+ * CLIENT-chosen request id (`_requestToStreamMapping`) and silently OVERWRITES
9
+ * the mapping when a second POST on the same session reuses an id that is
10
+ * still in flight — the first handler's late response is then written to the
11
+ * SECOND request's SSE stream with a matching id, so the client trusts a
12
+ * payload that belongs to a different tool call. http-server.ts rejects
13
+ * in-flight id reuse with an explicit 400 instead.
14
+ *
15
+ * These tests also pin the SDK-private location of the in-flight map: if an
16
+ * SDK upgrade moves `_requestToStreamMapping`, the guard silently disarms and
17
+ * the "rejected with 400" test here fails loudly.
18
+ */
19
+ import { describe, it, expect } from "vitest";
20
+ function deferred() {
21
+ let resolve;
22
+ const promise = new Promise((r) => (resolve = r));
23
+ return { promise, resolve };
24
+ }
25
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
26
+ /**
27
+ * Stub issuer + real HTTP server wired to a minimal MCP server exposing
28
+ * controllable tools: `echo` (optional delay_ms), `slow_tool` (blocks on the
29
+ * test-held gate), `fast_tool` (immediate). Every tool echoes back its own
30
+ * name + the caller's `marker` argument so a response can be traced to the
31
+ * exact request that produced it.
32
+ */
33
+ async function withToolServer(run) {
34
+ const express = (await import("express")).default;
35
+ const { Server } = await import("@modelcontextprotocol/sdk/server/index.js");
36
+ const { ListToolsRequestSchema, CallToolRequestSchema } = await import("@modelcontextprotocol/sdk/types.js");
37
+ const { startHttpServer } = await import("../http-server.js");
38
+ const issuer = express();
39
+ issuer.use(express.json());
40
+ issuer.post("/oauth/token/introspect", (_req, res) => {
41
+ res.json({
42
+ active: true,
43
+ user_id: "pu_conc",
44
+ org_id: "org_conc",
45
+ tenant_id: "tenant_conc",
46
+ scope: "mcp:*",
47
+ client_id: "key_conc",
48
+ exp: Math.floor(Date.now() / 1000) + 3600,
49
+ });
50
+ });
51
+ const issuerServer = issuer.listen(0);
52
+ const issuerPort = issuerServer.address().port;
53
+ const gate = deferred();
54
+ const { server, tokenVerifier } = await startHttpServer({
55
+ port: 0,
56
+ issuerUrl: `http://127.0.0.1:${issuerPort}`,
57
+ mcpPublicUrl: "http://127.0.0.1:0",
58
+ createMcpServer: async () => {
59
+ const srv = new Server({ name: "conc-server", version: "0.0.0" }, { capabilities: { tools: {} } });
60
+ srv.setRequestHandler(ListToolsRequestSchema, async () => ({
61
+ tools: [
62
+ {
63
+ name: "echo",
64
+ description: "echo",
65
+ inputSchema: { type: "object" },
66
+ },
67
+ {
68
+ name: "slow_tool",
69
+ description: "blocks until the test releases the gate",
70
+ inputSchema: { type: "object" },
71
+ },
72
+ {
73
+ name: "fast_tool",
74
+ description: "returns immediately",
75
+ inputSchema: { type: "object" },
76
+ },
77
+ ],
78
+ }));
79
+ srv.setRequestHandler(CallToolRequestSchema, async (req) => {
80
+ const name = req.params.name;
81
+ const args = (req.params.arguments ?? {});
82
+ if (name === "slow_tool")
83
+ await gate.promise;
84
+ if (name === "echo" && typeof args.delay_ms === "number") {
85
+ await sleep(args.delay_ms);
86
+ }
87
+ return {
88
+ content: [
89
+ {
90
+ type: "text",
91
+ text: JSON.stringify({ tool: name, marker: args.marker ?? null }),
92
+ },
93
+ ],
94
+ };
95
+ });
96
+ return srv;
97
+ },
98
+ });
99
+ const mcpPort = server.address().port;
100
+ const mcpUrl = `http://127.0.0.1:${mcpPort}/mcp`;
101
+ const baseHeaders = {
102
+ Authorization: "Bearer sk_live_conc_test",
103
+ "Content-Type": "application/json",
104
+ Accept: "application/json, text/event-stream",
105
+ };
106
+ const initRes = await fetch(mcpUrl, {
107
+ method: "POST",
108
+ headers: baseHeaders,
109
+ body: JSON.stringify({
110
+ jsonrpc: "2.0",
111
+ id: 1,
112
+ method: "initialize",
113
+ params: {
114
+ protocolVersion: "2025-03-26",
115
+ capabilities: {},
116
+ clientInfo: { name: "conc-probe", version: "0" },
117
+ },
118
+ }),
119
+ });
120
+ expect(initRes.status).toBe(200);
121
+ const sessionId = initRes.headers.get("mcp-session-id");
122
+ expect(sessionId).toBeTruthy();
123
+ await initRes.text(); // drain the initialize SSE stream
124
+ try {
125
+ await run({
126
+ mcpUrl,
127
+ headers: { ...baseHeaders, "Mcp-Session-Id": sessionId },
128
+ gate,
129
+ });
130
+ }
131
+ finally {
132
+ gate.resolve(); // never leave a handler blocked across tests
133
+ tokenVerifier.clearCache();
134
+ server.close();
135
+ issuerServer.close();
136
+ }
137
+ }
138
+ /** Extract the LAST JSON-RPC message from an SSE response body. */
139
+ function parseSse(text) {
140
+ const dataLines = text.split("\n").filter((l) => l.startsWith("data: "));
141
+ expect(dataLines.length).toBeGreaterThan(0);
142
+ return JSON.parse(dataLines[dataLines.length - 1].slice(6));
143
+ }
144
+ function callBody(id, tool, args = {}) {
145
+ return JSON.stringify({
146
+ jsonrpc: "2.0",
147
+ id,
148
+ method: "tools/call",
149
+ params: { name: tool, arguments: args },
150
+ });
151
+ }
152
+ describe("Streamable-HTTP concurrent request/response correlation", () => {
153
+ it("N concurrent tools/call on ONE session — each response arrives on its own request's stream with matching id AND payload", async () => {
154
+ await withToolServer(async ({ mcpUrl, headers }) => {
155
+ // Inverted delays: the FIRST request finishes LAST, forcing fully
156
+ // out-of-order completion across the shared transport.
157
+ const delays = [250, 200, 150, 100, 0];
158
+ const results = await Promise.all(delays.map((delay_ms, i) => fetch(mcpUrl, {
159
+ method: "POST",
160
+ headers,
161
+ body: callBody(10 + i, "echo", { marker: `m${i}`, delay_ms }),
162
+ }).then(async (res) => ({
163
+ i,
164
+ status: res.status,
165
+ text: await res.text(),
166
+ }))));
167
+ for (const { i, status, text } of results) {
168
+ expect(status).toBe(200);
169
+ const msg = parseSse(text);
170
+ // The JSON-RPC id must match the request THIS stream carried…
171
+ expect(msg.id).toBe(10 + i);
172
+ // …and the payload must come from THIS request's handler invocation.
173
+ const payload = JSON.parse(msg.result.content[0].text);
174
+ expect(payload.tool).toBe("echo");
175
+ expect(payload.marker).toBe(`m${i}`);
176
+ }
177
+ });
178
+ });
179
+ it("reusing an IN-FLIGHT JSON-RPC id on the same session is rejected with 400 — never cross-delivered", async () => {
180
+ await withToolServer(async ({ mcpUrl, headers, gate }) => {
181
+ // First call blocks server-side; fetch resolves once SSE headers arrive,
182
+ // which happens strictly AFTER the SDK registered id→stream — so the
183
+ // collision below is deterministic, no sleeps needed.
184
+ const firstRes = await fetch(mcpUrl, {
185
+ method: "POST",
186
+ headers,
187
+ body: callBody(7, "slow_tool", { marker: "original" }),
188
+ });
189
+ expect(firstRes.status).toBe(200);
190
+ const firstTextP = firstRes.text();
191
+ // A second POST reusing the in-flight id — the retry-after-reconnect
192
+ // shape from the 2026-07-18 incident. Must be rejected loudly, not
193
+ // spliced into the first request's correlation slot.
194
+ const second = await fetch(mcpUrl, {
195
+ method: "POST",
196
+ headers,
197
+ body: callBody(7, "fast_tool", { marker: "retry" }),
198
+ });
199
+ expect(second.status).toBe(400);
200
+ const err = (await second.json());
201
+ expect(err.error.message).toContain("already in flight");
202
+ // The original request still completes normally with ITS OWN payload.
203
+ gate.resolve();
204
+ const msg = parseSse(await firstTextP);
205
+ expect(msg.id).toBe(7);
206
+ const payload = JSON.parse(msg.result.content[0].text);
207
+ expect(payload.tool).toBe("slow_tool");
208
+ expect(payload.marker).toBe("original");
209
+ });
210
+ });
211
+ it("reusing an id AFTER its request completed is allowed (mapping is cleaned on completion)", async () => {
212
+ // Deliberate minimal guard: only the dangerous in-flight subset is
213
+ // rejected, so clients that reset id counters between turns keep working.
214
+ await withToolServer(async ({ mcpUrl, headers }) => {
215
+ for (const marker of ["first", "second"]) {
216
+ const res = await fetch(mcpUrl, {
217
+ method: "POST",
218
+ headers,
219
+ body: callBody(42, "fast_tool", { marker }),
220
+ });
221
+ expect(res.status).toBe(200);
222
+ const msg = parseSse(await res.text());
223
+ expect(msg.id).toBe(42);
224
+ expect(JSON.parse(msg.result.content[0].text).marker).toBe(marker);
225
+ }
226
+ });
227
+ });
228
+ it("duplicate ids WITHIN one batch POST are rejected with 400", async () => {
229
+ await withToolServer(async ({ mcpUrl, headers }) => {
230
+ const res = await fetch(mcpUrl, {
231
+ method: "POST",
232
+ headers,
233
+ body: JSON.stringify([
234
+ {
235
+ jsonrpc: "2.0",
236
+ id: 9,
237
+ method: "tools/call",
238
+ params: { name: "fast_tool", arguments: { marker: "a" } },
239
+ },
240
+ {
241
+ jsonrpc: "2.0",
242
+ id: 9,
243
+ method: "tools/call",
244
+ params: { name: "fast_tool", arguments: { marker: "b" } },
245
+ },
246
+ ]),
247
+ });
248
+ expect(res.status).toBe(400);
249
+ const err = (await res.json());
250
+ expect(err.error.message).toContain("already in flight");
251
+ });
252
+ });
253
+ });
254
+ //# sourceMappingURL=http-concurrency.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-concurrency.test.js","sourceRoot":"","sources":["../../src/__tests__/http-concurrency.test.ts"],"names":[],"mappings":"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"}
@@ -53,17 +53,23 @@ describe('MCP Protocol Compliance', () => {
53
53
  });
54
54
  });
55
55
  describe('tier consistency', () => {
56
- it('MVP count matches documentation (22 tools)', () => {
57
- expect(MVP_TOOLS.length).toBe(22);
58
- expect(TIER_COUNTS.mvp).toBe(22);
56
+ // Exact tier counts are pinned once, in tiers.test.ts ("tier sizes")
57
+ // here we only assert the structural invariants between the tiers.
58
+ it('TIER_COUNTS reflects the tier allowlists', () => {
59
+ expect(TIER_COUNTS.mvp).toBe(MVP_TOOLS.length);
60
+ expect(TIER_COUNTS.pro).toBe(PRO_TOOLS.length);
59
61
  });
60
- it('Pro count matches documentation (50 tools)', () => {
61
- expect(PRO_TOOLS.length).toBe(50);
62
- expect(TIER_COUNTS.pro).toBe(50);
62
+ it('tiers grow strictly: MVP < Pro < all tools', () => {
63
+ expect(MVP_TOOLS.length).toBeGreaterThan(0);
64
+ expect(PRO_TOOLS.length).toBeGreaterThan(MVP_TOOLS.length);
65
+ expect(Object.keys(allTools).length).toBeGreaterThan(PRO_TOOLS.length);
63
66
  });
64
- it('enterprise tier includes all registered tools', () => {
67
+ it('enterprise tier includes all registered tools (for a superadmin)', () => {
68
+ // "All registered tools" = the full catalog, reachable by a superadmin.
69
+ // capability-core 0.1.2 hides the 5 superAdminOnly ops tools from every
70
+ // non-superadmin — so the FULL set is asserted via a superadmin principal.
65
71
  const allNames = Object.keys(allTools);
66
- const defs = getToolDefinitions('enterprise');
72
+ const defs = getToolDefinitions('enterprise', { isSuperAdmin: true });
67
73
  expect(defs.length).toBe(allNames.length);
68
74
  });
69
75
  it('each tool belongs to exactly one tier level', () => {
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/protocol.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"protocol.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/protocol.test.ts"],"names":[],"mappings":"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"}