@maadb/core 0.0.1 → 0.7.9
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/LICENSE +21 -0
- package/README.md +371 -3
- package/dist/architect.d.ts +2 -0
- package/dist/architect.d.ts.map +1 -0
- package/dist/architect.js +273 -0
- package/dist/architect.js.map +1 -0
- package/dist/auth/resolve.d.ts +36 -0
- package/dist/auth/resolve.d.ts.map +1 -0
- package/dist/auth/resolve.js +77 -0
- package/dist/auth/resolve.js.map +1 -0
- package/dist/auth/token-store.d.ts +82 -0
- package/dist/auth/token-store.d.ts.map +1 -0
- package/dist/auth/token-store.js +464 -0
- package/dist/auth/token-store.js.map +1 -0
- package/dist/auth/types.d.ts +75 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +15 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/backend/adapter.d.ts +57 -0
- package/dist/backend/adapter.d.ts.map +1 -0
- package/dist/backend/adapter.js +6 -0
- package/dist/backend/adapter.js.map +1 -0
- package/dist/backend/index.d.ts +3 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +2 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/sqlite/index.d.ts +63 -0
- package/dist/backend/sqlite/index.d.ts.map +1 -0
- package/dist/backend/sqlite/index.js +521 -0
- package/dist/backend/sqlite/index.js.map +1 -0
- package/dist/backend/sqlite/schema.d.ts +2 -0
- package/dist/backend/sqlite/schema.d.ts.map +1 -0
- package/dist/backend/sqlite/schema.js +88 -0
- package/dist/backend/sqlite/schema.js.map +1 -0
- package/dist/claude-md.d.ts +2 -0
- package/dist/claude-md.d.ts.map +1 -0
- package/dist/claude-md.js +97 -0
- package/dist/claude-md.js.map +1 -0
- package/dist/cli/commands/audit.d.ts +4 -0
- package/dist/cli/commands/audit.d.ts.map +1 -0
- package/dist/cli/commands/audit.js +39 -0
- package/dist/cli/commands/audit.js.map +1 -0
- package/dist/cli/commands/auth.d.ts +8 -0
- package/dist/cli/commands/auth.d.ts.map +1 -0
- package/dist/cli/commands/auth.js +242 -0
- package/dist/cli/commands/auth.js.map +1 -0
- package/dist/cli/commands/discover.d.ts +5 -0
- package/dist/cli/commands/discover.d.ts.map +1 -0
- package/dist/cli/commands/discover.js +48 -0
- package/dist/cli/commands/discover.js.map +1 -0
- package/dist/cli/commands/maintain.d.ts +6 -0
- package/dist/cli/commands/maintain.d.ts.map +1 -0
- package/dist/cli/commands/maintain.js +168 -0
- package/dist/cli/commands/maintain.js.map +1 -0
- package/dist/cli/commands/read.d.ts +7 -0
- package/dist/cli/commands/read.d.ts.map +1 -0
- package/dist/cli/commands/read.js +139 -0
- package/dist/cli/commands/read.js.map +1 -0
- package/dist/cli/commands/write.d.ts +4 -0
- package/dist/cli/commands/write.d.ts.map +1 -0
- package/dist/cli/commands/write.js +99 -0
- package/dist/cli/commands/write.js.map +1 -0
- package/dist/cli/helpers.d.ts +8 -0
- package/dist/cli/helpers.d.ts.map +1 -0
- package/dist/cli/helpers.js +17 -0
- package/dist/cli/helpers.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +296 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +7 -0
- package/dist/cli.js.map +1 -0
- package/dist/engine/audit.d.ts +15 -0
- package/dist/engine/audit.d.ts.map +1 -0
- package/dist/engine/audit.js +42 -0
- package/dist/engine/audit.js.map +1 -0
- package/dist/engine/composites.d.ts +6 -0
- package/dist/engine/composites.d.ts.map +1 -0
- package/dist/engine/composites.js +102 -0
- package/dist/engine/composites.js.map +1 -0
- package/dist/engine/context.d.ts +47 -0
- package/dist/engine/context.d.ts.map +1 -0
- package/dist/engine/context.js +55 -0
- package/dist/engine/context.js.map +1 -0
- package/dist/engine/docid-safe.d.ts +8 -0
- package/dist/engine/docid-safe.d.ts.map +1 -0
- package/dist/engine/docid-safe.js +0 -0
- package/dist/engine/docid-safe.js.map +1 -0
- package/dist/engine/helpers.d.ts +8 -0
- package/dist/engine/helpers.d.ts.map +1 -0
- package/dist/engine/helpers.js +102 -0
- package/dist/engine/helpers.js.map +1 -0
- package/dist/engine/index.d.ts +209 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +489 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/indexing.d.ts +14 -0
- package/dist/engine/indexing.d.ts.map +1 -0
- package/dist/engine/indexing.js +225 -0
- package/dist/engine/indexing.js.map +1 -0
- package/dist/engine/journal.d.ts +32 -0
- package/dist/engine/journal.d.ts.map +1 -0
- package/dist/engine/journal.js +111 -0
- package/dist/engine/journal.js.map +1 -0
- package/dist/engine/logger.d.ts +19 -0
- package/dist/engine/logger.d.ts.map +1 -0
- package/dist/engine/logger.js +40 -0
- package/dist/engine/logger.js.map +1 -0
- package/dist/engine/maintenance.d.ts +15 -0
- package/dist/engine/maintenance.d.ts.map +1 -0
- package/dist/engine/maintenance.js +87 -0
- package/dist/engine/maintenance.js.map +1 -0
- package/dist/engine/mutex.d.ts +24 -0
- package/dist/engine/mutex.d.ts.map +1 -0
- package/dist/engine/mutex.js +50 -0
- package/dist/engine/mutex.js.map +1 -0
- package/dist/engine/pathguard.d.ts +16 -0
- package/dist/engine/pathguard.d.ts.map +1 -0
- package/dist/engine/pathguard.js +41 -0
- package/dist/engine/pathguard.js.map +1 -0
- package/dist/engine/reads.d.ts +24 -0
- package/dist/engine/reads.d.ts.map +1 -0
- package/dist/engine/reads.js +701 -0
- package/dist/engine/reads.js.map +1 -0
- package/dist/engine/types.d.ts +350 -0
- package/dist/engine/types.d.ts.map +1 -0
- package/dist/engine/types.js +5 -0
- package/dist/engine/types.js.map +1 -0
- package/dist/engine/writes.d.ts +10 -0
- package/dist/engine/writes.d.ts.map +1 -0
- package/dist/engine/writes.js +606 -0
- package/dist/engine/writes.js.map +1 -0
- package/dist/engine.d.ts +3 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +6 -0
- package/dist/engine.js.map +1 -0
- package/dist/errors.d.ts +20 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +17 -0
- package/dist/errors.js.map +1 -0
- package/dist/extractor/fields.d.ts +3 -0
- package/dist/extractor/fields.d.ts.map +1 -0
- package/dist/extractor/fields.js +58 -0
- package/dist/extractor/fields.js.map +1 -0
- package/dist/extractor/index.d.ts +7 -0
- package/dist/extractor/index.d.ts.map +1 -0
- package/dist/extractor/index.js +22 -0
- package/dist/extractor/index.js.map +1 -0
- package/dist/extractor/normalizers.d.ts +22 -0
- package/dist/extractor/normalizers.d.ts.map +1 -0
- package/dist/extractor/normalizers.js +250 -0
- package/dist/extractor/normalizers.js.map +1 -0
- package/dist/extractor/objects.d.ts +3 -0
- package/dist/extractor/objects.d.ts.map +1 -0
- package/dist/extractor/objects.js +33 -0
- package/dist/extractor/objects.js.map +1 -0
- package/dist/extractor/relationships.d.ts +3 -0
- package/dist/extractor/relationships.d.ts.map +1 -0
- package/dist/extractor/relationships.js +58 -0
- package/dist/extractor/relationships.js.map +1 -0
- package/dist/git/commit.d.ts +63 -0
- package/dist/git/commit.d.ts.map +1 -0
- package/dist/git/commit.js +161 -0
- package/dist/git/commit.js.map +1 -0
- package/dist/git/diff.d.ts +4 -0
- package/dist/git/diff.d.ts.map +1 -0
- package/dist/git/diff.js +56 -0
- package/dist/git/diff.js.map +1 -0
- package/dist/git/index.d.ts +41 -0
- package/dist/git/index.d.ts.map +1 -0
- package/dist/git/index.js +86 -0
- package/dist/git/index.js.map +1 -0
- package/dist/git/log.d.ts +13 -0
- package/dist/git/log.d.ts.map +1 -0
- package/dist/git/log.js +116 -0
- package/dist/git/log.js.map +1 -0
- package/dist/git/snapshot.d.ts +4 -0
- package/dist/git/snapshot.d.ts.map +1 -0
- package/dist/git/snapshot.js +65 -0
- package/dist/git/snapshot.js.map +1 -0
- package/dist/instance/config.d.ts +19 -0
- package/dist/instance/config.d.ts.map +1 -0
- package/dist/instance/config.js +107 -0
- package/dist/instance/config.js.map +1 -0
- package/dist/instance/pool.d.ts +138 -0
- package/dist/instance/pool.d.ts.map +1 -0
- package/dist/instance/pool.js +335 -0
- package/dist/instance/pool.js.map +1 -0
- package/dist/instance/session.d.ts +140 -0
- package/dist/instance/session.d.ts.map +1 -0
- package/dist/instance/session.js +267 -0
- package/dist/instance/session.js.map +1 -0
- package/dist/logging.d.ts +108 -0
- package/dist/logging.d.ts.map +1 -0
- package/dist/logging.js +120 -0
- package/dist/logging.js.map +1 -0
- package/dist/maad-md.d.ts +11 -0
- package/dist/maad-md.d.ts.map +1 -0
- package/dist/maad-md.js +252 -0
- package/dist/maad-md.js.map +1 -0
- package/dist/mcp/bulk-cap.d.ts +10 -0
- package/dist/mcp/bulk-cap.d.ts.map +1 -0
- package/dist/mcp/bulk-cap.js +37 -0
- package/dist/mcp/bulk-cap.js.map +1 -0
- package/dist/mcp/config.d.ts +18 -0
- package/dist/mcp/config.d.ts.map +1 -0
- package/dist/mcp/config.js +20 -0
- package/dist/mcp/config.js.map +1 -0
- package/dist/mcp/ctx.d.ts +17 -0
- package/dist/mcp/ctx.d.ts.map +1 -0
- package/dist/mcp/ctx.js +7 -0
- package/dist/mcp/ctx.js.map +1 -0
- package/dist/mcp/guardrails.d.ts +21 -0
- package/dist/mcp/guardrails.d.ts.map +1 -0
- package/dist/mcp/guardrails.js +39 -0
- package/dist/mcp/guardrails.js.map +1 -0
- package/dist/mcp/idempotency.d.ts +69 -0
- package/dist/mcp/idempotency.d.ts.map +1 -0
- package/dist/mcp/idempotency.js +168 -0
- package/dist/mcp/idempotency.js.map +1 -0
- package/dist/mcp/instance-reload.d.ts +23 -0
- package/dist/mcp/instance-reload.d.ts.map +1 -0
- package/dist/mcp/instance-reload.js +126 -0
- package/dist/mcp/instance-reload.js.map +1 -0
- package/dist/mcp/kinds.d.ts +22 -0
- package/dist/mcp/kinds.d.ts.map +1 -0
- package/dist/mcp/kinds.js +110 -0
- package/dist/mcp/kinds.js.map +1 -0
- package/dist/mcp/lifecycle.d.ts +8 -0
- package/dist/mcp/lifecycle.d.ts.map +1 -0
- package/dist/mcp/lifecycle.js +65 -0
- package/dist/mcp/lifecycle.js.map +1 -0
- package/dist/mcp/notifications.d.ts +87 -0
- package/dist/mcp/notifications.d.ts.map +1 -0
- package/dist/mcp/notifications.js +154 -0
- package/dist/mcp/notifications.js.map +1 -0
- package/dist/mcp/query-depth.d.ts +28 -0
- package/dist/mcp/query-depth.d.ts.map +1 -0
- package/dist/mcp/query-depth.js +43 -0
- package/dist/mcp/query-depth.js.map +1 -0
- package/dist/mcp/rate-limit.d.ts +60 -0
- package/dist/mcp/rate-limit.d.ts.map +1 -0
- package/dist/mcp/rate-limit.js +203 -0
- package/dist/mcp/rate-limit.js.map +1 -0
- package/dist/mcp/reload-signal.d.ts +13 -0
- package/dist/mcp/reload-signal.d.ts.map +1 -0
- package/dist/mcp/reload-signal.js +68 -0
- package/dist/mcp/reload-signal.js.map +1 -0
- package/dist/mcp/response.d.ts +109 -0
- package/dist/mcp/response.d.ts.map +1 -0
- package/dist/mcp/response.js +132 -0
- package/dist/mcp/response.js.map +1 -0
- package/dist/mcp/roles.d.ts +7 -0
- package/dist/mcp/roles.d.ts.map +1 -0
- package/dist/mcp/roles.js +56 -0
- package/dist/mcp/roles.js.map +1 -0
- package/dist/mcp/server.d.ts +33 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +242 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/shutdown.d.ts +32 -0
- package/dist/mcp/shutdown.d.ts.map +1 -0
- package/dist/mcp/shutdown.js +130 -0
- package/dist/mcp/shutdown.js.map +1 -0
- package/dist/mcp/tools/audit.d.ts +4 -0
- package/dist/mcp/tools/audit.d.ts.map +1 -0
- package/dist/mcp/tools/audit.js +45 -0
- package/dist/mcp/tools/audit.js.map +1 -0
- package/dist/mcp/tools/auth.d.ts +4 -0
- package/dist/mcp/tools/auth.d.ts.map +1 -0
- package/dist/mcp/tools/auth.js +181 -0
- package/dist/mcp/tools/auth.js.map +1 -0
- package/dist/mcp/tools/discover.d.ts +4 -0
- package/dist/mcp/tools/discover.d.ts.map +1 -0
- package/dist/mcp/tools/discover.js +83 -0
- package/dist/mcp/tools/discover.js.map +1 -0
- package/dist/mcp/tools/instance.d.ts +15 -0
- package/dist/mcp/tools/instance.d.ts.map +1 -0
- package/dist/mcp/tools/instance.js +207 -0
- package/dist/mcp/tools/instance.js.map +1 -0
- package/dist/mcp/tools/maintain.d.ts +4 -0
- package/dist/mcp/tools/maintain.d.ts.map +1 -0
- package/dist/mcp/tools/maintain.js +118 -0
- package/dist/mcp/tools/maintain.js.map +1 -0
- package/dist/mcp/tools/read.d.ts +4 -0
- package/dist/mcp/tools/read.d.ts.map +1 -0
- package/dist/mcp/tools/read.js +260 -0
- package/dist/mcp/tools/read.js.map +1 -0
- package/dist/mcp/tools/write.d.ts +4 -0
- package/dist/mcp/tools/write.d.ts.map +1 -0
- package/dist/mcp/tools/write.js +342 -0
- package/dist/mcp/tools/write.js.map +1 -0
- package/dist/mcp/transport/auth.d.ts +41 -0
- package/dist/mcp/transport/auth.d.ts.map +1 -0
- package/dist/mcp/transport/auth.js +115 -0
- package/dist/mcp/transport/auth.js.map +1 -0
- package/dist/mcp/transport/http.d.ts +62 -0
- package/dist/mcp/transport/http.d.ts.map +1 -0
- package/dist/mcp/transport/http.js +357 -0
- package/dist/mcp/transport/http.js.map +1 -0
- package/dist/mcp/transport/pin.d.ts +15 -0
- package/dist/mcp/transport/pin.d.ts.map +1 -0
- package/dist/mcp/transport/pin.js +71 -0
- package/dist/mcp/transport/pin.js.map +1 -0
- package/dist/mcp/transport/telemetry.d.ts +79 -0
- package/dist/mcp/transport/telemetry.d.ts.map +1 -0
- package/dist/mcp/transport/telemetry.js +97 -0
- package/dist/mcp/transport/telemetry.js.map +1 -0
- package/dist/mcp/with-session.d.ts +26 -0
- package/dist/mcp/with-session.d.ts.map +1 -0
- package/dist/mcp/with-session.js +275 -0
- package/dist/mcp/with-session.js.map +1 -0
- package/dist/parser/annotations.d.ts +3 -0
- package/dist/parser/annotations.d.ts.map +1 -0
- package/dist/parser/annotations.js +41 -0
- package/dist/parser/annotations.js.map +1 -0
- package/dist/parser/blocks.d.ts +3 -0
- package/dist/parser/blocks.d.ts.map +1 -0
- package/dist/parser/blocks.js +99 -0
- package/dist/parser/blocks.js.map +1 -0
- package/dist/parser/frontmatter.d.ts +9 -0
- package/dist/parser/frontmatter.d.ts.map +1 -0
- package/dist/parser/frontmatter.js +33 -0
- package/dist/parser/frontmatter.js.map +1 -0
- package/dist/parser/index.d.ts +11 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +54 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/matter.d.ts +3 -0
- package/dist/parser/matter.d.ts.map +1 -0
- package/dist/parser/matter.js +32 -0
- package/dist/parser/matter.js.map +1 -0
- package/dist/parser/tags.d.ts +3 -0
- package/dist/parser/tags.d.ts.map +1 -0
- package/dist/parser/tags.js +32 -0
- package/dist/parser/tags.js.map +1 -0
- package/dist/parser/verbatim.d.ts +4 -0
- package/dist/parser/verbatim.d.ts.map +1 -0
- package/dist/parser/verbatim.js +121 -0
- package/dist/parser/verbatim.js.map +1 -0
- package/dist/parser/yaml-profile.d.ts +4 -0
- package/dist/parser/yaml-profile.d.ts.map +1 -0
- package/dist/parser/yaml-profile.js +73 -0
- package/dist/parser/yaml-profile.js.map +1 -0
- package/dist/registry/index.d.ts +2 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +2 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/loader.d.ts +4 -0
- package/dist/registry/loader.d.ts.map +1 -0
- package/dist/registry/loader.js +147 -0
- package/dist/registry/loader.js.map +1 -0
- package/dist/registry/types.d.ts +2 -0
- package/dist/registry/types.d.ts.map +1 -0
- package/dist/registry/types.js +5 -0
- package/dist/registry/types.js.map +1 -0
- package/dist/scanner.d.ts +57 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +223 -0
- package/dist/scanner.js.map +1 -0
- package/dist/schema/index.d.ts +3 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +3 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/loader.d.ts +4 -0
- package/dist/schema/loader.d.ts.map +1 -0
- package/dist/schema/loader.js +303 -0
- package/dist/schema/loader.js.map +1 -0
- package/dist/schema/precision.d.ts +6 -0
- package/dist/schema/precision.d.ts.map +1 -0
- package/dist/schema/precision.js +59 -0
- package/dist/schema/precision.js.map +1 -0
- package/dist/schema/validator.d.ts +21 -0
- package/dist/schema/validator.d.ts.map +1 -0
- package/dist/schema/validator.js +200 -0
- package/dist/schema/validator.js.map +1 -0
- package/dist/schema-md.d.ts +8 -0
- package/dist/schema-md.d.ts.map +1 -0
- package/dist/schema-md.js +98 -0
- package/dist/schema-md.js.map +1 -0
- package/dist/skill-files.d.ts +3 -0
- package/dist/skill-files.d.ts.map +1 -0
- package/dist/skill-files.js +362 -0
- package/dist/skill-files.js.map +1 -0
- package/dist/skills-scaffold.d.ts +10 -0
- package/dist/skills-scaffold.d.ts.map +1 -0
- package/dist/skills-scaffold.js +52 -0
- package/dist/skills-scaffold.js.map +1 -0
- package/dist/types.d.ts +309 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +111 -0
- package/dist/types.js.map +1 -0
- package/dist/writer/index.d.ts +7 -0
- package/dist/writer/index.d.ts.map +1 -0
- package/dist/writer/index.js +32 -0
- package/dist/writer/index.js.map +1 -0
- package/dist/writer/serializer.d.ts +4 -0
- package/dist/writer/serializer.d.ts.map +1 -0
- package/dist/writer/serializer.js +103 -0
- package/dist/writer/serializer.js.map +1 -0
- package/dist/writer/template.d.ts +3 -0
- package/dist/writer/template.d.ts.map +1 -0
- package/dist/writer/template.js +27 -0
- package/dist/writer/template.js.map +1 -0
- package/package.json +59 -7
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { type Server as HttpServer } from 'node:http';
|
|
2
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
+
import type { TokenStore } from '../../auth/token-store.js';
|
|
4
|
+
import type { SessionRegistry } from '../../instance/session.js';
|
|
5
|
+
import type { InstanceConfig } from '../../instance/config.js';
|
|
6
|
+
export interface HttpTransportOptions {
|
|
7
|
+
host: string;
|
|
8
|
+
port: number;
|
|
9
|
+
/**
|
|
10
|
+
* 0.7.5 (fup-2026-148) — When set, the server binds to this Unix domain
|
|
11
|
+
* socket path instead of host:port. Same MCP protocol over a different
|
|
12
|
+
* socket, so all auth/session/SSE plumbing is reused unchanged. Intended
|
|
13
|
+
* deployment: trusted-app-process colocated with the engine, socket file
|
|
14
|
+
* mode gates access at the filesystem layer (defense-in-depth on top of
|
|
15
|
+
* the bearer auth that's still required). `host`/`port`/`trustProxy` are
|
|
16
|
+
* ignored when this is set.
|
|
17
|
+
*/
|
|
18
|
+
socketPath?: string | undefined;
|
|
19
|
+
/** Octal file mode applied to the socket after bind. Default 0o660. */
|
|
20
|
+
socketMode?: number | undefined;
|
|
21
|
+
maxBodyBytes: number;
|
|
22
|
+
headersTimeoutMs: number;
|
|
23
|
+
requestTimeoutMs: number;
|
|
24
|
+
keepAliveTimeoutMs: number;
|
|
25
|
+
trustProxy: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Per-session idle threshold. A session with no inbound client request for
|
|
28
|
+
* this many milliseconds is evicted by the idle sweeper. Defaults to 30 min.
|
|
29
|
+
* Outbound SSE pushes from the server do NOT count as activity — server
|
|
30
|
+
* activity != client activity.
|
|
31
|
+
*/
|
|
32
|
+
idleMs: number;
|
|
33
|
+
/**
|
|
34
|
+
* 0.7.0 — Token registry for scoped auth. Production HTTP mode requires a
|
|
35
|
+
* non-null store with ≥1 active token (server.ts enforces via
|
|
36
|
+
* checkHttpAuthAtBoot before this transport is even instantiated). Tests
|
|
37
|
+
* and dev convenience may pass undefined to bypass auth entirely; when
|
|
38
|
+
* undefined, every request is accepted without a bearer check.
|
|
39
|
+
*/
|
|
40
|
+
tokens?: TokenStore | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Session registry for protocol-level state. HTTP transport fires destroy()
|
|
43
|
+
* on its close, which fans out to whatever close handlers the server
|
|
44
|
+
* wired in (rate-limit dispose, audit log, etc.).
|
|
45
|
+
*/
|
|
46
|
+
sessions: SessionRegistry;
|
|
47
|
+
/**
|
|
48
|
+
* Instance config — needed for X-Maad-Pin-Project header validation.
|
|
49
|
+
* The pin validator checks values against instance.projects[].name and
|
|
50
|
+
* skips validation entirely for synthetic (legacy single-project) mode.
|
|
51
|
+
*/
|
|
52
|
+
instance: InstanceConfig;
|
|
53
|
+
/** Factory called once per new session to produce a fresh McpServer with tools registered. */
|
|
54
|
+
serverFactory: () => McpServer;
|
|
55
|
+
}
|
|
56
|
+
export interface HttpTransportHandle {
|
|
57
|
+
httpServer: HttpServer;
|
|
58
|
+
close: () => Promise<void>;
|
|
59
|
+
activeSessionCount: () => number;
|
|
60
|
+
}
|
|
61
|
+
export declare function startHttpTransport(opts: HttpTransportOptions): Promise<HttpTransportHandle>;
|
|
62
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/mcp/transport/http.ts"],"names":[],"mappings":"AAUA,OAAO,EAAoC,KAAK,MAAM,IAAI,UAAU,EAA6C,MAAM,WAAW,CAAC;AAInI,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAG5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAK/D,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAChC;;;;OAIG;IACH,QAAQ,EAAE,eAAe,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,EAAE,cAAc,CAAC;IACzB,8FAA8F;IAC9F,aAAa,EAAE,MAAM,SAAS,CAAC;CAChC;AASD,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,kBAAkB,EAAE,MAAM,MAAM,CAAC;CAClC;AA8BD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAoTjG"}
|
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// HTTP/SSE transport for MCP (0.5.0 R1 — transport scaffold, no auth yet)
|
|
3
|
+
//
|
|
4
|
+
// Creates a node:http server, routes /mcp POST/GET/DELETE through the SDK's
|
|
5
|
+
// StreamableHTTPServerTransport. One transport instance per session, stored
|
|
6
|
+
// in a session-keyed map. node:http timeouts are set explicitly (slowloris +
|
|
7
|
+
// hung-request defense). Response hardening headers injected on every response.
|
|
8
|
+
// Auth layers in R2, session registry fan-out in R3.
|
|
9
|
+
// ============================================================================
|
|
10
|
+
import { createServer as createHttpServer } from 'node:http';
|
|
11
|
+
import { existsSync, unlinkSync, chmodSync } from 'node:fs';
|
|
12
|
+
import { randomBytes } from 'node:crypto';
|
|
13
|
+
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
14
|
+
import { logger } from '../../engine/logger.js';
|
|
15
|
+
import { logAuthFailure, logPinRejected } from '../../logging.js';
|
|
16
|
+
import { resolveToken } from './auth.js';
|
|
17
|
+
import { validatePinHeader } from './pin.js';
|
|
18
|
+
import { recordIdleSweep, recordSessionOpen } from './telemetry.js';
|
|
19
|
+
import { isShuttingDown } from '../shutdown.js';
|
|
20
|
+
import { registerNotifier, unregisterNotifier } from '../notifications.js';
|
|
21
|
+
function remoteAddrFor(req, trustProxy) {
|
|
22
|
+
if (trustProxy) {
|
|
23
|
+
const xff = req.headers['x-forwarded-for'];
|
|
24
|
+
if (typeof xff === 'string' && xff.length > 0)
|
|
25
|
+
return xff.split(',')[0].trim();
|
|
26
|
+
if (Array.isArray(xff) && xff.length > 0)
|
|
27
|
+
return xff[0].trim();
|
|
28
|
+
}
|
|
29
|
+
return req.socket.remoteAddress ?? 'unknown';
|
|
30
|
+
}
|
|
31
|
+
function writeJsonError(res, status, code, message) {
|
|
32
|
+
if (!res.headersSent) {
|
|
33
|
+
res.statusCode = status;
|
|
34
|
+
res.setHeader('Content-Type', 'application/json');
|
|
35
|
+
res.setHeader('Cache-Control', 'no-store');
|
|
36
|
+
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
37
|
+
}
|
|
38
|
+
res.end(JSON.stringify({ ok: false, errors: [{ code, message }] }));
|
|
39
|
+
}
|
|
40
|
+
function applyResponseHardening(res, kind) {
|
|
41
|
+
// SDK emits Cache-Control: no-cache (or no-cache, no-transform) on SSE and some JSON paths.
|
|
42
|
+
// We layer in no-store on JSON responses and nosniff on all responses.
|
|
43
|
+
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
44
|
+
if (kind === 'json') {
|
|
45
|
+
res.setHeader('Cache-Control', 'no-store');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export async function startHttpTransport(opts) {
|
|
49
|
+
const entries = new Map();
|
|
50
|
+
// Fire `pin_ignored_legacy` at most once per process so operators see the
|
|
51
|
+
// signal without getting log spam when a legacy deployment is being probed.
|
|
52
|
+
let legacyPinWarned = false;
|
|
53
|
+
const httpServer = createHttpServer(async (req, res) => {
|
|
54
|
+
try {
|
|
55
|
+
// Body-size pre-check via Content-Length. Streaming bypass is possible but
|
|
56
|
+
// stretches the threat model — clients that chunk around this cap are
|
|
57
|
+
// already hostile, and 0.5.0's rate limiter catches sustained abuse.
|
|
58
|
+
const contentLength = Number.parseInt(req.headers['content-length'] ?? '0', 10);
|
|
59
|
+
if (Number.isFinite(contentLength) && contentLength > opts.maxBodyBytes) {
|
|
60
|
+
writeJsonError(res, 413, 'PAYLOAD_TOO_LARGE', `Request body exceeds ${opts.maxBodyBytes} bytes`);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const url = new URL(req.url ?? '/', `http://${opts.host}`);
|
|
64
|
+
// Liveness probe — unauthenticated, minimal, no state leak. Routed
|
|
65
|
+
// BEFORE auth so container runtimes and orchestrators can probe the
|
|
66
|
+
// process without holding a copy of the bearer token. Returns 503
|
|
67
|
+
// SHUTTING_DOWN during drain so an orchestrator's failing probe during
|
|
68
|
+
// deploy signals "process is exiting" rather than "process is broken".
|
|
69
|
+
if (url.pathname === '/healthz' && req.method === 'GET') {
|
|
70
|
+
const draining = isShuttingDown();
|
|
71
|
+
res.statusCode = draining ? 503 : 200;
|
|
72
|
+
res.setHeader('Content-Type', 'application/json');
|
|
73
|
+
res.setHeader('Cache-Control', 'no-store');
|
|
74
|
+
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
75
|
+
if (draining) {
|
|
76
|
+
res.end(JSON.stringify({ ok: false, errors: [{ code: 'SHUTTING_DOWN', message: 'server is draining' }] }));
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
res.end(JSON.stringify({ ok: true }));
|
|
80
|
+
}
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (url.pathname !== '/mcp') {
|
|
84
|
+
writeJsonError(res, 404, 'NOT_FOUND', 'Unknown path');
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
// Middleware step 1: auth. Runs BEFORE session resolution so an
|
|
88
|
+
// unauthenticated caller can never discover whether a session id
|
|
89
|
+
// exists (404 SESSION_NOT_FOUND is reserved for authenticated callers).
|
|
90
|
+
// 0.7.0 — resolveToken replaces shared-secret validateBearer. Every
|
|
91
|
+
// failure reason maps to a plain 401; distinct codes surface only in
|
|
92
|
+
// the ops log. Success returns the TokenRecord, which we capture for
|
|
93
|
+
// session-creation binding below. If tokens is undefined (test/dev
|
|
94
|
+
// bypass), we skip auth entirely — production boot enforces presence.
|
|
95
|
+
let authedToken = null;
|
|
96
|
+
if (opts.tokens !== undefined) {
|
|
97
|
+
const authOutcome = resolveToken(req, opts.tokens);
|
|
98
|
+
if (!authOutcome.ok) {
|
|
99
|
+
logAuthFailure({
|
|
100
|
+
remote_addr: remoteAddrFor(req, opts.trustProxy),
|
|
101
|
+
reason: authOutcome.reason === 'missing' ? 'missing' : 'invalid',
|
|
102
|
+
});
|
|
103
|
+
writeJsonError(res, 401, 'UNAUTHORIZED', 'missing or invalid bearer token');
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
authedToken = authOutcome.record;
|
|
107
|
+
}
|
|
108
|
+
// Middleware step 2: X-Maad-Pin-Project (0.6.8) — trusted-gateway
|
|
109
|
+
// session pinning for multi-tenant hosted deployments. Runs AFTER auth
|
|
110
|
+
// (rejections need an authenticated context) and BEFORE session
|
|
111
|
+
// resolution (pin is a session-creation property). Silent skip in
|
|
112
|
+
// synthetic/legacy single-project mode per spec §Interaction with
|
|
113
|
+
// existing features.
|
|
114
|
+
let pinnedProjectName;
|
|
115
|
+
if (opts.instance.source === 'synthetic') {
|
|
116
|
+
if (req.headers['x-maad-pin-project'] !== undefined && !legacyPinWarned) {
|
|
117
|
+
logger.info('mcp', 'http', 'X-Maad-Pin-Project received on synthetic single-project instance; ignoring (pin_ignored_legacy)');
|
|
118
|
+
legacyPinWarned = true;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
const pin = validatePinHeader(req, opts.instance);
|
|
123
|
+
if (pin.status === 'rejected') {
|
|
124
|
+
const pinValueRaw = req.headers['x-maad-pin-project'];
|
|
125
|
+
const pinValue = typeof pinValueRaw === 'string' ? pinValueRaw : null;
|
|
126
|
+
logPinRejected({
|
|
127
|
+
remote_addr: remoteAddrFor(req, opts.trustProxy),
|
|
128
|
+
code: pin.code,
|
|
129
|
+
project: pinValue,
|
|
130
|
+
});
|
|
131
|
+
writeJsonError(res, 400, pin.code, pin.message);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (pin.status === 'valid') {
|
|
135
|
+
pinnedProjectName = pin.projectName;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const sessionIdHeader = req.headers['mcp-session-id'];
|
|
139
|
+
const sessionId = typeof sessionIdHeader === 'string' ? sessionIdHeader : undefined;
|
|
140
|
+
// Existing session — route to its transport
|
|
141
|
+
if (sessionId && entries.has(sessionId)) {
|
|
142
|
+
const entry = entries.get(sessionId);
|
|
143
|
+
// Inbound client request — bump transport-level lastActivityAt. This
|
|
144
|
+
// is the clock the idle sweeper uses. We intentionally do NOT update
|
|
145
|
+
// it on outbound SSE pushes; those are server activity, not client.
|
|
146
|
+
entry.lastActivityAt = Date.now();
|
|
147
|
+
applyResponseHardening(res, req.method === 'GET' ? 'sse' : 'json');
|
|
148
|
+
await entry.transport.handleRequest(req, res);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
// Unknown session ID on non-initialize request — 404
|
|
152
|
+
if (sessionId) {
|
|
153
|
+
writeJsonError(res, 404, 'SESSION_NOT_FOUND', 'Unknown session');
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
// No session ID: must be POST for initialize
|
|
157
|
+
if (req.method !== 'POST') {
|
|
158
|
+
writeJsonError(res, 400, 'BAD_REQUEST', 'Mcp-Session-Id header required');
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
// New session: transport delegates ID generation to us (128-bit CSPRNG)
|
|
162
|
+
const remoteAddr = remoteAddrFor(req, opts.trustProxy);
|
|
163
|
+
const pinForClosure = pinnedProjectName;
|
|
164
|
+
const tokenForClosure = authedToken;
|
|
165
|
+
// Forward-reference to the McpServer built below. Captured by the
|
|
166
|
+
// onsessioninitialized closure so 0.6.11 live-notification registration
|
|
167
|
+
// can fire `sendResourceUpdated` through the right per-session server.
|
|
168
|
+
let mcpServerRef = null;
|
|
169
|
+
const transport = new StreamableHTTPServerTransport({
|
|
170
|
+
sessionIdGenerator: () => randomBytes(16).toString('base64url'),
|
|
171
|
+
onsessioninitialized: (sid) => {
|
|
172
|
+
const now = Date.now();
|
|
173
|
+
entries.set(sid, { transport, createdAt: now, lastActivityAt: now, remoteAddr });
|
|
174
|
+
// Register protocol-level state so registry.destroy(sid) has
|
|
175
|
+
// something to destroy — otherwise the fan-out chain (rate-limit
|
|
176
|
+
// dispose, audit handlers) never runs. withSession may also
|
|
177
|
+
// create(sid) lazily on first tool call; create() is idempotent.
|
|
178
|
+
const state = opts.sessions.create(sid);
|
|
179
|
+
// 0.7.0 — Attach the authed token BEFORE any bindSingle/bindMulti
|
|
180
|
+
// call so the three-cap effective-role composition sees it. Subsequent
|
|
181
|
+
// requests on this session re-validate their bearer at the middleware
|
|
182
|
+
// layer; the state.token is a snapshot at initialize time for
|
|
183
|
+
// consistent effective-role resolution.
|
|
184
|
+
if (tokenForClosure !== null)
|
|
185
|
+
state.token = tokenForClosure;
|
|
186
|
+
// Gateway pin (0.6.8): if the pin header validated, bind the session
|
|
187
|
+
// synchronously before any tool call can reach a handler. Rebind
|
|
188
|
+
// protection lives in SessionRegistry.bindSingle (SESSION_PINNED
|
|
189
|
+
// error on subsequent maad_use_project calls).
|
|
190
|
+
if (pinForClosure !== undefined) {
|
|
191
|
+
const pinBind = opts.sessions.bindSingle(sid, pinForClosure, { source: 'gateway_pin' });
|
|
192
|
+
if (!pinBind.ok) {
|
|
193
|
+
// Should be impossible — we validated the project exists before
|
|
194
|
+
// session creation. Log loudly if it ever fires.
|
|
195
|
+
const msg = pinBind.errors.map(e => `${e.code}: ${e.message}`).join('; ');
|
|
196
|
+
logger.error('mcp', 'http', `gateway pin bind failed for session ${sid}: ${msg}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// 0.6.11 — register per-session notifier keyed on this sid. Fires
|
|
200
|
+
// `notifications/resources/updated` with a synthetic maad://records/
|
|
201
|
+
// URI plus extra params carrying the full ChangeEvent shape.
|
|
202
|
+
// MCP clients that only read `uri` still get a valid notification;
|
|
203
|
+
// clients that read params get the typed event.
|
|
204
|
+
if (mcpServerRef) {
|
|
205
|
+
const capturedServer = mcpServerRef;
|
|
206
|
+
registerNotifier(sid, async (event) => {
|
|
207
|
+
await capturedServer.server.sendResourceUpdated({
|
|
208
|
+
uri: `maad://records/${event.docId}`,
|
|
209
|
+
...{ action: event.action, docId: event.docId, docType: event.docType, project: event.project, updatedAt: event.updatedAt },
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
const ua = req.headers['user-agent'];
|
|
214
|
+
const openFields = {
|
|
215
|
+
session_id: sid,
|
|
216
|
+
remote_addr: remoteAddr,
|
|
217
|
+
user_agent: typeof ua === 'string' ? ua : null,
|
|
218
|
+
transport: 'http',
|
|
219
|
+
};
|
|
220
|
+
if (pinForClosure !== undefined)
|
|
221
|
+
openFields.binding_source = 'gateway_pin';
|
|
222
|
+
recordSessionOpen(openFields);
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
transport.onclose = () => {
|
|
226
|
+
const sid = transport.sessionId;
|
|
227
|
+
if (sid && entries.has(sid)) {
|
|
228
|
+
entries.delete(sid);
|
|
229
|
+
// 0.6.11 — drop the notifier before destroy so it can't race with
|
|
230
|
+
// in-flight writes. destroy() itself fires close handlers but the
|
|
231
|
+
// notifier lives outside that registry.
|
|
232
|
+
unregisterNotifier(sid);
|
|
233
|
+
// Fan out to the registry — this fires close handlers the server
|
|
234
|
+
// wired in (rate-limit dispose, session_close audit, etc.).
|
|
235
|
+
opts.sessions.destroy(sid, 'transport');
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
const mcpServer = opts.serverFactory();
|
|
239
|
+
mcpServerRef = mcpServer;
|
|
240
|
+
// SDK's StreamableHTTPServerTransport declares onclose/onerror/onmessage
|
|
241
|
+
// as optional, but Server.connect's Transport interface declares them
|
|
242
|
+
// non-optional under exactOptionalPropertyTypes. Widening cast is the
|
|
243
|
+
// least invasive workaround; the runtime shape is identical.
|
|
244
|
+
await mcpServer.connect(transport);
|
|
245
|
+
applyResponseHardening(res, 'json');
|
|
246
|
+
await transport.handleRequest(req, res);
|
|
247
|
+
}
|
|
248
|
+
catch (err) {
|
|
249
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
250
|
+
logger.error('mcp', 'http', `request error: ${msg}`);
|
|
251
|
+
if (!res.headersSent) {
|
|
252
|
+
writeJsonError(res, 500, 'INTERNAL', 'Internal server error');
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
try {
|
|
256
|
+
res.end();
|
|
257
|
+
}
|
|
258
|
+
catch { /* best-effort */ }
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
httpServer.headersTimeout = opts.headersTimeoutMs;
|
|
263
|
+
httpServer.requestTimeout = opts.requestTimeoutMs;
|
|
264
|
+
httpServer.keepAliveTimeout = opts.keepAliveTimeoutMs;
|
|
265
|
+
// 0.7.5 (fup-2026-148) — bind to Unix socket when configured; otherwise TCP.
|
|
266
|
+
// Stale-socket cleanup before listen() handles the common case where a
|
|
267
|
+
// crashed prior process left the socket file behind. Socket mode (default
|
|
268
|
+
// 0o660) chmod-applied after listen so transient world-readable race is
|
|
269
|
+
// bounded by listen-then-chmod (well under any real attacker window for
|
|
270
|
+
// the trusted-host deploy this targets).
|
|
271
|
+
if (opts.socketPath) {
|
|
272
|
+
try {
|
|
273
|
+
if (existsSync(opts.socketPath))
|
|
274
|
+
unlinkSync(opts.socketPath);
|
|
275
|
+
}
|
|
276
|
+
catch (e) {
|
|
277
|
+
throw new Error(`failed to remove stale Unix socket at ${opts.socketPath}: ${e instanceof Error ? e.message : String(e)}`);
|
|
278
|
+
}
|
|
279
|
+
await new Promise((resolve, reject) => {
|
|
280
|
+
httpServer.once('error', reject);
|
|
281
|
+
httpServer.listen(opts.socketPath, () => {
|
|
282
|
+
httpServer.off('error', reject);
|
|
283
|
+
const mode = opts.socketMode ?? 0o660;
|
|
284
|
+
try {
|
|
285
|
+
chmodSync(opts.socketPath, mode);
|
|
286
|
+
}
|
|
287
|
+
catch (e) {
|
|
288
|
+
logger.bestEffort('mcp', 'http.unix.chmod', `chmod ${mode.toString(8)} on ${opts.socketPath} failed`, { error: e instanceof Error ? e.message : String(e) });
|
|
289
|
+
}
|
|
290
|
+
resolve();
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
logger.info('mcp', 'http', `Server started on unix:${opts.socketPath}/mcp (mode ${(opts.socketMode ?? 0o660).toString(8)})`);
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
await new Promise((resolve, reject) => {
|
|
297
|
+
httpServer.once('error', reject);
|
|
298
|
+
httpServer.listen(opts.port, opts.host, () => {
|
|
299
|
+
httpServer.off('error', reject);
|
|
300
|
+
resolve();
|
|
301
|
+
});
|
|
302
|
+
});
|
|
303
|
+
logger.info('mcp', 'http', `Server started on http://${opts.host}:${opts.port}/mcp`);
|
|
304
|
+
}
|
|
305
|
+
// Idle sweeper — walks the entries map every ~60s and evicts transports
|
|
306
|
+
// whose lastActivityAt is past the idle threshold. Unref'd so the interval
|
|
307
|
+
// alone doesn't keep the event loop alive; tick cadence is capped at
|
|
308
|
+
// idleMs so tiny idle thresholds don't produce microsecond spins in tests.
|
|
309
|
+
const sweepIntervalMs = Math.max(1_000, Math.min(60_000, Math.floor(opts.idleMs / 2) || 60_000));
|
|
310
|
+
const idleSweeper = setInterval(() => {
|
|
311
|
+
const now = Date.now();
|
|
312
|
+
const threshold = now - opts.idleMs;
|
|
313
|
+
let swept = 0;
|
|
314
|
+
for (const [sid, entry] of entries) {
|
|
315
|
+
if (entry.lastActivityAt < threshold) {
|
|
316
|
+
// Mark the registry first so the fan-out reason reflects WHY it
|
|
317
|
+
// closed. The transport.onclose below would otherwise fire with
|
|
318
|
+
// reason=transport. Destroy is idempotent so calling it twice is safe.
|
|
319
|
+
opts.sessions.destroy(sid, 'idle');
|
|
320
|
+
entries.delete(sid);
|
|
321
|
+
// Close the SSE transport — frees sockets and triggers SDK cleanup.
|
|
322
|
+
void entry.transport.close().catch(() => { });
|
|
323
|
+
swept += 1;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
if (swept > 0) {
|
|
327
|
+
recordIdleSweep({ swept, remaining: entries.size });
|
|
328
|
+
}
|
|
329
|
+
}, sweepIntervalMs);
|
|
330
|
+
idleSweeper.unref?.();
|
|
331
|
+
return {
|
|
332
|
+
httpServer,
|
|
333
|
+
activeSessionCount: () => entries.size,
|
|
334
|
+
close: async () => {
|
|
335
|
+
clearInterval(idleSweeper);
|
|
336
|
+
await new Promise((resolve) => httpServer.close(() => resolve()));
|
|
337
|
+
for (const [sid, entry] of entries) {
|
|
338
|
+
try {
|
|
339
|
+
await entry.transport.close();
|
|
340
|
+
}
|
|
341
|
+
catch { /* best-effort */ }
|
|
342
|
+
opts.sessions.destroy(sid, 'shutdown');
|
|
343
|
+
}
|
|
344
|
+
entries.clear();
|
|
345
|
+
// 0.7.5 — UDS cleanup. Best-effort: if a fast SIGKILL beat us here,
|
|
346
|
+
// the next startup's stale-socket unlink will catch it.
|
|
347
|
+
if (opts.socketPath) {
|
|
348
|
+
try {
|
|
349
|
+
if (existsSync(opts.socketPath))
|
|
350
|
+
unlinkSync(opts.socketPath);
|
|
351
|
+
}
|
|
352
|
+
catch { /* best-effort */ }
|
|
353
|
+
}
|
|
354
|
+
},
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/mcp/transport/http.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { IncomingMessage } from 'node:http';
|
|
2
|
+
import type { InstanceConfig } from '../../instance/config.js';
|
|
3
|
+
export type PinFailureCode = 'PIN_PROJECT_INVALID' | 'PIN_PROJECT_NOT_FOUND' | 'PIN_ON_EXISTING_SESSION';
|
|
4
|
+
export type PinResult = {
|
|
5
|
+
status: 'absent';
|
|
6
|
+
} | {
|
|
7
|
+
status: 'valid';
|
|
8
|
+
projectName: string;
|
|
9
|
+
} | {
|
|
10
|
+
status: 'rejected';
|
|
11
|
+
code: PinFailureCode;
|
|
12
|
+
message: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function validatePinHeader(req: IncomingMessage, instance: InstanceConfig): PinResult;
|
|
15
|
+
//# sourceMappingURL=pin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pin.d.ts","sourceRoot":"","sources":["../../../src/mcp/transport/pin.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,MAAM,MAAM,cAAc,GACtB,qBAAqB,GACrB,uBAAuB,GACvB,yBAAyB,CAAC;AAE9B,MAAM,MAAM,SAAS,GACjB;IAAE,MAAM,EAAE,QAAQ,CAAA;CAAE,GACpB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAOlE,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,cAAc,GAAG,SAAS,CAgB3F"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// X-Maad-Pin-Project header validation for HTTP transport (0.6.8)
|
|
3
|
+
//
|
|
4
|
+
// Gateway-enforced session pinning: a trusted upstream gateway sets
|
|
5
|
+
// X-Maad-Pin-Project: <project-name> on the MCP initialize request, and the
|
|
6
|
+
// engine pins the session to that project irrevocably. Server-side rebind
|
|
7
|
+
// rejection lives in SessionRegistry.bindSingle/bindMulti (emits SESSION_PINNED
|
|
8
|
+
// when bindingSource === 'gateway_pin').
|
|
9
|
+
//
|
|
10
|
+
// Validation rules (applied at every HTTP request BEFORE session resolution):
|
|
11
|
+
// - Header absent → status 'absent', proceed unpinned
|
|
12
|
+
// - Multiple values → PIN_PROJECT_INVALID (spec §Interface #3)
|
|
13
|
+
// - Empty or regex-failing value → PIN_PROJECT_INVALID
|
|
14
|
+
// - Header present AND Mcp-Session-Id present → PIN_ON_EXISTING_SESSION
|
|
15
|
+
// (pin is a session-creation property; not valid on existing sessions)
|
|
16
|
+
// - Value not in instance.projects[].name → PIN_PROJECT_NOT_FOUND
|
|
17
|
+
//
|
|
18
|
+
// This module is PURE — no side effects, no logging. Caller (http.ts) handles
|
|
19
|
+
// HTTP response + logging so remote_addr and trust-proxy policy stay in the
|
|
20
|
+
// transport layer.
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// Same regex as instance.yaml project names (src/instance/config.ts).
|
|
23
|
+
// Kept local to avoid importing internals; drift-risk is minimal — the spec
|
|
24
|
+
// locks this regex as the project-name contract.
|
|
25
|
+
const VALID_PROJECT_NAME = /^[a-z][a-z0-9_-]*$/;
|
|
26
|
+
export function validatePinHeader(req, instance) {
|
|
27
|
+
const raw = req.headers['x-maad-pin-project'];
|
|
28
|
+
if (raw === undefined)
|
|
29
|
+
return { status: 'absent' };
|
|
30
|
+
// Node normalizes repeated headers to string[]. Per spec, exactly one value.
|
|
31
|
+
if (Array.isArray(raw)) {
|
|
32
|
+
if (raw.length !== 1) {
|
|
33
|
+
return {
|
|
34
|
+
status: 'rejected',
|
|
35
|
+
code: 'PIN_PROJECT_INVALID',
|
|
36
|
+
message: 'X-Maad-Pin-Project header present multiple times; exactly one value required',
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
return validateSingle(raw[0], req, instance);
|
|
40
|
+
}
|
|
41
|
+
return validateSingle(raw, req, instance);
|
|
42
|
+
}
|
|
43
|
+
function validateSingle(value, req, instance) {
|
|
44
|
+
// Pin is a session-creation property. Presence on a request carrying an
|
|
45
|
+
// Mcp-Session-Id means the client is trying to mid-session rebind via the
|
|
46
|
+
// header, which is nonsensical — pin is irrevocable for the session's life.
|
|
47
|
+
if (req.headers['mcp-session-id']) {
|
|
48
|
+
return {
|
|
49
|
+
status: 'rejected',
|
|
50
|
+
code: 'PIN_ON_EXISTING_SESSION',
|
|
51
|
+
message: 'X-Maad-Pin-Project is only valid at session initialize; open a new session without Mcp-Session-Id to change the pin',
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
const trimmed = value.trim();
|
|
55
|
+
if (trimmed.length === 0 || !VALID_PROJECT_NAME.test(trimmed)) {
|
|
56
|
+
return {
|
|
57
|
+
status: 'rejected',
|
|
58
|
+
code: 'PIN_PROJECT_INVALID',
|
|
59
|
+
message: `X-Maad-Pin-Project value ${JSON.stringify(value)} is not a valid project name (expected /^[a-z][a-z0-9_-]*$/)`,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (!instance.projects.some(p => p.name === trimmed)) {
|
|
63
|
+
return {
|
|
64
|
+
status: 'rejected',
|
|
65
|
+
code: 'PIN_PROJECT_NOT_FOUND',
|
|
66
|
+
message: `X-Maad-Pin-Project value "${trimmed}" does not match any project in this instance`,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return { status: 'valid', projectName: trimmed };
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=pin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pin.js","sourceRoot":"","sources":["../../../src/mcp/transport/pin.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,kEAAkE;AAClE,EAAE;AACF,oEAAoE;AACpE,4EAA4E;AAC5E,0EAA0E;AAC1E,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,8EAA8E;AAC9E,yDAAyD;AACzD,iEAAiE;AACjE,yDAAyD;AACzD,0EAA0E;AAC1E,2EAA2E;AAC3E,oEAAoE;AACpE,EAAE;AACF,8EAA8E;AAC9E,4EAA4E;AAC5E,mBAAmB;AACnB,+EAA+E;AAe/E,sEAAsE;AACtE,4EAA4E;AAC5E,iDAAiD;AACjD,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AAEhD,MAAM,UAAU,iBAAiB,CAAC,GAAoB,EAAE,QAAwB;IAC9E,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC9C,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAEnD,6EAA6E;IAC7E,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO;gBACL,MAAM,EAAE,UAAU;gBAClB,IAAI,EAAE,qBAAqB;gBAC3B,OAAO,EAAE,8EAA8E;aACxF,CAAC;QACJ,CAAC;QACD,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC,CAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,cAAc,CAAC,KAAa,EAAE,GAAoB,EAAE,QAAwB;IACnF,wEAAwE;IACxE,0EAA0E;IAC1E,4EAA4E;IAC5E,IAAI,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAClC,OAAO;YACL,MAAM,EAAE,UAAU;YAClB,IAAI,EAAE,yBAAyB;YAC/B,OAAO,EAAE,qHAAqH;SAC/H,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9D,OAAO;YACL,MAAM,EAAE,UAAU;YAClB,IAAI,EAAE,qBAAqB;YAC3B,OAAO,EAAE,4BAA4B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,8DAA8D;SACzH,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,EAAE,CAAC;QACrD,OAAO;YACL,MAAM,EAAE,UAAU;YAClB,IAAI,EAAE,uBAAuB;YAC7B,OAAO,EAAE,6BAA6B,OAAO,+CAA+C;SAC7F,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { BindingSource, SessionCloseReason } from '../../instance/session.js';
|
|
2
|
+
export type TransportKind = 'stdio' | 'http' | 'unix';
|
|
3
|
+
export interface TransportInfo {
|
|
4
|
+
kind: TransportKind;
|
|
5
|
+
host?: string | undefined;
|
|
6
|
+
port?: number | undefined;
|
|
7
|
+
/** 0.7.5 (fup-2026-148) — unix transport socket path. */
|
|
8
|
+
socketPath?: string | undefined;
|
|
9
|
+
startedAt: string;
|
|
10
|
+
}
|
|
11
|
+
export interface SessionCounters {
|
|
12
|
+
openedTotal: number;
|
|
13
|
+
closedTotal: number;
|
|
14
|
+
lastOpenedAt: string | null;
|
|
15
|
+
lastClosedAt: string | null;
|
|
16
|
+
idleSweepLastRunAt: string | null;
|
|
17
|
+
}
|
|
18
|
+
export interface SessionsBlock extends SessionCounters {
|
|
19
|
+
active: number;
|
|
20
|
+
/**
|
|
21
|
+
* Count of currently-active sessions bound via X-Maad-Pin-Project header
|
|
22
|
+
* (bindingSource === 'gateway_pin'). 0 on stdio and on HTTP deployments
|
|
23
|
+
* that don't use gateway pinning. Operators track this to confirm their
|
|
24
|
+
* gateway is actually applying the pin.
|
|
25
|
+
*/
|
|
26
|
+
pinned: number;
|
|
27
|
+
}
|
|
28
|
+
export interface TransportSnapshot {
|
|
29
|
+
transport: {
|
|
30
|
+
kind: TransportKind;
|
|
31
|
+
host?: string | undefined;
|
|
32
|
+
port?: number | undefined;
|
|
33
|
+
socketPath?: string | undefined;
|
|
34
|
+
uptimeSeconds: number;
|
|
35
|
+
};
|
|
36
|
+
sessions: SessionsBlock;
|
|
37
|
+
}
|
|
38
|
+
export declare function initTransportTelemetry(info: {
|
|
39
|
+
kind: TransportKind;
|
|
40
|
+
host?: string | undefined;
|
|
41
|
+
port?: number | undefined;
|
|
42
|
+
socketPath?: string | undefined;
|
|
43
|
+
}): void;
|
|
44
|
+
/**
|
|
45
|
+
* Test hook — resets telemetry state so each test starts clean.
|
|
46
|
+
*/
|
|
47
|
+
export declare function __resetTransportTelemetry(): void;
|
|
48
|
+
export interface SessionOpenFields {
|
|
49
|
+
session_id: string;
|
|
50
|
+
remote_addr: string;
|
|
51
|
+
user_agent: string | null;
|
|
52
|
+
transport: TransportKind;
|
|
53
|
+
/**
|
|
54
|
+
* 0.6.8 — present when the session was pinned at initialize via the
|
|
55
|
+
* X-Maad-Pin-Project header. Omitted (undefined) when the session was
|
|
56
|
+
* created unbound; a later maad_use_project tool call does NOT emit an
|
|
57
|
+
* additional session_open event (binding_source at session_open captures
|
|
58
|
+
* the gateway-pin signal, not the eventual client bind).
|
|
59
|
+
*/
|
|
60
|
+
binding_source?: BindingSource;
|
|
61
|
+
}
|
|
62
|
+
export declare function recordSessionOpen(fields: SessionOpenFields): void;
|
|
63
|
+
export interface SessionCloseFields {
|
|
64
|
+
session_id: string;
|
|
65
|
+
reason: SessionCloseReason;
|
|
66
|
+
duration_ms: number;
|
|
67
|
+
}
|
|
68
|
+
export declare function recordSessionClose(args: {
|
|
69
|
+
session_id: string;
|
|
70
|
+
reason: SessionCloseReason;
|
|
71
|
+
}): void;
|
|
72
|
+
export interface IdleSweepFields {
|
|
73
|
+
swept: number;
|
|
74
|
+
remaining: number;
|
|
75
|
+
}
|
|
76
|
+
export declare function recordIdleSweep(fields: IdleSweepFields): void;
|
|
77
|
+
export declare function getTransportSnapshot(activeSessions: number, pinnedSessions?: number): TransportSnapshot;
|
|
78
|
+
export declare function isInitialized(): boolean;
|
|
79
|
+
//# sourceMappingURL=telemetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../../src/mcp/transport/telemetry.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAGnF,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAEtD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,aAAc,SAAQ,eAAe;IACpD,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE;QACT,IAAI,EAAE,aAAa,CAAC;QACpB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAChC,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,QAAQ,EAAE,aAAa,CAAC;CACzB;AAWD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC,GAAG,IAAI,CAoBP;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AAGD,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,aAAa,CAAC;IACzB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,aAAa,CAAC;CAChC;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAUjE;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAA;CAAE,GAAG,IAAI,CAcjG;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAI7D;AAED,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,MAAM,EAAE,cAAc,SAAI,GAAG,iBAAiB,CAoBlG;AAED,wBAAgB,aAAa,IAAI,OAAO,CAEvC"}
|