@dobbyai/mcp-external 1.0.4 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -14
- package/dist/__tests__/agent-mail-tools.test.d.ts +8 -0
- package/dist/__tests__/agent-mail-tools.test.d.ts.map +1 -0
- package/dist/__tests__/agent-mail-tools.test.js +255 -0
- package/dist/__tests__/agent-mail-tools.test.js.map +1 -0
- package/dist/__tests__/annotations.test.d.ts +8 -0
- package/dist/__tests__/annotations.test.d.ts.map +1 -0
- package/dist/__tests__/annotations.test.js +108 -0
- package/dist/__tests__/annotations.test.js.map +1 -0
- package/dist/__tests__/auth.test.d.ts +7 -0
- package/dist/__tests__/auth.test.d.ts.map +1 -0
- package/dist/__tests__/auth.test.js +161 -0
- package/dist/__tests__/auth.test.js.map +1 -0
- package/dist/__tests__/doctor.test.d.ts +16 -0
- package/dist/__tests__/doctor.test.d.ts.map +1 -0
- package/dist/__tests__/doctor.test.js +258 -0
- package/dist/__tests__/doctor.test.js.map +1 -0
- package/dist/__tests__/external-agents-tools.test.d.ts +11 -0
- package/dist/__tests__/external-agents-tools.test.d.ts.map +1 -0
- package/dist/__tests__/external-agents-tools.test.js +619 -0
- package/dist/__tests__/external-agents-tools.test.js.map +1 -0
- package/dist/__tests__/gateway-bearer.test.d.ts +12 -0
- package/dist/__tests__/gateway-bearer.test.d.ts.map +1 -0
- package/dist/__tests__/gateway-bearer.test.js +112 -0
- package/dist/__tests__/gateway-bearer.test.js.map +1 -0
- package/dist/__tests__/gateway-key-resolver.test.d.ts +10 -0
- package/dist/__tests__/gateway-key-resolver.test.d.ts.map +1 -0
- package/dist/__tests__/gateway-key-resolver.test.js +125 -0
- package/dist/__tests__/gateway-key-resolver.test.js.map +1 -0
- package/dist/__tests__/http-concurrency.test.d.ts +20 -0
- package/dist/__tests__/http-concurrency.test.d.ts.map +1 -0
- package/dist/__tests__/http-concurrency.test.js +254 -0
- package/dist/__tests__/http-concurrency.test.js.map +1 -0
- package/dist/__tests__/integration/protocol.test.d.ts +8 -0
- package/dist/__tests__/integration/protocol.test.d.ts.map +1 -0
- package/dist/__tests__/integration/protocol.test.js +110 -0
- package/dist/__tests__/integration/protocol.test.js.map +1 -0
- package/dist/__tests__/mcp-integrations.test.d.ts +8 -0
- package/dist/__tests__/mcp-integrations.test.d.ts.map +1 -0
- package/dist/__tests__/mcp-integrations.test.js +365 -0
- package/dist/__tests__/mcp-integrations.test.js.map +1 -0
- package/dist/__tests__/memory-graph-tools.test.d.ts +8 -0
- package/dist/__tests__/memory-graph-tools.test.d.ts.map +1 -0
- package/dist/__tests__/memory-graph-tools.test.js +254 -0
- package/dist/__tests__/memory-graph-tools.test.js.map +1 -0
- package/dist/__tests__/registry-dispatch.test.d.ts +11 -0
- package/dist/__tests__/registry-dispatch.test.d.ts.map +1 -0
- package/dist/__tests__/registry-dispatch.test.js +30 -0
- package/dist/__tests__/registry-dispatch.test.js.map +1 -0
- package/dist/__tests__/registry-listing-parity.test.d.ts +2 -0
- package/dist/__tests__/registry-listing-parity.test.d.ts.map +1 -0
- package/dist/__tests__/registry-listing-parity.test.js +89 -0
- package/dist/__tests__/registry-listing-parity.test.js.map +1 -0
- package/dist/__tests__/role-cap.test.d.ts +2 -0
- package/dist/__tests__/role-cap.test.d.ts.map +1 -0
- package/dist/__tests__/role-cap.test.js +113 -0
- package/dist/__tests__/role-cap.test.js.map +1 -0
- package/dist/__tests__/schedule-tools.test.d.ts +8 -0
- package/dist/__tests__/schedule-tools.test.d.ts.map +1 -0
- package/dist/__tests__/schedule-tools.test.js +285 -0
- package/dist/__tests__/schedule-tools.test.js.map +1 -0
- package/dist/__tests__/server-gateway-key.test.d.ts +18 -0
- package/dist/__tests__/server-gateway-key.test.d.ts.map +1 -0
- package/dist/__tests__/server-gateway-key.test.js +148 -0
- package/dist/__tests__/server-gateway-key.test.js.map +1 -0
- package/dist/__tests__/server-user-scoped.test.d.ts +34 -0
- package/dist/__tests__/server-user-scoped.test.d.ts.map +1 -0
- package/dist/__tests__/server-user-scoped.test.js +577 -0
- package/dist/__tests__/server-user-scoped.test.js.map +1 -0
- package/dist/__tests__/task-id-pattern.test.d.ts +12 -0
- package/dist/__tests__/task-id-pattern.test.d.ts.map +1 -0
- package/dist/__tests__/task-id-pattern.test.js +43 -0
- package/dist/__tests__/task-id-pattern.test.js.map +1 -0
- package/dist/__tests__/tiers.test.d.ts +7 -0
- package/dist/__tests__/tiers.test.d.ts.map +1 -0
- package/dist/__tests__/tiers.test.js +199 -0
- package/dist/__tests__/tiers.test.js.map +1 -0
- package/dist/__tests__/tools/hosted-agents.test.d.ts +9 -0
- package/dist/__tests__/tools/hosted-agents.test.d.ts.map +1 -0
- package/dist/__tests__/tools/hosted-agents.test.js +301 -0
- package/dist/__tests__/tools/hosted-agents.test.js.map +1 -0
- package/dist/__tests__/tools/llm-providers.test.d.ts +10 -0
- package/dist/__tests__/tools/llm-providers.test.d.ts.map +1 -0
- package/dist/__tests__/tools/llm-providers.test.js +105 -0
- package/dist/__tests__/tools/llm-providers.test.js.map +1 -0
- package/dist/__tests__/tools/services.test.js +139 -98
- package/dist/__tests__/tools/services.test.js.map +1 -1
- package/dist/__tests__/tools.test.d.ts +7 -0
- package/dist/__tests__/tools.test.d.ts.map +1 -0
- package/dist/__tests__/tools.test.js +152 -0
- package/dist/__tests__/tools.test.js.map +1 -0
- package/dist/__tests__/transport.test.d.ts +7 -0
- package/dist/__tests__/transport.test.d.ts.map +1 -0
- package/dist/__tests__/transport.test.js +397 -0
- package/dist/__tests__/transport.test.js.map +1 -0
- package/dist/__tests__/validate-credentials.test.d.ts +9 -0
- package/dist/__tests__/validate-credentials.test.d.ts.map +1 -0
- package/dist/__tests__/validate-credentials.test.js +172 -0
- package/dist/__tests__/validate-credentials.test.js.map +1 -0
- package/dist/__tests__/web-eval-tools.test.d.ts +8 -0
- package/dist/__tests__/web-eval-tools.test.d.ts.map +1 -0
- package/dist/__tests__/web-eval-tools.test.js +241 -0
- package/dist/__tests__/web-eval-tools.test.js.map +1 -0
- package/dist/__tests__/whoami.test.d.ts +11 -0
- package/dist/__tests__/whoami.test.d.ts.map +1 -0
- package/dist/__tests__/whoami.test.js +194 -0
- package/dist/__tests__/whoami.test.js.map +1 -0
- package/dist/__tests__/workflow-tools.test.d.ts +8 -0
- package/dist/__tests__/workflow-tools.test.d.ts.map +1 -0
- package/dist/__tests__/workflow-tools.test.js +261 -0
- package/dist/__tests__/workflow-tools.test.js.map +1 -0
- package/dist/__tests__/workloads.test.d.ts +9 -0
- package/dist/__tests__/workloads.test.d.ts.map +1 -0
- package/dist/__tests__/workloads.test.js +169 -0
- package/dist/__tests__/workloads.test.js.map +1 -0
- package/dist/auth/oauth-provider.d.ts +34 -0
- package/dist/auth/oauth-provider.d.ts.map +1 -0
- package/dist/auth/oauth-provider.js +75 -0
- package/dist/auth/oauth-provider.js.map +1 -0
- package/dist/auth/token-verifier.d.ts +45 -0
- package/dist/auth/token-verifier.d.ts.map +1 -0
- package/dist/auth/token-verifier.js +160 -0
- package/dist/auth/token-verifier.js.map +1 -0
- package/dist/connectors/claude-desktop.d.ts.map +1 -1
- package/dist/connectors/claude-desktop.js +3 -2
- package/dist/connectors/claude-desktop.js.map +1 -1
- package/dist/connectors/cursor.d.ts.map +1 -1
- package/dist/connectors/cursor.js +3 -2
- package/dist/connectors/cursor.js.map +1 -1
- package/dist/connectors/setup.d.ts.map +1 -1
- package/dist/connectors/setup.js +2 -1
- package/dist/connectors/setup.js.map +1 -1
- package/dist/connectors/vscode.d.ts.map +1 -1
- package/dist/connectors/vscode.js +3 -2
- package/dist/connectors/vscode.js.map +1 -1
- package/dist/connectors/windsurf.d.ts.map +1 -1
- package/dist/connectors/windsurf.js +3 -2
- package/dist/connectors/windsurf.js.map +1 -1
- package/dist/doctor.d.ts +34 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +134 -0
- package/dist/doctor.js.map +1 -0
- package/dist/http-server.d.ts +56 -0
- package/dist/http-server.d.ts.map +1 -0
- package/dist/http-server.js +455 -0
- package/dist/http-server.js.map +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +96 -171
- package/dist/index.js.map +1 -1
- package/dist/lib/consts.d.ts +21 -0
- package/dist/lib/consts.d.ts.map +1 -0
- package/dist/lib/consts.js +30 -0
- package/dist/lib/consts.js.map +1 -0
- package/dist/lib/dobby-client.d.ts +60 -3
- package/dist/lib/dobby-client.d.ts.map +1 -1
- package/dist/lib/dobby-client.js +145 -44
- package/dist/lib/dobby-client.js.map +1 -1
- package/dist/lib/gateway-key-resolver.d.ts +38 -0
- package/dist/lib/gateway-key-resolver.d.ts.map +1 -0
- package/dist/lib/gateway-key-resolver.js +59 -0
- package/dist/lib/gateway-key-resolver.js.map +1 -0
- package/dist/lib/log.d.ts +25 -0
- package/dist/lib/log.d.ts.map +1 -0
- package/dist/lib/log.js +36 -0
- package/dist/lib/log.js.map +1 -0
- package/dist/server.d.ts +175 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +1017 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/agent-mail.d.ts +112 -0
- package/dist/tools/agent-mail.d.ts.map +1 -0
- package/dist/tools/agent-mail.js +118 -0
- package/dist/tools/agent-mail.js.map +1 -0
- package/dist/tools/agent-versions.d.ts +93 -0
- package/dist/tools/agent-versions.d.ts.map +1 -0
- package/dist/tools/agent-versions.js +99 -0
- package/dist/tools/agent-versions.js.map +1 -0
- package/dist/tools/approvals.d.ts +24 -34
- package/dist/tools/approvals.d.ts.map +1 -1
- package/dist/tools/approvals.js +24 -81
- package/dist/tools/approvals.js.map +1 -1
- package/dist/tools/claude-code-sync.d.ts +40 -0
- package/dist/tools/claude-code-sync.d.ts.map +1 -0
- package/dist/tools/claude-code-sync.js +52 -0
- package/dist/tools/claude-code-sync.js.map +1 -0
- package/dist/tools/control-plane.d.ts +118 -0
- package/dist/tools/control-plane.d.ts.map +1 -0
- package/dist/tools/control-plane.js +135 -0
- package/dist/tools/control-plane.js.map +1 -0
- package/dist/tools/crew-builder.d.ts +24 -66
- package/dist/tools/crew-builder.d.ts.map +1 -1
- package/dist/tools/crew-builder.js +24 -185
- package/dist/tools/crew-builder.js.map +1 -1
- package/dist/tools/crewai.d.ts +24 -63
- package/dist/tools/crewai.d.ts.map +1 -1
- package/dist/tools/crewai.js +24 -145
- package/dist/tools/crewai.js.map +1 -1
- package/dist/tools/exa.d.ts +126 -0
- package/dist/tools/exa.d.ts.map +1 -0
- package/dist/tools/exa.js +125 -0
- package/dist/tools/exa.js.map +1 -0
- package/dist/tools/external-agents.d.ts +440 -0
- package/dist/tools/external-agents.d.ts.map +1 -0
- package/dist/tools/external-agents.js +386 -0
- package/dist/tools/external-agents.js.map +1 -0
- package/dist/tools/github-mcp.d.ts +228 -0
- package/dist/tools/github-mcp.d.ts.map +1 -0
- package/dist/tools/github-mcp.js +235 -0
- package/dist/tools/github-mcp.js.map +1 -0
- package/dist/tools/governance.d.ts +273 -0
- package/dist/tools/governance.d.ts.map +1 -0
- package/dist/tools/governance.js +286 -0
- package/dist/tools/governance.js.map +1 -0
- package/dist/tools/hosted-agents.d.ts +216 -0
- package/dist/tools/hosted-agents.d.ts.map +1 -0
- package/dist/tools/hosted-agents.js +214 -0
- package/dist/tools/hosted-agents.js.map +1 -0
- package/dist/tools/index.d.ts +6335 -191
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +441 -172
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/jira.d.ts +60 -176
- package/dist/tools/jira.d.ts.map +1 -1
- package/dist/tools/jira.js +60 -365
- package/dist/tools/jira.js.map +1 -1
- package/dist/tools/llm-providers.d.ts +50 -0
- package/dist/tools/llm-providers.d.ts.map +1 -0
- package/dist/tools/llm-providers.js +41 -0
- package/dist/tools/llm-providers.js.map +1 -0
- package/dist/tools/mcp-metrics.d.ts +47 -0
- package/dist/tools/mcp-metrics.d.ts.map +1 -0
- package/dist/tools/mcp-metrics.js +53 -0
- package/dist/tools/mcp-metrics.js.map +1 -0
- package/dist/tools/mcp-tools.d.ts +12 -29
- package/dist/tools/mcp-tools.d.ts.map +1 -1
- package/dist/tools/mcp-tools.js +12 -131
- package/dist/tools/mcp-tools.js.map +1 -1
- package/dist/tools/mem0.d.ts +127 -0
- package/dist/tools/mem0.d.ts.map +1 -0
- package/dist/tools/mem0.js +155 -0
- package/dist/tools/mem0.js.map +1 -0
- package/dist/tools/memory-graph.d.ts +151 -0
- package/dist/tools/memory-graph.d.ts.map +1 -0
- package/dist/tools/memory-graph.js +159 -0
- package/dist/tools/memory-graph.js.map +1 -0
- package/dist/tools/memory-stores.d.ts +141 -0
- package/dist/tools/memory-stores.d.ts.map +1 -0
- package/dist/tools/memory-stores.js +147 -0
- package/dist/tools/memory-stores.js.map +1 -0
- package/dist/tools/messages.d.ts +12 -20
- package/dist/tools/messages.d.ts.map +1 -1
- package/dist/tools/messages.js +12 -49
- package/dist/tools/messages.js.map +1 -1
- package/dist/tools/moltbook.d.ts +328 -0
- package/dist/tools/moltbook.d.ts.map +1 -0
- package/dist/tools/moltbook.js +334 -0
- package/dist/tools/moltbook.js.map +1 -0
- package/dist/tools/monitoring-attribution.d.ts +71 -0
- package/dist/tools/monitoring-attribution.d.ts.map +1 -0
- package/dist/tools/monitoring-attribution.js +74 -0
- package/dist/tools/monitoring-attribution.js.map +1 -0
- package/dist/tools/ops.d.ts +139 -0
- package/dist/tools/ops.d.ts.map +1 -0
- package/dist/tools/ops.js +151 -0
- package/dist/tools/ops.js.map +1 -0
- package/dist/tools/orchestrations.d.ts +109 -0
- package/dist/tools/orchestrations.d.ts.map +1 -0
- package/dist/tools/orchestrations.js +115 -0
- package/dist/tools/orchestrations.js.map +1 -0
- package/dist/tools/outcomes.d.ts +138 -0
- package/dist/tools/outcomes.d.ts.map +1 -0
- package/dist/tools/outcomes.js +136 -0
- package/dist/tools/outcomes.js.map +1 -0
- package/dist/tools/schedules.d.ts +149 -0
- package/dist/tools/schedules.d.ts.map +1 -0
- package/dist/tools/schedules.js +155 -0
- package/dist/tools/schedules.js.map +1 -0
- package/dist/tools/services.d.ts +6 -16
- package/dist/tools/services.d.ts.map +1 -1
- package/dist/tools/services.js +6 -135
- package/dist/tools/services.js.map +1 -1
- package/dist/tools/sessions.d.ts +124 -0
- package/dist/tools/sessions.d.ts.map +1 -0
- package/dist/tools/sessions.js +130 -0
- package/dist/tools/sessions.js.map +1 -0
- package/dist/tools/setup-status.d.ts +29 -0
- package/dist/tools/setup-status.d.ts.map +1 -0
- package/dist/tools/setup-status.js +35 -0
- package/dist/tools/setup-status.js.map +1 -0
- package/dist/tools/tasks.d.ts +44 -56
- package/dist/tools/tasks.d.ts.map +1 -1
- package/dist/tools/tasks.js +48 -212
- package/dist/tools/tasks.js.map +1 -1
- package/dist/tools/tiers.d.ts +55 -0
- package/dist/tools/tiers.d.ts.map +1 -0
- package/dist/tools/tiers.js +239 -0
- package/dist/tools/tiers.js.map +1 -0
- package/dist/tools/unified-agents.d.ts +43 -0
- package/dist/tools/unified-agents.d.ts.map +1 -0
- package/dist/tools/unified-agents.js +46 -0
- package/dist/tools/unified-agents.js.map +1 -0
- package/dist/tools/web-eval.d.ts +129 -0
- package/dist/tools/web-eval.d.ts.map +1 -0
- package/dist/tools/web-eval.js +136 -0
- package/dist/tools/web-eval.js.map +1 -0
- package/dist/tools/workflow.d.ts +105 -0
- package/dist/tools/workflow.d.ts.map +1 -0
- package/dist/tools/workflow.js +111 -0
- package/dist/tools/workflow.js.map +1 -0
- package/dist/tools/workloads.d.ts +81 -0
- package/dist/tools/workloads.d.ts.map +1 -0
- package/dist/tools/workloads.js +81 -0
- package/dist/tools/workloads.js.map +1 -0
- package/package.json +13 -7
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Server for Dobby MCP
|
|
3
|
+
*
|
|
4
|
+
* Express app serving MCP over Streamable HTTP transport with OAuth 2.1 auth.
|
|
5
|
+
* Runs alongside the existing STDIO mode — selected via --transport http.
|
|
6
|
+
*
|
|
7
|
+
* Endpoints:
|
|
8
|
+
* GET / — Landing/info page: HTML for browsers, JSON otherwise (no auth)
|
|
9
|
+
* GET /.well-known/oauth-authorization-server — OAuth metadata (via mcpAuthRouter)
|
|
10
|
+
* GET /authorize — Redirect to web app consent page (via mcpAuthRouter)
|
|
11
|
+
* POST /token — Token exchange proxy (via mcpAuthRouter)
|
|
12
|
+
* POST /register — Dynamic client registration proxy (via mcpAuthRouter)
|
|
13
|
+
* POST /revoke — Token revocation proxy (via mcpAuthRouter)
|
|
14
|
+
* POST /mcp — Streamable HTTP MCP endpoint (Bearer auth required)
|
|
15
|
+
* GET /mcp — SSE stream for Streamable HTTP (Bearer auth required)
|
|
16
|
+
* DELETE /mcp — Session termination (Bearer auth required)
|
|
17
|
+
* GET /health — Health check (no auth)
|
|
18
|
+
*/
|
|
19
|
+
import express from "express";
|
|
20
|
+
import cors from "cors";
|
|
21
|
+
import { randomUUID } from "node:crypto";
|
|
22
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
23
|
+
import { mcpAuthRouter } from "@modelcontextprotocol/sdk/server/auth/router.js";
|
|
24
|
+
import { requireBearerAuth } from "@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js";
|
|
25
|
+
import { createOAuthProvider, } from "./auth/oauth-provider.js";
|
|
26
|
+
import { log } from "./lib/log.js";
|
|
27
|
+
// ============================================
|
|
28
|
+
// Session Management
|
|
29
|
+
// ============================================
|
|
30
|
+
/** Active transport sessions keyed by session ID */
|
|
31
|
+
const sessions = new Map();
|
|
32
|
+
/**
|
|
33
|
+
* Principal (`user:org:tenant`) that OWNS each session. A session may only be
|
|
34
|
+
* used or terminated by the SAME principal that created it (2026-07-05 audit
|
|
35
|
+
* M-12). Without this, any holder of a valid bearer token who knew/guessed a
|
|
36
|
+
* session ID could hijack another user's MCP session (its tool context runs
|
|
37
|
+
* under the original principal). Bound to the stable identity from the token's
|
|
38
|
+
* `extra` (survives token refresh), not the raw token.
|
|
39
|
+
*/
|
|
40
|
+
const sessionPrincipals = new Map();
|
|
41
|
+
function principalKey(req) {
|
|
42
|
+
const extra = req.auth?.extra ?? {};
|
|
43
|
+
return `${extra.user_id ?? ""}:${extra.org_id ?? ""}:${extra.tenant_id ?? ""}`;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Cross-wiring guard (2026-07-18 customer incident): the SDK correlates
|
|
47
|
+
* JSON-RPC responses to HTTP streams by the CLIENT-chosen request id and
|
|
48
|
+
* silently OVERWRITES that mapping when a second POST on the same session
|
|
49
|
+
* reuses an id that is still in flight. The first handler's late response is
|
|
50
|
+
* then delivered on the SECOND request's SSE stream with a matching id — the
|
|
51
|
+
* client trusts a payload that belongs to a different tool call (observed
|
|
52
|
+
* live: a list_services result parsed as get_task's). The MCP spec forbids id
|
|
53
|
+
* reuse within a session; reject the dangerous in-flight subset loudly so a
|
|
54
|
+
* retrying client gets an explicit error instead of silently wrong data.
|
|
55
|
+
* Completed requests are removed from the SDK map, so clients that reset id
|
|
56
|
+
* counters between turns keep working.
|
|
57
|
+
*
|
|
58
|
+
* Returns the offending id, or null when the body is clean. The in-flight
|
|
59
|
+
* requestId→streamId map is SDK-private (`_webStandardTransport` since 1.29,
|
|
60
|
+
* the transport itself before) — if an SDK upgrade moves it the guard
|
|
61
|
+
* disarms, which the http-concurrency tests catch loudly.
|
|
62
|
+
*/
|
|
63
|
+
function findInflightIdCollision(transport, body) {
|
|
64
|
+
const inner = transport._webStandardTransport ??
|
|
65
|
+
transport;
|
|
66
|
+
const mapping = inner._requestToStreamMapping;
|
|
67
|
+
if (!(mapping instanceof Map))
|
|
68
|
+
return null;
|
|
69
|
+
const messages = Array.isArray(body) ? body : [body];
|
|
70
|
+
const seenInBatch = new Set();
|
|
71
|
+
for (const msg of messages) {
|
|
72
|
+
if (!msg || typeof msg !== "object")
|
|
73
|
+
continue;
|
|
74
|
+
const m = msg;
|
|
75
|
+
// A JSON-RPC request has both `method` and `id` (notifications lack an
|
|
76
|
+
// id, responses lack a method) — only requests enter the SDK's mapping.
|
|
77
|
+
if (typeof m.method !== "string")
|
|
78
|
+
continue;
|
|
79
|
+
if (typeof m.id !== "string" && typeof m.id !== "number")
|
|
80
|
+
continue;
|
|
81
|
+
if (mapping.has(m.id) || seenInBatch.has(m.id))
|
|
82
|
+
return m.id;
|
|
83
|
+
seenInBatch.add(m.id);
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
// ============================================
|
|
88
|
+
// Per-request logging
|
|
89
|
+
// ============================================
|
|
90
|
+
/**
|
|
91
|
+
* Identity fields safe to log: internal IDs only — NEVER the bearer token.
|
|
92
|
+
* Populated by requireBearerAuth by the time the response finishes; undefined
|
|
93
|
+
* on unauthenticated (401) requests.
|
|
94
|
+
*/
|
|
95
|
+
function principalFields(req) {
|
|
96
|
+
const extra = req.auth?.extra;
|
|
97
|
+
if (!extra)
|
|
98
|
+
return { clientId: req.auth?.clientId };
|
|
99
|
+
return {
|
|
100
|
+
clientId: req.auth?.clientId,
|
|
101
|
+
userId: extra.user_id,
|
|
102
|
+
orgId: extra.org_id,
|
|
103
|
+
tenantId: extra.tenant_id,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* One structured JSON log line per request on the MCP data plane. Before this
|
|
108
|
+
* existed a pod's entire lifetime output was the 8-line startup banner, and
|
|
109
|
+
* the 2026-07-18 cross-labeled-response incident was unforensicable — the only
|
|
110
|
+
* per-request record was the Caddy access log. Captures just enough to
|
|
111
|
+
* correlate a request to its session, principal, and JSON-RPC id; payload
|
|
112
|
+
* bodies are deliberately NOT logged.
|
|
113
|
+
*/
|
|
114
|
+
function mcpRequestLogger(req, res, next) {
|
|
115
|
+
const startedAt = Date.now();
|
|
116
|
+
let logged = false;
|
|
117
|
+
const finish = () => {
|
|
118
|
+
if (logged)
|
|
119
|
+
return;
|
|
120
|
+
logged = true;
|
|
121
|
+
// req.body is parsed by express.json() before the routes run. A body may
|
|
122
|
+
// be a single JSON-RPC message or a batch array.
|
|
123
|
+
const body = req.body;
|
|
124
|
+
const rpcs = Array.isArray(body)
|
|
125
|
+
? body
|
|
126
|
+
: body && typeof body === "object"
|
|
127
|
+
? [body]
|
|
128
|
+
: [];
|
|
129
|
+
const rpcMethods = rpcs
|
|
130
|
+
.map((r) => r.method)
|
|
131
|
+
.filter((m) => typeof m === "string");
|
|
132
|
+
const toolName = rpcs.find((r) => r.method === "tools/call")?.params;
|
|
133
|
+
const rpcIds = rpcs.map((r) => r.id).filter((id) => id !== undefined);
|
|
134
|
+
// On initialize the session ID is assigned in the RESPONSE header.
|
|
135
|
+
const sessionId = req.headers["mcp-session-id"] ??
|
|
136
|
+
res.getHeader("mcp-session-id");
|
|
137
|
+
const status = res.statusCode;
|
|
138
|
+
const durationMs = Date.now() - startedAt;
|
|
139
|
+
const method = rpcMethods.join(",") || undefined;
|
|
140
|
+
const tool = typeof toolName?.name === "string" ? toolName.name : undefined;
|
|
141
|
+
const level = status >= 500 ? "error" : status >= 400 ? "warn" : "info";
|
|
142
|
+
log[level](`mcp ${req.method} ${method ?? ""}${tool ? `(${tool})` : ""} ${status} ${durationMs}ms`.replace(/\s+/g, " "), {
|
|
143
|
+
httpMethod: req.method,
|
|
144
|
+
rpcMethod: method,
|
|
145
|
+
toolName: tool,
|
|
146
|
+
rpcId: rpcIds.length === 1 ? rpcIds[0] : rpcIds.length ? rpcIds : undefined,
|
|
147
|
+
sessionId,
|
|
148
|
+
...principalFields(req),
|
|
149
|
+
status,
|
|
150
|
+
durationMs,
|
|
151
|
+
userAgent: req.headers["user-agent"],
|
|
152
|
+
});
|
|
153
|
+
};
|
|
154
|
+
// 'finish' for normal responses; 'close' so long-lived SSE streams
|
|
155
|
+
// (GET /mcp) and aborted requests still log once, with durationMs = stream
|
|
156
|
+
// lifetime.
|
|
157
|
+
res.on("finish", finish);
|
|
158
|
+
res.on("close", finish);
|
|
159
|
+
next();
|
|
160
|
+
}
|
|
161
|
+
// ============================================
|
|
162
|
+
// CORS configuration
|
|
163
|
+
// ============================================
|
|
164
|
+
/**
|
|
165
|
+
* CORS policy for the MCP HTTP transport.
|
|
166
|
+
*
|
|
167
|
+
* We reflect ANY browser origin, which is safe ONLY because `credentials` is
|
|
168
|
+
* disabled: the MCP data plane (`/mcp`) authenticates via Bearer tokens in the
|
|
169
|
+
* `Authorization` header, and the OAuth proxy routes (`/authorize` redirect,
|
|
170
|
+
* `/token`/`/register`/`/revoke`) carry client credentials / auth codes in the
|
|
171
|
+
* request body — never via ambient cookies. With no cross-origin credentials to
|
|
172
|
+
* leak, reflecting the origin exposes nothing.
|
|
173
|
+
*
|
|
174
|
+
* Reflecting the origin together with `credentials: true` is the classic
|
|
175
|
+
* dangerous CORS combo (any site could read credentialed responses), so
|
|
176
|
+
* `credentials` MUST stay `false`. If cookie-based auth is ever introduced on
|
|
177
|
+
* this server, replace the reflect-any-origin callback with an explicit
|
|
178
|
+
* allowlist BEFORE re-enabling credentials.
|
|
179
|
+
*/
|
|
180
|
+
export const corsOptions = {
|
|
181
|
+
origin: (origin, callback) => {
|
|
182
|
+
// Allow requests with no origin (curl, server-to-server, native MCP clients)
|
|
183
|
+
if (!origin)
|
|
184
|
+
return callback(null, true);
|
|
185
|
+
// Reflect any browser origin — safe because credentials are disabled below.
|
|
186
|
+
callback(null, true);
|
|
187
|
+
},
|
|
188
|
+
methods: ["GET", "POST", "DELETE", "OPTIONS"],
|
|
189
|
+
allowedHeaders: ["Content-Type", "Authorization", "Mcp-Session-Id"],
|
|
190
|
+
exposedHeaders: ["Mcp-Session-Id"],
|
|
191
|
+
credentials: false,
|
|
192
|
+
maxAge: 86400,
|
|
193
|
+
};
|
|
194
|
+
// ============================================
|
|
195
|
+
// Start HTTP Server
|
|
196
|
+
// ============================================
|
|
197
|
+
export async function startHttpServer(config) {
|
|
198
|
+
const { port, issuerUrl, mcpPublicUrl, createMcpServer } = config;
|
|
199
|
+
// Create OAuth proxy provider
|
|
200
|
+
const { provider, tokenVerifier } = createOAuthProvider({
|
|
201
|
+
issuerUrl,
|
|
202
|
+
mcpPublicUrl,
|
|
203
|
+
});
|
|
204
|
+
const app = express();
|
|
205
|
+
// ============================================
|
|
206
|
+
// CORS — reflect any origin, credentials disabled (see corsOptions above)
|
|
207
|
+
// ============================================
|
|
208
|
+
app.use(cors(corsOptions));
|
|
209
|
+
// Parse JSON for MCP requests
|
|
210
|
+
app.use(express.json());
|
|
211
|
+
// Structured per-request logging on the MCP data plane only — /health and
|
|
212
|
+
// the OAuth proxy routes stay quiet (health probes would spam; OAuth URLs
|
|
213
|
+
// carry authorization codes).
|
|
214
|
+
app.use("/mcp", mcpRequestLogger);
|
|
215
|
+
// ============================================
|
|
216
|
+
// OAuth proxy routes (served by MCP SDK's mcpAuthRouter)
|
|
217
|
+
// ============================================
|
|
218
|
+
const authRouter = mcpAuthRouter({
|
|
219
|
+
provider,
|
|
220
|
+
issuerUrl: new URL(issuerUrl),
|
|
221
|
+
baseUrl: new URL(mcpPublicUrl),
|
|
222
|
+
serviceDocumentationUrl: new URL(`${issuerUrl}/docs/mcp`),
|
|
223
|
+
scopesSupported: ["mcp:read", "mcp:execute", "mcp:pro", "mcp:*"],
|
|
224
|
+
});
|
|
225
|
+
app.use(authRouter);
|
|
226
|
+
// ============================================
|
|
227
|
+
// Landing page (no auth) — humans and clients hitting the bare domain.
|
|
228
|
+
// Express's default "Cannot GET /" reads as a broken server; peers
|
|
229
|
+
// (e.g. mcp.sentry.dev) serve a minimal info page here instead.
|
|
230
|
+
// ============================================
|
|
231
|
+
const docsUrl = `${issuerUrl}/docs/mcp`;
|
|
232
|
+
app.get("/", (req, res) => {
|
|
233
|
+
// Browsers get HTML; curl / programmatic clients (Accept: */*) get JSON.
|
|
234
|
+
if (req.accepts(["json", "html"]) === "html") {
|
|
235
|
+
res.type("html").send(`<!doctype html>
|
|
236
|
+
<html lang="en">
|
|
237
|
+
<head>
|
|
238
|
+
<meta charset="utf-8">
|
|
239
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
240
|
+
<title>Dobby MCP Server</title>
|
|
241
|
+
<style>
|
|
242
|
+
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #0a0f1e; color: #e5e7eb; display: flex; min-height: 100vh; align-items: center; justify-content: center; }
|
|
243
|
+
main { max-width: 640px; padding: 48px 24px; }
|
|
244
|
+
h1 { font-size: 28px; margin: 0 0 8px; color: #fff; }
|
|
245
|
+
h1 .accent { color: #7d95f0; }
|
|
246
|
+
h2 { font-size: 13px; text-transform: uppercase; letter-spacing: .08em; color: #6b7280; margin: 28px 0 8px; }
|
|
247
|
+
p, li { color: #9ca3af; line-height: 1.6; font-size: 15px; }
|
|
248
|
+
ul { padding-left: 20px; margin: 0; }
|
|
249
|
+
li { margin: 6px 0; }
|
|
250
|
+
code { background: #161d33; border: 1px solid #26304f; border-radius: 6px; padding: 2px 8px; font-size: 13px; color: #aab8f5; }
|
|
251
|
+
pre { background: #161d33; border: 1px solid #26304f; border-radius: 8px; padding: 12px 16px; overflow-x: auto; font-size: 14px; color: #aab8f5; margin: 0; }
|
|
252
|
+
a { color: #7d95f0; }
|
|
253
|
+
strong { color: #d1d5db; }
|
|
254
|
+
</style>
|
|
255
|
+
</head>
|
|
256
|
+
<body>
|
|
257
|
+
<main>
|
|
258
|
+
<h1>Dobby <span class="accent">MCP</span> Server</h1>
|
|
259
|
+
<p>Remote Model Context Protocol server for the <a href="https://dobby-ai.com">Dobby AI platform</a> — manage tasks, approvals, agents, and compliance from any MCP client.</p>
|
|
260
|
+
<h2>Endpoint</h2>
|
|
261
|
+
<pre>${mcpPublicUrl}/mcp</pre>
|
|
262
|
+
<h2>Connect</h2>
|
|
263
|
+
<ul>
|
|
264
|
+
<li><strong>OAuth 2.1</strong> — add <code>${mcpPublicUrl}</code> as a remote connector in Claude Code, Cursor, or VS Code and log in via the browser.</li>
|
|
265
|
+
<li><strong>API key</strong> — send <code>Authorization: Bearer <key></code> with a Dobby tenant API key (<code>sk_live_*</code>) or gateway key (<code>gk_*</code>).</li>
|
|
266
|
+
</ul>
|
|
267
|
+
<h2>Links</h2>
|
|
268
|
+
<ul>
|
|
269
|
+
<li><a href="${docsUrl}">Documentation</a></li>
|
|
270
|
+
<li><a href="/health">Health</a></li>
|
|
271
|
+
</ul>
|
|
272
|
+
</main>
|
|
273
|
+
</body>
|
|
274
|
+
</html>`);
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
res.json({
|
|
278
|
+
name: "Dobby MCP Server",
|
|
279
|
+
version: "1.1.0",
|
|
280
|
+
transport: "streamable-http",
|
|
281
|
+
endpoint: `${mcpPublicUrl}/mcp`,
|
|
282
|
+
documentation: docsUrl,
|
|
283
|
+
health: `${mcpPublicUrl}/health`,
|
|
284
|
+
authentication: {
|
|
285
|
+
oauth: "OAuth 2.1 — add this server URL as a remote connector in your MCP client and log in via the browser",
|
|
286
|
+
bearer: "Authorization: Bearer <key> — a Dobby tenant API key (sk_live_*) or gateway key (gk_*)",
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
// ============================================
|
|
291
|
+
// Health check (no auth)
|
|
292
|
+
// ============================================
|
|
293
|
+
app.get("/health", (_req, res) => {
|
|
294
|
+
res.json({
|
|
295
|
+
status: "ok",
|
|
296
|
+
server: "dobby-mcp",
|
|
297
|
+
version: "1.1.0",
|
|
298
|
+
transport: "streamable-http",
|
|
299
|
+
activeSessions: sessions.size,
|
|
300
|
+
tokenCacheSize: tokenVerifier.cacheSize,
|
|
301
|
+
});
|
|
302
|
+
});
|
|
303
|
+
// ============================================
|
|
304
|
+
// MCP Streamable HTTP endpoint (Bearer auth required)
|
|
305
|
+
// ============================================
|
|
306
|
+
// resourceMetadataUrl → RFC 9728: clients discover the authorization server
|
|
307
|
+
// from the resource_metadata parameter in the WWW-Authenticate header on 401.
|
|
308
|
+
const bearerAuth = requireBearerAuth({
|
|
309
|
+
verifier: provider,
|
|
310
|
+
resourceMetadataUrl: `${mcpPublicUrl}/.well-known/oauth-protected-resource`,
|
|
311
|
+
});
|
|
312
|
+
// POST /mcp — JSON-RPC requests (initialize, tools/list, tools/call, etc.)
|
|
313
|
+
app.post("/mcp", bearerAuth, async (req, res) => {
|
|
314
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
315
|
+
let transport;
|
|
316
|
+
if (sessionId && sessions.has(sessionId)) {
|
|
317
|
+
// Existing session — must belong to the SAME principal that created it
|
|
318
|
+
// (M-12). 404 (not 403) so a different principal can't confirm the
|
|
319
|
+
// session even exists.
|
|
320
|
+
if (sessionPrincipals.get(sessionId) !== principalKey(req)) {
|
|
321
|
+
res.status(404).json({
|
|
322
|
+
jsonrpc: "2.0",
|
|
323
|
+
error: { code: -32000, message: "Session not found" },
|
|
324
|
+
id: null,
|
|
325
|
+
});
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
transport = sessions.get(sessionId);
|
|
329
|
+
// Reject in-flight JSON-RPC id reuse before it reaches the transport —
|
|
330
|
+
// the SDK would overwrite its id→stream mapping and cross-deliver
|
|
331
|
+
// another request's response (see findInflightIdCollision).
|
|
332
|
+
const dupId = findInflightIdCollision(transport, req.body);
|
|
333
|
+
if (dupId !== null) {
|
|
334
|
+
res.status(400).json({
|
|
335
|
+
jsonrpc: "2.0",
|
|
336
|
+
error: {
|
|
337
|
+
code: -32600,
|
|
338
|
+
message: `Request id ${JSON.stringify(dupId)} is already in flight on this session — reusing it would cross-deliver another request's response. Retry with a fresh JSON-RPC id.`,
|
|
339
|
+
},
|
|
340
|
+
id: dupId,
|
|
341
|
+
});
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
else if (!sessionId) {
|
|
346
|
+
// New session — create transport and connect to a fresh MCP server.
|
|
347
|
+
// The session MUST be registered via onsessioninitialized: the SDK only
|
|
348
|
+
// assigns transport.sessionId while handleRequest processes the
|
|
349
|
+
// initialize message, so checking transport.sessionId right after
|
|
350
|
+
// connect() always saw undefined — no session was ever stored and every
|
|
351
|
+
// follow-up request 404'd "Session not found" (caught live on prod,
|
|
352
|
+
// 2026-07-12).
|
|
353
|
+
const newTransport = new StreamableHTTPServerTransport({
|
|
354
|
+
sessionIdGenerator: () => randomUUID(),
|
|
355
|
+
onsessioninitialized: (newSessionId) => {
|
|
356
|
+
sessions.set(newSessionId, newTransport);
|
|
357
|
+
sessionPrincipals.set(newSessionId, principalKey(req));
|
|
358
|
+
log.info("mcp session initialized", {
|
|
359
|
+
sessionId: newSessionId,
|
|
360
|
+
...principalFields(req),
|
|
361
|
+
activeSessions: sessions.size,
|
|
362
|
+
});
|
|
363
|
+
},
|
|
364
|
+
});
|
|
365
|
+
transport = newTransport;
|
|
366
|
+
// Connect MCP server to this transport
|
|
367
|
+
const mcpServer = await createMcpServer();
|
|
368
|
+
await mcpServer.connect(transport);
|
|
369
|
+
// Clean up on close
|
|
370
|
+
transport.onclose = () => {
|
|
371
|
+
if (transport.sessionId) {
|
|
372
|
+
sessions.delete(transport.sessionId);
|
|
373
|
+
sessionPrincipals.delete(transport.sessionId);
|
|
374
|
+
log.info("mcp session closed", {
|
|
375
|
+
sessionId: transport.sessionId,
|
|
376
|
+
activeSessions: sessions.size,
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
// Invalid session ID
|
|
383
|
+
res.status(404).json({
|
|
384
|
+
jsonrpc: "2.0",
|
|
385
|
+
error: { code: -32000, message: "Session not found" },
|
|
386
|
+
id: null,
|
|
387
|
+
});
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
await transport.handleRequest(req, res, req.body);
|
|
391
|
+
});
|
|
392
|
+
// GET /mcp — SSE stream for server-to-client notifications
|
|
393
|
+
app.get("/mcp", bearerAuth, async (req, res) => {
|
|
394
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
395
|
+
// Session must exist AND belong to the requesting principal (M-12).
|
|
396
|
+
if (!sessionId ||
|
|
397
|
+
!sessions.has(sessionId) ||
|
|
398
|
+
sessionPrincipals.get(sessionId) !== principalKey(req)) {
|
|
399
|
+
res.status(404).json({
|
|
400
|
+
jsonrpc: "2.0",
|
|
401
|
+
error: { code: -32000, message: "Session not found" },
|
|
402
|
+
id: null,
|
|
403
|
+
});
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
const transport = sessions.get(sessionId);
|
|
407
|
+
await transport.handleRequest(req, res);
|
|
408
|
+
});
|
|
409
|
+
// DELETE /mcp — Session termination
|
|
410
|
+
app.delete("/mcp", bearerAuth, async (req, res) => {
|
|
411
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
412
|
+
// Only the owning principal may terminate the session (M-12).
|
|
413
|
+
if (!sessionId ||
|
|
414
|
+
!sessions.has(sessionId) ||
|
|
415
|
+
sessionPrincipals.get(sessionId) !== principalKey(req)) {
|
|
416
|
+
res.status(404).json({
|
|
417
|
+
jsonrpc: "2.0",
|
|
418
|
+
error: { code: -32000, message: "Session not found" },
|
|
419
|
+
id: null,
|
|
420
|
+
});
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
const transport = sessions.get(sessionId);
|
|
424
|
+
await transport.close();
|
|
425
|
+
sessions.delete(sessionId);
|
|
426
|
+
sessionPrincipals.delete(sessionId);
|
|
427
|
+
res.status(200).json({ ok: true });
|
|
428
|
+
});
|
|
429
|
+
// ============================================
|
|
430
|
+
// Start listening
|
|
431
|
+
// ============================================
|
|
432
|
+
return new Promise((resolve) => {
|
|
433
|
+
const server = app.listen(port, () => {
|
|
434
|
+
// Structured on stdout — the old console.error banner landed in Cloud
|
|
435
|
+
// Logging at severity ERROR (stderr default) and was the pod's ONLY
|
|
436
|
+
// lifetime output.
|
|
437
|
+
log.info(`Dobby MCP HTTP server listening on port ${port}`, {
|
|
438
|
+
port,
|
|
439
|
+
issuerUrl,
|
|
440
|
+
mcpPublicUrl,
|
|
441
|
+
healthEndpoint: `http://localhost:${port}/health`,
|
|
442
|
+
mcpEndpoint: `POST http://localhost:${port}/mcp`,
|
|
443
|
+
});
|
|
444
|
+
resolve({ app, tokenVerifier, server });
|
|
445
|
+
});
|
|
446
|
+
// Keep idle keep-alive sockets warm longer than typical upstream LB/proxy
|
|
447
|
+
// idle timeouts (~60s). Node's default keepAliveTimeout is 5s, which drops
|
|
448
|
+
// idle Streamable-HTTP MCP sessions and surfaces as "connection lost" on the
|
|
449
|
+
// client (where the same call then succeeds on retry). headersTimeout must
|
|
450
|
+
// stay above keepAliveTimeout.
|
|
451
|
+
server.keepAliveTimeout = 65000;
|
|
452
|
+
server.headersTimeout = 66000;
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
//# sourceMappingURL=http-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-server.js","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* Dobby MCP Server
|
|
3
|
+
* Dobby MCP Server — CLI entry point
|
|
4
4
|
*
|
|
5
5
|
* Model Context Protocol server for Dobby AI Platform.
|
|
6
6
|
* Enables access from Claude Desktop, Cursor, Windsurf, and other MCP clients.
|
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
* npx @dobbyai/mcp-external # STDIO mode (default)
|
|
10
10
|
* npx @dobbyai/mcp-external --transport http # HTTP mode
|
|
11
11
|
* npx @dobbyai/mcp-external --setup # Interactive setup
|
|
12
|
+
*
|
|
13
|
+
* The server factory (handler registration, tier enforcement) lives in
|
|
14
|
+
* server.ts — this file only parses the CLI and starts the transport.
|
|
15
|
+
* Importing THIS module runs main(); tests import server.ts instead.
|
|
12
16
|
*/
|
|
13
17
|
export {};
|
|
14
18
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;GAcG"}
|