@i4ctime/q-ring 0.17.5 → 0.18.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/dist/mcp.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mcp.ts","../src/mcp/server.ts","../src/mcp/tool-annotations.ts","../src/mcp/tools/secrets.ts","../src/services/list-secrets-filter.ts","../src/core/noise.ts","../src/core/import.ts","../src/mcp/tools/_shared.ts","../src/core/validate.ts","../src/core/context.ts","../src/mcp/tools/project.ts","../src/mcp/tools/tunnel.ts","../src/mcp/tools/teleport.ts","../src/core/teleport.ts","../src/mcp/tools/audit.ts","../src/mcp/tools/validation.ts","../src/mcp/tools/hooks.ts","../src/mcp/tools/tooling.ts","../src/utils/colors.ts","../src/core/agent.ts","../src/core/exec.ts","../src/core/scan.ts","../src/core/secrets-detect.ts","../src/core/linter.ts","../src/mcp/tools/agent.ts","../src/mcp/tools/policy.ts","../src/mcp/resources.ts","../src/mcp/tool-registration.ts"],"sourcesContent":["import { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { createMcpServer } from \"./mcp/server.js\";\n\nconst server = createMcpServer();\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { PACKAGE_VERSION } from \"../version.js\";\nimport { registerMcpTools } from \"./tool-registration.js\";\nimport { setPolicyRoot } from \"../core/policy.js\";\nimport { setAuditAgentLabel } from \"../core/observer.js\";\n\nexport function createMcpServer(): McpServer {\n // Anchor governance policy to the directory the operator launched the server\n // in. Agents pass projectPath freely, so resolving policy from it would let a\n // malicious agent escape `.q-ring.json` restrictions by pointing elsewhere.\n setPolicyRoot(process.cwd());\n\n const server = new McpServer({\n name: \"q-ring\",\n version: PACKAGE_VERSION,\n });\n registerMcpTools(server);\n // Stamp audit events with the connecting client's self-reported identity\n // (clientInfo from the initialize handshake). Label only — spoofable, so it\n // must never feed policy or approval decisions.\n server.server.oninitialized = () => {\n const info = server.server.getClientVersion();\n if (info) setAuditAgentLabel(`${info.name}@${info.version}`);\n };\n return server;\n}\n","import type { ToolAnnotations } from \"@modelcontextprotocol/sdk/types.js\";\n\n/**\n * MCP tool annotations for every q-ring tool — the structured behavior hints\n * (MCP spec: readOnlyHint / destructiveHint / idempotentHint / openWorldHint)\n * that let hosts decide what to auto-approve and what to confirm.\n *\n * Every hint is set explicitly; nothing relies on the spec defaults. The\n * prose descriptions remain the authority on *why* — keep both in sync when a\n * tool's behavior changes. `src/__tests__/mcp/server.test.ts` asserts that\n * every registered tool has an entry here and that no entry is orphaned.\n *\n * Conventions:\n * - readOnlyHint: the tool never changes the keyring, files, hooks, memory,\n * or running processes. Appending to the audit log does not count.\n * - destructiveHint: a non-read-only tool that overwrites, deletes, replaces\n * a credential, edits source files, or runs arbitrary commands.\n * - idempotentHint: repeating the call with the same arguments has no further\n * effect.\n * - openWorldHint: the tool talks to external services or runs commands that\n * can — validation, rotation, exec, agent auto-rotate.\n */\nconst hints = (\n readOnlyHint: boolean,\n destructiveHint: boolean,\n idempotentHint: boolean,\n openWorldHint: boolean,\n): ToolAnnotations => ({ readOnlyHint, destructiveHint, idempotentHint, openWorldHint });\n\nconst READ = hints(true, false, true, false);\nconst READ_OPEN = hints(true, false, true, true);\n\nexport const TOOL_ANNOTATIONS: Record<string, ToolAnnotations> = {\n // secrets\n get_secret: READ,\n list_secrets: READ,\n set_secret: hints(false, true, true, false),\n delete_secret: hints(false, true, true, false),\n has_secret: READ,\n export_secrets: READ,\n import_dotenv: hints(false, false, true, false), // existing keys are skipped, not overwritten\n inspect_secret: READ,\n generate_secret: hints(false, true, false, false), // saveAs overwrites; fresh value every call\n entangle_secrets: hints(false, false, true, false),\n disentangle_secrets: hints(false, false, true, false),\n // project\n check_project: READ,\n env_generate: READ, // renders text, never writes files\n detect_environment: READ,\n get_project_context: READ,\n // tunnels (memory-only)\n tunnel_create: hints(false, false, false, false),\n tunnel_read: hints(false, true, false, false), // may self-destruct on read\n tunnel_list: READ,\n tunnel_destroy: hints(false, true, true, false),\n // teleport\n teleport_pack: READ,\n teleport_unpack: hints(false, true, true, false), // imports may overwrite keys\n // audit / health\n audit_log: READ,\n detect_anomalies: READ,\n health_check: READ,\n verify_audit_chain: READ,\n export_audit: READ,\n // validation / rotation (network)\n validate_secret: READ_OPEN,\n list_providers: READ,\n rotate_secret: hints(false, true, false, true), // replaces the credential upstream and locally\n ci_validate_secrets: READ_OPEN,\n // hooks\n register_hook: hints(false, false, false, false),\n list_hooks: READ,\n remove_hook: hints(false, true, true, false),\n // execution / scanning\n exec_with_secrets: hints(false, true, false, true), // arbitrary command\n scan_codebase_for_secrets: READ,\n lint_files: hints(false, true, true, false), // fix:true rewrites source files\n analyze_secrets: READ,\n status_dashboard: hints(false, false, false, false), // starts a local server, new token per launch\n agent_scan: hints(false, true, false, true), // autoRotate replaces expired credentials\n // agent memory\n agent_remember: hints(false, true, true, false),\n agent_recall: READ,\n agent_forget: hints(false, true, true, false),\n // policy\n check_policy: READ,\n get_policy_summary: READ,\n};\n\n/** Look up a tool's annotations; a missing entry is a programming error. */\nexport function toolAnnotations(name: string): ToolAnnotations {\n const a = TOOL_ANNOTATIONS[name];\n if (!a) throw new Error(`q-ring: no tool annotations defined for \"${name}\"`);\n return a;\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { z } from \"zod\";\nimport { filterSecretsByKeyGlob } from \"../../services/list-secrets-filter.js\";\nimport {\n getSecret,\n setSecret,\n deleteSecret,\n hasSecret,\n listSecrets,\n getEnvelope,\n entangleSecrets,\n disentangleSecrets,\n exportSecrets,\n} from \"../../core/keyring.js\";\nimport { checkDecay } from \"../../core/envelope.js\";\nimport type { Scope } from \"../../core/scope.js\";\nimport { generateSecret, estimateEntropy, type NoiseFormat } from \"../../core/noise.js\";\nimport { importDotenv } from \"../../core/import.js\";\nimport { checkKeyReadPolicy } from \"../../core/policy.js\";\nimport { text, opts, enforceToolPolicy, commonSchemas } from \"./_shared.js\";\n\nconst { teamId, orgId, scope, projectPath, env } = commonSchemas;\n\nexport function registerSecretTools(server: McpServer): void {\n server.tool(\n \"get_secret\",\n [\n \"[secrets] Read the plaintext value of a single secret from the q-ring keyring.\",\n \"Use when an agent needs the actual credential to call an external API or inject into a runtime; prefer `inspect_secret` to see metadata only, `has_secret` for presence-only checks, and `exec_with_secrets` to run a command without exposing the value to chat.\",\n \"Side effects: collapses superposition (selects the per-env state) and writes a 'read' event to the audit log (observer effect). Subject to project tool/key policy and may be denied with a 'Policy Denied' message. Returns JSON `{ ok, data: { key, value } }` on success or an error message if missing/blocked.\",\n ].join(\" \"),\n {\n key: z\n .string()\n .describe(\n \"Exact secret key name as stored in the keyring (case-sensitive). Example: 'OPENAI_API_KEY'.\",\n ),\n scope,\n projectPath,\n env,\n teamId,\n orgId,\n },\n toolAnnotations(\"get_secret\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"get_secret\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n try {\n const keyBlock = checkKeyReadPolicy(params.key, undefined, params.projectPath);\n if (!keyBlock.allowed) {\n return text(`Policy Denied: ${keyBlock.reason}`, true);\n }\n\n const value = getSecret(params.key, opts(params));\n if (value === null) return text(`Secret \"${params.key}\" not found`, true);\n return text(JSON.stringify({ ok: true, data: { key: params.key, value } }, null, 2));\n } catch (err) {\n return text(err instanceof Error ? err.message : String(err), true);\n }\n },\n );\n\n server.tool(\n \"list_secrets\",\n [\n \"[secrets] List secret keys and quantum metadata in the requested scope, never the values.\",\n \"Use to discover what secrets exist before reading or writing; pair with `inspect_secret` for full metadata on one key, `analyze_secrets` for usage trends, or `health_check` for decay/anomaly summaries.\",\n \"Read-only; safe to call repeatedly. Returns JSON `{ ok, data: { entries: [...] } }` where each entry has scope, key, stateKeys (env names if superposed), expired, stale, lifetimePercent, timeRemaining, entangledCount, accessCount.\",\n ].join(\" \"),\n {\n scope,\n projectPath,\n tag: z\n .string()\n .optional()\n .describe(\n \"Return only secrets that include this exact tag (case-sensitive). Example: 'production'.\",\n ),\n expired: z\n .boolean()\n .optional()\n .describe(\n \"If true, return only secrets whose decay TTL has elapsed (lifetimePercent >= 100).\",\n ),\n stale: z\n .boolean()\n .optional()\n .describe(\n \"If true, return only secrets in the stale window (lifetimePercent >= 75 and not yet expired).\",\n ),\n filter: z\n .string()\n .optional()\n .describe(\n \"Glob pattern matched against the key name. Supports `*` and `?`. Examples: 'API_*', 'STRIPE_?_KEY'.\",\n ),\n teamId,\n orgId,\n },\n toolAnnotations(\"list_secrets\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"list_secrets\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n let entries = listSecrets(opts(params));\n\n if (params.tag) {\n entries = entries.filter((e) => e.envelope?.meta.tags?.includes(params.tag!));\n }\n if (params.expired) {\n entries = entries.filter((e) => e.decay?.isExpired);\n }\n if (params.stale) {\n entries = entries.filter((e) => e.decay?.isStale && !e.decay?.isExpired);\n }\n if (params.filter) {\n entries = filterSecretsByKeyGlob(entries, params.filter);\n }\n const rows = entries.map((e) => ({\n scope: e.scope,\n key: e.key,\n stateKeys: e.envelope?.states ? Object.keys(e.envelope.states) : undefined,\n expired: !!e.decay?.isExpired,\n stale: !!e.decay?.isStale && !e.decay?.isExpired,\n lifetimePercent: e.decay?.lifetimePercent,\n timeRemaining: e.decay?.timeRemaining ?? null,\n entangledCount: e.envelope?.meta.entangled?.length ?? 0,\n accessCount: e.envelope?.meta.accessCount ?? 0,\n }));\n\n return text(JSON.stringify({ ok: true, data: { entries: rows } }, null, 2));\n },\n );\n\n server.tool(\n \"set_secret\",\n [\n \"[secrets] Create or overwrite a single secret value, optionally with TTL/decay, per-env superposition, description, tags, and rotation hints.\",\n \"Use to add or update one key at a time; prefer `import_dotenv` for bulk .env ingest, `generate_secret` (with saveAs) to generate-and-store in one step, and `entangle_secrets` instead of duplicating the same value under two keys.\",\n \"Mutates the keyring (overwrites any existing value at the same key/scope), writes a 'write' event to the audit log, and triggers any matching hooks. Subject to tool policy. Returns a short confirmation text like '[scope] KEY saved' (or '[scope] KEY set for env:NAME' when `env` is provided).\",\n ].join(\" \"),\n {\n key: z\n .string()\n .describe(\"Secret key name (UPPER_SNAKE_CASE recommended). Example: 'STRIPE_SECRET_KEY'.\"),\n value: z\n .string()\n .describe(\n \"The secret value to store. Stored as-is; never logged or echoed. May be empty only when `env` is provided to register a new env without a default.\",\n ),\n scope: scope.default(\"global\"),\n projectPath,\n env: z\n .string()\n .optional()\n .describe(\n \"If set, writes this value to the named per-env state (superposition) instead of the default slot. Existing default value is preserved as state 'default'. Example: 'prod'.\",\n ),\n ttlSeconds: z\n .number()\n .optional()\n .describe(\n \"Quantum decay window in seconds. After this many seconds the secret is marked expired (still readable, but `has_secret` returns false and `health_check` flags it). Omit for no decay.\",\n ),\n description: z\n .string()\n .optional()\n .describe(\n \"Free-text human-readable description shown in `inspect_secret` and the dashboard.\",\n ),\n tags: z\n .array(z.string())\n .optional()\n .describe(\"Tag list for filtering and hook matching. Example: ['production', 'payments'].\"),\n rotationFormat: z\n .enum([\"hex\", \"base64\", \"alphanumeric\", \"uuid\", \"api-key\", \"token\", \"password\"])\n .optional()\n .describe(\n \"Format used by `agent_scan --autoRotate` and `rotate_secret` when this secret expires. Pick the format that matches the upstream service's accepted shape.\",\n ),\n rotationPrefix: z\n .string()\n .optional()\n .describe(\n \"Literal prefix prepended on auto-rotation (only used with rotationFormat 'api-key' or 'token'). Example: 'sk-'.\",\n ),\n teamId,\n orgId,\n },\n toolAnnotations(\"set_secret\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"set_secret\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const o = opts(params);\n\n if (params.env) {\n const existing = getEnvelope(params.key, o);\n const states = existing?.envelope?.states ?? {};\n states[params.env] = params.value;\n\n if (existing?.envelope?.value && !states[\"default\"]) {\n states[\"default\"] = existing.envelope.value;\n }\n\n setSecret(params.key, \"\", {\n ...o,\n states,\n defaultEnv: existing?.envelope?.defaultEnv ?? params.env,\n ttlSeconds: params.ttlSeconds,\n description: params.description,\n tags: params.tags,\n rotationFormat: params.rotationFormat,\n rotationPrefix: params.rotationPrefix,\n });\n\n return text(`[${params.scope ?? \"global\"}] ${params.key} set for env:${params.env}`);\n }\n\n setSecret(params.key, params.value, {\n ...o,\n ttlSeconds: params.ttlSeconds,\n description: params.description,\n tags: params.tags,\n rotationFormat: params.rotationFormat,\n rotationPrefix: params.rotationPrefix,\n });\n\n return text(`[${params.scope ?? \"global\"}] ${params.key} saved`);\n },\n );\n\n server.tool(\n \"delete_secret\",\n [\n \"[secrets] Permanently remove a secret value (and all its env states) from the keyring for the given scope.\",\n \"Use when a credential is being retired or was created in error; prefer `disentangle_secrets` to break a sync link without erasing values, `remove_hook` to detach lifecycle callbacks, and `tunnel_destroy` for ephemeral tunnels.\",\n \"Destructive and not undoable from q-ring (no built-in trash). Writes a 'delete' event to the audit log and fires matching hooks. Returns 'Deleted \\\"KEY\\\"' on success or a not-found error if the key did not exist in the requested scope. Subject to tool policy.\",\n ].join(\" \"),\n {\n key: z.string().describe(\"Exact secret key name to delete. Example: 'OLD_API_KEY'.\"),\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"delete_secret\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"delete_secret\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const deleted = deleteSecret(params.key, opts(params));\n return text(\n deleted ? `Deleted \"${params.key}\"` : `Secret \"${params.key}\" not found`,\n !deleted,\n );\n },\n );\n\n server.tool(\n \"has_secret\",\n [\n \"[secrets] Check whether a secret exists in the requested scope without reading the value.\",\n \"Use as a cheap precondition before reading or writing — for example, to skip prompting the user for a key that is already configured. Prefer `inspect_secret` when you also need metadata.\",\n \"Read-only; does not record a 'read' in the audit log. Decay-aware: returns 'false' for expired secrets even though the value is still in the store. Returns the literal text 'true' or 'false'.\",\n ].join(\" \"),\n {\n key: z.string().describe(\"Exact secret key name. Example: 'GITHUB_TOKEN'.\"),\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"has_secret\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"has_secret\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n return text(hasSecret(params.key, opts(params)) ? \"true\" : \"false\");\n },\n );\n\n server.tool(\n \"export_secrets\",\n [\n \"[secrets] Render multiple secrets as a single .env or JSON document for piping into another tool or file.\",\n \"Use to materialize secrets for a one-off export or copy; prefer `env_generate` when you want output driven by the project's `.q-ring.json` manifest, and `teleport_pack` for an encrypted bundle to share between machines.\",\n \"Reads values (collapses superposition for the requested env) and writes one 'export' event per included secret to the audit log. Returns the rendered text directly (no JSON wrapper). Returns an error if no secrets matched the filters. Values are surfaced in plaintext — handle with care.\",\n ].join(\" \"),\n {\n format: z\n .enum([\"env\", \"json\"])\n .optional()\n .default(\"env\")\n .describe(\n \"'env' renders KEY=\\\"value\\\" lines suitable for a .env file; 'json' renders an object keyed by secret name. Defaults to 'env'.\",\n ),\n keys: z\n .array(z.string())\n .optional()\n .describe(\n \"Whitelist of exact key names to include. If omitted, every key in scope is considered (subject to `tags`).\",\n ),\n tags: z\n .array(z.string())\n .optional()\n .describe(\n \"Include only secrets tagged with at least one of these tags. Combined with `keys` as an AND filter when both are supplied.\",\n ),\n scope,\n projectPath,\n env,\n teamId,\n orgId,\n },\n toolAnnotations(\"export_secrets\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"export_secrets\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const output = exportSecrets({\n ...opts(params),\n format: params.format as \"env\" | \"json\",\n keys: params.keys,\n tags: params.tags,\n });\n\n if (!output.trim()) return text(\"No secrets matched the filters\", true);\n return text(output);\n },\n );\n\n server.tool(\n \"import_dotenv\",\n [\n \"[secrets] Parse standard dotenv-formatted text and store each key/value pair into the keyring in one batch.\",\n \"Use when migrating an existing `.env` file into q-ring or onboarding a new project; prefer `set_secret` for a single key, and `teleport_unpack` to import an encrypted bundle.\",\n \"Mutates the keyring (one write per parsed key) and emits a 'write' audit event for each. Supports comments, single/double quotes, and `\\\\n` escapes. Returns a multiline summary listing imported keys and any skipped (existing) keys; in dryRun mode no writes happen and the same summary is produced for review.\",\n ].join(\" \"),\n {\n content: z\n .string()\n .describe(\n \"Raw .env file content as a single string (newline-separated KEY=VALUE lines, comments allowed).\",\n ),\n scope: scope.default(\"global\"),\n projectPath,\n skipExisting: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n \"If true, leave already-present keys untouched and add them to the 'skipped' list instead of overwriting.\",\n ),\n dryRun: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n \"If true, parse and report what would happen but do not write to the keyring. Useful for previewing imports before committing.\",\n ),\n },\n toolAnnotations(\"import_dotenv\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"import_dotenv\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const result = importDotenv(params.content, {\n scope: params.scope as \"global\" | \"project\",\n projectPath: params.projectPath ?? process.cwd(),\n source: \"mcp\",\n skipExisting: params.skipExisting,\n dryRun: params.dryRun,\n });\n\n const lines = [\n params.dryRun\n ? \"Dry run — no changes made\"\n : `Imported ${result.imported.length} secret(s)`,\n ];\n\n if (result.imported.length > 0) {\n lines.push(`Keys: ${result.imported.join(\", \")}`);\n }\n if (result.skipped.length > 0) {\n lines.push(`Skipped (existing): ${result.skipped.join(\", \")}`);\n }\n\n return text(lines.join(\"\\n\"));\n },\n );\n\n server.tool(\n \"inspect_secret\",\n [\n \"[secrets] Show full metadata for a single secret — env states, decay window, entanglement links, access counters — without ever revealing the value.\",\n \"Use when you need to understand the shape of a key before reading it or to debug 'why is this expired/stale'; prefer `get_secret` for the actual value, `list_secrets` for a many-key overview, and `audit_log` for the full access timeline.\",\n \"Read-only; does not write a 'read' event since the value is not exposed. Returns pretty-printed JSON with fields: key, scope, type ('superposition'|'collapsed'), created, updated, accessCount, lastAccessed, environments, defaultEnv, decay { expired, stale, lifetimePercent, timeRemaining }, entangled, description, tags. Errors with not-found if the key is absent.\",\n ].join(\" \"),\n {\n key: z.string().describe(\"Exact secret key name to inspect. Example: 'OPENAI_API_KEY'.\"),\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"inspect_secret\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"inspect_secret\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const result = getEnvelope(params.key, opts(params));\n if (!result) return text(`Secret \"${params.key}\" not found`, true);\n\n const { envelope, scope: entryScope } = result;\n const decay = checkDecay(envelope);\n\n const info: Record<string, unknown> = {\n key: params.key,\n scope: entryScope,\n type: envelope.states ? \"superposition\" : \"collapsed\",\n created: envelope.meta.createdAt,\n updated: envelope.meta.updatedAt,\n accessCount: envelope.meta.accessCount,\n lastAccessed: envelope.meta.lastAccessedAt ?? \"never\",\n };\n\n if (envelope.states) {\n info.environments = Object.keys(envelope.states);\n info.defaultEnv = envelope.defaultEnv;\n }\n\n if (decay.timeRemaining) {\n info.decay = {\n expired: decay.isExpired,\n stale: decay.isStale,\n lifetimePercent: decay.lifetimePercent,\n timeRemaining: decay.timeRemaining,\n };\n }\n\n if (envelope.meta.entangled?.length) {\n info.entangled = envelope.meta.entangled;\n }\n\n if (envelope.meta.description) info.description = envelope.meta.description;\n if (envelope.meta.tags?.length) info.tags = envelope.meta.tags;\n\n return text(JSON.stringify(info, null, 2));\n },\n );\n\n server.tool(\n \"generate_secret\",\n [\n \"[secrets] Generate a cryptographically random secret using Node's CSPRNG and optionally store it in the keyring in one step.\",\n \"Use to create new credentials that you control (signing keys, internal tokens, passwords); for issuer-issued credentials (Stripe/OpenAI etc.) use `rotate_secret` to ask the upstream provider for a fresh key, and use `set_secret` for values you already have in hand.\",\n \"If `saveAs` is provided this mutates the keyring (one 'write' event) and returns a summary like 'Generated and saved as \\\"KEY\\\" (FORMAT, ~N bits entropy)'. Without `saveAs` the call is read-only and returns JSON `{ ok, data: { value } }` containing the freshly generated string.\",\n ].join(\" \"),\n {\n format: z\n .enum([\"hex\", \"base64\", \"alphanumeric\", \"uuid\", \"api-key\", \"token\", \"password\"])\n .optional()\n .default(\"api-key\")\n .describe(\n \"Output shape. 'hex' / 'base64' / 'alphanumeric' = raw random string of `length` characters; 'uuid' = RFC4122 v4; 'api-key' / 'token' = random alphanumeric with optional `prefix`; 'password' = mixed-case alphanumeric with symbols. Defaults to 'api-key'.\",\n ),\n length: z\n .number()\n .optional()\n .describe(\n \"Number of characters (or bytes for hex/base64) to generate. Ignored for 'uuid'. Defaults to a sensible per-format value (e.g. 32 for api-key).\",\n ),\n prefix: z\n .string()\n .optional()\n .describe(\n \"Literal prefix prepended to the random portion. Only meaningful for 'api-key' and 'token'. Example: 'sk-' or 'svc_'.\",\n ),\n saveAs: z\n .string()\n .optional()\n .describe(\n \"If provided, store the generated value at this key name in the keyring (one mutation). Omit to just return the value without persisting.\",\n ),\n scope: scope.default(\"global\"),\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"generate_secret\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"generate_secret\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const secret = generateSecret({\n format: params.format as NoiseFormat,\n length: params.length,\n prefix: params.prefix,\n });\n\n if (params.saveAs) {\n setSecret(params.saveAs, secret, {\n ...opts(params),\n description: `Generated ${params.format} secret`,\n });\n const entropy = estimateEntropy(secret);\n return text(\n `Generated and saved as \"${params.saveAs}\" (${params.format}, ~${entropy} bits entropy)`,\n );\n }\n\n return text(JSON.stringify({ ok: true, data: { value: secret } }, null, 2));\n },\n );\n\n server.tool(\n \"entangle_secrets\",\n [\n \"[secrets] Link two keys (across the same or different scopes) so future writes/rotations of either propagate the same value to the other.\",\n \"Use when one logical credential lives under multiple names (e.g. `STRIPE_SECRET_KEY` global and project) and should never drift; prefer `set_secret` for unrelated values, and reverse the link with `disentangle_secrets` (does not delete values).\",\n \"Mutates only the metadata of both envelopes — the values themselves are not changed by this call. Idempotent: re-running on an already-entangled pair is a no-op. Subject to tool policy. Returns a short confirmation: 'Entangled: SOURCE <-> TARGET'.\",\n ].join(\" \"),\n {\n sourceKey: z.string().describe(\"First secret key in the pair. Example: 'STRIPE_SECRET_KEY'.\"),\n targetKey: z.string().describe(\"Second secret key to keep in lockstep with the source.\"),\n sourceScope: scope.default(\"global\"),\n targetScope: scope.default(\"global\"),\n sourceProjectPath: z\n .string()\n .optional()\n .describe(\n \"Project root for sourceKey when sourceScope='project'. Defaults to the server cwd.\",\n ),\n targetProjectPath: z\n .string()\n .optional()\n .describe(\n \"Project root for targetKey when targetScope='project'. Defaults to the server cwd.\",\n ),\n },\n toolAnnotations(\"entangle_secrets\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"entangle_secrets\", params.sourceProjectPath);\n if (toolBlock) return toolBlock;\n\n // Entangling links two keys so a write to one propagates to the other —\n // i.e. it grants write access to targetKey. Gate BOTH keys with the same\n // key-level policy a direct read/write would face, so an agent can't link\n // a scratch key to a denied one and overwrite it via propagation (A2).\n for (const key of [params.sourceKey, params.targetKey]) {\n const decision = checkKeyReadPolicy(key, undefined, params.sourceProjectPath);\n if (!decision.allowed) {\n return text(`Policy Denied: ${decision.reason} (source: ${decision.policySource})`, true);\n }\n }\n\n entangleSecrets(\n params.sourceKey,\n {\n scope: params.sourceScope as Scope,\n projectPath: params.sourceProjectPath ?? process.cwd(),\n source: \"mcp\",\n },\n params.targetKey,\n {\n scope: params.targetScope as Scope,\n projectPath: params.targetProjectPath ?? process.cwd(),\n source: \"mcp\",\n },\n );\n\n return text(`Entangled: ${params.sourceKey} <-> ${params.targetKey}`);\n },\n );\n\n server.tool(\n \"disentangle_secrets\",\n [\n \"[secrets] Break the sync link between two previously entangled keys so future rotations no longer propagate.\",\n \"Use when one of the keys is being retired or should diverge intentionally; pair with `delete_secret` if you also want to erase one of the values, and use `entangle_secrets` to recreate the link.\",\n \"Mutates only metadata; the current values remain untouched. Safe and idempotent — running on a pair that was never linked returns success without effect. Subject to tool policy. Returns 'Disentangled: SOURCE </> TARGET'.\",\n ].join(\" \"),\n {\n sourceKey: z.string().describe(\"First key in the previously linked pair.\"),\n targetKey: z.string().describe(\"Second key in the previously linked pair.\"),\n sourceScope: scope.default(\"global\"),\n targetScope: scope.default(\"global\"),\n sourceProjectPath: z\n .string()\n .optional()\n .describe(\"Project root for sourceKey when sourceScope='project'.\"),\n targetProjectPath: z\n .string()\n .optional()\n .describe(\"Project root for targetKey when targetScope='project'.\"),\n },\n toolAnnotations(\"disentangle_secrets\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"disentangle_secrets\", params.sourceProjectPath);\n if (toolBlock) return toolBlock;\n\n disentangleSecrets(\n params.sourceKey,\n {\n scope: params.sourceScope as Scope,\n projectPath: params.sourceProjectPath ?? process.cwd(),\n source: \"mcp\",\n },\n params.targetKey,\n {\n scope: params.targetScope as Scope,\n projectPath: params.targetProjectPath ?? process.cwd(),\n source: \"mcp\",\n },\n );\n\n return text(`Disentangled: ${params.sourceKey} </> ${params.targetKey}`);\n },\n );\n}\n","import type { SecretEntry } from \"../core/keyring.js\";\n\n/**\n * Turn a user glob (`*`, `?`) into a case-insensitive RegExp source.\n * Other regex metacharacters are escaped.\n */\nfunction globKeyPatternToRegexSource(pattern: string): string {\n let out = \"\";\n for (const c of pattern) {\n if (c === \"*\") out += \".*\";\n else if (c === \"?\") out += \".\";\n else if (\"\\\\^$+{}()|[]\".includes(c)) out += \"\\\\\" + c;\n else if (c === \".\") out += \"\\\\.\";\n else out += c;\n }\n return out;\n}\n\n/**\n * Key name glob: `*` → `.*`, `?` → `.`, other regex metacharacters escaped (CLI + MCP aligned).\n */\nexport function filterSecretsByKeyGlob(\n entries: SecretEntry[],\n filter?: string,\n): SecretEntry[] {\n if (!filter?.trim()) return entries;\n const regex = new RegExp(\"^\" + globKeyPatternToRegexSource(filter) + \"$\", \"i\");\n return entries.filter((e) => regex.test(e.key));\n}\n","/**\n * Quantum Noise: cryptographic secret generation.\n * Generates high-entropy values in common formats.\n */\n\nimport { randomBytes, randomInt } from \"node:crypto\";\n\nexport type NoiseFormat =\n | \"hex\"\n | \"base64\"\n | \"alphanumeric\"\n | \"uuid\"\n | \"api-key\"\n | \"token\"\n | \"password\";\n\nexport interface NoiseOptions {\n format?: NoiseFormat;\n /** Length in bytes (for hex/base64) or characters (for alphanumeric/password) */\n length?: number;\n /** Prefix for api-key format (e.g., \"sk-\", \"pk-\") */\n prefix?: string;\n}\n\nconst ALPHA_NUM =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\nconst PASSWORD_CHARS =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+[]{}|;:,.<>?\";\n\nfunction randomString(charset: string, length: number): string {\n let result = \"\";\n for (let i = 0; i < length; i++) {\n result += charset[randomInt(charset.length)];\n }\n return result;\n}\n\nexport function generateSecret(opts: NoiseOptions = {}): string {\n const format = opts.format ?? \"api-key\";\n\n switch (format) {\n case \"hex\": {\n const len = opts.length ?? 32;\n return randomBytes(len).toString(\"hex\");\n }\n\n case \"base64\": {\n const len = opts.length ?? 32;\n return randomBytes(len).toString(\"base64url\");\n }\n\n case \"alphanumeric\": {\n const len = opts.length ?? 32;\n return randomString(ALPHA_NUM, len);\n }\n\n case \"uuid\": {\n const bytes = randomBytes(16);\n bytes[6] = (bytes[6] & 0x0f) | 0x40; // version 4\n bytes[8] = (bytes[8] & 0x3f) | 0x80; // variant 1\n const hex = bytes.toString(\"hex\");\n return [\n hex.slice(0, 8),\n hex.slice(8, 12),\n hex.slice(12, 16),\n hex.slice(16, 20),\n hex.slice(20, 32),\n ].join(\"-\");\n }\n\n case \"api-key\": {\n const prefix = opts.prefix ?? \"qr_\";\n const len = opts.length ?? 48;\n return prefix + randomString(ALPHA_NUM, len);\n }\n\n case \"token\": {\n const prefix = opts.prefix ?? \"\";\n const len = opts.length ?? 64;\n return prefix + randomBytes(len).toString(\"base64url\");\n }\n\n case \"password\": {\n const len = opts.length ?? 24;\n\n // Construct from one guaranteed char per class, fill the rest, then\n // shuffle. This guarantees every class is present (when len ≥ #classes)\n // without any fixup pass that could clobber an already-placed class.\n const classCharsets = [\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\",\n \"abcdefghijklmnopqrstuvwxyz\",\n \"0123456789\",\n \"!@#$%^&*()-_=+\",\n ];\n const guaranteed = classCharsets\n .slice(0, Math.min(classCharsets.length, len))\n .map((cs) => randomString(cs, 1));\n const remaining = Math.max(0, len - guaranteed.length);\n const chars = [\n ...guaranteed,\n ...(remaining > 0 ? randomString(PASSWORD_CHARS, remaining).split(\"\") : []),\n ];\n\n // Fisher-Yates shuffle backed by the CSPRNG.\n for (let i = chars.length - 1; i > 0; i--) {\n const j = randomInt(i + 1);\n [chars[i], chars[j]] = [chars[j], chars[i]];\n }\n\n return chars.join(\"\");\n }\n\n default:\n return randomBytes(32).toString(\"hex\");\n }\n}\n\n/**\n * Estimate the entropy of a secret in bits.\n */\nexport function estimateEntropy(secret: string): number {\n const charsets = [\n { regex: /[a-z]/, size: 26 },\n { regex: /[A-Z]/, size: 26 },\n { regex: /[0-9]/, size: 10 },\n { regex: /[^A-Za-z0-9]/, size: 32 },\n ];\n\n let poolSize = 0;\n for (const { regex, size } of charsets) {\n if (regex.test(secret)) poolSize += size;\n }\n\n return poolSize > 0 ? Math.floor(Math.log2(poolSize) * secret.length) : 0;\n}\n","/**\n * Import module: parse .env files and bulk-store secrets into q-ring.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { setSecret, hasSecret, type SetSecretOptions } from \"./keyring.js\";\n\nexport interface ImportOptions {\n scope?: \"global\" | \"project\";\n projectPath?: string;\n env?: string;\n source?: \"cli\" | \"mcp\" | \"agent\" | \"api\";\n skipExisting?: boolean;\n dryRun?: boolean;\n}\n\nexport interface ImportResult {\n imported: string[];\n skipped: string[];\n total: number;\n}\n\n/**\n * Parse .env content into key-value pairs.\n * Handles comments, blank lines, quoted values, and basic multiline.\n */\nexport function parseDotenv(content: string): Map<string, string> {\n const result = new Map<string, string>();\n const lines = content.split(/\\r?\\n/);\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n\n if (!line || line.startsWith(\"#\")) continue;\n\n const eqIdx = line.indexOf(\"=\");\n if (eqIdx === -1) continue;\n\n const key = line.slice(0, eqIdx).trim();\n let value = line.slice(eqIdx + 1).trim();\n\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n\n const escapeMap: Record<string, string> = {\n n: \"\\n\", r: \"\\r\", t: \"\\t\", \"\\\\\": \"\\\\\", '\"': '\"',\n };\n value = value.replace(/\\\\([nrt\"\\\\])/g, (_, ch) => escapeMap[ch] ?? ch);\n\n // Strip inline comments only when the `#` is preceded by whitespace (the\n // dotenv convention), so unquoted values like `foo#bar` are preserved.\n if (!line.includes('\"') && !line.includes(\"'\")) {\n const commentMatch = value.match(/\\s#/);\n if (commentMatch && commentMatch.index !== undefined) {\n value = value.slice(0, commentMatch.index).trim();\n }\n }\n\n if (key) result.set(key, value);\n }\n\n return result;\n}\n\n/**\n * Import secrets from a .env file path or raw content string.\n */\nexport function importDotenv(\n filePathOrContent: string,\n options: ImportOptions = {},\n): ImportResult {\n let content: string;\n\n // The file-path convenience (read from disk if the arg is a path) is only\n // safe for the trusted local CLI. For MCP/agent/api callers the argument is\n // always treated as literal .env content — otherwise an agent could pass a\n // path like ~/.aws/credentials and exfiltrate it through the keyring.\n const source = options.source ?? \"cli\";\n if (source === \"cli\") {\n try {\n content = readFileSync(filePathOrContent, \"utf8\");\n } catch {\n content = filePathOrContent;\n }\n } else {\n content = filePathOrContent;\n }\n\n const pairs = parseDotenv(content);\n const result: ImportResult = {\n imported: [],\n skipped: [],\n total: pairs.size,\n };\n\n for (const [key, value] of pairs) {\n if (options.skipExisting && hasSecret(key, {\n scope: options.scope,\n projectPath: options.projectPath,\n source: options.source ?? \"cli\",\n })) {\n result.skipped.push(key);\n continue;\n }\n\n if (options.dryRun) {\n result.imported.push(key);\n continue;\n }\n\n const setOpts: SetSecretOptions = {\n scope: options.scope ?? \"global\",\n projectPath: options.projectPath ?? process.cwd(),\n source: options.source ?? \"cli\",\n };\n\n setSecret(key, value, setOpts);\n result.imported.push(key);\n }\n\n return result;\n}\n","import { z } from \"zod\";\nimport type { KeyringOptions } from \"../../core/keyring.js\";\nimport type { Scope } from \"../../core/scope.js\";\nimport { checkToolPolicy } from \"../../core/policy.js\";\n\n/**\n * Standard MCP tool response shape for text content.\n * Set `isError: true` for failure responses so clients surface them appropriately.\n */\nexport function text(t: string, isError = false) {\n return {\n content: [{ type: \"text\" as const, text: t }],\n ...(isError ? { isError: true } : {}),\n };\n}\n\n/** Build `KeyringOptions` from MCP tool params with `source: \"mcp\"` baked in. */\nexport function opts(params: {\n scope?: string;\n projectPath?: string;\n env?: string;\n teamId?: string;\n orgId?: string;\n}): KeyringOptions {\n return {\n scope: params.scope as Scope | undefined,\n projectPath: params.projectPath ?? process.cwd(),\n teamId: params.teamId,\n orgId: params.orgId,\n env: params.env,\n source: \"mcp\",\n };\n}\n\n/**\n * Short-circuit guard: returns a \"Policy Denied\" text response if the tool\n * is blocked by project governance, else `null` to continue.\n */\nexport function enforceToolPolicy(toolName: string, projectPath?: string) {\n const decision = checkToolPolicy(toolName, projectPath);\n if (!decision.allowed) {\n return text(`Policy Denied: ${decision.reason} (source: ${decision.policySource})`, true);\n }\n return null;\n}\n\n/** Reusable zod schemas for the common MCP tool parameters. */\nexport const commonSchemas = {\n teamId: z\n .string()\n .optional()\n .describe(\n \"Team identifier for team-scoped secrets. Required only when scope='team'. Example: 'acme-platform'.\",\n ),\n orgId: z\n .string()\n .optional()\n .describe(\n \"Organization identifier for org-scoped secrets. Required only when scope='org'. Example: 'acme-corp'.\",\n ),\n scope: z\n .enum([\"global\", \"project\", \"team\", \"org\"])\n .optional()\n .describe(\n \"Where the secret lives. 'global' = user keyring (default if omitted on reads), 'project' = scoped to projectPath, 'team' = team-shared (needs teamId), 'org' = org-shared (needs orgId).\",\n ),\n projectPath: z\n .string()\n .optional()\n .describe(\n \"Absolute path to the project root for project-scoped secrets and policy resolution. Defaults to the MCP server's current working directory when omitted.\",\n ),\n env: z\n .string()\n .optional()\n .describe(\n \"Environment slug used to collapse superposition when a secret has multiple per-env states. Examples: 'dev', 'staging', 'prod'. If omitted, the secret's defaultEnv is used.\",\n ),\n} as const;\n","/**\n * Secret Liveness Validation: test if a secret is actually valid\n * with its target service using a pluggable provider system.\n */\n\nimport { httpRequest } from \"../utils/http-request.js\";\nimport { generateSecret, type NoiseFormat } from \"./noise.js\";\nimport { checkSSRF } from \"./ssrf.js\";\n\nexport interface ValidationResult {\n valid: boolean;\n status: \"valid\" | \"invalid\" | \"error\" | \"unknown\";\n message: string;\n latencyMs: number;\n provider: string;\n}\n\nexport interface Provider {\n name: string;\n description: string;\n /** Prefixes that auto-detect to this provider */\n prefixes?: string[];\n validate(value: string): Promise<ValidationResult>;\n}\n\nfunction makeRequest(\n url: string,\n headers: Record<string, string>,\n timeoutMs = 10000,\n): Promise<{ statusCode: number; body: string }> {\n return httpRequest({ url, method: \"GET\", headers, timeoutMs });\n}\n\nexport class ProviderRegistry {\n private providers = new Map<string, Provider>();\n\n register(provider: Provider): void {\n this.providers.set(provider.name, provider);\n }\n\n get(name: string): Provider | undefined {\n return this.providers.get(name);\n }\n\n detectProvider(\n value: string,\n hints?: { provider?: string; prefix?: string },\n ): Provider | undefined {\n if (hints?.provider) {\n return this.providers.get(hints.provider);\n }\n\n for (const provider of this.providers.values()) {\n if (provider.prefixes) {\n for (const pfx of provider.prefixes) {\n if (value.startsWith(pfx)) return provider;\n }\n }\n }\n\n return undefined;\n }\n\n listProviders(): Provider[] {\n return [...this.providers.values()];\n }\n}\n\n// ─── Built-in Providers ───\n\n/**\n * Factory for the common liveness shape: one authenticated GET against a\n * cheap endpoint, with the standard 200/401/403/429 interpretation.\n */\nfunction livenessProvider(cfg: {\n name: string;\n description: string;\n prefixes?: string[];\n url: string;\n headers: (value: string) => Record<string, string>;\n}): Provider {\n return {\n name: cfg.name,\n description: cfg.description,\n prefixes: cfg.prefixes,\n async validate(value: string): Promise<ValidationResult> {\n const start = Date.now();\n try {\n const { statusCode } = await makeRequest(cfg.url, {\n \"User-Agent\": \"q-ring-validator/1.0\",\n ...cfg.headers(value),\n });\n const latencyMs = Date.now() - start;\n\n if (statusCode === 200)\n return { valid: true, status: \"valid\", message: \"API key is valid\", latencyMs, provider: cfg.name };\n if (statusCode === 401 || statusCode === 403)\n return { valid: false, status: \"invalid\", message: `Invalid or revoked API key (${statusCode})`, latencyMs, provider: cfg.name };\n if (statusCode === 429)\n return { valid: true, status: \"error\", message: \"Rate limited — key may be valid\", latencyMs, provider: cfg.name };\n return { valid: false, status: \"error\", message: `Unexpected status ${statusCode}`, latencyMs, provider: cfg.name };\n } catch (err) {\n return { valid: false, status: \"error\", message: `${err instanceof Error ? err.message : \"Network error\"}`, latencyMs: Date.now() - start, provider: cfg.name };\n }\n },\n };\n}\n\n// AI-stack providers. Keys are only ever sent in headers (never the URL —\n// URLs land in server logs), against the cheapest read-only endpoint each\n// platform has.\n\nconst anthropicProvider = livenessProvider({\n name: \"anthropic\",\n description: \"Anthropic API key validation\",\n prefixes: [\"sk-ant-\"],\n url: \"https://api.anthropic.com/v1/models?limit=1\",\n headers: (value) => ({ \"x-api-key\": value, \"anthropic-version\": \"2023-06-01\" }),\n});\n\nconst openrouterProvider = livenessProvider({\n name: \"openrouter\",\n description: \"OpenRouter API key validation\",\n prefixes: [\"sk-or-\"],\n url: \"https://openrouter.ai/api/v1/key\",\n headers: (value) => ({ Authorization: `Bearer ${value}` }),\n});\n\nconst googleAiProvider = livenessProvider({\n name: \"google-ai\",\n description: \"Google AI (Gemini) API key validation\",\n prefixes: [\"AIza\"],\n url: \"https://generativelanguage.googleapis.com/v1beta/models?pageSize=1\",\n headers: (value) => ({ \"x-goog-api-key\": value }),\n});\n\nconst groqProvider = livenessProvider({\n name: \"groq\",\n description: \"Groq API key validation\",\n prefixes: [\"gsk_\"],\n url: \"https://api.groq.com/openai/v1/models\",\n headers: (value) => ({ Authorization: `Bearer ${value}` }),\n});\n\nconst huggingfaceProvider = livenessProvider({\n name: \"huggingface\",\n description: \"Hugging Face token validation\",\n prefixes: [\"hf_\"],\n url: \"https://huggingface.co/api/whoami-v2\",\n headers: (value) => ({ Authorization: `Bearer ${value}` }),\n});\n\n// No prefix: ElevenLabs \"sk_...\" would shadow Stripe's sk_live_/sk_test_,\n// so it is explicit-only (set `provider: \"elevenlabs\"` on the secret/manifest).\nconst elevenlabsProvider = livenessProvider({\n name: \"elevenlabs\",\n description: \"ElevenLabs API key validation (explicit-only — set provider on the secret)\",\n url: \"https://api.elevenlabs.io/v1/user\",\n headers: (value) => ({ \"xi-api-key\": value }),\n});\n\n// No prefix: Vercel tokens have no stable public prefix — explicit-only.\nconst vercelProvider = livenessProvider({\n name: \"vercel\",\n description: \"Vercel token validation (explicit-only — set provider on the secret)\",\n url: \"https://api.vercel.com/v2/user\",\n headers: (value) => ({ Authorization: `Bearer ${value}` }),\n});\n\nconst openaiProvider: Provider = {\n name: \"openai\",\n description: \"OpenAI API key validation\",\n prefixes: [\"sk-\"],\n async validate(value: string): Promise<ValidationResult> {\n const start = Date.now();\n try {\n const { statusCode } = await makeRequest(\n \"https://api.openai.com/v1/models?limit=1\",\n {\n Authorization: `Bearer ${value}`,\n \"User-Agent\": \"q-ring-validator/1.0\",\n },\n );\n const latencyMs = Date.now() - start;\n\n if (statusCode === 200)\n return { valid: true, status: \"valid\", message: \"API key is valid\", latencyMs, provider: \"openai\" };\n if (statusCode === 401)\n return { valid: false, status: \"invalid\", message: \"Invalid or revoked API key\", latencyMs, provider: \"openai\" };\n if (statusCode === 429)\n return { valid: true, status: \"error\", message: \"Rate limited — key may be valid\", latencyMs, provider: \"openai\" };\n return { valid: false, status: \"error\", message: `Unexpected status ${statusCode}`, latencyMs, provider: \"openai\" };\n } catch (err) {\n return { valid: false, status: \"error\", message: `${err instanceof Error ? err.message : \"Network error\"}`, latencyMs: Date.now() - start, provider: \"openai\" };\n }\n },\n};\n\nconst stripeProvider: Provider = {\n name: \"stripe\",\n description: \"Stripe API key validation\",\n prefixes: [\"sk_live_\", \"sk_test_\", \"rk_live_\", \"rk_test_\", \"pk_live_\", \"pk_test_\"],\n async validate(value: string): Promise<ValidationResult> {\n const start = Date.now();\n try {\n const { statusCode } = await makeRequest(\n \"https://api.stripe.com/v1/balance\",\n {\n Authorization: `Bearer ${value}`,\n \"User-Agent\": \"q-ring-validator/1.0\",\n },\n );\n const latencyMs = Date.now() - start;\n\n if (statusCode === 200)\n return { valid: true, status: \"valid\", message: \"API key is valid\", latencyMs, provider: \"stripe\" };\n if (statusCode === 401)\n return { valid: false, status: \"invalid\", message: \"Invalid or revoked API key\", latencyMs, provider: \"stripe\" };\n if (statusCode === 429)\n return { valid: true, status: \"error\", message: \"Rate limited — key may be valid\", latencyMs, provider: \"stripe\" };\n return { valid: false, status: \"error\", message: `Unexpected status ${statusCode}`, latencyMs, provider: \"stripe\" };\n } catch (err) {\n return { valid: false, status: \"error\", message: `${err instanceof Error ? err.message : \"Network error\"}`, latencyMs: Date.now() - start, provider: \"stripe\" };\n }\n },\n};\n\nconst githubProvider: Provider = {\n name: \"github\",\n description: \"GitHub token validation\",\n prefixes: [\"ghp_\", \"gho_\", \"ghu_\", \"ghs_\", \"ghr_\", \"github_pat_\"],\n async validate(value: string): Promise<ValidationResult> {\n const start = Date.now();\n try {\n const { statusCode } = await makeRequest(\n \"https://api.github.com/user\",\n {\n Authorization: `token ${value}`,\n \"User-Agent\": \"q-ring-validator/1.0\",\n Accept: \"application/vnd.github+json\",\n },\n );\n const latencyMs = Date.now() - start;\n\n if (statusCode === 200)\n return { valid: true, status: \"valid\", message: \"Token is valid\", latencyMs, provider: \"github\" };\n if (statusCode === 401)\n return { valid: false, status: \"invalid\", message: \"Invalid or expired token\", latencyMs, provider: \"github\" };\n if (statusCode === 403)\n return { valid: false, status: \"invalid\", message: \"Token lacks required permissions\", latencyMs, provider: \"github\" };\n if (statusCode === 429)\n return { valid: true, status: \"error\", message: \"Rate limited — token may be valid\", latencyMs, provider: \"github\" };\n return { valid: false, status: \"error\", message: `Unexpected status ${statusCode}`, latencyMs, provider: \"github\" };\n } catch (err) {\n return { valid: false, status: \"error\", message: `${err instanceof Error ? err.message : \"Network error\"}`, latencyMs: Date.now() - start, provider: \"github\" };\n }\n },\n};\n\nconst awsProvider: Provider = {\n name: \"aws\",\n description: \"AWS access key validation (checks key format only — full STS validation requires secret key + region)\",\n prefixes: [\"AKIA\", \"ASIA\"],\n async validate(value: string): Promise<ValidationResult> {\n const start = Date.now();\n const latencyMs = Date.now() - start;\n\n if (/^(AKIA|ASIA)[A-Z0-9]{16}$/.test(value)) {\n return { valid: true, status: \"unknown\", message: \"Valid AWS access key format (STS validation requires secret key)\", latencyMs, provider: \"aws\" };\n }\n return { valid: false, status: \"invalid\", message: \"Invalid AWS access key format\", latencyMs, provider: \"aws\" };\n },\n};\n\nconst httpProvider: Provider = {\n name: \"http\",\n description: \"Generic HTTP endpoint validation\",\n async validate(value: string, url?: string): Promise<ValidationResult> {\n const start = Date.now();\n\n if (!url) {\n return { valid: false, status: \"unknown\", message: \"No validation URL configured\", latencyMs: 0, provider: \"http\" };\n }\n\n const ssrfBlock = await checkSSRF(url);\n if (ssrfBlock) {\n return { valid: false, status: \"error\", message: `SSRF blocked: ${ssrfBlock}`, latencyMs: Date.now() - start, provider: \"http\" };\n }\n\n try {\n const { statusCode } = await makeRequest(url, {\n Authorization: `Bearer ${value}`,\n \"User-Agent\": \"q-ring-validator/1.0\",\n });\n const latencyMs = Date.now() - start;\n\n if (statusCode >= 200 && statusCode < 300)\n return { valid: true, status: \"valid\", message: `Endpoint returned ${statusCode}`, latencyMs, provider: \"http\" };\n if (statusCode === 401 || statusCode === 403)\n return { valid: false, status: \"invalid\", message: `Authentication failed (${statusCode})`, latencyMs, provider: \"http\" };\n return { valid: false, status: \"error\", message: `Unexpected status ${statusCode}`, latencyMs, provider: \"http\" };\n } catch (err) {\n return { valid: false, status: \"error\", message: `${err instanceof Error ? err.message : \"Network error\"}`, latencyMs: Date.now() - start, provider: \"http\" };\n }\n },\n};\n\nexport const registry = new ProviderRegistry();\n// Prefix detection iterates in registration order: anthropic (sk-ant-) and\n// openrouter (sk-or-) MUST come before openai, whose bare \"sk-\" would\n// otherwise shadow them.\nregistry.register(anthropicProvider);\nregistry.register(openrouterProvider);\nregistry.register(openaiProvider);\nregistry.register(googleAiProvider);\nregistry.register(groqProvider);\nregistry.register(huggingfaceProvider);\nregistry.register(elevenlabsProvider);\nregistry.register(vercelProvider);\nregistry.register(stripeProvider);\nregistry.register(githubProvider);\nregistry.register(awsProvider);\nregistry.register(httpProvider);\n\n/**\n * Validate a secret value against its detected or specified provider.\n */\nexport async function validateSecret(\n value: string,\n opts?: { provider?: string; validationUrl?: string },\n): Promise<ValidationResult> {\n const provider = opts?.provider\n ? registry.get(opts.provider)\n : registry.detectProvider(value);\n\n if (!provider) {\n return {\n valid: false,\n status: \"unknown\",\n message: \"No provider detected — set a provider in the manifest or secret metadata\",\n latencyMs: 0,\n provider: \"none\",\n };\n }\n\n if (provider.name === \"http\" && opts?.validationUrl) {\n return (provider as any).validate(value, opts.validationUrl);\n }\n\n return provider.validate(value);\n}\n\n// ─── Rotation Support ───\n\nexport interface RotationResult {\n rotated: boolean;\n provider: string;\n message: string;\n newValue?: string;\n}\n\nexport interface RotatableProvider extends Provider {\n rotate?(currentValue: string): Promise<RotationResult>;\n supportsRotation: boolean;\n}\n\n/**\n * Attempt provider-native rotation of a secret.\n * Falls back to local generation if the provider does not support native rotation.\n */\nexport async function rotateWithProvider(\n value: string,\n providerName?: string,\n): Promise<RotationResult> {\n const provider = providerName\n ? registry.get(providerName)\n : registry.detectProvider(value);\n\n if (!provider) {\n return { rotated: false, provider: \"none\", message: \"No provider detected for rotation\" };\n }\n\n const rotatable = provider as RotatableProvider;\n if (rotatable.supportsRotation && rotatable.rotate) {\n return rotatable.rotate(value);\n }\n\n // Fall back to local generation\n const format: NoiseFormat = \"api-key\";\n const newValue = generateSecret({ format, length: 48 });\n return {\n rotated: true,\n provider: provider.name,\n message: `Provider \"${provider.name}\" does not support native rotation — generated new value locally`,\n newValue,\n };\n}\n\n// ─── CI Scan ───\n\nexport interface CiScanResult {\n key: string;\n validation: ValidationResult;\n requiresRotation: boolean;\n}\n\n/**\n * CI-oriented batch validation: validates all secrets and returns\n * a structured report suitable for CI pipeline gating.\n */\nexport async function ciValidateBatch(\n secrets: { key: string; value: string; provider?: string; validationUrl?: string }[],\n): Promise<{ results: CiScanResult[]; allValid: boolean; failCount: number }> {\n const results: CiScanResult[] = [];\n\n for (const s of secrets) {\n const validation = await validateSecret(s.value, {\n provider: s.provider,\n validationUrl: s.validationUrl,\n });\n\n results.push({\n key: s.key,\n validation,\n requiresRotation: validation.status === \"invalid\",\n });\n }\n\n const failCount = results.filter((r) => !r.validation.valid).length;\n\n return { results, allValid: failCount === 0, failCount };\n}\n","/**\n * Self-Documenting Project Context for AI Agents\n *\n * Provides a safe, redacted view of the project's secrets, configuration,\n * and state without ever exposing actual secret values.\n */\n\nimport { listSecrets } from \"./keyring.js\";\nimport { collapseEnvironment, readProjectConfig } from \"./collapse.js\";\nimport { queryAudit } from \"./observer.js\";\nimport { listHooks } from \"./hooks.js\";\nimport { registry as providerRegistry } from \"./validate.js\";\nimport { registry as jitRegistry } from \"./provision.js\";\nimport type { KeyringOptions } from \"./keyring.js\";\n\nexport interface SecretSummary {\n key: string;\n scope: string;\n tags?: string[];\n description?: string;\n provider?: string;\n requiresApproval?: boolean;\n jitProvider?: string;\n hasStates: boolean;\n isExpired: boolean;\n isStale: boolean;\n timeRemaining: string | null;\n accessCount: number;\n lastAccessed: string | null;\n rotationFormat?: string;\n}\n\nexport interface ProjectContext {\n projectPath: string;\n environment: {\n env: string;\n source: string;\n } | null;\n secrets: SecretSummary[];\n totalSecrets: number;\n expiredCount: number;\n staleCount: number;\n protectedCount: number;\n manifest: {\n declared: number;\n missing: string[];\n } | null;\n validationProviders: string[];\n jitProviders: string[];\n hooksCount: number;\n recentActions: Array<{\n action: string;\n key?: string;\n source: string;\n timestamp: string;\n }>;\n}\n\nexport function getProjectContext(opts: KeyringOptions = {}): ProjectContext {\n const projectPath = opts.projectPath ?? process.cwd();\n const envResult = collapseEnvironment({ projectPath });\n\n const secretsList = listSecrets({\n ...opts,\n projectPath,\n silent: true,\n });\n\n let expiredCount = 0;\n let staleCount = 0;\n let protectedCount = 0;\n\n const secrets: SecretSummary[] = secretsList.map((entry) => {\n const meta = entry.envelope?.meta;\n const decay = entry.decay;\n\n if (decay?.isExpired) expiredCount++;\n if (decay?.isStale) staleCount++;\n if (meta?.requiresApproval) protectedCount++;\n\n return {\n key: entry.key,\n scope: entry.scope,\n tags: meta?.tags,\n description: meta?.description,\n provider: meta?.provider,\n requiresApproval: meta?.requiresApproval,\n jitProvider: meta?.jitProvider,\n hasStates: !!(entry.envelope?.states && Object.keys(entry.envelope.states).length > 0),\n isExpired: decay?.isExpired ?? false,\n isStale: decay?.isStale ?? false,\n timeRemaining: decay?.timeRemaining ?? null,\n accessCount: meta?.accessCount ?? 0,\n lastAccessed: meta?.lastAccessedAt ?? null,\n rotationFormat: meta?.rotationFormat,\n };\n });\n\n // Manifest analysis\n let manifest: ProjectContext[\"manifest\"] = null;\n const config = readProjectConfig(projectPath);\n if (config?.secrets) {\n const declaredKeys = Object.keys(config.secrets);\n const existingKeys = new Set(secrets.map((s) => s.key));\n const missing = declaredKeys.filter((k) => !existingKeys.has(k));\n manifest = { declared: declaredKeys.length, missing };\n }\n\n // Recent audit activity (last 20 events, redacted)\n const recentEvents = queryAudit({ limit: 20 });\n const recentActions = recentEvents.map((e) => ({\n action: e.action,\n key: e.key,\n source: e.source,\n timestamp: e.timestamp,\n }));\n\n return {\n projectPath,\n environment: envResult\n ? { env: envResult.env, source: envResult.source }\n : null,\n secrets,\n totalSecrets: secrets.length,\n expiredCount,\n staleCount,\n protectedCount,\n manifest,\n validationProviders: providerRegistry.listProviders().map((p) => p.name),\n jitProviders: jitRegistry.listProviders().map((p) => p.name),\n hooksCount: listHooks().length,\n recentActions,\n };\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { getSecret, getEnvelope } from \"../../core/keyring.js\";\nimport { checkDecay } from \"../../core/envelope.js\";\nimport { collapseEnvironment, readProjectConfig } from \"../../core/collapse.js\";\nimport { getProjectContext } from \"../../core/context.js\";\nimport { text, opts, enforceToolPolicy, commonSchemas } from \"./_shared.js\";\n\nconst { teamId, orgId, scope, projectPath, env } = commonSchemas;\n\nexport function registerProjectTools(server: McpServer): void {\n server.tool(\n \"check_project\",\n [\n \"[project] Compare the keys declared in the project's `.q-ring.json` manifest against what is actually present in the keyring.\",\n \"Use as the canonical 'is this project ready to run' gate before starting a dev server, deploying, or onboarding a teammate; prefer `health_check` for a scope-wide decay sweep (no manifest), and `agent_scan` for multi-project scans with optional auto-rotation.\",\n \"Read-only; does not mutate the keyring or audit log materially beyond a 'list' read. Returns JSON `{ total, present, missing, expired, stale, ready, secrets: [...] }` where `ready` is true only when nothing is missing or expired. Errors with 'No secrets manifest found in .q-ring.json' if the project has no manifest.\",\n ].join(\" \"),\n {\n projectPath,\n },\n toolAnnotations(\"check_project\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"check_project\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const pp = params.projectPath ?? process.cwd();\n const config = readProjectConfig(pp);\n\n if (!config?.secrets || Object.keys(config.secrets).length === 0) {\n return text(\"No secrets manifest found in .q-ring.json\", true);\n }\n\n const results: Record<string, unknown>[] = [];\n let presentCount = 0;\n let missingCount = 0;\n let expiredCount = 0;\n let staleCount = 0;\n\n for (const [key, manifest] of Object.entries(config.secrets)) {\n const result = getEnvelope(key, { projectPath: pp, source: \"mcp\" });\n\n if (!result) {\n const status = manifest.required !== false ? \"missing\" : \"optional_missing\";\n if (manifest.required !== false) missingCount++;\n results.push({\n key,\n status,\n required: manifest.required !== false,\n description: manifest.description,\n });\n continue;\n }\n\n const decay = checkDecay(result.envelope);\n\n if (decay.isExpired) {\n expiredCount++;\n results.push({\n key,\n status: \"expired\",\n timeRemaining: decay.timeRemaining,\n description: manifest.description,\n });\n } else if (decay.isStale) {\n staleCount++;\n results.push({\n key,\n status: \"stale\",\n lifetimePercent: decay.lifetimePercent,\n timeRemaining: decay.timeRemaining,\n description: manifest.description,\n });\n } else {\n presentCount++;\n results.push({ key, status: \"ok\", description: manifest.description });\n }\n }\n\n const summary = {\n total: Object.keys(config.secrets).length,\n present: presentCount,\n missing: missingCount,\n expired: expiredCount,\n stale: staleCount,\n ready: missingCount === 0 && expiredCount === 0,\n secrets: results,\n };\n\n return text(JSON.stringify(summary, null, 2));\n },\n );\n\n server.tool(\n \"env_generate\",\n [\n \"[project] Render a complete `.env` file body from the project's `.q-ring.json` manifest, resolving each declared key from the keyring.\",\n \"Use when a build step or local runtime needs a real `.env` materialized on disk and you want exactly the keys the manifest declares; prefer `export_secrets` when you want every key in scope (manifest-agnostic) and `exec_with_secrets` to inject secrets into a child process without writing them to a file.\",\n \"Reads values (records 'read' audit events) and collapses superposition for the requested env. Returns the raw `.env` text, with `# MISSING (required): KEY` / `# EXPIRED: KEY` / `# STALE: KEY` warnings appended as comments. Missing keys appear as commented-out `# KEY=` placeholders so the file remains a valid drop-in.\",\n ].join(\" \"),\n {\n projectPath,\n env,\n },\n toolAnnotations(\"env_generate\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"env_generate\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const pp = params.projectPath ?? process.cwd();\n const config = readProjectConfig(pp);\n\n if (!config?.secrets || Object.keys(config.secrets).length === 0) {\n return text(\"No secrets manifest found in .q-ring.json\", true);\n }\n\n const lines: string[] = [];\n const warnings: string[] = [];\n\n for (const [key, manifest] of Object.entries(config.secrets)) {\n const value = getSecret(key, {\n projectPath: pp,\n env: params.env,\n source: \"mcp\",\n });\n\n if (value === null) {\n if (manifest.required !== false) {\n warnings.push(`MISSING (required): ${key}`);\n }\n lines.push(`# ${key}=`);\n continue;\n }\n\n const result = getEnvelope(key, { projectPath: pp, source: \"mcp\" });\n if (result) {\n const decay = checkDecay(result.envelope);\n if (decay.isExpired) warnings.push(`EXPIRED: ${key}`);\n else if (decay.isStale) warnings.push(`STALE: ${key}`);\n }\n\n const escaped = value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\");\n lines.push(`${key}=\"${escaped}\"`);\n }\n\n const output = lines.join(\"\\n\");\n const result =\n warnings.length > 0\n ? `${output}\\n\\n# Warnings:\\n${warnings.map((w) => `# ${w}`).join(\"\\n\")}`\n : output;\n\n return text(result);\n },\n );\n\n server.tool(\n \"detect_environment\",\n [\n \"[project] Resolve which environment slug (e.g. 'dev', 'staging', 'prod') the current invocation should collapse to.\",\n \"Use before reading secrets when you want to mirror the same env q-ring would auto-pick (e.g. to log it, or to pass through to another tool); prefer passing an explicit `env` to `get_secret`/`env_generate` when you already know which env you want.\",\n \"Read-only; checks the QRING_ENV env var, NODE_ENV, the project's `.q-ring.json`, and the current git branch in priority order. Returns JSON `{ env, source }` (e.g. `{ env: 'dev', source: 'NODE_ENV' }`), or a plain message indicating that no env could be detected.\",\n ].join(\" \"),\n {\n projectPath,\n },\n toolAnnotations(\"detect_environment\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"detect_environment\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const result = collapseEnvironment({\n projectPath: params.projectPath ?? process.cwd(),\n });\n\n if (!result) {\n return text(\"No environment detected. Set QRING_ENV, NODE_ENV, or create .q-ring.json\");\n }\n\n return text(JSON.stringify(result, null, 2));\n },\n );\n\n server.tool(\n \"get_project_context\",\n [\n \"[agent] Return a single redacted snapshot of everything an AI agent typically wants to know about this project: secrets present (keys + metadata only), detected env, manifest declarations, configured providers, registered hooks, and recent audit activity.\",\n \"Use this as the very first call in a session to orient the agent before it asks for any individual secret; prefer `list_secrets` for a flat key listing, `check_project` for manifest-vs-keyring drift, and `audit_log` for a deeper access trail.\",\n \"Read-only and value-safe — no plaintext secret values are ever included. Returns a single pretty-printed JSON document; shape is intentionally broad and may grow over time, so read defensively.\",\n ].join(\" \"),\n {\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"get_project_context\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"get_project_context\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const context = getProjectContext(opts(params));\n return text(JSON.stringify(context, null, 2));\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { z } from \"zod\";\nimport { tunnelCreate, tunnelRead, tunnelDestroy, tunnelList } from \"../../core/tunnel.js\";\nimport { text, enforceToolPolicy } from \"./_shared.js\";\n\nexport function registerTunnelTools(server: McpServer): void {\n server.tool(\n \"tunnel_create\",\n [\n \"[tunnel] Stash a one-shot or short-lived secret in the q-ring server's process memory and return an ID that can be used to read it back.\",\n \"Use for handing a one-time value to another tool/process without persisting it (npm OTP codes, magic-link tokens, copy/paste between machines via a relay); prefer `set_secret` with `ttlSeconds` when you actually want a tracked, auditable secret.\",\n \"Mutates only in-memory state — the value never touches disk and is lost on server restart. Subject to tool policy. Returns JSON `{ ok, data: { id } }` where `id` is an opaque string to pass to `tunnel_read`/`tunnel_destroy`.\",\n ].join(\" \"),\n {\n value: z\n .string()\n .describe(\"The plaintext value to tunnel. Held only in process memory; never logged.\"),\n ttlSeconds: z\n .number()\n .optional()\n .describe(\n \"Auto-destroy the tunnel after this many seconds. Omit for no time limit (then a `maxReads` is highly recommended).\",\n ),\n maxReads: z\n .number()\n .optional()\n .describe(\n \"Self-destruct after this many successful `tunnel_read` calls. Use 1 for true one-shot delivery.\",\n ),\n },\n toolAnnotations(\"tunnel_create\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"tunnel_create\");\n if (toolBlock) return toolBlock;\n\n const id = tunnelCreate(params.value, {\n ttlSeconds: params.ttlSeconds,\n maxReads: params.maxReads,\n });\n return text(JSON.stringify({ ok: true, data: { id } }, null, 2));\n },\n );\n\n server.tool(\n \"tunnel_read\",\n [\n \"[tunnel] Fetch the value stashed by a prior `tunnel_create` call by its ID.\",\n \"Use exactly once per intended consumer; the value is destructive-by-design and may self-delete after this call.\",\n \"Increments the read counter and may auto-destroy the tunnel if `maxReads` was set. Returns JSON `{ ok, data: { id, value } }` on success, or an error 'Tunnel \\\"...\\\" not found or expired' if the tunnel has been destroyed, hit its TTL, or never existed.\",\n ].join(\" \"),\n {\n id: z.string().describe(\"The opaque tunnel ID returned by `tunnel_create`. Case-sensitive.\"),\n },\n toolAnnotations(\"tunnel_read\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"tunnel_read\");\n if (toolBlock) return toolBlock;\n\n const value = tunnelRead(params.id);\n if (value === null) {\n return text(`Tunnel \"${params.id}\" not found or expired`, true);\n }\n return text(JSON.stringify({ ok: true, data: { id: params.id, value } }, null, 2));\n },\n );\n\n server.tool(\n \"tunnel_list\",\n [\n \"[tunnel] Enumerate all currently-active tunnels in the q-ring server with their remaining read budget and time-to-live.\",\n \"Use to audit what is still in memory or to look up an ID you forgot; values are never included in the output.\",\n \"Read-only. Returns one line per tunnel formatted as `id | reads:N | max:N | expires:Ns`, or the literal text 'No active tunnels' when the list is empty.\",\n ].join(\" \"),\n {},\n toolAnnotations(\"tunnel_list\"),\n async () => {\n const toolBlock = enforceToolPolicy(\"tunnel_list\");\n if (toolBlock) return toolBlock;\n\n const tunnels = tunnelList();\n if (tunnels.length === 0) return text(\"No active tunnels\");\n\n const lines = tunnels.map((t) => {\n const parts = [t.id];\n parts.push(`reads:${t.accessCount}`);\n if (t.maxReads) parts.push(`max:${t.maxReads}`);\n if (t.expiresAt) {\n const rem = Math.max(0, Math.floor((t.expiresAt - Date.now()) / 1000));\n parts.push(`expires:${rem}s`);\n }\n return parts.join(\" | \");\n });\n\n return text(lines.join(\"\\n\"));\n },\n );\n\n server.tool(\n \"tunnel_destroy\",\n [\n \"[tunnel] Immediately remove a tunnel from memory, regardless of remaining reads or TTL.\",\n \"Use when a tunneled value should be cancelled before delivery (e.g. wrong recipient, secret already rotated); prefer letting `maxReads`/TTL handle cleanup for normal flows.\",\n \"Mutates in-memory state only. Returns 'Destroyed ID' on success or a not-found error if the ID is unknown or already gone.\",\n ].join(\" \"),\n {\n id: z.string().describe(\"The opaque tunnel ID to destroy.\"),\n },\n toolAnnotations(\"tunnel_destroy\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"tunnel_destroy\");\n if (toolBlock) return toolBlock;\n\n const destroyed = tunnelDestroy(params.id);\n return text(\n destroyed ? `Destroyed ${params.id}` : `Tunnel \"${params.id}\" not found`,\n !destroyed,\n );\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { z } from \"zod\";\nimport { getSecret, setSecret, listSecrets } from \"../../core/keyring.js\";\nimport { teleportPack, teleportUnpack } from \"../../core/teleport.js\";\nimport { text, opts, enforceToolPolicy, commonSchemas } from \"./_shared.js\";\n\nconst { teamId, orgId, scope, projectPath } = commonSchemas;\n\nexport function registerTeleportTools(server: McpServer): void {\n server.tool(\n \"teleport_pack\",\n [\n \"[teleport] Encrypt one or more secrets into a single AES-256-GCM bundle string that can be safely transferred between machines.\",\n \"Use to hand off a curated set of credentials to another developer or environment; prefer `export_secrets` for plaintext .env output (single machine, trusted) and `tunnel_create` for ephemeral one-shot delivery on the same machine.\",\n \"Reads each secret value (records 'export' audit events) and produces a base64-encoded ciphertext. The bundle is unreadable without the same passphrase via `teleport_unpack`. Returns the bundle string directly. Errors with 'No secrets to pack' if the filter matched zero secrets.\",\n ].join(\" \"),\n {\n keys: z\n .array(z.string())\n .optional()\n .describe(\n \"Whitelist of exact key names to include. Omit to pack every secret in the requested scope.\",\n ),\n passphrase: z\n .string()\n .describe(\n \"Symmetric passphrase used to derive the AES-256-GCM key. The receiver must supply the same string to `teleport_unpack`. Pick something high-entropy and share it out-of-band.\",\n ),\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"teleport_pack\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"teleport_pack\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const o = opts(params);\n const entries = listSecrets(o);\n\n const secrets: { key: string; value: string; scope?: string }[] = [];\n for (const entry of entries) {\n if (params.keys && !params.keys.includes(entry.key)) continue;\n const value = getSecret(entry.key, { ...o, scope: entry.scope });\n if (value !== null) {\n secrets.push({ key: entry.key, value, scope: entry.scope });\n }\n }\n\n if (secrets.length === 0) return text(\"No secrets to pack\", true);\n\n const bundle = teleportPack(secrets, params.passphrase);\n return text(bundle);\n },\n );\n\n server.tool(\n \"teleport_unpack\",\n [\n \"[teleport] Decrypt a bundle produced by `teleport_pack` and import each contained secret into the local keyring.\",\n \"Use on the receiving machine after a packer hands you the bundle and passphrase out-of-band; prefer `dryRun=true` first to preview what will be written.\",\n \"When dryRun is false this mutates the keyring (one 'write' event per imported secret) at the requested scope. Bad passphrase or tampered bundle returns JSON `{ ok: false, error: { message } }` with `isError: true`. On success returns 'Imported N secret(s) from teleport bundle'; in dryRun mode returns 'Would import N secrets:' followed by a `KEY [scope]` listing.\",\n ].join(\" \"),\n {\n bundle: z\n .string()\n .describe(\n \"Base64-encoded ciphertext returned by `teleport_pack`. Pass through whitespace untouched if possible.\",\n ),\n passphrase: z\n .string()\n .describe(\n \"The same passphrase that was used to pack this bundle. Bad passphrases return an authentication error rather than wrong plaintext.\",\n ),\n scope: scope.default(\"global\"),\n projectPath,\n teamId,\n orgId,\n dryRun: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n \"If true, decrypt and report what would be written but do not mutate the keyring. Useful for verifying bundle contents before commit.\",\n ),\n },\n toolAnnotations(\"teleport_unpack\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"teleport_unpack\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n try {\n const payload = teleportUnpack(params.bundle, params.passphrase);\n\n if (params.dryRun) {\n const preview = payload.secrets\n .map((s) => `${s.key} [${s.scope ?? \"global\"}]`)\n .join(\"\\n\");\n return text(`Would import ${payload.secrets.length} secrets:\\n${preview}`);\n }\n\n const o = opts(params);\n for (const s of payload.secrets) {\n setSecret(s.key, s.value, o);\n }\n\n return text(`Imported ${payload.secrets.length} secret(s) from teleport bundle`);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return text(JSON.stringify({ ok: false, error: { message: msg } }), true);\n }\n },\n );\n}\n","/**\n * Quantum Teleportation: securely share/transfer secrets between machines.\n *\n * Generates encrypted bundles that can be shared via any channel.\n * The recipient decrypts with a shared passphrase (out-of-band exchange).\n * Uses AES-256-GCM with PBKDF2-derived keys.\n */\n\nimport {\n randomBytes,\n createCipheriv,\n createDecipheriv,\n pbkdf2Sync,\n} from \"node:crypto\";\nimport { z } from \"zod\";\n\nconst ALGORITHM = \"aes-256-gcm\";\nconst KEY_LENGTH = 32;\n/** NIST / OpenSSL recommendation for AES-GCM (96-bit nonce). */\nconst IV_LENGTH = 12;\nconst SALT_LENGTH = 32;\n/** OWASP-recommended floor for PBKDF2-HMAC-SHA512 (2023). */\nconst PBKDF2_ITERATIONS = 210000;\n/** Bundles without an explicit `iter` predate the bump; decrypt at the old cost. */\nconst LEGACY_PBKDF2_ITERATIONS = 100000;\n\nexport interface TeleportBundle {\n /** Format version */\n v: 1;\n /** Base64-encoded encrypted payload */\n data: string;\n /** Base64-encoded salt for key derivation */\n salt: string;\n /** Base64-encoded initialization vector */\n iv: string;\n /** Base64-encoded auth tag */\n tag: string;\n /** ISO timestamp of creation */\n createdAt: string;\n /** Number of secrets in the bundle */\n count: number;\n /** PBKDF2 iteration count used for key derivation (absent = legacy 100k). */\n iter?: number;\n}\n\nexport interface TeleportPayload {\n secrets: { key: string; value: string; scope?: string }[];\n exportedAt: string;\n exportedBy?: string;\n}\n\nexport const TeleportBundleSchema = z.object({\n v: z.literal(1),\n data: z.string(),\n salt: z.string(),\n iv: z.string(),\n tag: z.string(),\n createdAt: z.string(),\n count: z.number(),\n iter: z.number().optional(),\n});\n\nexport const TeleportPayloadSchema = z.object({\n secrets: z.array(\n z.object({\n key: z.string(),\n value: z.string(),\n scope: z.string().optional(),\n }),\n ),\n exportedAt: z.string(),\n exportedBy: z.string().optional(),\n});\n\nfunction deriveKey(\n passphrase: string,\n salt: Buffer,\n iterations: number = PBKDF2_ITERATIONS,\n): Buffer {\n return pbkdf2Sync(passphrase, salt, iterations, KEY_LENGTH, \"sha512\");\n}\n\n/**\n * Pack secrets into an encrypted teleport bundle.\n */\nexport function teleportPack(\n secrets: { key: string; value: string; scope?: string }[],\n passphrase: string,\n): string {\n const payload: TeleportPayload = {\n secrets,\n exportedAt: new Date().toISOString(),\n };\n\n const plaintext = JSON.stringify(payload);\n const salt = randomBytes(SALT_LENGTH);\n const iv = randomBytes(IV_LENGTH);\n const key = deriveKey(passphrase, salt, PBKDF2_ITERATIONS);\n\n const cipher = createCipheriv(ALGORITHM, key, iv);\n const encrypted = Buffer.concat([\n cipher.update(plaintext, \"utf8\"),\n cipher.final(),\n ]);\n const tag = cipher.getAuthTag();\n\n const bundle: TeleportBundle = {\n v: 1,\n data: encrypted.toString(\"base64\"),\n salt: salt.toString(\"base64\"),\n iv: iv.toString(\"base64\"),\n tag: tag.toString(\"base64\"),\n createdAt: new Date().toISOString(),\n count: secrets.length,\n iter: PBKDF2_ITERATIONS,\n };\n\n return Buffer.from(JSON.stringify(bundle)).toString(\"base64\");\n}\n\n/**\n * Unpack and decrypt a teleport bundle.\n */\nexport function teleportUnpack(\n encoded: string,\n passphrase: string,\n): TeleportPayload {\n let bundleJson: string;\n try {\n bundleJson = Buffer.from(encoded, \"base64\").toString(\"utf8\");\n } catch {\n throw new Error(\"ERR_TELEPORT_CORRUPT: invalid base64 bundle\");\n }\n\n let rawBundle: unknown;\n try {\n rawBundle = JSON.parse(bundleJson);\n } catch {\n throw new Error(\"ERR_TELEPORT_CORRUPT: bundle is not valid JSON\");\n }\n\n const parsedBundle = TeleportBundleSchema.safeParse(rawBundle);\n if (!parsedBundle.success) {\n throw new Error(\n `ERR_TELEPORT_CORRUPT: invalid bundle shape (${parsedBundle.error.message})`,\n );\n }\n const bundle = parsedBundle.data;\n\n const salt = Buffer.from(bundle.salt, \"base64\");\n const iv = Buffer.from(bundle.iv, \"base64\");\n const tag = Buffer.from(bundle.tag, \"base64\");\n const encrypted = Buffer.from(bundle.data, \"base64\");\n const key = deriveKey(passphrase, salt, bundle.iter ?? LEGACY_PBKDF2_ITERATIONS);\n\n const decipher = createDecipheriv(ALGORITHM, key, iv);\n decipher.setAuthTag(tag);\n\n let decrypted: Buffer;\n try {\n decrypted = Buffer.concat([\n decipher.update(encrypted),\n decipher.final(),\n ]);\n } catch {\n throw new Error(\"ERR_TELEPORT_BAD_PASSPHRASE: decryption failed (wrong passphrase or corrupt data)\");\n }\n\n let rawPayload: unknown;\n try {\n rawPayload = JSON.parse(decrypted.toString(\"utf8\"));\n } catch {\n throw new Error(\"ERR_TELEPORT_CORRUPT: decrypted payload is not valid JSON\");\n }\n\n const payload = TeleportPayloadSchema.safeParse(rawPayload);\n if (!payload.success) {\n throw new Error(\n `ERR_TELEPORT_CORRUPT: invalid payload (${payload.error.message})`,\n );\n }\n return payload.data;\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { z } from \"zod\";\nimport { listSecrets } from \"../../core/keyring.js\";\nimport { queryAudit, detectAnomalies, verifyAuditChain, exportAudit } from \"../../core/observer.js\";\nimport { text, opts, enforceToolPolicy, commonSchemas } from \"./_shared.js\";\n\nconst { teamId, orgId, scope, projectPath } = commonSchemas;\n\nexport function registerAuditTools(server: McpServer): void {\n server.tool(\n \"audit_log\",\n [\n \"[audit] Query the q-ring audit log — a tamper-evident record of every read/write/delete touching a secret.\",\n \"Use to investigate 'who accessed KEY recently?' or to feed an agent the access timeline for a specific credential; prefer `detect_anomalies` for automated unusual-pattern detection and `health_check` for decay-state-plus-anomalies in one call.\",\n \"Read-only. Returns one line per event in chronological order, formatted `timestamp | action | key | [scope] | env:NAME | detail`. Returns 'No audit events found' when the filter matches nothing.\",\n ].join(\" \"),\n {\n key: z\n .string()\n .optional()\n .describe(\"Limit to events touching this exact key. Omit for the full log.\"),\n action: z\n .enum([\n \"read\",\n \"write\",\n \"delete\",\n \"list\",\n \"export\",\n \"generate\",\n \"entangle\",\n \"tunnel\",\n \"teleport\",\n \"collapse\",\n \"approve\",\n \"revoke\",\n \"policy_deny\",\n \"rotate\",\n \"push\",\n \"wrap\",\n ])\n .optional()\n .describe(\n \"Limit to a single action verb (e.g. 'read' to see only reads). Omit for all actions.\",\n ),\n agent: z\n .string()\n .optional()\n .describe(\n \"Limit to events stamped with this agent label (clientInfo name@version). Omit for all agents.\",\n ),\n limit: z\n .number()\n .optional()\n .default(20)\n .describe(\n \"Maximum events to return, newest first. Defaults to 20. Increase for deeper investigations.\",\n ),\n },\n toolAnnotations(\"audit_log\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"audit_log\");\n if (toolBlock) return toolBlock;\n\n // Canary trip events are operator-facing counter-intelligence: exposing\n // them over MCP would let an agent enumerate which tripwires fired.\n // CLI `qring audit` remains the surface for reviewing trips.\n const events = queryAudit({\n key: params.key,\n action: params.action,\n agent: params.agent,\n })\n .filter((e) => e.action !== \"canary\")\n .slice(0, params.limit);\n\n if (events.length === 0) return text(\"No audit events found\");\n\n const lines = events.map((e) => {\n const parts = [e.timestamp, e.action];\n if (e.key) parts.push(e.key);\n if (e.scope) parts.push(`[${e.scope}]`);\n if (e.env) parts.push(`env:${e.env}`);\n if (e.agent) parts.push(`agent:${e.agent}`);\n if (e.detail) parts.push(e.detail);\n return parts.join(\" | \");\n });\n\n return text(lines.join(\"\\n\"));\n },\n );\n\n server.tool(\n \"detect_anomalies\",\n [\n \"[audit] Scan the audit history for suspicious access patterns — burst reads of the same key, off-hours access, and other heuristics.\",\n \"Use as a quick triage signal when investigating a single key or before letting an agent rotate credentials; prefer `health_check` for a scope-wide decay+anomaly summary, and `agent_scan` for multi-project JSON reports with optional auto-rotation.\",\n \"Read-only; never mutates secrets or the audit log. Returns one line per finding formatted `[type] description`, or 'No anomalies detected' when the log looks clean.\",\n ].join(\" \"),\n {\n key: z\n .string()\n .optional()\n .describe(\n \"If provided, narrow the scan to this exact key. Omit to scan across every key in the audit log.\",\n ),\n },\n toolAnnotations(\"detect_anomalies\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"detect_anomalies\");\n if (toolBlock) return toolBlock;\n\n const anomalies = detectAnomalies(params.key);\n if (anomalies.length === 0) return text(\"No anomalies detected\");\n\n const lines = anomalies.map((a) => `[${a.type}] ${a.description}`);\n return text(lines.join(\"\\n\"));\n },\n );\n\n server.tool(\n \"health_check\",\n [\n \"[health] Run a single read-only sweep over every secret in the requested scope and report counts of healthy/stale/expired secrets plus any current audit anomalies.\",\n \"Use as the default 'is everything OK?' command for an agent or operator; prefer `check_project` to validate manifest compliance specifically, `detect_anomalies` for audit-only triage, and `agent_scan` for multi-project JSON output or optional auto-rotation.\",\n \"Read-only — never writes. Returns a multi-line text summary: header counts (Total / Healthy / Stale / Expired / No decay / Anomalies), then per-secret `EXPIRED:` / `STALE:` issue lines, then per-anomaly `[type] description` lines.\",\n ].join(\" \"),\n {\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"health_check\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"health_check\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const entries = listSecrets(opts(params));\n const anomalies = detectAnomalies();\n\n let healthy = 0;\n let stale = 0;\n let expired = 0;\n let noDecay = 0;\n const issues: string[] = [];\n\n for (const entry of entries) {\n if (!entry.decay?.timeRemaining) {\n noDecay++;\n continue;\n }\n if (entry.decay.isExpired) {\n expired++;\n issues.push(`EXPIRED: ${entry.key}`);\n } else if (entry.decay.isStale) {\n stale++;\n issues.push(\n `STALE: ${entry.key} (${entry.decay.lifetimePercent}%, ${entry.decay.timeRemaining} left)`,\n );\n } else {\n healthy++;\n }\n }\n\n const summary = [\n `Secrets: ${entries.length} total`,\n `Healthy: ${healthy} | Stale: ${stale} | Expired: ${expired} | No decay: ${noDecay}`,\n `Anomalies: ${anomalies.length}`,\n ];\n\n if (issues.length > 0) {\n summary.push(\"\", \"Issues:\", ...issues);\n }\n if (anomalies.length > 0) {\n summary.push(\"\", \"Anomalies:\", ...anomalies.map((a) => `[${a.type}] ${a.description}`));\n }\n\n return text(summary.join(\"\\n\"));\n },\n );\n\n server.tool(\n \"verify_audit_chain\",\n [\n \"[audit] Recompute the SHA-256 hash chain over the audit log and confirm no event has been mutated, deleted, or reordered.\",\n \"Use periodically as a tamper-evidence check, or whenever you suspect the audit log has been touched outside q-ring; the result is informational — this tool does not repair the chain if it is broken.\",\n \"Read-only. Returns JSON `{ ok, valid, brokenAt? }` where `valid` is `true` for an intact chain and `brokenAt` (when present) names the first event whose hash did not match.\",\n ].join(\" \"),\n {},\n toolAnnotations(\"verify_audit_chain\"),\n async () => {\n const toolBlock = enforceToolPolicy(\"verify_audit_chain\");\n if (toolBlock) return toolBlock;\n\n const result = verifyAuditChain();\n return text(JSON.stringify(result, null, 2));\n },\n );\n\n server.tool(\n \"export_audit\",\n [\n \"[audit] Export the audit log as a portable text artifact suitable for archiving or feeding into another SIEM/analyzer.\",\n \"Use for compliance exports, after-the-fact investigations, or to hand the trail to a non-MCP consumer; prefer `audit_log` for an in-conversation tail and `verify_audit_chain` to confirm integrity before exporting.\",\n \"Read-only. Returns the rendered text directly (no JSON wrapper). 'jsonl' is one event per line; 'json' is a single array; 'csv' is a header row plus events. Time filters are applied to the event timestamps before formatting.\",\n ].join(\" \"),\n {\n since: z\n .string()\n .optional()\n .describe(\n \"Inclusive lower bound on event timestamp, ISO 8601. Example: '2026-04-01T00:00:00Z'. Omit for no lower bound.\",\n ),\n until: z\n .string()\n .optional()\n .describe(\n \"Inclusive upper bound on event timestamp, ISO 8601. Omit for now/no upper bound.\",\n ),\n format: z\n .enum([\"jsonl\", \"json\", \"csv\"])\n .optional()\n .default(\"jsonl\")\n .describe(\n \"Output format. 'jsonl' (default) is most stream-friendly; 'json' is a single array; 'csv' is spreadsheet-friendly.\",\n ),\n },\n toolAnnotations(\"export_audit\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"export_audit\");\n if (toolBlock) return toolBlock;\n\n const output = exportAudit({\n since: params.since,\n until: params.until,\n format: params.format,\n // Same rationale as audit_log: trip records stay operator-facing.\n excludeActions: [\"canary\"],\n });\n return text(output);\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { z } from \"zod\";\nimport { getSecret, setSecret, getEnvelope, listSecrets } from \"../../core/keyring.js\";\nimport type { Scope } from \"../../core/scope.js\";\nimport {\n validateSecret,\n rotateWithProvider,\n ciValidateBatch,\n registry as providerRegistry,\n} from \"../../core/validate.js\";\nimport { text, opts, enforceToolPolicy, commonSchemas } from \"./_shared.js\";\n\nconst { teamId, orgId, scope, projectPath } = commonSchemas;\n\nexport function registerValidationTools(server: McpServer): void {\n server.tool(\n \"validate_secret\",\n [\n \"[validation] Test whether a stored secret is still accepted by its upstream service (OpenAI, Stripe, GitHub, AWS, generic HTTP, etc.) by making a minimal authenticated request.\",\n \"Use to confirm liveness before relying on a credential or as the verification step after `rotate_secret`; prefer `ci_validate_secrets` for a batch run across every key in scope.\",\n \"Side effects: makes one outbound network request per call (may incur tiny provider-side rate-limit cost). Records 'read' for the underlying secret value in the audit log; the value itself is never logged. Returns JSON `{ valid, provider, status?, message?, rateLimit?, ... }` (provider-specific shape).\",\n ].join(\" \"),\n {\n key: z\n .string()\n .describe(\n \"The exact key whose value should be tested upstream. Example: 'OPENAI_API_KEY'.\",\n ),\n provider: z\n .string()\n .optional()\n .describe(\n \"Force a specific provider id. Built-ins include 'openai', 'stripe', 'github', 'aws', 'http'. Omit to auto-detect from the value's prefix or the secret's stored provider hint.\",\n ),\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"validate_secret\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"validate_secret\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const value = getSecret(params.key, opts(params));\n if (value === null) return text(`Secret \"${params.key}\" not found`, true);\n\n const envelope = getEnvelope(params.key, opts(params));\n const provHint = params.provider ?? envelope?.envelope.meta.provider;\n\n const result = await validateSecret(value, { provider: provHint });\n return text(JSON.stringify(result, null, 2));\n },\n );\n\n server.tool(\n \"list_providers\",\n [\n \"[validation] Enumerate the secret-validation providers q-ring knows how to call (OpenAI, Stripe, GitHub, …) along with their auto-detect prefixes.\",\n \"Use to discover what `provider` string to pass to `validate_secret`/`rotate_secret`, or to check whether your custom provider is registered.\",\n \"Read-only. Returns JSON array of `{ name, description, prefixes }` objects. `prefixes` are the literal key-value prefixes (e.g. 'sk-' for OpenAI) used for auto-detection.\",\n ].join(\" \"),\n {},\n toolAnnotations(\"list_providers\"),\n async () => {\n const toolBlock = enforceToolPolicy(\"list_providers\");\n if (toolBlock) return toolBlock;\n\n const providers = providerRegistry.listProviders().map((p) => ({\n name: p.name,\n description: p.description,\n prefixes: p.prefixes ?? [],\n }));\n return text(JSON.stringify(providers, null, 2));\n },\n );\n\n server.tool(\n \"rotate_secret\",\n [\n \"[validation] Ask the upstream provider to issue a fresh credential for this secret and store the new value back into the keyring.\",\n \"Use when a secret is expiring, leaked, or part of a scheduled rotation; prefer `generate_secret` for self-managed values you fully control, and `agent_scan --autoRotate` for sweep-style rotation across multiple expired keys.\",\n \"Mutates the keyring with the newly-issued value if rotation succeeds (one 'write' audit event), and makes outbound network requests against the provider's rotation API. Returns JSON `{ rotated, newValue?, message?, ... }`. If `rotated` is false, the existing value is left untouched.\",\n ].join(\" \"),\n {\n key: z.string().describe(\"Exact key to rotate. Must already exist in the keyring.\"),\n provider: z\n .string()\n .optional()\n .describe(\n \"Force a specific provider id (see `list_providers`). Omit to auto-detect from the current value or the secret's stored provider hint.\",\n ),\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"rotate_secret\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"rotate_secret\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const value = getSecret(params.key, opts(params));\n if (!value) return text(`Secret \"${params.key}\" not found`, true);\n\n const result = await rotateWithProvider(value, params.provider);\n if (result.rotated && result.newValue) {\n setSecret(params.key, result.newValue, {\n scope: (params.scope as Scope) ?? \"global\",\n projectPath: params.projectPath,\n source: \"mcp\",\n });\n }\n return text(JSON.stringify(result, null, 2));\n },\n );\n\n server.tool(\n \"ci_validate_secrets\",\n [\n \"[validation] Validate every accessible secret in the requested scope against its detected provider in a single batch and return a structured pass/fail report.\",\n \"Use as a CI gate ('do all our credentials still work before deploy?') or as a pre-rotation health pass; prefer `validate_secret` for a single key.\",\n \"Side effects: one outbound request per validatable secret (cost scales with N). Reads each secret value (records 'read' audit events). Returns JSON `{ total, valid, invalid, results: [...] }` listing per-key status, provider, and error messages where applicable. Returns 'No secrets to validate' if nothing in scope has a provider mapping.\",\n ].join(\" \"),\n {\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"ci_validate_secrets\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"ci_validate_secrets\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const entries = listSecrets(opts(params));\n const secrets = entries\n .map((e) => {\n const val = getSecret(e.key, {\n ...opts(params),\n scope: e.scope,\n silent: true,\n });\n if (!val) return null;\n return {\n key: e.key,\n value: val,\n provider: e.envelope?.meta.provider,\n validationUrl: e.envelope?.meta.validationUrl,\n };\n })\n .filter((s): s is NonNullable<typeof s> => s !== null);\n\n if (secrets.length === 0) return text(\"No secrets to validate\");\n\n const report = await ciValidateBatch(secrets);\n return text(JSON.stringify(report, null, 2));\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { z } from \"zod\";\nimport {\n registerHook,\n removeHook,\n listHooks as listAllHooks,\n type HookType,\n type HookAction,\n} from \"../../core/hooks.js\";\nimport { text, enforceToolPolicy } from \"./_shared.js\";\n\nexport function registerHookTools(server: McpServer): void {\n server.tool(\n \"register_hook\",\n [\n \"[hooks] Register a side-effect (shell command, HTTP webhook, or process signal) that fires automatically when a matching secret is written, deleted, or rotated.\",\n \"Use to keep external systems in sync (restart a service after rotation, post to Slack on delete, kick a build); prefer `agent_remember` for storing facts an agent should recall later, and `register_hook` is not the right tool for time-based scheduled rotation (use `agent_scan` for that).\",\n \"Mutates the hook registry on disk. At least one match criterion (`key`, `keyPattern`, or `tag`) is required — calls without any return an error. Returns JSON of the registered hook entry including its assigned `id` (use that `id` with `remove_hook`).\",\n ].join(\" \"),\n {\n type: z\n .enum([\"shell\", \"http\", \"signal\"])\n .describe(\n \"Hook delivery mechanism. 'shell' runs a local command, 'http' POSTs JSON to a URL, 'signal' sends an OS signal to a named process.\",\n ),\n key: z\n .string()\n .optional()\n .describe(\n \"Trigger only on this exact key name. Pick at most one of `key` / `keyPattern` / `tag` (or combine for stricter matching).\",\n ),\n keyPattern: z\n .string()\n .optional()\n .describe(\"Trigger on any key matching this glob pattern. Examples: 'DB_*', 'STRIPE_*'.\"),\n tag: z\n .string()\n .optional()\n .describe(\n \"Trigger on any secret carrying this exact tag. Combinable with key/keyPattern as an AND filter.\",\n ),\n scope: z\n .enum([\"global\", \"project\"])\n .optional()\n .describe(\n \"Restrict the hook to secrets in this scope. Omit to fire across both global and project secrets.\",\n ),\n actions: z\n .array(z.enum([\"write\", \"delete\", \"rotate\"]))\n .optional()\n .default([\"write\", \"delete\", \"rotate\"])\n .describe(\"Which lifecycle actions trigger this hook. Defaults to all three.\"),\n command: z\n .string()\n .optional()\n .describe(\n \"Required when type='shell'. The literal shell command to run; q-ring exposes the matching key as $QRING_HOOK_KEY and action as $QRING_HOOK_ACTION.\",\n ),\n url: z\n .string()\n .optional()\n .describe(\n \"Required when type='http'. Full URL to POST a JSON body `{ id, key, scope, action, timestamp }` to (the value itself is never sent).\",\n ),\n signalTarget: z\n .string()\n .optional()\n .describe(\n \"Required when type='signal'. Either a numeric PID or a process name resolvable via `ps`.\",\n ),\n signalName: z\n .string()\n .optional()\n .default(\"SIGHUP\")\n .describe(\n \"Signal name to send (e.g. 'SIGHUP', 'SIGUSR1'). Defaults to SIGHUP, which most daemons treat as 'reload config'.\",\n ),\n description: z\n .string()\n .optional()\n .describe(\n \"Free-text human-readable description, surfaced by `list_hooks` and the dashboard.\",\n ),\n },\n toolAnnotations(\"register_hook\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"register_hook\");\n if (toolBlock) return toolBlock;\n\n if (!params.key && !params.keyPattern && !params.tag) {\n return text(\"At least one match criterion required: key, keyPattern, or tag\", true);\n }\n\n const entry = registerHook({\n type: params.type as HookType,\n match: {\n key: params.key,\n keyPattern: params.keyPattern,\n tag: params.tag,\n scope: params.scope as \"global\" | \"project\" | undefined,\n action: params.actions as HookAction[],\n },\n command: params.command,\n url: params.url,\n signal: params.signalTarget\n ? { target: params.signalTarget, signal: params.signalName }\n : undefined,\n description: params.description,\n enabled: true,\n });\n\n return text(JSON.stringify(entry, null, 2));\n },\n );\n\n server.tool(\n \"list_hooks\",\n [\n \"[hooks] Enumerate every registered lifecycle hook with its match criteria, delivery type, enabled flag, and description.\",\n \"Use to find a hook's `id` before calling `remove_hook`, audit what side effects are wired up, or diagnose why a hook did not fire.\",\n \"Read-only. Returns pretty-printed JSON array of hook entries, or 'No hooks registered' when the registry is empty.\",\n ].join(\" \"),\n {},\n toolAnnotations(\"list_hooks\"),\n async () => {\n const toolBlock = enforceToolPolicy(\"list_hooks\");\n if (toolBlock) return toolBlock;\n\n const hooks = listAllHooks();\n if (hooks.length === 0) return text(\"No hooks registered\");\n return text(JSON.stringify(hooks, null, 2));\n },\n );\n\n server.tool(\n \"remove_hook\",\n [\n \"[hooks] Detach a single lifecycle hook by its registry id so it stops firing.\",\n \"Use to retire a specific webhook/command without touching any secrets; prefer `delete_secret` to remove a credential and `tunnel_destroy` for ephemeral tunnels.\",\n \"Mutates the hook registry only — does not touch secret values, audit log, or env states. Idempotent in spirit: removing an already-absent id returns a not-found error rather than partial work. Returns 'Removed hook ID' on success.\",\n ].join(\" \"),\n {\n id: z\n .string()\n .describe(\n \"Hook id returned by `register_hook` or visible in `list_hooks` (opaque string).\",\n ),\n },\n toolAnnotations(\"remove_hook\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"remove_hook\");\n if (toolBlock) return toolBlock;\n\n const removed = removeHook(params.id);\n return text(\n removed ? `Removed hook ${params.id}` : `Hook \"${params.id}\" not found`,\n !removed,\n );\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { z } from \"zod\";\nimport { listSecrets } from \"../../core/keyring.js\";\nimport { runHealthScan } from \"../../core/agent.js\";\nimport { queryAudit } from \"../../core/observer.js\";\nimport { execCommand } from \"../../core/exec.js\";\nimport { scanCodebase } from \"../../core/scan.js\";\nimport { lintFiles } from \"../../core/linter.js\";\nimport { checkExecPolicy } from \"../../core/policy.js\";\nimport { text, opts, enforceToolPolicy, commonSchemas } from \"./_shared.js\";\n\nconst { teamId, orgId, scope, projectPath } = commonSchemas;\n\nexport function registerToolingTools(server: McpServer): void {\n server.tool(\n \"exec_with_secrets\",\n [\n \"[exec] Run a child shell command with project secrets injected as environment variables and any leaked secret values redacted from captured stdout/stderr before they return to the agent.\",\n \"Use to let an agent run a script that needs credentials (`npm run db:migrate`, `terraform plan`, `vercel deploy`) without ever putting plaintext values in the chat; prefer `env_generate` if you need to write a `.env` file to disk and `validate_secret` for upstream liveness checks.\",\n \"Spawns a real child process — has whatever side effects the command itself causes (writes, network, exec). Subject to BOTH tool policy and exec policy (allowlist/denylist). Returns a text body with `Exit code: N` then `STDOUT:` and `STDERR:` blocks; both streams are scrubbed against the secret values that were injected.\",\n ].join(\" \"),\n {\n command: z\n .string()\n .describe(\n \"Executable name or full command to run. Example: 'pnpm', 'node', '/usr/bin/env'. Must be allowed by exec policy.\",\n ),\n args: z\n .array(z.string())\n .optional()\n .describe(\n \"Positional arguments passed to `command`. Example: ['run', 'db:migrate']. Each element is passed verbatim with no extra shell parsing.\",\n ),\n keys: z\n .array(z.string())\n .optional()\n .describe(\n \"Whitelist of exact key names to inject. Omit to inject every secret in scope (subject to `tags`).\",\n ),\n tags: z\n .array(z.string())\n .optional()\n .describe(\n \"Inject only secrets carrying at least one of these tags. Combinable with `keys` as an AND filter.\",\n ),\n profile: z\n .enum([\"unrestricted\", \"restricted\", \"ci\"])\n .optional()\n .default(\"restricted\")\n .describe(\n \"Exec sandbox profile. 'restricted' (default) denies network-tool binaries (curl, wget, ssh, scp, nc, netcat, ncat) AND common interpreters/shells (python, node, deno, bun, perl, ruby, php, sh, bash, zsh) — since those could otherwise egress the injected secrets — strips proxy env vars, and caps runtime at 30s. It still is NOT a real OS sandbox (it does not restrict PATH, and some allowed binary could in principle make network calls); for genuinely untrusted commands use OS-level isolation (containers, network namespaces). 'ci' allows network and interpreters with a 300s cap and blocks a few destructive commands; 'unrestricted' inherits the full server environment. Define a custom profile in .q-ring.json to allow specific interpreters with secrets.\",\n ),\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"exec_with_secrets\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"exec_with_secrets\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const execBlock = checkExecPolicy(params.command, params.projectPath);\n if (!execBlock.allowed) {\n return text(`Policy Denied: ${execBlock.reason}`, true);\n }\n\n try {\n const result = await execCommand({\n command: params.command,\n args: params.args ?? [],\n keys: params.keys,\n tags: params.tags,\n profile: params.profile,\n scope: params.scope,\n projectPath: params.projectPath,\n source: \"mcp\",\n captureOutput: true,\n });\n\n const output: string[] = [];\n output.push(`Exit code: ${result.code}`);\n if (result.stdout) output.push(`STDOUT:\\n${result.stdout}`);\n if (result.stderr) output.push(`STDERR:\\n${result.stderr}`);\n\n return text(output.join(\"\\n\\n\"));\n } catch (err) {\n return text(`Execution failed: ${err instanceof Error ? err.message : String(err)}`, true);\n }\n },\n );\n\n server.tool(\n \"scan_codebase_for_secrets\",\n [\n \"[scan] Walk a directory tree and flag plausible hardcoded secrets using regex heuristics plus Shannon-entropy scoring on string literals.\",\n \"Use as a one-shot 'is anything leaking in this repo?' audit before commit/release; prefer `lint_files` when you already know the specific files to check (and want optional auto-fix).\",\n \"Read-only — never modifies source files. Honors `.gitignore`. Returns JSON array of `{ file, line, key, value, kind }` findings, or 'No hardcoded secrets found in the specified directory.' when clean. False positives are possible — review before treating as ground truth.\",\n ].join(\" \"),\n {\n dirPath: z\n .string()\n .describe(\n \"Directory to scan, absolute or relative to the server cwd. The scan recurses into subdirectories.\",\n ),\n },\n toolAnnotations(\"scan_codebase_for_secrets\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"scan_codebase_for_secrets\");\n if (toolBlock) return toolBlock;\n\n try {\n const results = scanCodebase(params.dirPath);\n if (results.length === 0) {\n return text(\"No hardcoded secrets found in the specified directory.\");\n }\n return text(JSON.stringify(results, null, 2));\n } catch (err) {\n return text(`Scan failed: ${err instanceof Error ? err.message : String(err)}`, true);\n }\n },\n );\n\n server.tool(\n \"lint_files\",\n [\n \"[scan] Inspect a specific list of files for hardcoded secrets and, when `fix` is true, replace each finding with `process.env.KEY` while storing the extracted value into the keyring.\",\n \"Use to migrate a known set of files (e.g. just-changed files in a pre-commit hook) into q-ring; prefer `scan_codebase_for_secrets` for a whole-tree audit and `import_dotenv` to ingest an existing .env.\",\n \"With `fix: false` this is read-only. With `fix: true` this MUTATES the listed source files in place (review with git diff!) and writes one new secret per finding to the keyring. Returns a JSON array of `{ file, line, key, value, kind }` findings, or 'No hardcoded secrets found in the specified files.'.\",\n ].join(\" \"),\n {\n files: z\n .array(z.string())\n .describe(\"Absolute or relative paths to lint. Non-existent paths surface as scan errors.\"),\n fix: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n \"If true, rewrite the source files to read `process.env.KEY` and store the extracted value in the keyring. If false (default), only report findings.\",\n ),\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"lint_files\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"lint_files\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n try {\n const results = lintFiles(params.files, {\n fix: params.fix,\n scope: params.scope as \"global\" | \"project\" | undefined,\n projectPath: params.projectPath,\n });\n if (results.length === 0) {\n return text(\"No hardcoded secrets found in the specified files.\");\n }\n return text(JSON.stringify(results, null, 2));\n } catch (err) {\n return text(`Lint failed: ${err instanceof Error ? err.message : String(err)}`, true);\n }\n },\n );\n\n server.tool(\n \"analyze_secrets\",\n [\n \"[agent] Cross-reference the secrets in scope with recent audit events to produce a usage profile and rotation/retirement suggestions.\",\n \"Use as a quarterly hygiene check or as input to a planner that decides what to rotate or delete; prefer `health_check` for decay-only triage and `audit_log` to inspect access timelines for one key.\",\n \"Read-only; uses the most recent ~500 audit events. Returns JSON `{ total, expired, stale, neverAccessed: [...], noRotationFormat: [...], mostAccessed: [{ key, reads }] }`. `neverAccessed` and `noRotationFormat` are good candidates for cleanup or for adding rotation hints.\",\n ].join(\" \"),\n {\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"analyze_secrets\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"analyze_secrets\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const o = opts(params);\n const entries = listSecrets({ ...o, silent: true });\n const audit = queryAudit({ limit: 500 });\n\n const accessMap = new Map<string, number>();\n for (const e of audit) {\n if (e.action === \"read\" && e.key) {\n accessMap.set(e.key, (accessMap.get(e.key) || 0) + 1);\n }\n }\n\n const analysis = {\n total: entries.length,\n expired: entries.filter((e) => e.decay?.isExpired).length,\n stale: entries.filter((e) => e.decay?.isStale && !e.decay?.isExpired).length,\n neverAccessed: entries\n .filter((e) => (e.envelope?.meta.accessCount ?? 0) === 0)\n .map((e) => e.key),\n noRotationFormat: entries.filter((e) => !e.envelope?.meta.rotationFormat).map((e) => e.key),\n mostAccessed: [...accessMap.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 10)\n .map(([key, count]) => ({ key, reads: count })),\n };\n\n return text(JSON.stringify(analysis, null, 2));\n },\n );\n\n // One process-scoped instance; reusing across tool invocations avoids\n // leaking listeners when the MCP client pings `status_dashboard` twice.\n let dashboardInstance: { port: number; url: string; close: () => void } | null = null;\n\n server.tool(\n \"status_dashboard\",\n [\n \"[dashboard] Start a local web dashboard (`http://127.0.0.1:PORT`) that streams live KPIs, secret tables, manifest gaps, hooks, audit events, and anomalies via Server-Sent Events.\",\n \"Use when an operator (or an agent on behalf of one) wants a richer visual surface than chat output; prefer `health_check` / `analyze_secrets` for one-shot text summaries inside the conversation.\",\n \"Side effect: binds an HTTP server on the requested port (one process-wide instance — re-running returns the existing URL instead of starting a second server). Never exposes secret values. Returns the URL string to open in a browser.\",\n ].join(\" \"),\n {\n port: z\n .number()\n .optional()\n .default(9876)\n .describe(\n \"TCP port to listen on (default 9876). Pick another port if 9876 is already in use; the call fails if binding errors.\",\n ),\n },\n toolAnnotations(\"status_dashboard\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"status_dashboard\");\n if (toolBlock) return toolBlock;\n\n if (dashboardInstance) {\n return text(`Dashboard already running at ${dashboardInstance.url}`);\n }\n\n const { startDashboardServer } = await import(\"../../core/dashboard.js\");\n dashboardInstance = startDashboardServer({ port: params.port });\n\n return text(\n `Dashboard started at ${dashboardInstance.url}\\nOpen this URL in a browser to see live quantum status. The token is required for access.`,\n );\n },\n );\n\n server.tool(\n \"agent_scan\",\n [\n \"[agent] Run a multi-project health pass that gathers decay status, audit anomalies, and `.q-ring.json` manifest gaps across one or more project paths and (optionally) auto-rotates expired secrets with freshly generated values.\",\n \"Use as the canonical 'agent maintenance loop' across a portfolio of repos; prefer `health_check` for a single read-only scope, `detect_anomalies` for audit-only triage, and `check_project` for a single-project manifest check.\",\n \"With `autoRotate=false` (default) this is read-only. With `autoRotate=true` it OVERWRITES expired secret values in the keyring with generated replacements — credential changes that may break upstream integrations until they are propagated. Subject to tool policy. Returns a JSON report of per-project findings and any rotations performed.\",\n ].join(\" \"),\n {\n autoRotate: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n \"If true, replace expired secrets with newly generated values (using each secret's `rotationFormat`/`rotationPrefix`). Only enable when intentional rotation is desired — this is destructive on the upstream side.\",\n ),\n projectPaths: z\n .array(z.string())\n .optional()\n .describe(\n \"List of absolute project roots to scan. Defaults to `[server.cwd]` when omitted.\",\n ),\n },\n toolAnnotations(\"agent_scan\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"agent_scan\");\n if (toolBlock) return toolBlock;\n\n const report = runHealthScan({\n autoRotate: params.autoRotate,\n projectPaths: params.projectPaths ?? [process.cwd()],\n });\n return text(JSON.stringify(report, null, 2));\n },\n );\n}\n","/**\n * Minimal ANSI color helpers. No dependencies.\n */\n\nconst enabled = process.stdout.isTTY !== false && !process.env.NO_COLOR;\n\nfunction wrap(code: string, text: string): string {\n return enabled ? `\\x1b[${code}m${text}\\x1b[0m` : text;\n}\n\nexport const c = {\n bold: (t: string) => wrap(\"1\", t),\n dim: (t: string) => wrap(\"2\", t),\n italic: (t: string) => wrap(\"3\", t),\n underline: (t: string) => wrap(\"4\", t),\n\n red: (t: string) => wrap(\"31\", t),\n green: (t: string) => wrap(\"32\", t),\n yellow: (t: string) => wrap(\"33\", t),\n blue: (t: string) => wrap(\"34\", t),\n magenta: (t: string) => wrap(\"35\", t),\n cyan: (t: string) => wrap(\"36\", t),\n white: (t: string) => wrap(\"37\", t),\n gray: (t: string) => wrap(\"90\", t),\n\n bgRed: (t: string) => wrap(\"41\", t),\n bgGreen: (t: string) => wrap(\"42\", t),\n bgYellow: (t: string) => wrap(\"43\", t),\n bgBlue: (t: string) => wrap(\"44\", t),\n bgMagenta: (t: string) => wrap(\"45\", t),\n bgCyan: (t: string) => wrap(\"46\", t),\n};\n\nexport function scopeColor(scope: string): string {\n return scope === \"project\" ? c.cyan(scope) : c.blue(scope);\n}\n\nexport function decayIndicator(percent: number, expired: boolean): string {\n if (expired) return c.bgRed(c.white(\" EXPIRED \"));\n if (percent >= 90) return c.red(`[decay ${percent}%]`);\n if (percent >= 75) return c.yellow(`[decay ${percent}%]`);\n if (percent > 0) return c.green(`[decay ${percent}%]`);\n return \"\";\n}\n\nexport function envBadge(env: string): string {\n switch (env) {\n case \"prod\":\n return c.bgRed(c.white(` ${env} `));\n case \"staging\":\n return c.bgYellow(c.white(` ${env} `));\n case \"dev\":\n return c.bgGreen(c.white(` ${env} `));\n case \"test\":\n return c.bgBlue(c.white(` ${env} `));\n default:\n return c.bgMagenta(c.white(` ${env} `));\n }\n}\n\nexport const SYMBOLS = {\n check: enabled ? \"\\u2713\" : \"[ok]\",\n cross: enabled ? \"\\u2717\" : \"[x]\",\n arrow: enabled ? \"\\u2192\" : \"->\",\n dot: enabled ? \"\\u2022\" : \"*\",\n lock: enabled ? \"\\u{1f512}\" : \"[locked]\",\n key: enabled ? \"\\u{1f511}\" : \"[key]\",\n link: enabled ? \"\\u{1f517}\" : \"[link]\",\n warning: enabled ? \"\\u26a0\\ufe0f\" : \"[!]\",\n clock: enabled ? \"\\u23f0\" : \"[time]\",\n shield: enabled ? \"\\u{1f6e1}\\ufe0f\" : \"[shield]\",\n zap: enabled ? \"\\u26a1\" : \"[zap]\",\n eye: enabled ? \"\\u{1f441}\\ufe0f\" : \"[eye]\",\n ghost: enabled ? \"\\u{1f47b}\" : \"[ghost]\",\n package: enabled ? \"\\u{1f4e6}\" : \"[pkg]\",\n sparkle: enabled ? \"\\u2728\" : \"[*]\",\n} as const;\n","/**\n * Quantum Agent: autonomous background monitor for secret health.\n *\n * Runs as a long-lived process that periodically:\n * - Checks for expired/stale secrets (decay monitoring)\n * - Detects access anomalies (observer analysis)\n * - Logs health reports\n * - Can trigger rotation callbacks\n *\n * Designed to run as `qring agent` or be invoked by the MCP server.\n */\n\nimport { listSecrets, setSecret } from \"./keyring.js\";\nimport { checkDecay } from \"./envelope.js\";\nimport { detectAnomalies, logAudit } from \"./observer.js\";\nimport { generateSecret } from \"./noise.js\";\nimport { fireHooks } from \"./hooks.js\";\nimport { c, SYMBOLS } from \"../utils/colors.js\";\n\nexport interface AgentConfig {\n /** Check interval in seconds (default: 60) */\n intervalSeconds: number;\n /** Auto-rotate expired secrets with generated values */\n autoRotate: boolean;\n /** Project paths to monitor */\n projectPaths: string[];\n /** Verbose output */\n verbose: boolean;\n}\n\nexport interface AgentReport {\n timestamp: string;\n totalSecrets: number;\n healthy: number;\n stale: number;\n expired: number;\n anomalies: number;\n rotated: string[];\n warnings: string[];\n}\n\nfunction defaultConfig(): AgentConfig {\n return {\n intervalSeconds: 60,\n autoRotate: false,\n projectPaths: [process.cwd()],\n verbose: false,\n };\n}\n\nexport function runHealthScan(config: Partial<AgentConfig> = {}): AgentReport {\n const cfg = { ...defaultConfig(), ...config };\n\n const report: AgentReport = {\n timestamp: new Date().toISOString(),\n totalSecrets: 0,\n healthy: 0,\n stale: 0,\n expired: 0,\n anomalies: 0,\n rotated: [],\n warnings: [],\n };\n\n // Scan global scope\n const globalEntries = listSecrets({ scope: \"global\", source: \"agent\" });\n\n // Scan project scopes\n const projectEntries = cfg.projectPaths.flatMap((pp) =>\n listSecrets({ scope: \"project\", projectPath: pp, source: \"agent\" }),\n );\n\n const allEntries = [...globalEntries, ...projectEntries];\n report.totalSecrets = allEntries.length;\n\n for (const entry of allEntries) {\n if (!entry.envelope) continue;\n\n const decay = checkDecay(entry.envelope);\n\n if (decay.isExpired) {\n report.expired++;\n report.warnings.push(\n `EXPIRED: ${entry.key} [${entry.scope}] — expired ${decay.timeRemaining}`,\n );\n\n if (cfg.autoRotate) {\n const fmt = (entry.envelope?.meta.rotationFormat ?? \"api-key\") as import(\"./noise.js\").NoiseFormat;\n const prefix = entry.envelope?.meta.rotationPrefix;\n const newValue = generateSecret({ format: fmt, prefix });\n setSecret(entry.key, newValue, {\n scope: entry.scope,\n projectPath: cfg.projectPaths[0],\n source: \"agent\",\n });\n report.rotated.push(entry.key);\n logAudit({\n action: \"write\",\n key: entry.key,\n scope: entry.scope,\n source: \"agent\",\n detail: \"auto-rotated by agent (expired)\",\n });\n fireHooks({\n action: \"rotate\",\n key: entry.key,\n scope: entry.scope,\n timestamp: new Date().toISOString(),\n source: \"agent\",\n }, entry.envelope?.meta.tags).catch(() => {});\n }\n } else if (decay.isStale) {\n report.stale++;\n report.warnings.push(\n `STALE: ${entry.key} [${entry.scope}] — ${decay.lifetimePercent}% lifetime, ${decay.timeRemaining} remaining`,\n );\n } else {\n report.healthy++;\n }\n }\n\n // Check for anomalies\n const anomalies = detectAnomalies();\n report.anomalies = anomalies.length;\n for (const a of anomalies) {\n report.warnings.push(`ANOMALY [${a.type}]: ${a.description}`);\n }\n\n return report;\n}\n\nfunction formatReport(report: AgentReport, verbose: boolean): string {\n const lines: string[] = [];\n\n lines.push(\n `${c.bold(`${SYMBOLS.shield} q-ring agent scan`)} ${c.dim(report.timestamp)}`,\n );\n lines.push(\n ` ${c.dim(\"secrets:\")} ${report.totalSecrets} ${c.green(`${SYMBOLS.check} ${report.healthy}`)} ${c.yellow(`${SYMBOLS.warning} ${report.stale}`)} ${c.red(`${SYMBOLS.cross} ${report.expired}`)} ${c.dim(`anomalies: ${report.anomalies}`)}`,\n );\n\n if (report.rotated.length > 0) {\n lines.push(\n ` ${c.cyan(`${SYMBOLS.zap} auto-rotated:`)} ${report.rotated.join(\", \")}`,\n );\n }\n\n if (verbose && report.warnings.length > 0) {\n lines.push(\"\");\n for (const w of report.warnings) {\n if (w.startsWith(\"EXPIRED\")) lines.push(` ${c.red(w)}`);\n else if (w.startsWith(\"STALE\")) lines.push(` ${c.yellow(w)}`);\n else if (w.startsWith(\"ANOMALY\")) lines.push(` ${c.magenta(w)}`);\n else lines.push(` ${w}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Run the agent as a continuous background monitor.\n */\nexport async function startAgent(config: Partial<AgentConfig> = {}): Promise<void> {\n const cfg = { ...defaultConfig(), ...config };\n\n console.log(\n `${c.bold(`${SYMBOLS.zap} q-ring agent started`)} ${c.dim(`(interval: ${cfg.intervalSeconds}s, auto-rotate: ${cfg.autoRotate})`)}`,\n );\n console.log(\n c.dim(` monitoring: global + ${cfg.projectPaths.length} project(s)`),\n );\n console.log();\n\n const scan = () => {\n const report = runHealthScan(cfg);\n console.log(formatReport(report, cfg.verbose));\n\n if (report.warnings.length > 0 || cfg.verbose) {\n console.log();\n }\n };\n\n // Initial scan\n scan();\n\n // Continuous monitoring\n const interval = setInterval(scan, cfg.intervalSeconds * 1000);\n\n // Graceful shutdown\n const shutdown = () => {\n clearInterval(interval);\n console.log(`\\n${c.dim(\"q-ring agent stopped\")}`);\n process.exit(0);\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n\n // Keep alive\n await new Promise(() => {});\n}\n","/**\n * Secure Execution & Auto-Redaction\n *\n * Runs child processes with project secrets injected into the environment.\n * Captures stdout/stderr and redacts any known secret values before they\n * are printed to the terminal or returned to the MCP agent.\n *\n * Exec profiles restrict which commands may be run, with optional\n * network and timeout controls.\n */\n\nimport { spawn } from \"node:child_process\";\nimport { StringDecoder } from \"node:string_decoder\";\nimport { Transform } from \"node:stream\";\nimport { listSecrets, getSecret, type KeyringOptions } from \"./keyring.js\";\nimport { checkDecay } from \"./envelope.js\";\nimport { checkExecPolicy, getExecMaxRuntime } from \"./policy.js\";\n\nexport interface ExecProfile {\n name: string;\n allowCommands?: string[];\n denyCommands?: string[];\n maxRuntimeSeconds?: number;\n allowNetwork?: boolean;\n stripEnvVars?: string[];\n}\n\nconst BUILTIN_PROFILES: Record<string, ExecProfile> = {\n unrestricted: { name: \"unrestricted\" },\n restricted: {\n name: \"restricted\",\n denyCommands: [\n // Network tools.\n \"curl\", \"wget\", \"ssh\", \"scp\", \"nc\", \"netcat\", \"ncat\",\n // Interpreters and shells: given the secret env vars, `python -c`,\n // `node -e`, `bash -c`, etc. can perform arbitrary network I/O and\n // exfiltrate them, defeating allowNetwork. Denied by default in\n // `restricted`; to run them with secrets use a custom profile in\n // .q-ring.json, or the `ci` / `unrestricted` profile.\n \"python\", \"python2\", \"python3\", \"node\", \"deno\", \"bun\",\n \"perl\", \"ruby\", \"php\", \"sh\", \"bash\", \"zsh\",\n ],\n maxRuntimeSeconds: 30,\n allowNetwork: false,\n stripEnvVars: [\"HTTP_PROXY\", \"HTTPS_PROXY\", \"ALL_PROXY\"],\n },\n ci: {\n name: \"ci\",\n maxRuntimeSeconds: 300,\n allowNetwork: true,\n denyCommands: [\"rm -rf /\", \"mkfs\", \"dd if=\"],\n },\n};\n\nexport function getProfile(name?: string): ExecProfile {\n if (!name) return BUILTIN_PROFILES.unrestricted;\n return BUILTIN_PROFILES[name] ?? { name };\n}\n\nexport function listProfiles(): ExecProfile[] {\n return Object.values(BUILTIN_PROFILES);\n}\n\nexport interface ExecOptions extends KeyringOptions {\n tags?: string[];\n keys?: string[];\n command: string;\n args: string[];\n /** If true, return output as string instead of piping to process.stdout */\n captureOutput?: boolean;\n /** Exec profile name (unrestricted, restricted, ci) */\n profile?: string;\n}\n\nexport interface ExecResult {\n code: number;\n stdout: string;\n stderr: string;\n}\n\n/**\n * Best-effort output redaction: replaces verbatim occurrences of known secret\n * values (>5 chars) in a child process's stdout/stderr. This is a safety net,\n * NOT a guarantee — it cannot catch secrets that the child has transformed\n * (base64/hex/URL-encoded, split across writes beyond the tail window, etc.).\n */\nexport class RedactionTransform extends Transform {\n private patterns: { value: string; replacement: string }[] = [];\n private tail: string = \"\";\n private maxLen: number = 0;\n // Decodes UTF-8 across chunk boundaries: a multi-byte character split between\n // two Buffer chunks would otherwise be corrupted to U+FFFD by chunk.toString()\n // BEFORE matching runs, letting a multi-byte secret slip through unredacted.\n // StringDecoder buffers the incomplete trailing bytes until the rest arrives.\n private decoder = new StringDecoder(\"utf8\");\n\n constructor(secretsToRedact: string[]) {\n super();\n // Only redact secrets > 5 chars to avoid destroying output\n const validSecrets = secretsToRedact.filter((s) => s.length > 5);\n // Sort by length descending to match longest first\n validSecrets.sort((a, b) => b.length - a.length);\n\n this.patterns = validSecrets.map((s) => ({\n value: s,\n replacement: \"[QRING:REDACTED]\",\n }));\n\n if (validSecrets.length > 0) {\n this.maxLen = validSecrets[0].length;\n }\n }\n\n _transform(chunk: Buffer | string, _encoding: string, callback: () => void) {\n if (this.patterns.length === 0) {\n this.push(chunk);\n return callback();\n }\n\n const decoded =\n typeof chunk === \"string\" ? chunk : this.decoder.write(chunk);\n const text = this.tail + decoded;\n let redacted = text;\n\n for (const { value, replacement } of this.patterns) {\n redacted = redacted.split(value).join(replacement);\n }\n\n if (redacted.length < this.maxLen) {\n this.tail = redacted;\n return callback();\n }\n\n const outputLen = redacted.length - this.maxLen + 1;\n const output = redacted.slice(0, outputLen);\n this.tail = redacted.slice(outputLen);\n\n this.push(output);\n callback();\n }\n\n _flush(callback: () => void) {\n // Flush any bytes the decoder is still holding (an incomplete sequence at\n // end-of-stream) along with the retained tail, then redact once more.\n let final = this.tail + this.decoder.end();\n if (final) {\n for (const { value, replacement } of this.patterns) {\n final = final.split(value).join(replacement);\n }\n this.push(final);\n }\n callback();\n }\n}\n\n/**\n * Enforce the exec policy and profile allow/deny lists for a command.\n * Shared by `qring exec` (scope-wide injection) and `qring run` (declared-only\n * injection). Throws on denial.\n */\nexport function enforceExecPolicy(\n profile: ExecProfile,\n command: string,\n args: string[],\n projectPath?: string,\n): void {\n const fullCommand = [command, ...args].join(\" \");\n\n const policyDecision = checkExecPolicy(fullCommand, projectPath);\n if (!policyDecision.allowed) {\n throw new Error(`Policy Denied: ${policyDecision.reason}`);\n }\n\n if (profile.denyCommands) {\n const denied = profile.denyCommands.find((d) => {\n const pattern = new RegExp(`(^|[\\\\s/])${d.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}(\\\\s|$)`, \"i\");\n return pattern.test(fullCommand);\n });\n if (denied) {\n throw new Error(`Exec profile \"${profile.name}\" denies command containing \"${denied}\"`);\n }\n }\n if (profile.allowCommands) {\n const allowed = profile.allowCommands.some((a) => fullCommand.startsWith(a));\n if (!allowed) {\n throw new Error(`Exec profile \"${profile.name}\" does not allow command \"${command}\"`);\n }\n }\n}\n\nexport async function execCommand(opts: ExecOptions): Promise<ExecResult> {\n const profile = getProfile(opts.profile);\n enforceExecPolicy(profile, opts.command, opts.args, opts.projectPath);\n\n const envMap: Record<string, string> = {};\n for (const [k, v] of Object.entries(process.env)) {\n if (v !== undefined) envMap[k] = v;\n }\n\n if (profile.stripEnvVars) {\n for (const key of profile.stripEnvVars) {\n delete envMap[key];\n }\n }\n\n const secretsToRedact = new Set<string>();\n\n let entries = listSecrets({\n scope: opts.scope,\n projectPath: opts.projectPath,\n source: opts.source ?? \"cli\",\n silent: true, // list silently\n });\n\n if (opts.keys?.length) {\n const keySet = new Set(opts.keys);\n entries = entries.filter((e) => keySet.has(e.key));\n }\n\n if (opts.tags?.length) {\n entries = entries.filter((e) =>\n opts.tags!.some((t) => e.envelope?.meta.tags?.includes(t)),\n );\n }\n\n for (const entry of entries) {\n if (entry.envelope) {\n const decay = checkDecay(entry.envelope);\n if (decay.isExpired) continue;\n }\n\n const val = getSecret(entry.key, {\n scope: entry.scope,\n projectPath: opts.projectPath,\n env: opts.env,\n source: opts.source ?? \"cli\",\n silent: false, // Log access for execution\n });\n\n if (val !== null) {\n envMap[entry.key] = val;\n if (val.length > 5) {\n secretsToRedact.add(val);\n }\n }\n }\n\n return spawnRedacted({\n profile,\n command: opts.command,\n args: opts.args,\n envMap,\n secretsToRedact: [...secretsToRedact],\n captureOutput: opts.captureOutput,\n projectPath: opts.projectPath,\n });\n}\n\nexport interface SpawnRedactedOptions {\n profile: ExecProfile;\n command: string;\n args: string[];\n /** Complete child environment (caller composes inheritance + injection). */\n envMap: Record<string, string>;\n /** Values to redact from the child's stdout/stderr. */\n secretsToRedact: string[];\n captureOutput?: boolean;\n /** Used only to resolve the policy-configured max runtime. */\n projectPath?: string;\n}\n\n/**\n * Spawn a child process with a fully-composed environment, enforcing the\n * profile's network restriction and runtime limit, and redacting known\n * secret values from its output.\n */\nexport function spawnRedacted(opts: SpawnRedactedOptions): Promise<ExecResult> {\n const { profile, secretsToRedact, envMap } = opts;\n const maxRuntime = profile.maxRuntimeSeconds ?? getExecMaxRuntime(opts.projectPath);\n\n return new Promise((resolve, reject) => {\n // Enforce network restrictions for profiles that disallow network access.\n const networkTools = new Set([\n \"curl\", \"wget\", \"ping\", \"nc\", \"netcat\", \"ssh\", \"telnet\", \"ftp\", \"dig\", \"nslookup\",\n ]);\n\n // Compare on the command basename so absolute paths like /usr/bin/curl are\n // still caught. (Interpreter-based egress — python -c, node -e — is out of\n // scope here; this is best-effort, not a hard sandbox.)\n const commandBase = opts.command.split(/[\\\\/]/).pop() ?? opts.command;\n\n if (profile.allowNetwork === false && networkTools.has(commandBase)) {\n const msg = `[QRING] Execution blocked: network access is disabled for profile \"${profile.name}\", command \"${opts.command}\" is considered network-related`;\n if (opts.captureOutput) {\n return resolve({ code: 126, stdout: \"\", stderr: msg });\n }\n process.stderr.write(msg + \"\\n\");\n return resolve({ code: 126, stdout: \"\", stderr: \"\" });\n }\n\n const child = spawn(opts.command, opts.args, {\n env: envMap,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: false,\n });\n\n let timedOut = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n if (maxRuntime) {\n timer = setTimeout(() => {\n timedOut = true;\n child.kill(\"SIGKILL\");\n }, maxRuntime * 1000);\n }\n\n const stdoutRedact = new RedactionTransform([...secretsToRedact]);\n const stderrRedact = new RedactionTransform([...secretsToRedact]);\n\n if (child.stdout) child.stdout.pipe(stdoutRedact);\n if (child.stderr) child.stderr.pipe(stderrRedact);\n\n let stdoutStr = \"\";\n let stderrStr = \"\";\n\n if (opts.captureOutput) {\n stdoutRedact.on(\"data\", (d) => (stdoutStr += d.toString()));\n stderrRedact.on(\"data\", (d) => (stderrStr += d.toString()));\n } else {\n stdoutRedact.pipe(process.stdout);\n stderrRedact.pipe(process.stderr);\n }\n\n child.on(\"close\", (code) => {\n if (timer) clearTimeout(timer);\n if (timedOut) {\n resolve({ code: 124, stdout: stdoutStr, stderr: stderrStr + `\\n[QRING] Process killed: exceeded ${maxRuntime}s runtime limit` });\n } else {\n resolve({ code: code ?? 0, stdout: stdoutStr, stderr: stderrStr });\n }\n });\n\n child.on(\"error\", (err) => {\n if (timer) clearTimeout(timer);\n reject(err);\n });\n });\n}\n","/**\n * Codebase Secret Scanner\n *\n * Scans a directory for hardcoded secrets using regex heuristics\n * and Shannon entropy analysis. Useful for migrating legacy codebases\n * into q-ring.\n */\n\nimport { readFileSync, readdirSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { findSecretsInLine, calculateEntropy } from \"./secrets-detect.js\";\n\nexport interface ScanResult {\n file: string;\n line: number;\n keyName: string;\n match: string;\n context: string;\n entropy: number;\n}\n\nconst IGNORE_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \".next\",\n \"dist\",\n \"build\",\n \"coverage\",\n \".cursor\",\n \"venv\",\n \"__pycache__\",\n]);\n\nconst IGNORE_EXTS = new Set([\n \".png\", \".jpg\", \".jpeg\", \".gif\", \".ico\", \".svg\", \".webp\",\n \".mp4\", \".mp3\", \".wav\", \".ogg\",\n \".pdf\", \".zip\", \".tar\", \".gz\", \".xz\",\n \".ttf\", \".woff\", \".woff2\", \".eot\",\n \".exe\", \".dll\", \".so\", \".dylib\",\n \".lock\",\n]);\n\nexport function scanCodebase(dir: string): ScanResult[] {\n const results: ScanResult[] = [];\n\n function walk(currentDir: string) {\n let entries;\n try {\n entries = readdirSync(currentDir);\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (IGNORE_DIRS.has(entry)) continue;\n\n const fullPath = join(currentDir, entry);\n let stat;\n try {\n stat = statSync(fullPath);\n } catch {\n continue;\n }\n\n if (stat.isDirectory()) {\n walk(fullPath);\n } else if (stat.isFile()) {\n const ext = fullPath.slice(fullPath.lastIndexOf(\".\")).toLowerCase();\n if (IGNORE_EXTS.has(ext) || entry.endsWith(\".lock\")) continue;\n\n let content;\n try {\n content = readFileSync(fullPath, \"utf8\");\n } catch {\n continue;\n }\n\n if (content.includes(\"\\0\")) continue;\n\n const lines = content.split(/\\r?\\n/);\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const matches = findSecretsInLine(line);\n for (const m of matches) {\n const entropy = calculateEntropy(m.value);\n const relPath = fullPath.startsWith(dir)\n ? fullPath.slice(dir.length).replace(/^[/\\\\]+/, \"\")\n : fullPath;\n\n results.push({\n file: relPath || fullPath,\n line: i + 1,\n keyName: m.varName,\n match: m.value,\n context: line.trim(),\n entropy: parseFloat(entropy.toFixed(2)),\n });\n }\n }\n }\n }\n }\n\n walk(dir);\n return results;\n}\n","/**\n * Shared heuristics for hardcoded-secret detection (scan + lint).\n * Both `scan.ts` and `linter.ts` use this module so rules stay aligned.\n */\n\n/** Same pattern for assignment-style secrets in source lines. */\nexport const SECRET_ASSIGNMENT_PATTERN =\n /((?:api_?key|secret|token|password|auth|credential|access_?key)[a-z0-9_]*)\\s*[:=]\\s*(['\"])([^'\"]+)\\2/gi;\n\nexport interface SecretMatchInLine {\n varName: string;\n value: string;\n quote: string;\n}\n\nexport function calculateEntropy(str: string): number {\n if (!str) return 0;\n const len = str.length;\n const frequencies = new Map<string, number>();\n\n for (let i = 0; i < len; i++) {\n const char = str[i];\n frequencies.set(char, (frequencies.get(char) || 0) + 1);\n }\n\n let entropy = 0;\n for (const count of frequencies.values()) {\n const p = count / len;\n entropy -= p * Math.log2(p);\n }\n\n return entropy;\n}\n\nfunction isPlaceholderValue(value: string): boolean {\n const lv = value.toLowerCase();\n return (\n lv.includes(\"example\") ||\n lv.includes(\"your_\") ||\n lv.includes(\"placeholder\") ||\n lv.includes(\"replace_me\") ||\n lv.includes(\"xxx\")\n );\n}\n\nfunction passesSecretHeuristic(value: string, entropy: number): boolean {\n return entropy > 3.5 || value.startsWith(\"sk-\") || value.startsWith(\"ghp_\");\n}\n\n/**\n * Find all secret-like assignments on one line (same behavior as the linter:\n * every match on the line is considered).\n */\nexport function findSecretsInLine(line: string): SecretMatchInLine[] {\n if (line.length > 500) return [];\n\n const out: SecretMatchInLine[] = [];\n SECRET_ASSIGNMENT_PATTERN.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = SECRET_ASSIGNMENT_PATTERN.exec(line)) !== null) {\n const varName = match[1];\n const quote = match[2];\n const value = match[3];\n\n if (value.length < 8) continue;\n if (isPlaceholderValue(value)) continue;\n\n const entropy = calculateEntropy(value);\n if (!passesSecretHeuristic(value, entropy)) continue;\n\n out.push({ varName, value, quote });\n }\n return out;\n}\n","/**\n * Secret-Aware Linter\n *\n * Scans individual files (or staged git content) for hardcoded secrets and\n * optionally rewrites them with `process.env.KEY` references, storing the\n * discovered values in q-ring.\n */\n\nimport { readFileSync, writeFileSync, existsSync } from \"node:fs\";\nimport { basename, extname } from \"node:path\";\nimport { type ScanResult } from \"./scan.js\";\nimport { setSecret, hasSecret } from \"./keyring.js\";\nimport { findSecretsInLine, calculateEntropy } from \"./secrets-detect.js\";\n\nexport interface LintResult extends ScanResult {\n fixed: boolean;\n}\n\nexport interface LintOptions {\n fix?: boolean;\n scope?: import(\"./scope.js\").Scope;\n projectPath?: string;\n}\n\nconst ENV_REF_BY_EXT: Record<string, (key: string) => string> = {\n \".ts\": (k) => `process.env.${k}`,\n \".tsx\": (k) => `process.env.${k}`,\n \".js\": (k) => `process.env.${k}`,\n \".jsx\": (k) => `process.env.${k}`,\n \".mjs\": (k) => `process.env.${k}`,\n \".cjs\": (k) => `process.env.${k}`,\n \".py\": (k) => `os.environ[\"${k}\"]`,\n \".rb\": (k) => `ENV[\"${k}\"]`,\n \".go\": (k) => `os.Getenv(\"${k}\")`,\n \".rs\": (k) => `std::env::var(\"${k}\")`,\n \".java\": (k) => `System.getenv(\"${k}\")`,\n \".kt\": (k) => `System.getenv(\"${k}\")`,\n \".cs\": (k) => `Environment.GetEnvironmentVariable(\"${k}\")`,\n \".php\": (k) => `getenv('${k}')`,\n \".sh\": (k) => `\\${${k}}`,\n \".bash\": (k) => `\\${${k}}`,\n};\n\nfunction getEnvRef(filePath: string, keyName: string): string {\n const ext = extname(filePath).toLowerCase();\n const formatter = ENV_REF_BY_EXT[ext];\n return formatter ? formatter(keyName) : `process.env.${keyName}`;\n}\n\n/**\n * Lint specific files for hardcoded secrets.\n */\nexport function lintFiles(\n files: string[],\n opts: LintOptions = {},\n): LintResult[] {\n const results: LintResult[] = [];\n\n for (const file of files) {\n if (!existsSync(file)) continue;\n\n let content: string;\n try {\n content = readFileSync(file, \"utf8\");\n } catch {\n continue;\n }\n\n if (content.includes(\"\\0\")) continue;\n\n const lines = content.split(/\\r?\\n/);\n const fixes: Array<{ line: number; original: string; replacement: string; keyName: string; value: string }> = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const matches = findSecretsInLine(line);\n\n for (const m of matches) {\n const varNameUpper = m.varName.toUpperCase();\n const entropy = calculateEntropy(m.value);\n const shouldFix = opts.fix === true;\n\n if (shouldFix) {\n const envRef = getEnvRef(file, varNameUpper);\n fixes.push({\n line: i,\n original: `${m.quote}${m.value}${m.quote}`,\n replacement: envRef,\n keyName: varNameUpper,\n value: m.value,\n });\n }\n\n results.push({\n file,\n line: i + 1,\n keyName: varNameUpper,\n match: m.value,\n context: line.trim(),\n entropy: parseFloat(entropy.toFixed(2)),\n fixed: shouldFix,\n });\n }\n }\n\n if (opts.fix && fixes.length > 0) {\n const fixLines = content.split(/\\r?\\n/);\n for (const fix of fixes.reverse()) {\n const lineIdx = fix.line;\n if (lineIdx >= 0 && lineIdx < fixLines.length) {\n fixLines[lineIdx] = fixLines[lineIdx].replace(fix.original, fix.replacement);\n }\n\n if (!hasSecret(fix.keyName, { scope: opts.scope, projectPath: opts.projectPath })) {\n setSecret(fix.keyName, fix.value, {\n scope: opts.scope ?? \"global\",\n projectPath: opts.projectPath,\n source: \"cli\",\n description: `Auto-imported from ${basename(file)}:${fix.line + 1}`,\n });\n }\n }\n\n writeFileSync(file, fixLines.join(\"\\n\"), \"utf8\");\n }\n }\n\n return results;\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { z } from \"zod\";\nimport { remember, recall, listMemory, forget } from \"../../core/memory.js\";\nimport { text, enforceToolPolicy } from \"./_shared.js\";\n\nexport function registerAgentTools(server: McpServer): void {\n server.tool(\n \"agent_remember\",\n [\n \"[agent] Persist a non-secret key/value note in encrypted, on-disk agent memory that survives across MCP sessions.\",\n \"Use to record stable agent context — last rotation date for a key, the user's deployment preferences, decisions taken in earlier sessions; do NOT use this to store secrets (use `set_secret` instead) and prefer chat scratchpad for purely transient state.\",\n \"Mutates the encrypted memory store. Idempotent: rewriting the same key with a new value simply overwrites. Returns 'Remembered \\\"KEY\\\"' on success.\",\n ].join(\" \"),\n {\n key: z\n .string()\n .describe(\n \"Memory key (free-form string). Convention: lowercase dotted namespaces, e.g. 'project.lastDeploy'.\",\n ),\n value: z\n .string()\n .describe(\n \"Plain-string value to store. JSON-stringify structured data on the caller side if needed.\",\n ),\n },\n toolAnnotations(\"agent_remember\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"agent_remember\");\n if (toolBlock) return toolBlock;\n\n remember(params.key, params.value);\n return text(`Remembered \"${params.key}\"`);\n },\n );\n\n server.tool(\n \"agent_recall\",\n [\n \"[agent] Read a value from encrypted agent memory, or list every stored key when no specific key is supplied.\",\n \"Use at the start of an agent loop to rehydrate prior context, or to look up a single remembered fact; prefer `get_project_context` for a redacted overview of secrets and `get_secret` for actual credential values.\",\n \"Read-only. With a `key` argument: returns JSON `{ ok, data: { key, value } }` or a not-found error. Without `key`: returns a JSON listing of every stored key (no values), or 'Agent memory is empty'.\",\n ].join(\" \"),\n {\n key: z\n .string()\n .optional()\n .describe(\"Memory key to read. Omit to list every stored key (without values).\"),\n },\n toolAnnotations(\"agent_recall\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"agent_recall\");\n if (toolBlock) return toolBlock;\n\n if (!params.key) {\n const entries = listMemory();\n if (entries.length === 0) return text(\"Agent memory is empty\");\n return text(JSON.stringify(entries, null, 2));\n }\n const value = recall(params.key);\n if (value === null) return text(`No memory found for \"${params.key}\"`, true);\n return text(JSON.stringify({ ok: true, data: { key: params.key, value } }, null, 2));\n },\n );\n\n server.tool(\n \"agent_forget\",\n [\n \"[agent] Permanently delete a single key from encrypted agent memory.\",\n \"Use to retract obsolete or misremembered context; prefer overwriting via `agent_remember` when you just want to update the value, and use `delete_secret` for actual credentials (which never live in agent memory).\",\n \"Destructive: there is no recycle bin. Returns 'Forgot \\\"KEY\\\"' on success or a not-found error if the key was already absent.\",\n ].join(\" \"),\n {\n key: z.string().describe(\"Memory key to delete.\"),\n },\n toolAnnotations(\"agent_forget\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"agent_forget\");\n if (toolBlock) return toolBlock;\n\n const removed = forget(params.key);\n return text(\n removed ? `Forgot \"${params.key}\"` : `No memory found for \"${params.key}\"`,\n !removed,\n );\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { z } from \"zod\";\nimport {\n checkToolPolicy,\n checkKeyReadPolicy,\n checkExecPolicy,\n getPolicySummary,\n} from \"../../core/policy.js\";\nimport { text, enforceToolPolicy, commonSchemas } from \"./_shared.js\";\n\nconst { projectPath } = commonSchemas;\n\nexport function registerPolicyTools(server: McpServer): void {\n server.tool(\n \"check_policy\",\n [\n \"[policy] Ask whether a single intended action would be allowed by the project's `.q-ring.json` policy without actually performing it.\",\n \"Use as a dry-run before calling a potentially-blocked tool, attempting to read a sensitive key, or invoking `exec_with_secrets` with a non-trivial command; prefer `get_policy_summary` for a one-shot overview of the entire policy.\",\n \"Read-only. Returns JSON `{ allowed, reason?, policySource }` describing the decision. Returns an error 'Missing required parameter for the selected action type' if the matching argument for the chosen `action` is not supplied.\",\n ].join(\" \"),\n {\n action: z\n .enum([\"tool\", \"key_read\", \"exec\"])\n .describe(\n \"Which policy surface to query. 'tool' = MCP tool gate (needs `toolName`); 'key_read' = secret read gate (needs `key`); 'exec' = exec_with_secrets command gate (needs `command`).\",\n ),\n toolName: z\n .string()\n .optional()\n .describe(\"Tool id to evaluate, e.g. 'rotate_secret'. Required when `action` is 'tool'.\"),\n key: z\n .string()\n .optional()\n .describe(\"Secret key name to evaluate. Required when `action` is 'key_read'.\"),\n command: z\n .string()\n .optional()\n .describe(\n \"Command to evaluate against the exec allowlist/denylist. Required when `action` is 'exec'.\",\n ),\n projectPath,\n },\n toolAnnotations(\"check_policy\"),\n async (params) => {\n if (params.action === \"tool\" && params.toolName) {\n const d = checkToolPolicy(params.toolName, params.projectPath);\n return text(JSON.stringify(d, null, 2));\n }\n if (params.action === \"key_read\" && params.key) {\n const d = checkKeyReadPolicy(params.key, undefined, params.projectPath);\n return text(JSON.stringify(d, null, 2));\n }\n if (params.action === \"exec\" && params.command) {\n const d = checkExecPolicy(params.command, params.projectPath);\n return text(JSON.stringify(d, null, 2));\n }\n return text(\"Missing required parameter for the selected action type\", true);\n },\n );\n\n server.tool(\n \"get_policy_summary\",\n [\n \"[policy] Return a high-level summary of the project's `.q-ring.json` governance policy — counts of allow/deny rules for tools, key reads, exec commands, plus approval and rotation requirements.\",\n \"Use to orient an agent (or the user) on what guardrails are active before attempting policy-restricted actions; prefer `check_policy` for a precise per-action verdict.\",\n \"Read-only. Returns pretty-printed JSON; missing policy file returns an empty/default summary rather than an error so callers can branch on the counts.\",\n ].join(\" \"),\n {\n projectPath,\n },\n toolAnnotations(\"get_policy_summary\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"get_policy_summary\", params.projectPath);\n if (toolBlock) return toolBlock;\n const summary = getPolicySummary(params.projectPath);\n return text(JSON.stringify(summary, null, 2));\n },\n );\n}\n","import { McpServer, ResourceTemplate } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { checkToolPolicy } from \"../core/policy.js\";\nimport {\n listAgentSessionsForAgents,\n summariseSession,\n type SessionQuery,\n} from \"../core/sessions.js\";\n\n/**\n * MCP resources exposed by the q-ring server.\n *\n * Standing rule: state an agent should *look at* is a resource, not a tool.\n * The agent session timeline is the first: `qring://sessions` lists every\n * agent session the audit chain knows about, `qring://sessions/{id}` is one\n * session's timeline.\n *\n * Both are agent surfaces, so they read through `listAgentSessionsForAgents`,\n * which strips canary trips before anything is summarised — a honeytoken must\n * never be discoverable from the agent side. They also honour the operator's\n * one switch for audit visibility: denying the `audit_log` tool in\n * `.q-ring.json` policy hides these resources too.\n */\n\nconst MIME = \"application/json\";\nconst LIST_URI = \"qring://sessions\";\n\n/** Window a resource read covers; agents don't need the whole chain. */\nconst RESOURCE_QUERY: SessionQuery = {\n since: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(),\n limit: 50,\n maxEvents: 200,\n};\n\nfunction auditVisible(): boolean {\n return checkToolPolicy(\"audit_log\").allowed;\n}\n\nexport function registerMcpResources(server: McpServer): void {\n server.registerResource(\n \"agent-sessions\",\n LIST_URI,\n {\n title: \"Agent sessions\",\n description:\n \"Audit activity folded into per-agent sessions (last 7 days): which MCP client did what, when, against which key names. Summaries only — read qring://sessions/{id} for a session's event timeline. Never contains secret values.\",\n mimeType: MIME,\n },\n async (uri) => {\n const sessions = auditVisible()\n ? listAgentSessionsForAgents(RESOURCE_QUERY).map(summariseSession)\n : [];\n return {\n contents: [{ uri: uri.href, mimeType: MIME, text: JSON.stringify({ sessions }, null, 2) }],\n };\n },\n );\n\n server.registerResource(\n \"agent-session\",\n new ResourceTemplate(\"qring://sessions/{id}\", {\n list: async () => {\n if (!auditVisible()) return { resources: [] };\n return {\n resources: listAgentSessionsForAgents(RESOURCE_QUERY).map((s) => ({\n uri: `${LIST_URI}/${s.id}`,\n name: s.wrapLabel ? `airlock: ${s.wrapLabel}` : s.agent,\n description: `${s.eventCount} events, ${s.startedAt} → ${s.endedAt}`,\n mimeType: MIME,\n })),\n };\n },\n }),\n {\n title: \"Agent session timeline\",\n description:\n \"One agent session's audit timeline, most recent event first. Key names and actions only — never secret values.\",\n mimeType: MIME,\n },\n async (uri, variables) => {\n const id = String(variables.id ?? \"\");\n const session = auditVisible()\n ? listAgentSessionsForAgents({ ...RESOURCE_QUERY, limit: undefined }).find(\n (s) => s.id === id,\n )\n : undefined;\n if (!session) throw new Error(`Session not found: ${id}`);\n return {\n contents: [{ uri: uri.href, mimeType: MIME, text: JSON.stringify(session, null, 2) }],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { registerSecretTools } from \"./tools/secrets.js\";\nimport { registerProjectTools } from \"./tools/project.js\";\nimport { registerTunnelTools } from \"./tools/tunnel.js\";\nimport { registerTeleportTools } from \"./tools/teleport.js\";\nimport { registerAuditTools } from \"./tools/audit.js\";\nimport { registerValidationTools } from \"./tools/validation.js\";\nimport { registerHookTools } from \"./tools/hooks.js\";\nimport { registerToolingTools } from \"./tools/tooling.js\";\nimport { registerAgentTools } from \"./tools/agent.js\";\nimport { registerPolicyTools } from \"./tools/policy.js\";\nimport { registerMcpResources } from \"./resources.js\";\n\n/**\n * Register every MCP tool (and resource) on the given server.\n *\n * Tools are grouped by concern in `src/mcp/tools/*.ts`. Keep the registration\n * order stable — some MCP clients cache the tool list ordering. Resources\n * (read-only state such as the agent session timeline) live in\n * `src/mcp/resources.ts`.\n */\nexport function registerMcpTools(server: McpServer): void {\n registerMcpResources(server);\n registerSecretTools(server);\n registerProjectTools(server);\n registerTunnelTools(server);\n registerTeleportTools(server);\n registerAuditTools(server);\n registerValidationTools(server);\n registerHookTools(server);\n registerToolingTools(server);\n registerAgentTools(server);\n registerPolicyTools(server);\n}\n"],"mappings":"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","names":["McpServer","z","c","opts","projectPath","server","z","hints","registry","opts","opts","projectPath","registry","teamId","orgId","scope","projectPath","env","server","result","z","server","z","z","randomBytes","z","teamId","orgId","scope","projectPath","server","z","z","teamId","orgId","scope","projectPath","server","z","z","teamId","orgId","scope","projectPath","server","z","registry","z","server","z","z","text","projectPath","opts","readFileSync","readFileSync","readFileSync","opts","readFileSync","teamId","orgId","scope","projectPath","server","z","z","server","z","z","projectPath","server","z","server","server","server","McpServer"]}
1
+ {"version":3,"sources":["../src/mcp.ts","../src/mcp/server.ts","../src/mcp/tool-annotations.ts","../src/mcp/tools/secrets.ts","../src/services/list-secrets-filter.ts","../src/core/noise.ts","../src/core/import.ts","../src/mcp/tools/_shared.ts","../src/mcp/tools/environments.ts","../src/core/promote.ts","../src/core/validate.ts","../src/core/context.ts","../src/mcp/tools/project.ts","../src/mcp/tools/tunnel.ts","../src/mcp/tools/teleport.ts","../src/core/teleport.ts","../src/mcp/tools/audit.ts","../src/mcp/tools/validation.ts","../src/mcp/tools/hooks.ts","../src/mcp/tools/tooling.ts","../src/utils/colors.ts","../src/core/agent.ts","../src/core/exec.ts","../src/core/scan.ts","../src/core/secrets-detect.ts","../src/core/linter.ts","../src/mcp/tools/agent.ts","../src/mcp/tools/policy.ts","../src/mcp/resources.ts","../src/mcp/tool-registration.ts"],"sourcesContent":["import { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { createMcpServer } from \"./mcp/server.js\";\n\nconst server = createMcpServer();\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { PACKAGE_VERSION } from \"../version.js\";\nimport { registerMcpTools } from \"./tool-registration.js\";\nimport { setPolicyRoot } from \"../core/policy.js\";\nimport { setAuditAgentLabel } from \"../core/observer.js\";\n\nexport function createMcpServer(): McpServer {\n // Anchor governance policy to the directory the operator launched the server\n // in. Agents pass projectPath freely, so resolving policy from it would let a\n // malicious agent escape `.q-ring.json` restrictions by pointing elsewhere.\n setPolicyRoot(process.cwd());\n\n const server = new McpServer({\n name: \"q-ring\",\n version: PACKAGE_VERSION,\n });\n registerMcpTools(server);\n // Stamp audit events with the connecting client's self-reported identity\n // (clientInfo from the initialize handshake). Label only — spoofable, so it\n // must never feed policy or approval decisions.\n server.server.oninitialized = () => {\n const info = server.server.getClientVersion();\n if (info) setAuditAgentLabel(`${info.name}@${info.version}`);\n };\n return server;\n}\n","import type { ToolAnnotations } from \"@modelcontextprotocol/sdk/types.js\";\n\n/**\n * MCP tool annotations for every q-ring tool — the structured behavior hints\n * (MCP spec: readOnlyHint / destructiveHint / idempotentHint / openWorldHint)\n * that let hosts decide what to auto-approve and what to confirm.\n *\n * Every hint is set explicitly; nothing relies on the spec defaults. The\n * prose descriptions remain the authority on *why* — keep both in sync when a\n * tool's behavior changes. `src/__tests__/mcp/server.test.ts` asserts that\n * every registered tool has an entry here and that no entry is orphaned.\n *\n * Conventions:\n * - readOnlyHint: the tool never changes the keyring, files, hooks, memory,\n * or running processes. Appending to the audit log does not count.\n * - destructiveHint: a non-read-only tool that overwrites, deletes, replaces\n * a credential, edits source files, or runs arbitrary commands.\n * - idempotentHint: repeating the call with the same arguments has no further\n * effect.\n * - openWorldHint: the tool talks to external services or runs commands that\n * can — validation, rotation, exec, agent auto-rotate.\n */\nconst hints = (\n readOnlyHint: boolean,\n destructiveHint: boolean,\n idempotentHint: boolean,\n openWorldHint: boolean,\n): ToolAnnotations => ({ readOnlyHint, destructiveHint, idempotentHint, openWorldHint });\n\nconst READ = hints(true, false, true, false);\nconst READ_OPEN = hints(true, false, true, true);\n\nexport const TOOL_ANNOTATIONS: Record<string, ToolAnnotations> = {\n // secrets\n get_secret: READ,\n list_secrets: READ,\n set_secret: hints(false, true, true, false),\n promote_secret: hints(false, true, true, false),\n diff_environments: hints(true, false, true, false),\n delete_secret: hints(false, true, true, false),\n has_secret: READ,\n export_secrets: READ,\n import_dotenv: hints(false, false, true, false), // existing keys are skipped, not overwritten\n inspect_secret: READ,\n generate_secret: hints(false, true, false, false), // saveAs overwrites; fresh value every call\n entangle_secrets: hints(false, false, true, false),\n disentangle_secrets: hints(false, false, true, false),\n // project\n check_project: READ,\n env_generate: READ, // renders text, never writes files\n detect_environment: READ,\n get_project_context: READ,\n // tunnels (memory-only)\n tunnel_create: hints(false, false, false, false),\n tunnel_read: hints(false, true, false, false), // may self-destruct on read\n tunnel_list: READ,\n tunnel_destroy: hints(false, true, true, false),\n // teleport\n teleport_pack: READ,\n teleport_unpack: hints(false, true, true, false), // imports may overwrite keys\n // audit / health\n audit_log: READ,\n detect_anomalies: READ,\n health_check: READ,\n verify_audit_chain: READ,\n export_audit: READ,\n // validation / rotation (network)\n validate_secret: READ_OPEN,\n list_providers: READ,\n rotate_secret: hints(false, true, false, true), // replaces the credential upstream and locally\n ci_validate_secrets: READ_OPEN,\n // hooks\n register_hook: hints(false, false, false, false),\n list_hooks: READ,\n remove_hook: hints(false, true, true, false),\n // execution / scanning\n exec_with_secrets: hints(false, true, false, true), // arbitrary command\n scan_codebase_for_secrets: READ,\n lint_files: hints(false, true, true, false), // fix:true rewrites source files\n analyze_secrets: READ,\n status_dashboard: hints(false, false, false, false), // starts a local server, new token per launch\n agent_scan: hints(false, true, false, true), // autoRotate replaces expired credentials\n // agent memory\n agent_remember: hints(false, true, true, false),\n agent_recall: READ,\n agent_forget: hints(false, true, true, false),\n // policy\n check_policy: READ,\n get_policy_summary: READ,\n};\n\n/** Look up a tool's annotations; a missing entry is a programming error. */\nexport function toolAnnotations(name: string): ToolAnnotations {\n const a = TOOL_ANNOTATIONS[name];\n if (!a) throw new Error(`q-ring: no tool annotations defined for \"${name}\"`);\n return a;\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { z } from \"zod\";\nimport { filterSecretsByKeyGlob } from \"../../services/list-secrets-filter.js\";\nimport {\n getSecret,\n setSecret,\n deleteSecret,\n hasSecret,\n listSecrets,\n getEnvelope,\n entangleSecrets,\n disentangleSecrets,\n exportSecrets,\n} from \"../../core/keyring.js\";\nimport { checkDecay } from \"../../core/envelope.js\";\nimport { rotationStatus } from \"../../core/rotation.js\";\nimport type { Scope } from \"../../core/scope.js\";\nimport { generateSecret, estimateEntropy, type NoiseFormat } from \"../../core/noise.js\";\nimport { importDotenv } from \"../../core/import.js\";\nimport { checkKeyReadPolicy } from \"../../core/policy.js\";\nimport { text, opts, enforceToolPolicy, commonSchemas } from \"./_shared.js\";\n\nconst { teamId, orgId, scope, projectPath, env } = commonSchemas;\n\nexport function registerSecretTools(server: McpServer): void {\n server.tool(\n \"get_secret\",\n [\n \"[secrets] Read the plaintext value of a single secret from the q-ring keyring.\",\n \"Use when an agent needs the actual credential to call an external API or inject into a runtime; prefer `inspect_secret` to see metadata only, `has_secret` for presence-only checks, and `exec_with_secrets` to run a command without exposing the value to chat.\",\n \"Side effects: collapses superposition (selects the per-env state) and writes a 'read' event to the audit log (observer effect). Subject to project tool/key policy and may be denied with a 'Policy Denied' message. Returns JSON `{ ok, data: { key, value } }` on success or an error message if missing/blocked.\",\n ].join(\" \"),\n {\n key: z\n .string()\n .describe(\n \"Exact secret key name as stored in the keyring (case-sensitive). Example: 'OPENAI_API_KEY'.\",\n ),\n scope,\n projectPath,\n env,\n teamId,\n orgId,\n },\n toolAnnotations(\"get_secret\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"get_secret\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n try {\n const keyBlock = checkKeyReadPolicy(params.key, undefined, params.projectPath);\n if (!keyBlock.allowed) {\n return text(`Policy Denied: ${keyBlock.reason}`, true);\n }\n\n const value = getSecret(params.key, opts(params));\n if (value === null) return text(`Secret \"${params.key}\" not found`, true);\n return text(JSON.stringify({ ok: true, data: { key: params.key, value } }, null, 2));\n } catch (err) {\n return text(err instanceof Error ? err.message : String(err), true);\n }\n },\n );\n\n server.tool(\n \"list_secrets\",\n [\n \"[secrets] List secret keys and quantum metadata in the requested scope, never the values.\",\n \"Use to discover what secrets exist before reading or writing; pair with `inspect_secret` for full metadata on one key, `analyze_secrets` for usage trends, or `health_check` for decay/anomaly summaries.\",\n \"Read-only; safe to call repeatedly. Returns JSON `{ ok, data: { entries: [...] } }` where each entry has scope, key, stateKeys (env names if superposed), expired, stale, lifetimePercent, timeRemaining, entangledCount, accessCount.\",\n ].join(\" \"),\n {\n scope,\n projectPath,\n tag: z\n .string()\n .optional()\n .describe(\n \"Return only secrets that include this exact tag (case-sensitive). Example: 'production'.\",\n ),\n expired: z\n .boolean()\n .optional()\n .describe(\n \"If true, return only secrets whose decay TTL has elapsed (lifetimePercent >= 100).\",\n ),\n stale: z\n .boolean()\n .optional()\n .describe(\n \"If true, return only secrets in the stale window (lifetimePercent >= 75 and not yet expired).\",\n ),\n filter: z\n .string()\n .optional()\n .describe(\n \"Glob pattern matched against the key name. Supports `*` and `?`. Examples: 'API_*', 'STRIPE_?_KEY'.\",\n ),\n teamId,\n orgId,\n },\n toolAnnotations(\"list_secrets\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"list_secrets\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n let entries = listSecrets(opts(params));\n\n if (params.tag) {\n entries = entries.filter((e) => e.envelope?.meta.tags?.includes(params.tag!));\n }\n if (params.expired) {\n entries = entries.filter((e) => e.decay?.isExpired);\n }\n if (params.stale) {\n entries = entries.filter((e) => e.decay?.isStale && !e.decay?.isExpired);\n }\n if (params.filter) {\n entries = filterSecretsByKeyGlob(entries, params.filter);\n }\n const rows = entries.map((e) => ({\n scope: e.scope,\n key: e.key,\n stateKeys: e.envelope?.states ? Object.keys(e.envelope.states) : undefined,\n expired: !!e.decay?.isExpired,\n stale: !!e.decay?.isStale && !e.decay?.isExpired,\n lifetimePercent: e.decay?.lifetimePercent,\n timeRemaining: e.decay?.timeRemaining ?? null,\n entangledCount: e.envelope?.meta.entangled?.length ?? 0,\n accessCount: e.envelope?.meta.accessCount ?? 0,\n }));\n\n return text(JSON.stringify({ ok: true, data: { entries: rows } }, null, 2));\n },\n );\n\n server.tool(\n \"set_secret\",\n [\n \"[secrets] Create or overwrite a single secret value, optionally with TTL/decay, per-env superposition, description, tags, and rotation hints.\",\n \"Use to add or update one key at a time; prefer `import_dotenv` for bulk .env ingest, `generate_secret` (with saveAs) to generate-and-store in one step, and `entangle_secrets` instead of duplicating the same value under two keys.\",\n \"Mutates the keyring (overwrites any existing value at the same key/scope), writes a 'write' event to the audit log, and triggers any matching hooks. Subject to tool policy. Returns a short confirmation text like '[scope] KEY saved' (or '[scope] KEY set for env:NAME' when `env` is provided).\",\n ].join(\" \"),\n {\n key: z\n .string()\n .describe(\"Secret key name (UPPER_SNAKE_CASE recommended). Example: 'STRIPE_SECRET_KEY'.\"),\n value: z\n .string()\n .describe(\n \"The secret value to store. Stored as-is; never logged or echoed. May be empty only when `env` is provided to register a new env without a default.\",\n ),\n scope: scope.default(\"global\"),\n projectPath,\n env: z\n .string()\n .optional()\n .describe(\n \"If set, writes this value to the named per-env state (superposition) instead of the default slot. Existing default value is preserved as state 'default'. Example: 'prod'.\",\n ),\n ttlSeconds: z\n .number()\n .optional()\n .describe(\n \"Quantum decay window in seconds. After this many seconds the secret is marked expired (still readable, but `has_secret` returns false and `health_check` flags it). Omit for no decay.\",\n ),\n description: z\n .string()\n .optional()\n .describe(\n \"Free-text human-readable description shown in `inspect_secret` and the dashboard.\",\n ),\n tags: z\n .array(z.string())\n .optional()\n .describe(\"Tag list for filtering and hook matching. Example: ['production', 'payments'].\"),\n rotationFormat: z\n .enum([\"hex\", \"base64\", \"alphanumeric\", \"uuid\", \"api-key\", \"token\", \"password\"])\n .optional()\n .describe(\n \"Format used by `agent_scan --autoRotate` and `rotate_secret` when this secret expires. Pick the format that matches the upstream service's accepted shape.\",\n ),\n rotationPrefix: z\n .string()\n .optional()\n .describe(\n \"Literal prefix prepended on auto-rotation (only used with rotationFormat 'api-key' or 'token'). Example: 'sk-'.\",\n ),\n rotateEveryDays: z\n .number()\n .int()\n .min(1)\n .max(3650)\n .optional()\n .describe(\n \"Rotation reminder interval in days (1-3650). `inspect_secret` then reports rotation state ok / due-soon / overdue, and the dashboard and `qring rotate:due` surface it. Purely a reminder — nothing rotates automatically. Omit to keep the existing interval.\",\n ),\n teamId,\n orgId,\n },\n toolAnnotations(\"set_secret\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"set_secret\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const o = opts(params);\n\n if (params.env) {\n const existing = getEnvelope(params.key, o);\n const states = existing?.envelope?.states ?? {};\n states[params.env] = params.value;\n\n if (existing?.envelope?.value && !states[\"default\"]) {\n states[\"default\"] = existing.envelope.value;\n }\n\n setSecret(params.key, \"\", {\n ...o,\n states,\n defaultEnv: existing?.envelope?.defaultEnv ?? params.env,\n ttlSeconds: params.ttlSeconds,\n description: params.description,\n tags: params.tags,\n rotationFormat: params.rotationFormat,\n rotationPrefix: params.rotationPrefix,\n rotateEveryDays: params.rotateEveryDays,\n });\n\n return text(`[${params.scope ?? \"global\"}] ${params.key} set for env:${params.env}`);\n }\n\n setSecret(params.key, params.value, {\n ...o,\n ttlSeconds: params.ttlSeconds,\n description: params.description,\n tags: params.tags,\n rotationFormat: params.rotationFormat,\n rotationPrefix: params.rotationPrefix,\n rotateEveryDays: params.rotateEveryDays,\n });\n\n return text(`[${params.scope ?? \"global\"}] ${params.key} saved`);\n },\n );\n\n server.tool(\n \"delete_secret\",\n [\n \"[secrets] Permanently remove a secret value (and all its env states) from the keyring for the given scope.\",\n \"Use when a credential is being retired or was created in error; prefer `disentangle_secrets` to break a sync link without erasing values, `remove_hook` to detach lifecycle callbacks, and `tunnel_destroy` for ephemeral tunnels.\",\n \"Destructive and not undoable from q-ring (no built-in trash). Writes a 'delete' event to the audit log and fires matching hooks. Returns 'Deleted \\\"KEY\\\"' on success or a not-found error if the key did not exist in the requested scope. Subject to tool policy.\",\n ].join(\" \"),\n {\n key: z.string().describe(\"Exact secret key name to delete. Example: 'OLD_API_KEY'.\"),\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"delete_secret\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"delete_secret\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const deleted = deleteSecret(params.key, opts(params));\n return text(\n deleted ? `Deleted \"${params.key}\"` : `Secret \"${params.key}\" not found`,\n !deleted,\n );\n },\n );\n\n server.tool(\n \"has_secret\",\n [\n \"[secrets] Check whether a secret exists in the requested scope without reading the value.\",\n \"Use as a cheap precondition before reading or writing — for example, to skip prompting the user for a key that is already configured. Prefer `inspect_secret` when you also need metadata.\",\n \"Read-only; does not record a 'read' in the audit log. Decay-aware: returns 'false' for expired secrets even though the value is still in the store. Returns the literal text 'true' or 'false'.\",\n ].join(\" \"),\n {\n key: z.string().describe(\"Exact secret key name. Example: 'GITHUB_TOKEN'.\"),\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"has_secret\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"has_secret\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n return text(hasSecret(params.key, opts(params)) ? \"true\" : \"false\");\n },\n );\n\n server.tool(\n \"export_secrets\",\n [\n \"[secrets] Render multiple secrets as a single .env or JSON document for piping into another tool or file.\",\n \"Use to materialize secrets for a one-off export or copy; prefer `env_generate` when you want output driven by the project's `.q-ring.json` manifest, and `teleport_pack` for an encrypted bundle to share between machines.\",\n \"Reads values (collapses superposition for the requested env) and writes one 'export' event per included secret to the audit log. Returns the rendered text directly (no JSON wrapper). Returns an error if no secrets matched the filters. Values are surfaced in plaintext — handle with care.\",\n ].join(\" \"),\n {\n format: z\n .enum([\"env\", \"json\"])\n .optional()\n .default(\"env\")\n .describe(\n \"'env' renders KEY=\\\"value\\\" lines suitable for a .env file; 'json' renders an object keyed by secret name. Defaults to 'env'.\",\n ),\n keys: z\n .array(z.string())\n .optional()\n .describe(\n \"Whitelist of exact key names to include. If omitted, every key in scope is considered (subject to `tags`).\",\n ),\n tags: z\n .array(z.string())\n .optional()\n .describe(\n \"Include only secrets tagged with at least one of these tags. Combined with `keys` as an AND filter when both are supplied.\",\n ),\n scope,\n projectPath,\n env,\n teamId,\n orgId,\n },\n toolAnnotations(\"export_secrets\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"export_secrets\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const output = exportSecrets({\n ...opts(params),\n format: params.format as \"env\" | \"json\",\n keys: params.keys,\n tags: params.tags,\n });\n\n if (!output.trim()) return text(\"No secrets matched the filters\", true);\n return text(output);\n },\n );\n\n server.tool(\n \"import_dotenv\",\n [\n \"[secrets] Parse standard dotenv-formatted text and store each key/value pair into the keyring in one batch.\",\n \"Use when migrating an existing `.env` file into q-ring or onboarding a new project; prefer `set_secret` for a single key, and `teleport_unpack` to import an encrypted bundle.\",\n \"Mutates the keyring (one write per parsed key) and emits a 'write' audit event for each. Supports comments, single/double quotes, and `\\\\n` escapes. Returns a multiline summary listing imported keys and any skipped (existing) keys; in dryRun mode no writes happen and the same summary is produced for review.\",\n ].join(\" \"),\n {\n content: z\n .string()\n .describe(\n \"Raw .env file content as a single string (newline-separated KEY=VALUE lines, comments allowed).\",\n ),\n scope: scope.default(\"global\"),\n projectPath,\n skipExisting: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n \"If true, leave already-present keys untouched and add them to the 'skipped' list instead of overwriting.\",\n ),\n dryRun: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n \"If true, parse and report what would happen but do not write to the keyring. Useful for previewing imports before committing.\",\n ),\n },\n toolAnnotations(\"import_dotenv\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"import_dotenv\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const result = importDotenv(params.content, {\n scope: params.scope as \"global\" | \"project\",\n projectPath: params.projectPath ?? process.cwd(),\n source: \"mcp\",\n skipExisting: params.skipExisting,\n dryRun: params.dryRun,\n });\n\n const lines = [\n params.dryRun\n ? \"Dry run — no changes made\"\n : `Imported ${result.imported.length} secret(s)`,\n ];\n\n if (result.imported.length > 0) {\n lines.push(`Keys: ${result.imported.join(\", \")}`);\n }\n if (result.skipped.length > 0) {\n lines.push(`Skipped (existing): ${result.skipped.join(\", \")}`);\n }\n\n return text(lines.join(\"\\n\"));\n },\n );\n\n server.tool(\n \"inspect_secret\",\n [\n \"[secrets] Show full metadata for a single secret — env states, decay window, entanglement links, access counters — without ever revealing the value.\",\n \"Use when you need to understand the shape of a key before reading it or to debug 'why is this expired/stale'; prefer `get_secret` for the actual value, `list_secrets` for a many-key overview, and `audit_log` for the full access timeline.\",\n \"Read-only; does not write a 'read' event since the value is not exposed. Returns pretty-printed JSON with fields: key, scope, type ('superposition'|'collapsed'), created, updated, accessCount, lastAccessed, environments, defaultEnv, decay { expired, stale, lifetimePercent, timeRemaining }, rotation { lastRotatedAt, ageDays, rotateEveryDays, dueAt, daysUntilDue, state: 'ok'|'due-soon'|'overdue'|'unscheduled' }, entangled, description, tags. Errors with not-found if the key is absent.\",\n ].join(\" \"),\n {\n key: z.string().describe(\"Exact secret key name to inspect. Example: 'OPENAI_API_KEY'.\"),\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"inspect_secret\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"inspect_secret\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const result = getEnvelope(params.key, opts(params));\n if (!result) return text(`Secret \"${params.key}\" not found`, true);\n\n const { envelope, scope: entryScope } = result;\n const decay = checkDecay(envelope);\n\n const info: Record<string, unknown> = {\n key: params.key,\n scope: entryScope,\n type: envelope.states ? \"superposition\" : \"collapsed\",\n created: envelope.meta.createdAt,\n updated: envelope.meta.updatedAt,\n accessCount: envelope.meta.accessCount,\n lastAccessed: envelope.meta.lastAccessedAt ?? \"never\",\n };\n\n if (envelope.states) {\n info.environments = Object.keys(envelope.states);\n info.defaultEnv = envelope.defaultEnv;\n }\n\n if (decay.timeRemaining) {\n info.decay = {\n expired: decay.isExpired,\n stale: decay.isStale,\n lifetimePercent: decay.lifetimePercent,\n timeRemaining: decay.timeRemaining,\n };\n }\n\n info.rotation = rotationStatus(envelope.meta);\n\n if (envelope.meta.entangled?.length) {\n info.entangled = envelope.meta.entangled;\n }\n\n if (envelope.meta.description) info.description = envelope.meta.description;\n if (envelope.meta.tags?.length) info.tags = envelope.meta.tags;\n\n return text(JSON.stringify(info, null, 2));\n },\n );\n\n server.tool(\n \"generate_secret\",\n [\n \"[secrets] Generate a cryptographically random secret using Node's CSPRNG and optionally store it in the keyring in one step.\",\n \"Use to create new credentials that you control (signing keys, internal tokens, passwords); for issuer-issued credentials (Stripe/OpenAI etc.) use `rotate_secret` to ask the upstream provider for a fresh key, and use `set_secret` for values you already have in hand.\",\n \"If `saveAs` is provided this mutates the keyring (one 'write' event) and returns a summary like 'Generated and saved as \\\"KEY\\\" (FORMAT, ~N bits entropy)'. Without `saveAs` the call is read-only and returns JSON `{ ok, data: { value } }` containing the freshly generated string.\",\n ].join(\" \"),\n {\n format: z\n .enum([\"hex\", \"base64\", \"alphanumeric\", \"uuid\", \"api-key\", \"token\", \"password\"])\n .optional()\n .default(\"api-key\")\n .describe(\n \"Output shape. 'hex' / 'base64' / 'alphanumeric' = raw random string of `length` characters; 'uuid' = RFC4122 v4; 'api-key' / 'token' = random alphanumeric with optional `prefix`; 'password' = mixed-case alphanumeric with symbols. Defaults to 'api-key'.\",\n ),\n length: z\n .number()\n .optional()\n .describe(\n \"Number of characters (or bytes for hex/base64) to generate. Ignored for 'uuid'. Defaults to a sensible per-format value (e.g. 32 for api-key).\",\n ),\n prefix: z\n .string()\n .optional()\n .describe(\n \"Literal prefix prepended to the random portion. Only meaningful for 'api-key' and 'token'. Example: 'sk-' or 'svc_'.\",\n ),\n saveAs: z\n .string()\n .optional()\n .describe(\n \"If provided, store the generated value at this key name in the keyring (one mutation). Omit to just return the value without persisting.\",\n ),\n scope: scope.default(\"global\"),\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"generate_secret\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"generate_secret\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const secret = generateSecret({\n format: params.format as NoiseFormat,\n length: params.length,\n prefix: params.prefix,\n });\n\n if (params.saveAs) {\n setSecret(params.saveAs, secret, {\n ...opts(params),\n description: `Generated ${params.format} secret`,\n });\n const entropy = estimateEntropy(secret);\n return text(\n `Generated and saved as \"${params.saveAs}\" (${params.format}, ~${entropy} bits entropy)`,\n );\n }\n\n return text(JSON.stringify({ ok: true, data: { value: secret } }, null, 2));\n },\n );\n\n server.tool(\n \"entangle_secrets\",\n [\n \"[secrets] Link two keys (across the same or different scopes) so future writes/rotations of either propagate the same value to the other.\",\n \"Use when one logical credential lives under multiple names (e.g. `STRIPE_SECRET_KEY` global and project) and should never drift; prefer `set_secret` for unrelated values, and reverse the link with `disentangle_secrets` (does not delete values).\",\n \"Mutates only the metadata of both envelopes — the values themselves are not changed by this call. Idempotent: re-running on an already-entangled pair is a no-op. Subject to tool policy. Returns a short confirmation: 'Entangled: SOURCE <-> TARGET'.\",\n ].join(\" \"),\n {\n sourceKey: z.string().describe(\"First secret key in the pair. Example: 'STRIPE_SECRET_KEY'.\"),\n targetKey: z.string().describe(\"Second secret key to keep in lockstep with the source.\"),\n sourceScope: scope.default(\"global\"),\n targetScope: scope.default(\"global\"),\n sourceProjectPath: z\n .string()\n .optional()\n .describe(\n \"Project root for sourceKey when sourceScope='project'. Defaults to the server cwd.\",\n ),\n targetProjectPath: z\n .string()\n .optional()\n .describe(\n \"Project root for targetKey when targetScope='project'. Defaults to the server cwd.\",\n ),\n },\n toolAnnotations(\"entangle_secrets\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"entangle_secrets\", params.sourceProjectPath);\n if (toolBlock) return toolBlock;\n\n // Entangling links two keys so a write to one propagates to the other —\n // i.e. it grants write access to targetKey. Gate BOTH keys with the same\n // key-level policy a direct read/write would face, so an agent can't link\n // a scratch key to a denied one and overwrite it via propagation (A2).\n for (const key of [params.sourceKey, params.targetKey]) {\n const decision = checkKeyReadPolicy(key, undefined, params.sourceProjectPath);\n if (!decision.allowed) {\n return text(`Policy Denied: ${decision.reason} (source: ${decision.policySource})`, true);\n }\n }\n\n entangleSecrets(\n params.sourceKey,\n {\n scope: params.sourceScope as Scope,\n projectPath: params.sourceProjectPath ?? process.cwd(),\n source: \"mcp\",\n },\n params.targetKey,\n {\n scope: params.targetScope as Scope,\n projectPath: params.targetProjectPath ?? process.cwd(),\n source: \"mcp\",\n },\n );\n\n return text(`Entangled: ${params.sourceKey} <-> ${params.targetKey}`);\n },\n );\n\n server.tool(\n \"disentangle_secrets\",\n [\n \"[secrets] Break the sync link between two previously entangled keys so future rotations no longer propagate.\",\n \"Use when one of the keys is being retired or should diverge intentionally; pair with `delete_secret` if you also want to erase one of the values, and use `entangle_secrets` to recreate the link.\",\n \"Mutates only metadata; the current values remain untouched. Safe and idempotent — running on a pair that was never linked returns success without effect. Subject to tool policy. Returns 'Disentangled: SOURCE </> TARGET'.\",\n ].join(\" \"),\n {\n sourceKey: z.string().describe(\"First key in the previously linked pair.\"),\n targetKey: z.string().describe(\"Second key in the previously linked pair.\"),\n sourceScope: scope.default(\"global\"),\n targetScope: scope.default(\"global\"),\n sourceProjectPath: z\n .string()\n .optional()\n .describe(\"Project root for sourceKey when sourceScope='project'.\"),\n targetProjectPath: z\n .string()\n .optional()\n .describe(\"Project root for targetKey when targetScope='project'.\"),\n },\n toolAnnotations(\"disentangle_secrets\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"disentangle_secrets\", params.sourceProjectPath);\n if (toolBlock) return toolBlock;\n\n disentangleSecrets(\n params.sourceKey,\n {\n scope: params.sourceScope as Scope,\n projectPath: params.sourceProjectPath ?? process.cwd(),\n source: \"mcp\",\n },\n params.targetKey,\n {\n scope: params.targetScope as Scope,\n projectPath: params.targetProjectPath ?? process.cwd(),\n source: \"mcp\",\n },\n );\n\n return text(`Disentangled: ${params.sourceKey} </> ${params.targetKey}`);\n },\n );\n}\n","import type { SecretEntry } from \"../core/keyring.js\";\n\n/**\n * Turn a user glob (`*`, `?`) into a case-insensitive RegExp source.\n * Other regex metacharacters are escaped.\n */\nfunction globKeyPatternToRegexSource(pattern: string): string {\n let out = \"\";\n for (const c of pattern) {\n if (c === \"*\") out += \".*\";\n else if (c === \"?\") out += \".\";\n else if (\"\\\\^$+{}()|[]\".includes(c)) out += \"\\\\\" + c;\n else if (c === \".\") out += \"\\\\.\";\n else out += c;\n }\n return out;\n}\n\n/**\n * Key name glob: `*` → `.*`, `?` → `.`, other regex metacharacters escaped (CLI + MCP aligned).\n */\nexport function filterSecretsByKeyGlob(\n entries: SecretEntry[],\n filter?: string,\n): SecretEntry[] {\n if (!filter?.trim()) return entries;\n const regex = new RegExp(\"^\" + globKeyPatternToRegexSource(filter) + \"$\", \"i\");\n return entries.filter((e) => regex.test(e.key));\n}\n","/**\n * Quantum Noise: cryptographic secret generation.\n * Generates high-entropy values in common formats.\n */\n\nimport { randomBytes, randomInt } from \"node:crypto\";\n\nexport type NoiseFormat =\n | \"hex\"\n | \"base64\"\n | \"alphanumeric\"\n | \"uuid\"\n | \"api-key\"\n | \"token\"\n | \"password\";\n\nexport interface NoiseOptions {\n format?: NoiseFormat;\n /** Length in bytes (for hex/base64) or characters (for alphanumeric/password) */\n length?: number;\n /** Prefix for api-key format (e.g., \"sk-\", \"pk-\") */\n prefix?: string;\n}\n\nconst ALPHA_NUM =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\nconst PASSWORD_CHARS =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+[]{}|;:,.<>?\";\n\nfunction randomString(charset: string, length: number): string {\n let result = \"\";\n for (let i = 0; i < length; i++) {\n result += charset[randomInt(charset.length)];\n }\n return result;\n}\n\nexport function generateSecret(opts: NoiseOptions = {}): string {\n const format = opts.format ?? \"api-key\";\n\n switch (format) {\n case \"hex\": {\n const len = opts.length ?? 32;\n return randomBytes(len).toString(\"hex\");\n }\n\n case \"base64\": {\n const len = opts.length ?? 32;\n return randomBytes(len).toString(\"base64url\");\n }\n\n case \"alphanumeric\": {\n const len = opts.length ?? 32;\n return randomString(ALPHA_NUM, len);\n }\n\n case \"uuid\": {\n const bytes = randomBytes(16);\n bytes[6] = (bytes[6] & 0x0f) | 0x40; // version 4\n bytes[8] = (bytes[8] & 0x3f) | 0x80; // variant 1\n const hex = bytes.toString(\"hex\");\n return [\n hex.slice(0, 8),\n hex.slice(8, 12),\n hex.slice(12, 16),\n hex.slice(16, 20),\n hex.slice(20, 32),\n ].join(\"-\");\n }\n\n case \"api-key\": {\n const prefix = opts.prefix ?? \"qr_\";\n const len = opts.length ?? 48;\n return prefix + randomString(ALPHA_NUM, len);\n }\n\n case \"token\": {\n const prefix = opts.prefix ?? \"\";\n const len = opts.length ?? 64;\n return prefix + randomBytes(len).toString(\"base64url\");\n }\n\n case \"password\": {\n const len = opts.length ?? 24;\n\n // Construct from one guaranteed char per class, fill the rest, then\n // shuffle. This guarantees every class is present (when len ≥ #classes)\n // without any fixup pass that could clobber an already-placed class.\n const classCharsets = [\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\",\n \"abcdefghijklmnopqrstuvwxyz\",\n \"0123456789\",\n \"!@#$%^&*()-_=+\",\n ];\n const guaranteed = classCharsets\n .slice(0, Math.min(classCharsets.length, len))\n .map((cs) => randomString(cs, 1));\n const remaining = Math.max(0, len - guaranteed.length);\n const chars = [\n ...guaranteed,\n ...(remaining > 0 ? randomString(PASSWORD_CHARS, remaining).split(\"\") : []),\n ];\n\n // Fisher-Yates shuffle backed by the CSPRNG.\n for (let i = chars.length - 1; i > 0; i--) {\n const j = randomInt(i + 1);\n [chars[i], chars[j]] = [chars[j], chars[i]];\n }\n\n return chars.join(\"\");\n }\n\n default:\n return randomBytes(32).toString(\"hex\");\n }\n}\n\n/**\n * Estimate the entropy of a secret in bits.\n */\nexport function estimateEntropy(secret: string): number {\n const charsets = [\n { regex: /[a-z]/, size: 26 },\n { regex: /[A-Z]/, size: 26 },\n { regex: /[0-9]/, size: 10 },\n { regex: /[^A-Za-z0-9]/, size: 32 },\n ];\n\n let poolSize = 0;\n for (const { regex, size } of charsets) {\n if (regex.test(secret)) poolSize += size;\n }\n\n return poolSize > 0 ? Math.floor(Math.log2(poolSize) * secret.length) : 0;\n}\n","/**\n * Import module: parse .env files and bulk-store secrets into q-ring.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { setSecret, hasSecret, type SetSecretOptions } from \"./keyring.js\";\n\nexport interface ImportOptions {\n scope?: \"global\" | \"project\";\n projectPath?: string;\n env?: string;\n source?: \"cli\" | \"mcp\" | \"agent\" | \"api\";\n skipExisting?: boolean;\n dryRun?: boolean;\n}\n\nexport interface ImportResult {\n imported: string[];\n skipped: string[];\n total: number;\n}\n\n/**\n * Parse .env content into key-value pairs.\n * Handles comments, blank lines, quoted values, and basic multiline.\n */\nexport function parseDotenv(content: string): Map<string, string> {\n const result = new Map<string, string>();\n const lines = content.split(/\\r?\\n/);\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n\n if (!line || line.startsWith(\"#\")) continue;\n\n const eqIdx = line.indexOf(\"=\");\n if (eqIdx === -1) continue;\n\n const key = line.slice(0, eqIdx).trim();\n let value = line.slice(eqIdx + 1).trim();\n\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n\n const escapeMap: Record<string, string> = {\n n: \"\\n\", r: \"\\r\", t: \"\\t\", \"\\\\\": \"\\\\\", '\"': '\"',\n };\n value = value.replace(/\\\\([nrt\"\\\\])/g, (_, ch) => escapeMap[ch] ?? ch);\n\n // Strip inline comments only when the `#` is preceded by whitespace (the\n // dotenv convention), so unquoted values like `foo#bar` are preserved.\n if (!line.includes('\"') && !line.includes(\"'\")) {\n const commentMatch = value.match(/\\s#/);\n if (commentMatch && commentMatch.index !== undefined) {\n value = value.slice(0, commentMatch.index).trim();\n }\n }\n\n if (key) result.set(key, value);\n }\n\n return result;\n}\n\n/**\n * Import secrets from a .env file path or raw content string.\n */\nexport function importDotenv(\n filePathOrContent: string,\n options: ImportOptions = {},\n): ImportResult {\n let content: string;\n\n // The file-path convenience (read from disk if the arg is a path) is only\n // safe for the trusted local CLI. For MCP/agent/api callers the argument is\n // always treated as literal .env content — otherwise an agent could pass a\n // path like ~/.aws/credentials and exfiltrate it through the keyring.\n const source = options.source ?? \"cli\";\n if (source === \"cli\") {\n try {\n content = readFileSync(filePathOrContent, \"utf8\");\n } catch {\n content = filePathOrContent;\n }\n } else {\n content = filePathOrContent;\n }\n\n const pairs = parseDotenv(content);\n const result: ImportResult = {\n imported: [],\n skipped: [],\n total: pairs.size,\n };\n\n for (const [key, value] of pairs) {\n if (options.skipExisting && hasSecret(key, {\n scope: options.scope,\n projectPath: options.projectPath,\n source: options.source ?? \"cli\",\n })) {\n result.skipped.push(key);\n continue;\n }\n\n if (options.dryRun) {\n result.imported.push(key);\n continue;\n }\n\n const setOpts: SetSecretOptions = {\n scope: options.scope ?? \"global\",\n projectPath: options.projectPath ?? process.cwd(),\n source: options.source ?? \"cli\",\n };\n\n setSecret(key, value, setOpts);\n result.imported.push(key);\n }\n\n return result;\n}\n","import { z } from \"zod\";\nimport type { KeyringOptions } from \"../../core/keyring.js\";\nimport type { Scope } from \"../../core/scope.js\";\nimport { checkToolPolicy } from \"../../core/policy.js\";\n\n/**\n * Standard MCP tool response shape for text content.\n * Set `isError: true` for failure responses so clients surface them appropriately.\n */\nexport function text(t: string, isError = false) {\n return {\n content: [{ type: \"text\" as const, text: t }],\n ...(isError ? { isError: true } : {}),\n };\n}\n\n/** Build `KeyringOptions` from MCP tool params with `source: \"mcp\"` baked in. */\nexport function opts(params: {\n scope?: string;\n projectPath?: string;\n env?: string;\n teamId?: string;\n orgId?: string;\n}): KeyringOptions {\n return {\n scope: params.scope as Scope | undefined,\n projectPath: params.projectPath ?? process.cwd(),\n teamId: params.teamId,\n orgId: params.orgId,\n env: params.env,\n source: \"mcp\",\n };\n}\n\n/**\n * Short-circuit guard: returns a \"Policy Denied\" text response if the tool\n * is blocked by project governance, else `null` to continue.\n */\nexport function enforceToolPolicy(toolName: string, projectPath?: string) {\n const decision = checkToolPolicy(toolName, projectPath);\n if (!decision.allowed) {\n return text(`Policy Denied: ${decision.reason} (source: ${decision.policySource})`, true);\n }\n return null;\n}\n\n/** Reusable zod schemas for the common MCP tool parameters. */\nexport const commonSchemas = {\n teamId: z\n .string()\n .optional()\n .describe(\n \"Team identifier for team-scoped secrets. Required only when scope='team'. Example: 'acme-platform'.\",\n ),\n orgId: z\n .string()\n .optional()\n .describe(\n \"Organization identifier for org-scoped secrets. Required only when scope='org'. Example: 'acme-corp'.\",\n ),\n scope: z\n .enum([\"global\", \"project\", \"team\", \"org\"])\n .optional()\n .describe(\n \"Where the secret lives. 'global' = user keyring (default if omitted on reads), 'project' = scoped to projectPath, 'team' = team-shared (needs teamId), 'org' = org-shared (needs orgId).\",\n ),\n projectPath: z\n .string()\n .optional()\n .describe(\n \"Absolute path to the project root for project-scoped secrets and policy resolution. Defaults to the MCP server's current working directory when omitted.\",\n ),\n env: z\n .string()\n .optional()\n .describe(\n \"Environment slug used to collapse superposition when a secret has multiple per-env states. Examples: 'dev', 'staging', 'prod'. If omitted, the secret's defaultEnv is used.\",\n ),\n} as const;\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { diffEnvironments, promoteSecret, PromoteConflictError } from \"../../core/promote.js\";\nimport { commonSchemas, enforceToolPolicy, opts, text } from \"./_shared.js\";\n\nconst { teamId, orgId, scope, projectPath } = commonSchemas;\n\nexport function registerEnvironmentTools(server: McpServer): void {\n server.tool(\n \"promote_secret\",\n [\n \"[secrets] Copy one secret's value from a source environment to a target environment (superposition states), e.g. staging → prod, without the value ever leaving the keyring.\",\n \"Use when an environment must match another for a single key; use `diff_environments` first to see what differs. Refuses to overwrite a differing target unless `force` is true; a target that already matches is a no-op.\",\n \"Mutates the keyring (one 'write' audit event, hooks fire) only when the target changes. Returns { key, scope, from, to, previous: 'absent'|'same'|'different', changed }. Never returns the value.\",\n ].join(\" \"),\n {\n key: z.string().describe(\"Secret key name. Example: 'DATABASE_URL'.\"),\n from: z.string().describe(\"Source environment state. Example: 'staging'.\"),\n to: z.string().describe(\"Target environment state. Example: 'prod'.\"),\n force: z\n .boolean()\n .default(false)\n .describe(\"Overwrite a differing target value. Default false → the call fails with ERR_PROMOTE_CONFLICT instead.\"),\n scope: scope.default(\"global\"),\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"promote_secret\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"promote_secret\", params.projectPath);\n if (toolBlock) return toolBlock;\n try {\n const result = promoteSecret(params.key, {\n ...opts(params),\n from: params.from,\n to: params.to,\n force: params.force,\n });\n return text(JSON.stringify({ ok: true, data: result }, null, 2));\n } catch (err) {\n const code = err instanceof PromoteConflictError ? err.code : \"ERR_PROMOTE\";\n const message = err instanceof Error ? err.message : String(err);\n return text(JSON.stringify({ ok: false, code, error: message }), true);\n }\n },\n );\n\n server.tool(\n \"diff_environments\",\n [\n \"[secrets] Compare two environments across the visible secrets and report, per key, whether the values are the same, different, or present on only one side — statuses only, never values.\",\n \"Use before a deploy or promotion to see environment drift; follow up with `promote_secret` per key. A single-value (collapsed) secret applies to every environment and is reported as 'collapsed'.\",\n \"Read-only apart from a 'list' audit event. Returns { a, b, entries: [{ key, scope, status }], summary, drift }.\",\n ].join(\" \"),\n {\n envA: z.string().describe(\"First environment. Example: 'staging'.\"),\n envB: z.string().describe(\"Second environment. Example: 'prod'.\"),\n keys: z.array(z.string()).optional().describe(\"Restrict the comparison to these keys.\"),\n scope: scope.optional(),\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"diff_environments\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"diff_environments\", params.projectPath);\n if (toolBlock) return toolBlock;\n try {\n const result = diffEnvironments({\n ...opts(params),\n a: params.envA,\n b: params.envB,\n keys: params.keys,\n });\n return text(JSON.stringify({ ok: true, data: result }, null, 2));\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return text(JSON.stringify({ ok: false, error: message }), true);\n }\n },\n );\n}\n","/**\n * Environment promotion (0.18 \"garrison\"): move a secret's value from one\n * superposition state to another, and diff two environments — without ever\n * printing a value.\n *\n * `qring set KEY --env dev` writes states one at a time; promotion is the\n * \"now make prod match staging\" step that used to mean copy-paste. Both\n * operations go through the normal keyring API so scope resolution, policy\n * checks, audit and hooks all apply.\n */\nimport { getEnvelope, listSecrets, setSecret, type KeyringOptions } from \"./keyring.js\";\nimport type { Environment } from \"./envelope.js\";\nimport type { Scope } from \"./scope.js\";\n\nexport interface PromoteOptions extends KeyringOptions {\n from: Environment;\n to: Environment;\n /** Overwrite a differing value in `to` without asking. */\n force?: boolean;\n}\n\nexport type PromotePrevious = \"absent\" | \"same\" | \"different\";\n\nexport interface PromoteResult {\n key: string;\n scope: Scope;\n from: Environment;\n to: Environment;\n /** What `to` held before: nothing, the same value, or a different one. */\n previous: PromotePrevious;\n /** False when `to` already matched (no write, no audit event). */\n changed: boolean;\n}\n\nexport class PromoteConflictError extends Error {\n readonly code = \"ERR_PROMOTE_CONFLICT\";\n constructor(key: string, to: Environment) {\n super(\n `\"${key}\" already has a different value for env \"${to}\" — pass force to overwrite it`,\n );\n }\n}\n\nfunction assertEnvName(env: string, label: string): void {\n if (!/^[A-Za-z0-9_.-]{1,64}$/.test(env)) {\n throw new Error(`${label} environment name \"${env}\" is invalid (letters, digits, _ . - only)`);\n }\n}\n\n/**\n * Copy the `from` state of `key` into its `to` state. A secret with a single\n * (collapsed) value has no states to promote from.\n */\nexport function promoteSecret(key: string, opts: PromoteOptions): PromoteResult {\n assertEnvName(opts.from, \"source\");\n assertEnvName(opts.to, \"target\");\n if (opts.from === opts.to) {\n throw new Error(`source and target environment are both \"${opts.from}\"`);\n }\n const found = getEnvelope(key, opts);\n if (!found) throw new Error(`Secret \"${key}\" not found`);\n const { envelope, scope } = found;\n const states = envelope.states;\n if (!states) {\n throw new Error(\n `\"${key}\" has a single value, not per-environment states — set one with: qring set ${key} --env ${opts.from}`,\n );\n }\n const source = states[opts.from];\n if (source === undefined) {\n const available = Object.keys(states).join(\", \") || \"none\";\n throw new Error(`\"${key}\" has no value for env \"${opts.from}\" (available: ${available})`);\n }\n const current = states[opts.to];\n const previous: PromotePrevious =\n current === undefined ? \"absent\" : current === source ? \"same\" : \"different\";\n if (previous === \"same\") {\n return { key, scope, from: opts.from, to: opts.to, previous, changed: false };\n }\n if (previous === \"different\" && !opts.force) {\n throw new PromoteConflictError(key, opts.to);\n }\n const nextStates = { ...states, [opts.to]: source };\n setSecret(key, \"\", {\n ...opts,\n scope,\n states: nextStates,\n defaultEnv: envelope.defaultEnv,\n });\n return { key, scope, from: opts.from, to: opts.to, previous, changed: true };\n}\n\nexport type DiffStatus = \"same\" | \"different\" | \"only-a\" | \"only-b\" | \"collapsed\";\n\nexport interface DiffEntry {\n key: string;\n scope: Scope;\n status: DiffStatus;\n}\n\nexport interface DiffOptions extends KeyringOptions {\n a: Environment;\n b: Environment;\n /** Restrict to these keys (exact names). */\n keys?: string[];\n}\n\nexport interface DiffResult {\n a: Environment;\n b: Environment;\n entries: DiffEntry[];\n summary: Record<DiffStatus, number>;\n /** True when anything differs or is missing on one side. */\n drift: boolean;\n}\n\n/**\n * Compare two environments across the visible secrets. Values are compared\n * for equality but never returned. A collapsed secret (single value) is the\n * same in every environment by definition and is reported as \"collapsed\".\n */\nexport function diffEnvironments(opts: DiffOptions): DiffResult {\n assertEnvName(opts.a, \"first\");\n assertEnvName(opts.b, \"second\");\n const wanted = opts.keys ? new Set(opts.keys) : null;\n const entries: DiffEntry[] = [];\n for (const entry of listSecrets(opts)) {\n if (wanted && !wanted.has(entry.key)) continue;\n const states = entry.envelope?.states;\n let status: DiffStatus;\n if (!states) {\n status = \"collapsed\";\n } else {\n const va = states[opts.a];\n const vb = states[opts.b];\n if (va === undefined && vb === undefined) continue; // in neither env\n if (va === undefined) status = \"only-b\";\n else if (vb === undefined) status = \"only-a\";\n else status = va === vb ? \"same\" : \"different\";\n }\n entries.push({ key: entry.key, scope: entry.scope, status });\n }\n const summary: Record<DiffStatus, number> = {\n same: 0,\n different: 0,\n \"only-a\": 0,\n \"only-b\": 0,\n collapsed: 0,\n };\n for (const e of entries) summary[e.status] += 1;\n const drift = summary.different + summary[\"only-a\"] + summary[\"only-b\"] > 0;\n return { a: opts.a, b: opts.b, entries, summary, drift };\n}\n","/**\n * Secret Liveness Validation: test if a secret is actually valid\n * with its target service using a pluggable provider system.\n */\n\nimport { httpRequest } from \"../utils/http-request.js\";\nimport { generateSecret, type NoiseFormat } from \"./noise.js\";\nimport { checkSSRF } from \"./ssrf.js\";\n\nexport interface ValidationResult {\n valid: boolean;\n status: \"valid\" | \"invalid\" | \"error\" | \"unknown\";\n message: string;\n latencyMs: number;\n provider: string;\n}\n\nexport interface Provider {\n name: string;\n description: string;\n /** Prefixes that auto-detect to this provider */\n prefixes?: string[];\n validate(value: string): Promise<ValidationResult>;\n}\n\nfunction makeRequest(\n url: string,\n headers: Record<string, string>,\n timeoutMs = 10000,\n): Promise<{ statusCode: number; body: string }> {\n return httpRequest({ url, method: \"GET\", headers, timeoutMs });\n}\n\nexport class ProviderRegistry {\n private providers = new Map<string, Provider>();\n\n register(provider: Provider): void {\n this.providers.set(provider.name, provider);\n }\n\n get(name: string): Provider | undefined {\n return this.providers.get(name);\n }\n\n detectProvider(\n value: string,\n hints?: { provider?: string; prefix?: string },\n ): Provider | undefined {\n if (hints?.provider) {\n return this.providers.get(hints.provider);\n }\n\n for (const provider of this.providers.values()) {\n if (provider.prefixes) {\n for (const pfx of provider.prefixes) {\n if (value.startsWith(pfx)) return provider;\n }\n }\n }\n\n return undefined;\n }\n\n listProviders(): Provider[] {\n return [...this.providers.values()];\n }\n}\n\n// ─── Built-in Providers ───\n\n/**\n * Factory for the common liveness shape: one authenticated GET against a\n * cheap endpoint, with the standard 200/401/403/429 interpretation.\n */\nfunction livenessProvider(cfg: {\n name: string;\n description: string;\n prefixes?: string[];\n url: string;\n headers: (value: string) => Record<string, string>;\n}): Provider {\n return {\n name: cfg.name,\n description: cfg.description,\n prefixes: cfg.prefixes,\n async validate(value: string): Promise<ValidationResult> {\n const start = Date.now();\n try {\n const { statusCode } = await makeRequest(cfg.url, {\n \"User-Agent\": \"q-ring-validator/1.0\",\n ...cfg.headers(value),\n });\n const latencyMs = Date.now() - start;\n\n if (statusCode === 200)\n return { valid: true, status: \"valid\", message: \"API key is valid\", latencyMs, provider: cfg.name };\n if (statusCode === 401 || statusCode === 403)\n return { valid: false, status: \"invalid\", message: `Invalid or revoked API key (${statusCode})`, latencyMs, provider: cfg.name };\n if (statusCode === 429)\n return { valid: true, status: \"error\", message: \"Rate limited — key may be valid\", latencyMs, provider: cfg.name };\n return { valid: false, status: \"error\", message: `Unexpected status ${statusCode}`, latencyMs, provider: cfg.name };\n } catch (err) {\n return { valid: false, status: \"error\", message: `${err instanceof Error ? err.message : \"Network error\"}`, latencyMs: Date.now() - start, provider: cfg.name };\n }\n },\n };\n}\n\n// AI-stack providers. Keys are only ever sent in headers (never the URL —\n// URLs land in server logs), against the cheapest read-only endpoint each\n// platform has.\n\nconst anthropicProvider = livenessProvider({\n name: \"anthropic\",\n description: \"Anthropic API key validation\",\n prefixes: [\"sk-ant-\"],\n url: \"https://api.anthropic.com/v1/models?limit=1\",\n headers: (value) => ({ \"x-api-key\": value, \"anthropic-version\": \"2023-06-01\" }),\n});\n\nconst openrouterProvider = livenessProvider({\n name: \"openrouter\",\n description: \"OpenRouter API key validation\",\n prefixes: [\"sk-or-\"],\n url: \"https://openrouter.ai/api/v1/key\",\n headers: (value) => ({ Authorization: `Bearer ${value}` }),\n});\n\nconst googleAiProvider = livenessProvider({\n name: \"google-ai\",\n description: \"Google AI (Gemini) API key validation\",\n prefixes: [\"AIza\"],\n url: \"https://generativelanguage.googleapis.com/v1beta/models?pageSize=1\",\n headers: (value) => ({ \"x-goog-api-key\": value }),\n});\n\nconst groqProvider = livenessProvider({\n name: \"groq\",\n description: \"Groq API key validation\",\n prefixes: [\"gsk_\"],\n url: \"https://api.groq.com/openai/v1/models\",\n headers: (value) => ({ Authorization: `Bearer ${value}` }),\n});\n\nconst huggingfaceProvider = livenessProvider({\n name: \"huggingface\",\n description: \"Hugging Face token validation\",\n prefixes: [\"hf_\"],\n url: \"https://huggingface.co/api/whoami-v2\",\n headers: (value) => ({ Authorization: `Bearer ${value}` }),\n});\n\n// No prefix: ElevenLabs \"sk_...\" would shadow Stripe's sk_live_/sk_test_,\n// so it is explicit-only (set `provider: \"elevenlabs\"` on the secret/manifest).\nconst elevenlabsProvider = livenessProvider({\n name: \"elevenlabs\",\n description: \"ElevenLabs API key validation (explicit-only — set provider on the secret)\",\n url: \"https://api.elevenlabs.io/v1/user\",\n headers: (value) => ({ \"xi-api-key\": value }),\n});\n\n// No prefix: Vercel tokens have no stable public prefix — explicit-only.\nconst vercelProvider = livenessProvider({\n name: \"vercel\",\n description: \"Vercel token validation (explicit-only — set provider on the secret)\",\n url: \"https://api.vercel.com/v2/user\",\n headers: (value) => ({ Authorization: `Bearer ${value}` }),\n});\n\nconst openaiProvider: Provider = {\n name: \"openai\",\n description: \"OpenAI API key validation\",\n prefixes: [\"sk-\"],\n async validate(value: string): Promise<ValidationResult> {\n const start = Date.now();\n try {\n const { statusCode } = await makeRequest(\n \"https://api.openai.com/v1/models?limit=1\",\n {\n Authorization: `Bearer ${value}`,\n \"User-Agent\": \"q-ring-validator/1.0\",\n },\n );\n const latencyMs = Date.now() - start;\n\n if (statusCode === 200)\n return { valid: true, status: \"valid\", message: \"API key is valid\", latencyMs, provider: \"openai\" };\n if (statusCode === 401)\n return { valid: false, status: \"invalid\", message: \"Invalid or revoked API key\", latencyMs, provider: \"openai\" };\n if (statusCode === 429)\n return { valid: true, status: \"error\", message: \"Rate limited — key may be valid\", latencyMs, provider: \"openai\" };\n return { valid: false, status: \"error\", message: `Unexpected status ${statusCode}`, latencyMs, provider: \"openai\" };\n } catch (err) {\n return { valid: false, status: \"error\", message: `${err instanceof Error ? err.message : \"Network error\"}`, latencyMs: Date.now() - start, provider: \"openai\" };\n }\n },\n};\n\nconst stripeProvider: Provider = {\n name: \"stripe\",\n description: \"Stripe API key validation\",\n prefixes: [\"sk_live_\", \"sk_test_\", \"rk_live_\", \"rk_test_\", \"pk_live_\", \"pk_test_\"],\n async validate(value: string): Promise<ValidationResult> {\n const start = Date.now();\n try {\n const { statusCode } = await makeRequest(\n \"https://api.stripe.com/v1/balance\",\n {\n Authorization: `Bearer ${value}`,\n \"User-Agent\": \"q-ring-validator/1.0\",\n },\n );\n const latencyMs = Date.now() - start;\n\n if (statusCode === 200)\n return { valid: true, status: \"valid\", message: \"API key is valid\", latencyMs, provider: \"stripe\" };\n if (statusCode === 401)\n return { valid: false, status: \"invalid\", message: \"Invalid or revoked API key\", latencyMs, provider: \"stripe\" };\n if (statusCode === 429)\n return { valid: true, status: \"error\", message: \"Rate limited — key may be valid\", latencyMs, provider: \"stripe\" };\n return { valid: false, status: \"error\", message: `Unexpected status ${statusCode}`, latencyMs, provider: \"stripe\" };\n } catch (err) {\n return { valid: false, status: \"error\", message: `${err instanceof Error ? err.message : \"Network error\"}`, latencyMs: Date.now() - start, provider: \"stripe\" };\n }\n },\n};\n\nconst githubProvider: Provider = {\n name: \"github\",\n description: \"GitHub token validation\",\n prefixes: [\"ghp_\", \"gho_\", \"ghu_\", \"ghs_\", \"ghr_\", \"github_pat_\"],\n async validate(value: string): Promise<ValidationResult> {\n const start = Date.now();\n try {\n const { statusCode } = await makeRequest(\n \"https://api.github.com/user\",\n {\n Authorization: `token ${value}`,\n \"User-Agent\": \"q-ring-validator/1.0\",\n Accept: \"application/vnd.github+json\",\n },\n );\n const latencyMs = Date.now() - start;\n\n if (statusCode === 200)\n return { valid: true, status: \"valid\", message: \"Token is valid\", latencyMs, provider: \"github\" };\n if (statusCode === 401)\n return { valid: false, status: \"invalid\", message: \"Invalid or expired token\", latencyMs, provider: \"github\" };\n if (statusCode === 403)\n return { valid: false, status: \"invalid\", message: \"Token lacks required permissions\", latencyMs, provider: \"github\" };\n if (statusCode === 429)\n return { valid: true, status: \"error\", message: \"Rate limited — token may be valid\", latencyMs, provider: \"github\" };\n return { valid: false, status: \"error\", message: `Unexpected status ${statusCode}`, latencyMs, provider: \"github\" };\n } catch (err) {\n return { valid: false, status: \"error\", message: `${err instanceof Error ? err.message : \"Network error\"}`, latencyMs: Date.now() - start, provider: \"github\" };\n }\n },\n};\n\nconst awsProvider: Provider = {\n name: \"aws\",\n description: \"AWS access key validation (checks key format only — full STS validation requires secret key + region)\",\n prefixes: [\"AKIA\", \"ASIA\"],\n async validate(value: string): Promise<ValidationResult> {\n const start = Date.now();\n const latencyMs = Date.now() - start;\n\n if (/^(AKIA|ASIA)[A-Z0-9]{16}$/.test(value)) {\n return { valid: true, status: \"unknown\", message: \"Valid AWS access key format (STS validation requires secret key)\", latencyMs, provider: \"aws\" };\n }\n return { valid: false, status: \"invalid\", message: \"Invalid AWS access key format\", latencyMs, provider: \"aws\" };\n },\n};\n\nconst httpProvider: Provider = {\n name: \"http\",\n description: \"Generic HTTP endpoint validation\",\n async validate(value: string, url?: string): Promise<ValidationResult> {\n const start = Date.now();\n\n if (!url) {\n return { valid: false, status: \"unknown\", message: \"No validation URL configured\", latencyMs: 0, provider: \"http\" };\n }\n\n const ssrfBlock = await checkSSRF(url);\n if (ssrfBlock) {\n return { valid: false, status: \"error\", message: `SSRF blocked: ${ssrfBlock}`, latencyMs: Date.now() - start, provider: \"http\" };\n }\n\n try {\n const { statusCode } = await makeRequest(url, {\n Authorization: `Bearer ${value}`,\n \"User-Agent\": \"q-ring-validator/1.0\",\n });\n const latencyMs = Date.now() - start;\n\n if (statusCode >= 200 && statusCode < 300)\n return { valid: true, status: \"valid\", message: `Endpoint returned ${statusCode}`, latencyMs, provider: \"http\" };\n if (statusCode === 401 || statusCode === 403)\n return { valid: false, status: \"invalid\", message: `Authentication failed (${statusCode})`, latencyMs, provider: \"http\" };\n return { valid: false, status: \"error\", message: `Unexpected status ${statusCode}`, latencyMs, provider: \"http\" };\n } catch (err) {\n return { valid: false, status: \"error\", message: `${err instanceof Error ? err.message : \"Network error\"}`, latencyMs: Date.now() - start, provider: \"http\" };\n }\n },\n};\n\nexport const registry = new ProviderRegistry();\n// Prefix detection iterates in registration order: anthropic (sk-ant-) and\n// openrouter (sk-or-) MUST come before openai, whose bare \"sk-\" would\n// otherwise shadow them.\nregistry.register(anthropicProvider);\nregistry.register(openrouterProvider);\nregistry.register(openaiProvider);\nregistry.register(googleAiProvider);\nregistry.register(groqProvider);\nregistry.register(huggingfaceProvider);\nregistry.register(elevenlabsProvider);\nregistry.register(vercelProvider);\nregistry.register(stripeProvider);\nregistry.register(githubProvider);\nregistry.register(awsProvider);\nregistry.register(httpProvider);\n\n/**\n * Validate a secret value against its detected or specified provider.\n */\nexport async function validateSecret(\n value: string,\n opts?: { provider?: string; validationUrl?: string },\n): Promise<ValidationResult> {\n const provider = opts?.provider\n ? registry.get(opts.provider)\n : registry.detectProvider(value);\n\n if (!provider) {\n return {\n valid: false,\n status: \"unknown\",\n message: \"No provider detected — set a provider in the manifest or secret metadata\",\n latencyMs: 0,\n provider: \"none\",\n };\n }\n\n if (provider.name === \"http\" && opts?.validationUrl) {\n return (provider as any).validate(value, opts.validationUrl);\n }\n\n return provider.validate(value);\n}\n\n// ─── Rotation Support ───\n\nexport interface RotationResult {\n rotated: boolean;\n provider: string;\n message: string;\n newValue?: string;\n}\n\nexport interface RotatableProvider extends Provider {\n rotate?(currentValue: string): Promise<RotationResult>;\n supportsRotation: boolean;\n}\n\n/**\n * Attempt provider-native rotation of a secret.\n * Falls back to local generation if the provider does not support native rotation.\n */\nexport async function rotateWithProvider(\n value: string,\n providerName?: string,\n): Promise<RotationResult> {\n const provider = providerName\n ? registry.get(providerName)\n : registry.detectProvider(value);\n\n if (!provider) {\n return { rotated: false, provider: \"none\", message: \"No provider detected for rotation\" };\n }\n\n const rotatable = provider as RotatableProvider;\n if (rotatable.supportsRotation && rotatable.rotate) {\n return rotatable.rotate(value);\n }\n\n // Fall back to local generation\n const format: NoiseFormat = \"api-key\";\n const newValue = generateSecret({ format, length: 48 });\n return {\n rotated: true,\n provider: provider.name,\n message: `Provider \"${provider.name}\" does not support native rotation — generated new value locally`,\n newValue,\n };\n}\n\n// ─── CI Scan ───\n\nexport interface CiScanResult {\n key: string;\n validation: ValidationResult;\n requiresRotation: boolean;\n}\n\n/**\n * CI-oriented batch validation: validates all secrets and returns\n * a structured report suitable for CI pipeline gating.\n */\nexport async function ciValidateBatch(\n secrets: { key: string; value: string; provider?: string; validationUrl?: string }[],\n): Promise<{ results: CiScanResult[]; allValid: boolean; failCount: number }> {\n const results: CiScanResult[] = [];\n\n for (const s of secrets) {\n const validation = await validateSecret(s.value, {\n provider: s.provider,\n validationUrl: s.validationUrl,\n });\n\n results.push({\n key: s.key,\n validation,\n requiresRotation: validation.status === \"invalid\",\n });\n }\n\n const failCount = results.filter((r) => !r.validation.valid).length;\n\n return { results, allValid: failCount === 0, failCount };\n}\n","/**\n * Self-Documenting Project Context for AI Agents\n *\n * Provides a safe, redacted view of the project's secrets, configuration,\n * and state without ever exposing actual secret values.\n */\n\nimport { listSecrets } from \"./keyring.js\";\nimport { collapseEnvironment, readProjectConfig } from \"./collapse.js\";\nimport { queryAudit } from \"./observer.js\";\nimport { listHooks } from \"./hooks.js\";\nimport { registry as providerRegistry } from \"./validate.js\";\nimport { registry as jitRegistry } from \"./provision.js\";\nimport type { KeyringOptions } from \"./keyring.js\";\n\nexport interface SecretSummary {\n key: string;\n scope: string;\n tags?: string[];\n description?: string;\n provider?: string;\n requiresApproval?: boolean;\n jitProvider?: string;\n hasStates: boolean;\n isExpired: boolean;\n isStale: boolean;\n timeRemaining: string | null;\n accessCount: number;\n lastAccessed: string | null;\n rotationFormat?: string;\n}\n\nexport interface ProjectContext {\n projectPath: string;\n environment: {\n env: string;\n source: string;\n } | null;\n secrets: SecretSummary[];\n totalSecrets: number;\n expiredCount: number;\n staleCount: number;\n protectedCount: number;\n manifest: {\n declared: number;\n missing: string[];\n } | null;\n validationProviders: string[];\n jitProviders: string[];\n hooksCount: number;\n recentActions: Array<{\n action: string;\n key?: string;\n source: string;\n timestamp: string;\n }>;\n}\n\nexport function getProjectContext(opts: KeyringOptions = {}): ProjectContext {\n const projectPath = opts.projectPath ?? process.cwd();\n const envResult = collapseEnvironment({ projectPath });\n\n const secretsList = listSecrets({\n ...opts,\n projectPath,\n silent: true,\n });\n\n let expiredCount = 0;\n let staleCount = 0;\n let protectedCount = 0;\n\n const secrets: SecretSummary[] = secretsList.map((entry) => {\n const meta = entry.envelope?.meta;\n const decay = entry.decay;\n\n if (decay?.isExpired) expiredCount++;\n if (decay?.isStale) staleCount++;\n if (meta?.requiresApproval) protectedCount++;\n\n return {\n key: entry.key,\n scope: entry.scope,\n tags: meta?.tags,\n description: meta?.description,\n provider: meta?.provider,\n requiresApproval: meta?.requiresApproval,\n jitProvider: meta?.jitProvider,\n hasStates: !!(entry.envelope?.states && Object.keys(entry.envelope.states).length > 0),\n isExpired: decay?.isExpired ?? false,\n isStale: decay?.isStale ?? false,\n timeRemaining: decay?.timeRemaining ?? null,\n accessCount: meta?.accessCount ?? 0,\n lastAccessed: meta?.lastAccessedAt ?? null,\n rotationFormat: meta?.rotationFormat,\n };\n });\n\n // Manifest analysis\n let manifest: ProjectContext[\"manifest\"] = null;\n const config = readProjectConfig(projectPath);\n if (config?.secrets) {\n const declaredKeys = Object.keys(config.secrets);\n const existingKeys = new Set(secrets.map((s) => s.key));\n const missing = declaredKeys.filter((k) => !existingKeys.has(k));\n manifest = { declared: declaredKeys.length, missing };\n }\n\n // Recent audit activity (last 20 events, redacted)\n const recentEvents = queryAudit({ limit: 20 });\n const recentActions = recentEvents.map((e) => ({\n action: e.action,\n key: e.key,\n source: e.source,\n timestamp: e.timestamp,\n }));\n\n return {\n projectPath,\n environment: envResult\n ? { env: envResult.env, source: envResult.source }\n : null,\n secrets,\n totalSecrets: secrets.length,\n expiredCount,\n staleCount,\n protectedCount,\n manifest,\n validationProviders: providerRegistry.listProviders().map((p) => p.name),\n jitProviders: jitRegistry.listProviders().map((p) => p.name),\n hooksCount: listHooks().length,\n recentActions,\n };\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { getSecret, getEnvelope } from \"../../core/keyring.js\";\nimport { checkDecay } from \"../../core/envelope.js\";\nimport { collapseEnvironment, readProjectConfig } from \"../../core/collapse.js\";\nimport { getProjectContext } from \"../../core/context.js\";\nimport { text, opts, enforceToolPolicy, commonSchemas } from \"./_shared.js\";\n\nconst { teamId, orgId, scope, projectPath, env } = commonSchemas;\n\nexport function registerProjectTools(server: McpServer): void {\n server.tool(\n \"check_project\",\n [\n \"[project] Compare the keys declared in the project's `.q-ring.json` manifest against what is actually present in the keyring.\",\n \"Use as the canonical 'is this project ready to run' gate before starting a dev server, deploying, or onboarding a teammate; prefer `health_check` for a scope-wide decay sweep (no manifest), and `agent_scan` for multi-project scans with optional auto-rotation.\",\n \"Read-only; does not mutate the keyring or audit log materially beyond a 'list' read. Returns JSON `{ total, present, missing, expired, stale, ready, secrets: [...] }` where `ready` is true only when nothing is missing or expired. Errors with 'No secrets manifest found in .q-ring.json' if the project has no manifest.\",\n ].join(\" \"),\n {\n projectPath,\n },\n toolAnnotations(\"check_project\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"check_project\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const pp = params.projectPath ?? process.cwd();\n const config = readProjectConfig(pp);\n\n if (!config?.secrets || Object.keys(config.secrets).length === 0) {\n return text(\"No secrets manifest found in .q-ring.json\", true);\n }\n\n const results: Record<string, unknown>[] = [];\n let presentCount = 0;\n let missingCount = 0;\n let expiredCount = 0;\n let staleCount = 0;\n\n for (const [key, manifest] of Object.entries(config.secrets)) {\n const result = getEnvelope(key, { projectPath: pp, source: \"mcp\" });\n\n if (!result) {\n const status = manifest.required !== false ? \"missing\" : \"optional_missing\";\n if (manifest.required !== false) missingCount++;\n results.push({\n key,\n status,\n required: manifest.required !== false,\n description: manifest.description,\n });\n continue;\n }\n\n const decay = checkDecay(result.envelope);\n\n if (decay.isExpired) {\n expiredCount++;\n results.push({\n key,\n status: \"expired\",\n timeRemaining: decay.timeRemaining,\n description: manifest.description,\n });\n } else if (decay.isStale) {\n staleCount++;\n results.push({\n key,\n status: \"stale\",\n lifetimePercent: decay.lifetimePercent,\n timeRemaining: decay.timeRemaining,\n description: manifest.description,\n });\n } else {\n presentCount++;\n results.push({ key, status: \"ok\", description: manifest.description });\n }\n }\n\n const summary = {\n total: Object.keys(config.secrets).length,\n present: presentCount,\n missing: missingCount,\n expired: expiredCount,\n stale: staleCount,\n ready: missingCount === 0 && expiredCount === 0,\n secrets: results,\n };\n\n return text(JSON.stringify(summary, null, 2));\n },\n );\n\n server.tool(\n \"env_generate\",\n [\n \"[project] Render a complete `.env` file body from the project's `.q-ring.json` manifest, resolving each declared key from the keyring.\",\n \"Use when a build step or local runtime needs a real `.env` materialized on disk and you want exactly the keys the manifest declares; prefer `export_secrets` when you want every key in scope (manifest-agnostic) and `exec_with_secrets` to inject secrets into a child process without writing them to a file.\",\n \"Reads values (records 'read' audit events) and collapses superposition for the requested env. Returns the raw `.env` text, with `# MISSING (required): KEY` / `# EXPIRED: KEY` / `# STALE: KEY` warnings appended as comments. Missing keys appear as commented-out `# KEY=` placeholders so the file remains a valid drop-in.\",\n ].join(\" \"),\n {\n projectPath,\n env,\n },\n toolAnnotations(\"env_generate\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"env_generate\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const pp = params.projectPath ?? process.cwd();\n const config = readProjectConfig(pp);\n\n if (!config?.secrets || Object.keys(config.secrets).length === 0) {\n return text(\"No secrets manifest found in .q-ring.json\", true);\n }\n\n const lines: string[] = [];\n const warnings: string[] = [];\n\n for (const [key, manifest] of Object.entries(config.secrets)) {\n const value = getSecret(key, {\n projectPath: pp,\n env: params.env,\n source: \"mcp\",\n });\n\n if (value === null) {\n if (manifest.required !== false) {\n warnings.push(`MISSING (required): ${key}`);\n }\n lines.push(`# ${key}=`);\n continue;\n }\n\n const result = getEnvelope(key, { projectPath: pp, source: \"mcp\" });\n if (result) {\n const decay = checkDecay(result.envelope);\n if (decay.isExpired) warnings.push(`EXPIRED: ${key}`);\n else if (decay.isStale) warnings.push(`STALE: ${key}`);\n }\n\n const escaped = value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\");\n lines.push(`${key}=\"${escaped}\"`);\n }\n\n const output = lines.join(\"\\n\");\n const result =\n warnings.length > 0\n ? `${output}\\n\\n# Warnings:\\n${warnings.map((w) => `# ${w}`).join(\"\\n\")}`\n : output;\n\n return text(result);\n },\n );\n\n server.tool(\n \"detect_environment\",\n [\n \"[project] Resolve which environment slug (e.g. 'dev', 'staging', 'prod') the current invocation should collapse to.\",\n \"Use before reading secrets when you want to mirror the same env q-ring would auto-pick (e.g. to log it, or to pass through to another tool); prefer passing an explicit `env` to `get_secret`/`env_generate` when you already know which env you want.\",\n \"Read-only; checks the QRING_ENV env var, NODE_ENV, the project's `.q-ring.json`, and the current git branch in priority order. Returns JSON `{ env, source }` (e.g. `{ env: 'dev', source: 'NODE_ENV' }`), or a plain message indicating that no env could be detected.\",\n ].join(\" \"),\n {\n projectPath,\n },\n toolAnnotations(\"detect_environment\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"detect_environment\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const result = collapseEnvironment({\n projectPath: params.projectPath ?? process.cwd(),\n });\n\n if (!result) {\n return text(\"No environment detected. Set QRING_ENV, NODE_ENV, or create .q-ring.json\");\n }\n\n return text(JSON.stringify(result, null, 2));\n },\n );\n\n server.tool(\n \"get_project_context\",\n [\n \"[agent] Return a single redacted snapshot of everything an AI agent typically wants to know about this project: secrets present (keys + metadata only), detected env, manifest declarations, configured providers, registered hooks, and recent audit activity.\",\n \"Use this as the very first call in a session to orient the agent before it asks for any individual secret; prefer `list_secrets` for a flat key listing, `check_project` for manifest-vs-keyring drift, and `audit_log` for a deeper access trail.\",\n \"Read-only and value-safe — no plaintext secret values are ever included. Returns a single pretty-printed JSON document; shape is intentionally broad and may grow over time, so read defensively.\",\n ].join(\" \"),\n {\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"get_project_context\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"get_project_context\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const context = getProjectContext(opts(params));\n return text(JSON.stringify(context, null, 2));\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { z } from \"zod\";\nimport { tunnelCreate, tunnelRead, tunnelDestroy, tunnelList } from \"../../core/tunnel.js\";\nimport { text, enforceToolPolicy } from \"./_shared.js\";\n\nexport function registerTunnelTools(server: McpServer): void {\n server.tool(\n \"tunnel_create\",\n [\n \"[tunnel] Stash a one-shot or short-lived secret in the q-ring server's process memory and return an ID that can be used to read it back.\",\n \"Use for handing a one-time value to another tool/process without persisting it (npm OTP codes, magic-link tokens, copy/paste between machines via a relay); prefer `set_secret` with `ttlSeconds` when you actually want a tracked, auditable secret.\",\n \"Mutates only in-memory state — the value never touches disk and is lost on server restart. Subject to tool policy. Returns JSON `{ ok, data: { id } }` where `id` is an opaque string to pass to `tunnel_read`/`tunnel_destroy`.\",\n ].join(\" \"),\n {\n value: z\n .string()\n .describe(\"The plaintext value to tunnel. Held only in process memory; never logged.\"),\n ttlSeconds: z\n .number()\n .optional()\n .describe(\n \"Auto-destroy the tunnel after this many seconds. Omit for no time limit (then a `maxReads` is highly recommended).\",\n ),\n maxReads: z\n .number()\n .optional()\n .describe(\n \"Self-destruct after this many successful `tunnel_read` calls. Use 1 for true one-shot delivery.\",\n ),\n },\n toolAnnotations(\"tunnel_create\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"tunnel_create\");\n if (toolBlock) return toolBlock;\n\n const id = tunnelCreate(params.value, {\n ttlSeconds: params.ttlSeconds,\n maxReads: params.maxReads,\n });\n return text(JSON.stringify({ ok: true, data: { id } }, null, 2));\n },\n );\n\n server.tool(\n \"tunnel_read\",\n [\n \"[tunnel] Fetch the value stashed by a prior `tunnel_create` call by its ID.\",\n \"Use exactly once per intended consumer; the value is destructive-by-design and may self-delete after this call.\",\n \"Increments the read counter and may auto-destroy the tunnel if `maxReads` was set. Returns JSON `{ ok, data: { id, value } }` on success, or an error 'Tunnel \\\"...\\\" not found or expired' if the tunnel has been destroyed, hit its TTL, or never existed.\",\n ].join(\" \"),\n {\n id: z.string().describe(\"The opaque tunnel ID returned by `tunnel_create`. Case-sensitive.\"),\n },\n toolAnnotations(\"tunnel_read\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"tunnel_read\");\n if (toolBlock) return toolBlock;\n\n const value = tunnelRead(params.id);\n if (value === null) {\n return text(`Tunnel \"${params.id}\" not found or expired`, true);\n }\n return text(JSON.stringify({ ok: true, data: { id: params.id, value } }, null, 2));\n },\n );\n\n server.tool(\n \"tunnel_list\",\n [\n \"[tunnel] Enumerate all currently-active tunnels in the q-ring server with their remaining read budget and time-to-live.\",\n \"Use to audit what is still in memory or to look up an ID you forgot; values are never included in the output.\",\n \"Read-only. Returns one line per tunnel formatted as `id | reads:N | max:N | expires:Ns`, or the literal text 'No active tunnels' when the list is empty.\",\n ].join(\" \"),\n {},\n toolAnnotations(\"tunnel_list\"),\n async () => {\n const toolBlock = enforceToolPolicy(\"tunnel_list\");\n if (toolBlock) return toolBlock;\n\n const tunnels = tunnelList();\n if (tunnels.length === 0) return text(\"No active tunnels\");\n\n const lines = tunnels.map((t) => {\n const parts = [t.id];\n parts.push(`reads:${t.accessCount}`);\n if (t.maxReads) parts.push(`max:${t.maxReads}`);\n if (t.expiresAt) {\n const rem = Math.max(0, Math.floor((t.expiresAt - Date.now()) / 1000));\n parts.push(`expires:${rem}s`);\n }\n return parts.join(\" | \");\n });\n\n return text(lines.join(\"\\n\"));\n },\n );\n\n server.tool(\n \"tunnel_destroy\",\n [\n \"[tunnel] Immediately remove a tunnel from memory, regardless of remaining reads or TTL.\",\n \"Use when a tunneled value should be cancelled before delivery (e.g. wrong recipient, secret already rotated); prefer letting `maxReads`/TTL handle cleanup for normal flows.\",\n \"Mutates in-memory state only. Returns 'Destroyed ID' on success or a not-found error if the ID is unknown or already gone.\",\n ].join(\" \"),\n {\n id: z.string().describe(\"The opaque tunnel ID to destroy.\"),\n },\n toolAnnotations(\"tunnel_destroy\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"tunnel_destroy\");\n if (toolBlock) return toolBlock;\n\n const destroyed = tunnelDestroy(params.id);\n return text(\n destroyed ? `Destroyed ${params.id}` : `Tunnel \"${params.id}\" not found`,\n !destroyed,\n );\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { z } from \"zod\";\nimport { getSecret, setSecret, listSecrets } from \"../../core/keyring.js\";\nimport {\n teleportPack,\n teleportPackFor,\n teleportUnpackAuto,\n inspectTeleportBundle,\n loadTeleportIdentity,\n parseRecipient,\n} from \"../../core/teleport.js\";\nimport { text, opts, enforceToolPolicy, commonSchemas } from \"./_shared.js\";\n\nconst { teamId, orgId, scope, projectPath } = commonSchemas;\n\nexport function registerTeleportTools(server: McpServer): void {\n server.tool(\n \"teleport_pack\",\n [\n \"[teleport] Encrypt one or more secrets into a single AES-256-GCM bundle string that can be safely transferred between machines.\",\n \"Use to hand off a curated set of credentials to another developer or environment; prefer `export_secrets` for plaintext .env output (single machine, trusted) and `tunnel_create` for ephemeral one-shot delivery on the same machine.\",\n \"Two modes, exactly one required: `passphrase` (v1, symmetric — receiver needs the same string) or `recipients` (v2, public-key — each receiver's `qring1...` string from `qring teleport identity`; no shared secret, only the listed identities can open it).\",\n \"Reads each secret value (records 'export' audit events) and produces a base64-encoded ciphertext. Returns the bundle string directly. Errors with 'No secrets to pack' if the filter matched zero secrets.\",\n ].join(\" \"),\n {\n keys: z\n .array(z.string())\n .optional()\n .describe(\n \"Whitelist of exact key names to include. Omit to pack every secret in the requested scope.\",\n ),\n passphrase: z\n .string()\n .optional()\n .describe(\n \"Symmetric passphrase used to derive the AES-256-GCM key (v1 bundle). The receiver must supply the same string to `teleport_unpack`. Pick something high-entropy and share it out-of-band. Mutually exclusive with `recipients`.\",\n ),\n recipients: z\n .array(z.string())\n .optional()\n .describe(\n \"Recipient public keys (`qring1...` strings, one per teammate) for a v2 recipient pack. The bundle can only be opened by the matching private keys, which each receiver created with `qring teleport keygen`. Mutually exclusive with `passphrase`.\",\n ),\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"teleport_pack\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"teleport_pack\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const recipients = (params.recipients ?? [])\n .flatMap((r) => r.split(\",\"))\n .map((r) => r.trim())\n .filter((r) => r.length > 0);\n const hasPassphrase =\n typeof params.passphrase === \"string\" && params.passphrase.length > 0;\n\n if (hasPassphrase === (recipients.length > 0)) {\n return text(\n \"teleport_pack needs exactly one of `passphrase` (v1) or `recipients` (v2)\",\n true,\n );\n }\n for (const r of recipients) {\n try {\n parseRecipient(r);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return text(`Bad recipient \"${r}\": ${msg}`, true);\n }\n }\n\n const o = opts(params);\n const entries = listSecrets(o);\n\n const secrets: { key: string; value: string; scope?: string }[] = [];\n for (const entry of entries) {\n if (params.keys && !params.keys.includes(entry.key)) continue;\n const value = getSecret(entry.key, { ...o, scope: entry.scope });\n if (value !== null) {\n secrets.push({ key: entry.key, value, scope: entry.scope });\n }\n }\n\n if (secrets.length === 0) return text(\"No secrets to pack\", true);\n\n const bundle =\n recipients.length > 0\n ? teleportPackFor(secrets, recipients)\n : teleportPack(secrets, params.passphrase as string);\n return text(bundle);\n },\n );\n\n server.tool(\n \"teleport_unpack\",\n [\n \"[teleport] Decrypt a bundle produced by `teleport_pack` and import each contained secret into the local keyring.\",\n \"Use on the receiving machine after a packer hands you the bundle; prefer `dryRun=true` first to preview what will be written.\",\n \"Passphrase (v1) bundles need `passphrase`. Recipient (v2) bundles need no input: this machine's teleport identity is read from the OS keyring (create one with `qring teleport keygen`; the private key is never returned).\",\n \"When dryRun is false this mutates the keyring (one 'write' event per imported secret) at the requested scope. Bad passphrase, missing identity, not-a-recipient or tampered bundle returns JSON `{ ok: false, error: { message } }` with `isError: true`. On success returns 'Imported N secret(s) from teleport bundle'; in dryRun mode returns 'Would import N secrets:' followed by a `KEY [scope]` listing (v2 also lists the recipient ids the bundle is addressed to).\",\n ].join(\" \"),\n {\n bundle: z\n .string()\n .describe(\n \"Base64-encoded ciphertext returned by `teleport_pack`. Pass through whitespace untouched if possible.\",\n ),\n passphrase: z\n .string()\n .optional()\n .describe(\n \"The passphrase used to pack a v1 bundle. Omit for v2 recipient bundles (decrypted with this machine's keyring identity). Bad passphrases return an authentication error rather than wrong plaintext.\",\n ),\n scope: scope.default(\"global\"),\n projectPath,\n teamId,\n orgId,\n dryRun: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n \"If true, decrypt and report what would be written but do not mutate the keyring. Useful for verifying bundle contents before commit.\",\n ),\n },\n toolAnnotations(\"teleport_unpack\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"teleport_unpack\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n try {\n const info = inspectTeleportBundle(params.bundle);\n\n let header = \"\";\n let identity: ReturnType<typeof loadTeleportIdentity> = null;\n if (info.v === 2) {\n identity = loadTeleportIdentity();\n if (!identity) {\n throw new Error(\n \"ERR_TELEPORT_NO_IDENTITY: this bundle is addressed to recipient keys and this machine has no teleport identity — run `qring teleport keygen` first\",\n );\n }\n const ids = info.recipients\n .map((id) => (id === identity!.id ? `${id} (you)` : id))\n .join(\", \");\n header = `Addressed to recipient id(s): ${ids}\\n`;\n } else if (params.passphrase === undefined) {\n throw new Error(\n \"ERR_TELEPORT_PASSPHRASE_REQUIRED: this is a passphrase (v1) bundle — pass `passphrase`\",\n );\n }\n\n const payload = teleportUnpackAuto(params.bundle, {\n passphrase: params.passphrase,\n identity: identity?.privateKey,\n });\n\n if (params.dryRun) {\n const preview = payload.secrets\n .map((s) => `${s.key} [${s.scope ?? \"global\"}]`)\n .join(\"\\n\");\n return text(\n `${header}Would import ${payload.secrets.length} secrets:\\n${preview}`,\n );\n }\n\n const o = opts(params);\n for (const s of payload.secrets) {\n setSecret(s.key, s.value, o);\n }\n\n return text(`Imported ${payload.secrets.length} secret(s) from teleport bundle`);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return text(JSON.stringify({ ok: false, error: { message: msg } }), true);\n }\n },\n );\n}\n","/**\n * Quantum Teleportation: securely share/transfer secrets between machines.\n *\n * Generates encrypted bundles that can be shared via any channel.\n *\n * - v1 (passphrase): AES-256-GCM under a PBKDF2-HMAC-SHA512 key derived from\n * a passphrase exchanged out-of-band.\n * - v2 (recipient packs): age-style public-key encryption. The packer wraps a\n * random content key for each recipient's X25519 public key (ECDH with an\n * ephemeral key, HKDF-SHA256, AES-256-GCM key wrap). No shared secret is\n * needed — recipients publish a `qring1...` string once and keep their\n * private key in the OS keyring (`qring teleport keygen`).\n */\n\nimport {\n randomBytes,\n createCipheriv,\n createDecipheriv,\n createHash,\n createPrivateKey,\n createPublicKey,\n diffieHellman,\n generateKeyPairSync,\n hkdfSync,\n pbkdf2Sync,\n type KeyObject,\n} from \"node:crypto\";\nimport { z } from \"zod\";\nimport { Entry } from \"./backend.js\";\n\nconst ALGORITHM = \"aes-256-gcm\";\nconst KEY_LENGTH = 32;\n/** NIST / OpenSSL recommendation for AES-GCM (96-bit nonce). */\nconst IV_LENGTH = 12;\nconst SALT_LENGTH = 32;\n/** OWASP-recommended floor for PBKDF2-HMAC-SHA512 (2023). */\nconst PBKDF2_ITERATIONS = 210000;\n/** Bundles without an explicit `iter` predate the bump; decrypt at the old cost. */\nconst LEGACY_PBKDF2_ITERATIONS = 100000;\n\nexport interface TeleportBundle {\n /** Format version */\n v: 1;\n /** Base64-encoded encrypted payload */\n data: string;\n /** Base64-encoded salt for key derivation */\n salt: string;\n /** Base64-encoded initialization vector */\n iv: string;\n /** Base64-encoded auth tag */\n tag: string;\n /** ISO timestamp of creation */\n createdAt: string;\n /** Number of secrets in the bundle */\n count: number;\n /** PBKDF2 iteration count used for key derivation (absent = legacy 100k). */\n iter?: number;\n}\n\nexport interface TeleportPayload {\n secrets: { key: string; value: string; scope?: string }[];\n exportedAt: string;\n exportedBy?: string;\n}\n\nexport const TeleportBundleSchema = z.object({\n v: z.literal(1),\n data: z.string(),\n salt: z.string(),\n iv: z.string(),\n tag: z.string(),\n createdAt: z.string(),\n count: z.number(),\n iter: z.number().optional(),\n});\n\nexport const TeleportPayloadSchema = z.object({\n secrets: z.array(\n z.object({\n key: z.string(),\n value: z.string(),\n scope: z.string().optional(),\n }),\n ),\n exportedAt: z.string(),\n exportedBy: z.string().optional(),\n});\n\nfunction deriveKey(\n passphrase: string,\n salt: Buffer,\n iterations: number = PBKDF2_ITERATIONS,\n): Buffer {\n return pbkdf2Sync(passphrase, salt, iterations, KEY_LENGTH, \"sha512\");\n}\n\n/** base64 → JSON, with the v1-era error codes preserved. */\nfunction decodeBundle(encoded: string): unknown {\n let bundleJson: string;\n try {\n bundleJson = Buffer.from(encoded, \"base64\").toString(\"utf8\");\n } catch {\n throw new Error(\"ERR_TELEPORT_CORRUPT: invalid base64 bundle\");\n }\n\n try {\n return JSON.parse(bundleJson);\n } catch {\n throw new Error(\"ERR_TELEPORT_CORRUPT: bundle is not valid JSON\");\n }\n}\n\nfunction parsePayload(decrypted: Buffer): TeleportPayload {\n let rawPayload: unknown;\n try {\n rawPayload = JSON.parse(decrypted.toString(\"utf8\"));\n } catch {\n throw new Error(\"ERR_TELEPORT_CORRUPT: decrypted payload is not valid JSON\");\n }\n\n const payload = TeleportPayloadSchema.safeParse(rawPayload);\n if (!payload.success) {\n throw new Error(\n `ERR_TELEPORT_CORRUPT: invalid payload (${payload.error.message})`,\n );\n }\n return payload.data;\n}\n\n/**\n * Pack secrets into an encrypted teleport bundle.\n */\nexport function teleportPack(\n secrets: { key: string; value: string; scope?: string }[],\n passphrase: string,\n): string {\n const payload: TeleportPayload = {\n secrets,\n exportedAt: new Date().toISOString(),\n };\n\n const plaintext = JSON.stringify(payload);\n const salt = randomBytes(SALT_LENGTH);\n const iv = randomBytes(IV_LENGTH);\n const key = deriveKey(passphrase, salt, PBKDF2_ITERATIONS);\n\n const cipher = createCipheriv(ALGORITHM, key, iv);\n const encrypted = Buffer.concat([\n cipher.update(plaintext, \"utf8\"),\n cipher.final(),\n ]);\n const tag = cipher.getAuthTag();\n\n const bundle: TeleportBundle = {\n v: 1,\n data: encrypted.toString(\"base64\"),\n salt: salt.toString(\"base64\"),\n iv: iv.toString(\"base64\"),\n tag: tag.toString(\"base64\"),\n createdAt: new Date().toISOString(),\n count: secrets.length,\n iter: PBKDF2_ITERATIONS,\n };\n\n return Buffer.from(JSON.stringify(bundle)).toString(\"base64\");\n}\n\n/**\n * Unpack and decrypt a teleport bundle.\n */\nexport function teleportUnpack(\n encoded: string,\n passphrase: string,\n): TeleportPayload {\n const rawBundle = decodeBundle(encoded);\n\n const parsedBundle = TeleportBundleSchema.safeParse(rawBundle);\n if (!parsedBundle.success) {\n throw new Error(\n `ERR_TELEPORT_CORRUPT: invalid bundle shape (${parsedBundle.error.message})`,\n );\n }\n const bundle = parsedBundle.data;\n\n const salt = Buffer.from(bundle.salt, \"base64\");\n const iv = Buffer.from(bundle.iv, \"base64\");\n const tag = Buffer.from(bundle.tag, \"base64\");\n const encrypted = Buffer.from(bundle.data, \"base64\");\n const key = deriveKey(passphrase, salt, bundle.iter ?? LEGACY_PBKDF2_ITERATIONS);\n\n const decipher = createDecipheriv(ALGORITHM, key, iv);\n decipher.setAuthTag(tag);\n\n let decrypted: Buffer;\n try {\n decrypted = Buffer.concat([\n decipher.update(encrypted),\n decipher.final(),\n ]);\n } catch {\n throw new Error(\"ERR_TELEPORT_BAD_PASSPHRASE: decryption failed (wrong passphrase or corrupt data)\");\n }\n\n return parsePayload(decrypted);\n}\n\n// ─── v2: recipient packs (X25519 + HKDF-SHA256 + AES-256-GCM key wrap) ───\n\n/** Recipient strings look like `qring1` + base64url(raw 32-byte X25519 pub). */\nconst RECIPIENT_PREFIX = \"qring1\";\nconst RECIPIENT_RE = /^qring1([A-Za-z0-9_-]{43})$/;\nconst X25519_RAW_LENGTH = 32;\n/** AAD binding the payload ciphertext to the v2 format. */\nconst V2_AAD = \"qring-teleport-v2\";\n/** HKDF info for the per-recipient wrapping key. */\nconst V2_WRAP_INFO = \"qring-teleport-v2-wrap\";\n/** Where our own private key lives: OS keyring, never a file. */\nexport const TELEPORT_KEYRING_SERVICE = \"q-ring-teleport\";\nexport const TELEPORT_KEYRING_ACCOUNT = \"identity\";\n\nexport interface TeleportRecipientEntry {\n /** First 8 hex chars of SHA-256(raw recipient public key). */\n id: string;\n /** Base64 AES-256-GCM ciphertext of the content-encryption key. */\n wrap: string;\n /** Base64 IV for the wrap. */\n iv: string;\n /** Base64 auth tag for the wrap. */\n tag: string;\n}\n\nexport interface TeleportBundleV2 {\n v: 2;\n createdAt: string;\n count: number;\n /** base64url raw 32-byte ephemeral X25519 public key. */\n ephemeral: string;\n recipients: TeleportRecipientEntry[];\n /** Base64 IV for the payload. */\n iv: string;\n /** Base64 auth tag for the payload. */\n tag: string;\n /** Base64 AES-256-GCM ciphertext of the JSON payload. */\n data: string;\n}\n\nexport const TeleportBundleV2Schema = z.object({\n v: z.literal(2),\n createdAt: z.string(),\n count: z.number(),\n ephemeral: z.string(),\n recipients: z\n .array(\n z.object({\n id: z.string(),\n wrap: z.string(),\n iv: z.string(),\n tag: z.string(),\n }),\n )\n .min(1),\n iv: z.string(),\n tag: z.string(),\n data: z.string(),\n});\n\nexport interface TeleportIdentity {\n /** Our X25519 private key (never serialised by callers). */\n privateKey: KeyObject;\n /** Our public recipient string (`qring1...`). */\n recipient: string;\n /** Our recipient id, as it appears in bundles addressed to us. */\n id: string;\n}\n\nfunction rawPublicKey(key: KeyObject): Buffer {\n const jwk = key.export({ format: \"jwk\" });\n if (jwk.kty !== \"OKP\" || jwk.crv !== \"X25519\" || typeof jwk.x !== \"string\") {\n throw new Error(\"ERR_TELEPORT_BAD_RECIPIENT: not an X25519 public key\");\n }\n const raw = Buffer.from(jwk.x, \"base64url\");\n if (raw.length !== X25519_RAW_LENGTH) {\n throw new Error(\"ERR_TELEPORT_BAD_RECIPIENT: not an X25519 public key\");\n }\n return raw;\n}\n\nfunction publicKeyFromRaw(raw: Buffer): KeyObject {\n return createPublicKey({\n key: { kty: \"OKP\", crv: \"X25519\", x: raw.toString(\"base64url\") },\n format: \"jwk\",\n });\n}\n\n/** `qring1` + base64url(raw public key), no padding. */\nexport function formatRecipient(publicKey: KeyObject | Buffer): string {\n const raw = Buffer.isBuffer(publicKey) ? publicKey : rawPublicKey(publicKey);\n if (raw.length !== X25519_RAW_LENGTH) {\n throw new Error(\"ERR_TELEPORT_BAD_RECIPIENT: public key must be 32 raw bytes\");\n }\n return `${RECIPIENT_PREFIX}${raw.toString(\"base64url\")}`;\n}\n\n/**\n * Parse a recipient string back into the raw 32-byte X25519 public key.\n * Throws `ERR_TELEPORT_BAD_RECIPIENT` on anything that is not exactly\n * `qring1` + 43 base64url characters decoding to 32 bytes.\n */\nexport function parseRecipient(str: string): Buffer {\n const trimmed = typeof str === \"string\" ? str.trim() : \"\";\n const match = RECIPIENT_RE.exec(trimmed);\n if (!match) {\n throw new Error(\n `ERR_TELEPORT_BAD_RECIPIENT: expected \"${RECIPIENT_PREFIX}\" followed by a base64url X25519 public key (run \\`qring teleport identity\\` on the recipient's machine to get one)`,\n );\n }\n const raw = Buffer.from(match[1], \"base64url\");\n if (raw.length !== X25519_RAW_LENGTH) {\n throw new Error(\n \"ERR_TELEPORT_BAD_RECIPIENT: recipient key does not decode to 32 bytes\",\n );\n }\n return raw;\n}\n\n/** First 8 hex chars of SHA-256(raw public key). */\nexport function recipientId(rawPub: Buffer): string {\n return createHash(\"sha256\").update(rawPub).digest(\"hex\").slice(0, 8);\n}\n\n/** HKDF-SHA256(ikm=shared, salt=ephemeralPub||recipientPub, info, 32). */\nfunction deriveWrapKey(\n shared: Buffer,\n ephemeralPub: Buffer,\n recipientPub: Buffer,\n): Buffer {\n return Buffer.from(\n hkdfSync(\n \"sha256\",\n shared,\n Buffer.concat([ephemeralPub, recipientPub]),\n V2_WRAP_INFO,\n KEY_LENGTH,\n ),\n );\n}\n\n/**\n * Pack secrets for one or more recipients (no shared passphrase).\n *\n * A fresh content-encryption key encrypts the payload; the CEK is then\n * wrapped once per recipient under a key agreed via X25519 with a\n * single-use ephemeral keypair. The CEK and every intermediate key are\n * zeroised before returning; the ephemeral private key is discarded.\n */\nexport function teleportPackFor(\n secrets: { key: string; value: string; scope?: string }[],\n recipients: string[],\n): string {\n const seen = new Map<string, Buffer>();\n for (const r of recipients) {\n const raw = parseRecipient(r);\n seen.set(recipientId(raw), raw);\n }\n if (seen.size === 0) {\n throw new Error(\"ERR_TELEPORT_NO_RECIPIENTS: at least one recipient is required\");\n }\n\n const payload: TeleportPayload = {\n secrets,\n exportedAt: new Date().toISOString(),\n };\n const plaintext = JSON.stringify(payload);\n\n const cek = randomBytes(KEY_LENGTH);\n const iv = randomBytes(IV_LENGTH);\n const cipher = createCipheriv(ALGORITHM, cek, iv);\n cipher.setAAD(Buffer.from(V2_AAD, \"utf8\"));\n const encrypted = Buffer.concat([\n cipher.update(plaintext, \"utf8\"),\n cipher.final(),\n ]);\n const tag = cipher.getAuthTag();\n\n const ephemeral = generateKeyPairSync(\"x25519\");\n const ephemeralPub = rawPublicKey(ephemeral.publicKey);\n\n const wrapped: TeleportRecipientEntry[] = [];\n for (const [id, recipientPub] of seen) {\n const shared = diffieHellman({\n privateKey: ephemeral.privateKey,\n publicKey: publicKeyFromRaw(recipientPub),\n });\n const wrapKey = deriveWrapKey(shared, ephemeralPub, recipientPub);\n shared.fill(0);\n\n const wrapIv = randomBytes(IV_LENGTH);\n const wrapCipher = createCipheriv(ALGORITHM, wrapKey, wrapIv);\n wrapCipher.setAAD(Buffer.from(id, \"utf8\"));\n const wrap = Buffer.concat([wrapCipher.update(cek), wrapCipher.final()]);\n const wrapTag = wrapCipher.getAuthTag();\n wrapKey.fill(0);\n\n wrapped.push({\n id,\n wrap: wrap.toString(\"base64\"),\n iv: wrapIv.toString(\"base64\"),\n tag: wrapTag.toString(\"base64\"),\n });\n }\n cek.fill(0);\n\n const bundle: TeleportBundleV2 = {\n v: 2,\n createdAt: new Date().toISOString(),\n count: secrets.length,\n ephemeral: ephemeralPub.toString(\"base64url\"),\n recipients: wrapped,\n iv: iv.toString(\"base64\"),\n tag: tag.toString(\"base64\"),\n data: encrypted.toString(\"base64\"),\n };\n\n return Buffer.from(JSON.stringify(bundle)).toString(\"base64\");\n}\n\nfunction toPrivateKey(identity: string | KeyObject): KeyObject {\n if (typeof identity !== \"string\") return identity;\n try {\n return createPrivateKey(identity);\n } catch {\n throw new Error(\"ERR_TELEPORT_BAD_IDENTITY: private key is not a valid PEM\");\n }\n}\n\n/**\n * Unpack a v2 bundle with our X25519 private key (PEM string or KeyObject).\n *\n * Throws `ERR_TELEPORT_NOT_A_RECIPIENT` when no entry matches our recipient\n * id, and `ERR_TELEPORT_CORRUPT` when the bundle is malformed or any GCM\n * tag fails (tampered payload, tampered wrap, or a swapped ephemeral key).\n */\nexport function teleportUnpackWith(\n encoded: string,\n identity: string | KeyObject,\n): TeleportPayload {\n const privateKey = toPrivateKey(identity);\n const rawBundle = decodeBundle(encoded);\n\n const parsedBundle = TeleportBundleV2Schema.safeParse(rawBundle);\n if (!parsedBundle.success) {\n throw new Error(\n `ERR_TELEPORT_CORRUPT: invalid bundle shape (${parsedBundle.error.message})`,\n );\n }\n const bundle = parsedBundle.data;\n\n const myPub = rawPublicKey(createPublicKey(privateKey));\n const myId = recipientId(myPub);\n const mine = bundle.recipients.filter((r) => r.id === myId);\n if (mine.length === 0) {\n const ids = bundle.recipients.map((r) => r.id).join(\", \");\n throw new Error(\n `ERR_TELEPORT_NOT_A_RECIPIENT: bundle is addressed to [${ids}], not to ${myId}`,\n );\n }\n\n const ephemeralPub = Buffer.from(bundle.ephemeral, \"base64url\");\n if (ephemeralPub.length !== X25519_RAW_LENGTH) {\n throw new Error(\"ERR_TELEPORT_CORRUPT: ephemeral key is not 32 bytes\");\n }\n\n let ephemeralKey: KeyObject;\n try {\n ephemeralKey = publicKeyFromRaw(ephemeralPub);\n } catch {\n throw new Error(\"ERR_TELEPORT_CORRUPT: ephemeral key is not a valid X25519 point\");\n }\n const shared = diffieHellman({ privateKey, publicKey: ephemeralKey });\n const wrapKey = deriveWrapKey(shared, ephemeralPub, myPub);\n shared.fill(0);\n\n // 8 hex chars of id leave room for a (vanishingly unlikely) collision, so\n // try every entry that claims our id before giving up.\n let cek: Buffer | null = null;\n for (const entry of mine) {\n try {\n const decipher = createDecipheriv(\n ALGORITHM,\n wrapKey,\n Buffer.from(entry.iv, \"base64\"),\n );\n decipher.setAAD(Buffer.from(entry.id, \"utf8\"));\n decipher.setAuthTag(Buffer.from(entry.tag, \"base64\"));\n cek = Buffer.concat([\n decipher.update(Buffer.from(entry.wrap, \"base64\")),\n decipher.final(),\n ]);\n break;\n } catch {\n cek = null;\n }\n }\n wrapKey.fill(0);\n if (cek === null || cek.length !== KEY_LENGTH) {\n cek?.fill(0);\n throw new Error(\n \"ERR_TELEPORT_CORRUPT: could not unwrap content key (tampered bundle or mismatched identity)\",\n );\n }\n\n let decrypted: Buffer;\n try {\n const decipher = createDecipheriv(\n ALGORITHM,\n cek,\n Buffer.from(bundle.iv, \"base64\"),\n );\n decipher.setAAD(Buffer.from(V2_AAD, \"utf8\"));\n decipher.setAuthTag(Buffer.from(bundle.tag, \"base64\"));\n decrypted = Buffer.concat([\n decipher.update(Buffer.from(bundle.data, \"base64\")),\n decipher.final(),\n ]);\n } catch {\n throw new Error(\"ERR_TELEPORT_CORRUPT: payload authentication failed (tampered bundle)\");\n } finally {\n cek.fill(0);\n }\n\n return parsePayload(decrypted);\n}\n\nexport type TeleportBundleInfo =\n | { v: 1; count: number }\n | { v: 2; count: number; recipients: string[] };\n\n/**\n * Cheap, non-decrypting look at a bundle: which format it is, how many\n * secrets it claims, and (v2) which recipient ids it is addressed to.\n */\nexport function inspectTeleportBundle(encoded: string): TeleportBundleInfo {\n const raw = decodeBundle(encoded);\n const v1 = TeleportBundleSchema.safeParse(raw);\n if (v1.success) return { v: 1, count: v1.data.count };\n const v2 = TeleportBundleV2Schema.safeParse(raw);\n if (v2.success) {\n return {\n v: 2,\n count: v2.data.count,\n recipients: v2.data.recipients.map((r) => r.id),\n };\n }\n const version =\n raw !== null && typeof raw === \"object\" && \"v\" in raw\n ? String((raw as { v: unknown }).v)\n : \"unknown\";\n throw new Error(\n `ERR_TELEPORT_CORRUPT: unsupported or malformed bundle (v=${version})`,\n );\n}\n\n/**\n * Unpack either format: v1 needs `passphrase`, v2 needs `identity`.\n */\nexport function teleportUnpackAuto(\n encoded: string,\n creds: { passphrase?: string; identity?: string | KeyObject },\n): TeleportPayload {\n const info = inspectTeleportBundle(encoded);\n if (info.v === 1) {\n if (creds.passphrase === undefined) {\n throw new Error(\n \"ERR_TELEPORT_PASSPHRASE_REQUIRED: this is a passphrase (v1) bundle\",\n );\n }\n return teleportUnpack(encoded, creds.passphrase);\n }\n if (creds.identity === undefined) {\n throw new Error(\n \"ERR_TELEPORT_NO_IDENTITY: this bundle is addressed to recipient keys — run `qring teleport keygen` to create yours\",\n );\n }\n return teleportUnpackWith(encoded, creds.identity);\n}\n\n// ─── Identity storage (OS keyring only) ───\n\nfunction identityFrom(privateKey: KeyObject): TeleportIdentity {\n const raw = rawPublicKey(createPublicKey(privateKey));\n return { privateKey, recipient: formatRecipient(raw), id: recipientId(raw) };\n}\n\n/**\n * Generate a fresh X25519 identity and store the private key (PKCS8 DER,\n * base64) in the keyring under `q-ring-teleport` / `identity`.\n * Refuses to overwrite an existing identity unless `force` is set.\n */\nexport function generateTeleportIdentity(\n options: { force?: boolean } = {},\n): TeleportIdentity {\n const entry = new Entry(TELEPORT_KEYRING_SERVICE, TELEPORT_KEYRING_ACCOUNT);\n if (!options.force && entry.getPassword()) {\n throw new Error(\n \"ERR_TELEPORT_IDENTITY_EXISTS: a teleport identity already exists — pass --force to replace it (bundles sent to the old key become unreadable)\",\n );\n }\n const { privateKey } = generateKeyPairSync(\"x25519\");\n const der = privateKey.export({ format: \"der\", type: \"pkcs8\" });\n entry.setPassword(der.toString(\"base64\"));\n der.fill(0);\n return identityFrom(privateKey);\n}\n\n/** Load our identity from the keyring, or null if none was generated yet. */\nexport function loadTeleportIdentity(): TeleportIdentity | null {\n const stored = new Entry(\n TELEPORT_KEYRING_SERVICE,\n TELEPORT_KEYRING_ACCOUNT,\n ).getPassword();\n if (!stored) return null;\n let privateKey: KeyObject;\n try {\n privateKey = createPrivateKey({\n key: Buffer.from(stored, \"base64\"),\n format: \"der\",\n type: \"pkcs8\",\n });\n } catch {\n throw new Error(\n \"ERR_TELEPORT_BAD_IDENTITY: stored teleport identity is unreadable — run `qring teleport keygen --force`\",\n );\n }\n return identityFrom(privateKey);\n}\n\n/** Load our identity or throw the keygen hint. */\nexport function requireTeleportIdentity(): TeleportIdentity {\n const identity = loadTeleportIdentity();\n if (!identity) {\n throw new Error(\n \"ERR_TELEPORT_NO_IDENTITY: no teleport identity found — run `qring teleport keygen` first\",\n );\n }\n return identity;\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { z } from \"zod\";\nimport { listSecrets } from \"../../core/keyring.js\";\nimport { queryAudit, detectAnomalies, verifyAuditChain, exportAudit } from \"../../core/observer.js\";\nimport { text, opts, enforceToolPolicy, commonSchemas } from \"./_shared.js\";\n\nconst { teamId, orgId, scope, projectPath } = commonSchemas;\n\nexport function registerAuditTools(server: McpServer): void {\n server.tool(\n \"audit_log\",\n [\n \"[audit] Query the q-ring audit log — a tamper-evident record of every read/write/delete touching a secret.\",\n \"Use to investigate 'who accessed KEY recently?' or to feed an agent the access timeline for a specific credential; prefer `detect_anomalies` for automated unusual-pattern detection and `health_check` for decay-state-plus-anomalies in one call.\",\n \"Read-only. Returns one line per event in chronological order, formatted `timestamp | action | key | [scope] | env:NAME | detail`. Returns 'No audit events found' when the filter matches nothing.\",\n ].join(\" \"),\n {\n key: z\n .string()\n .optional()\n .describe(\"Limit to events touching this exact key. Omit for the full log.\"),\n action: z\n .enum([\n \"read\",\n \"write\",\n \"delete\",\n \"list\",\n \"export\",\n \"generate\",\n \"entangle\",\n \"tunnel\",\n \"teleport\",\n \"collapse\",\n \"approve\",\n \"revoke\",\n \"policy_deny\",\n \"rotate\",\n \"push\",\n \"wrap\",\n ])\n .optional()\n .describe(\n \"Limit to a single action verb (e.g. 'read' to see only reads). Omit for all actions.\",\n ),\n agent: z\n .string()\n .optional()\n .describe(\n \"Limit to events stamped with this agent label (clientInfo name@version). Omit for all agents.\",\n ),\n limit: z\n .number()\n .optional()\n .default(20)\n .describe(\n \"Maximum events to return, newest first. Defaults to 20. Increase for deeper investigations.\",\n ),\n },\n toolAnnotations(\"audit_log\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"audit_log\");\n if (toolBlock) return toolBlock;\n\n // Canary trip events are operator-facing counter-intelligence: exposing\n // them over MCP would let an agent enumerate which tripwires fired.\n // CLI `qring audit` remains the surface for reviewing trips.\n const events = queryAudit({\n key: params.key,\n action: params.action,\n agent: params.agent,\n })\n .filter((e) => e.action !== \"canary\")\n .slice(0, params.limit);\n\n if (events.length === 0) return text(\"No audit events found\");\n\n const lines = events.map((e) => {\n const parts = [e.timestamp, e.action];\n if (e.key) parts.push(e.key);\n if (e.scope) parts.push(`[${e.scope}]`);\n if (e.env) parts.push(`env:${e.env}`);\n if (e.agent) parts.push(`agent:${e.agent}`);\n if (e.detail) parts.push(e.detail);\n return parts.join(\" | \");\n });\n\n return text(lines.join(\"\\n\"));\n },\n );\n\n server.tool(\n \"detect_anomalies\",\n [\n \"[audit] Scan the audit history for suspicious access patterns — burst reads of the same key, off-hours access, and other heuristics.\",\n \"Use as a quick triage signal when investigating a single key or before letting an agent rotate credentials; prefer `health_check` for a scope-wide decay+anomaly summary, and `agent_scan` for multi-project JSON reports with optional auto-rotation.\",\n \"Read-only; never mutates secrets or the audit log. Returns one line per finding formatted `[type] description`, or 'No anomalies detected' when the log looks clean.\",\n ].join(\" \"),\n {\n key: z\n .string()\n .optional()\n .describe(\n \"If provided, narrow the scan to this exact key. Omit to scan across every key in the audit log.\",\n ),\n },\n toolAnnotations(\"detect_anomalies\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"detect_anomalies\");\n if (toolBlock) return toolBlock;\n\n const anomalies = detectAnomalies(params.key);\n if (anomalies.length === 0) return text(\"No anomalies detected\");\n\n const lines = anomalies.map((a) => `[${a.type}] ${a.description}`);\n return text(lines.join(\"\\n\"));\n },\n );\n\n server.tool(\n \"health_check\",\n [\n \"[health] Run a single read-only sweep over every secret in the requested scope and report counts of healthy/stale/expired secrets plus any current audit anomalies.\",\n \"Use as the default 'is everything OK?' command for an agent or operator; prefer `check_project` to validate manifest compliance specifically, `detect_anomalies` for audit-only triage, and `agent_scan` for multi-project JSON output or optional auto-rotation.\",\n \"Read-only — never writes. Returns a multi-line text summary: header counts (Total / Healthy / Stale / Expired / No decay / Anomalies), then per-secret `EXPIRED:` / `STALE:` issue lines, then per-anomaly `[type] description` lines.\",\n ].join(\" \"),\n {\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"health_check\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"health_check\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const entries = listSecrets(opts(params));\n const anomalies = detectAnomalies();\n\n let healthy = 0;\n let stale = 0;\n let expired = 0;\n let noDecay = 0;\n const issues: string[] = [];\n\n for (const entry of entries) {\n if (!entry.decay?.timeRemaining) {\n noDecay++;\n continue;\n }\n if (entry.decay.isExpired) {\n expired++;\n issues.push(`EXPIRED: ${entry.key}`);\n } else if (entry.decay.isStale) {\n stale++;\n issues.push(\n `STALE: ${entry.key} (${entry.decay.lifetimePercent}%, ${entry.decay.timeRemaining} left)`,\n );\n } else {\n healthy++;\n }\n }\n\n const summary = [\n `Secrets: ${entries.length} total`,\n `Healthy: ${healthy} | Stale: ${stale} | Expired: ${expired} | No decay: ${noDecay}`,\n `Anomalies: ${anomalies.length}`,\n ];\n\n if (issues.length > 0) {\n summary.push(\"\", \"Issues:\", ...issues);\n }\n if (anomalies.length > 0) {\n summary.push(\"\", \"Anomalies:\", ...anomalies.map((a) => `[${a.type}] ${a.description}`));\n }\n\n return text(summary.join(\"\\n\"));\n },\n );\n\n server.tool(\n \"verify_audit_chain\",\n [\n \"[audit] Recompute the SHA-256 hash chain over the audit log and confirm no event has been mutated, deleted, or reordered.\",\n \"Use periodically as a tamper-evidence check, or whenever you suspect the audit log has been touched outside q-ring; the result is informational — this tool does not repair the chain if it is broken.\",\n \"Read-only. Returns JSON `{ ok, valid, brokenAt? }` where `valid` is `true` for an intact chain and `brokenAt` (when present) names the first event whose hash did not match.\",\n ].join(\" \"),\n {},\n toolAnnotations(\"verify_audit_chain\"),\n async () => {\n const toolBlock = enforceToolPolicy(\"verify_audit_chain\");\n if (toolBlock) return toolBlock;\n\n const result = verifyAuditChain();\n return text(JSON.stringify(result, null, 2));\n },\n );\n\n server.tool(\n \"export_audit\",\n [\n \"[audit] Export the audit log as a portable text artifact suitable for archiving or feeding into another SIEM/analyzer.\",\n \"Use for compliance exports, after-the-fact investigations, or to hand the trail to a non-MCP consumer; prefer `audit_log` for an in-conversation tail and `verify_audit_chain` to confirm integrity before exporting.\",\n \"Read-only. Returns the rendered text directly (no JSON wrapper). 'jsonl' is one event per line; 'json' is a single array; 'csv' is a header row plus events. Time filters are applied to the event timestamps before formatting.\",\n ].join(\" \"),\n {\n since: z\n .string()\n .optional()\n .describe(\n \"Inclusive lower bound on event timestamp, ISO 8601. Example: '2026-04-01T00:00:00Z'. Omit for no lower bound.\",\n ),\n until: z\n .string()\n .optional()\n .describe(\n \"Inclusive upper bound on event timestamp, ISO 8601. Omit for now/no upper bound.\",\n ),\n format: z\n .enum([\"jsonl\", \"json\", \"csv\"])\n .optional()\n .default(\"jsonl\")\n .describe(\n \"Output format. 'jsonl' (default) is most stream-friendly; 'json' is a single array; 'csv' is spreadsheet-friendly.\",\n ),\n },\n toolAnnotations(\"export_audit\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"export_audit\");\n if (toolBlock) return toolBlock;\n\n const output = exportAudit({\n since: params.since,\n until: params.until,\n format: params.format,\n // Same rationale as audit_log: trip records stay operator-facing.\n excludeActions: [\"canary\"],\n });\n return text(output);\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { z } from \"zod\";\nimport { getSecret, setSecret, getEnvelope, listSecrets } from \"../../core/keyring.js\";\nimport type { Scope } from \"../../core/scope.js\";\nimport {\n validateSecret,\n rotateWithProvider,\n ciValidateBatch,\n registry as providerRegistry,\n} from \"../../core/validate.js\";\nimport { text, opts, enforceToolPolicy, commonSchemas } from \"./_shared.js\";\n\nconst { teamId, orgId, scope, projectPath } = commonSchemas;\n\nexport function registerValidationTools(server: McpServer): void {\n server.tool(\n \"validate_secret\",\n [\n \"[validation] Test whether a stored secret is still accepted by its upstream service (OpenAI, Stripe, GitHub, AWS, generic HTTP, etc.) by making a minimal authenticated request.\",\n \"Use to confirm liveness before relying on a credential or as the verification step after `rotate_secret`; prefer `ci_validate_secrets` for a batch run across every key in scope.\",\n \"Side effects: makes one outbound network request per call (may incur tiny provider-side rate-limit cost). Records 'read' for the underlying secret value in the audit log; the value itself is never logged. Returns JSON `{ valid, provider, status?, message?, rateLimit?, ... }` (provider-specific shape).\",\n ].join(\" \"),\n {\n key: z\n .string()\n .describe(\n \"The exact key whose value should be tested upstream. Example: 'OPENAI_API_KEY'.\",\n ),\n provider: z\n .string()\n .optional()\n .describe(\n \"Force a specific provider id. Built-ins include 'openai', 'stripe', 'github', 'aws', 'http'. Omit to auto-detect from the value's prefix or the secret's stored provider hint.\",\n ),\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"validate_secret\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"validate_secret\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const value = getSecret(params.key, opts(params));\n if (value === null) return text(`Secret \"${params.key}\" not found`, true);\n\n const envelope = getEnvelope(params.key, opts(params));\n const provHint = params.provider ?? envelope?.envelope.meta.provider;\n\n const result = await validateSecret(value, { provider: provHint });\n return text(JSON.stringify(result, null, 2));\n },\n );\n\n server.tool(\n \"list_providers\",\n [\n \"[validation] Enumerate the secret-validation providers q-ring knows how to call (OpenAI, Stripe, GitHub, …) along with their auto-detect prefixes.\",\n \"Use to discover what `provider` string to pass to `validate_secret`/`rotate_secret`, or to check whether your custom provider is registered.\",\n \"Read-only. Returns JSON array of `{ name, description, prefixes }` objects. `prefixes` are the literal key-value prefixes (e.g. 'sk-' for OpenAI) used for auto-detection.\",\n ].join(\" \"),\n {},\n toolAnnotations(\"list_providers\"),\n async () => {\n const toolBlock = enforceToolPolicy(\"list_providers\");\n if (toolBlock) return toolBlock;\n\n const providers = providerRegistry.listProviders().map((p) => ({\n name: p.name,\n description: p.description,\n prefixes: p.prefixes ?? [],\n }));\n return text(JSON.stringify(providers, null, 2));\n },\n );\n\n server.tool(\n \"rotate_secret\",\n [\n \"[validation] Ask the upstream provider to issue a fresh credential for this secret and store the new value back into the keyring.\",\n \"Use when a secret is expiring, leaked, or part of a scheduled rotation; prefer `generate_secret` for self-managed values you fully control, and `agent_scan --autoRotate` for sweep-style rotation across multiple expired keys.\",\n \"Mutates the keyring with the newly-issued value if rotation succeeds (one 'write' audit event), and makes outbound network requests against the provider's rotation API. Returns JSON `{ rotated, newValue?, message?, ... }`. If `rotated` is false, the existing value is left untouched.\",\n ].join(\" \"),\n {\n key: z.string().describe(\"Exact key to rotate. Must already exist in the keyring.\"),\n provider: z\n .string()\n .optional()\n .describe(\n \"Force a specific provider id (see `list_providers`). Omit to auto-detect from the current value or the secret's stored provider hint.\",\n ),\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"rotate_secret\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"rotate_secret\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const value = getSecret(params.key, opts(params));\n if (!value) return text(`Secret \"${params.key}\" not found`, true);\n\n const result = await rotateWithProvider(value, params.provider);\n if (result.rotated && result.newValue) {\n setSecret(params.key, result.newValue, {\n scope: (params.scope as Scope) ?? \"global\",\n projectPath: params.projectPath,\n source: \"mcp\",\n });\n }\n return text(JSON.stringify(result, null, 2));\n },\n );\n\n server.tool(\n \"ci_validate_secrets\",\n [\n \"[validation] Validate every accessible secret in the requested scope against its detected provider in a single batch and return a structured pass/fail report.\",\n \"Use as a CI gate ('do all our credentials still work before deploy?') or as a pre-rotation health pass; prefer `validate_secret` for a single key.\",\n \"Side effects: one outbound request per validatable secret (cost scales with N). Reads each secret value (records 'read' audit events). Returns JSON `{ total, valid, invalid, results: [...] }` listing per-key status, provider, and error messages where applicable. Returns 'No secrets to validate' if nothing in scope has a provider mapping.\",\n ].join(\" \"),\n {\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"ci_validate_secrets\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"ci_validate_secrets\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const entries = listSecrets(opts(params));\n const secrets = entries\n .map((e) => {\n const val = getSecret(e.key, {\n ...opts(params),\n scope: e.scope,\n silent: true,\n });\n if (!val) return null;\n return {\n key: e.key,\n value: val,\n provider: e.envelope?.meta.provider,\n validationUrl: e.envelope?.meta.validationUrl,\n };\n })\n .filter((s): s is NonNullable<typeof s> => s !== null);\n\n if (secrets.length === 0) return text(\"No secrets to validate\");\n\n const report = await ciValidateBatch(secrets);\n return text(JSON.stringify(report, null, 2));\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { z } from \"zod\";\nimport {\n registerHook,\n removeHook,\n listHooks as listAllHooks,\n type HookType,\n type HookAction,\n} from \"../../core/hooks.js\";\nimport { text, enforceToolPolicy } from \"./_shared.js\";\n\nexport function registerHookTools(server: McpServer): void {\n server.tool(\n \"register_hook\",\n [\n \"[hooks] Register a side-effect (shell command, HTTP webhook, or process signal) that fires automatically when a matching secret is written, deleted, or rotated.\",\n \"Use to keep external systems in sync (restart a service after rotation, post to Slack on delete, kick a build); prefer `agent_remember` for storing facts an agent should recall later, and `register_hook` is not the right tool for time-based scheduled rotation (use `agent_scan` for that).\",\n \"Mutates the hook registry on disk. At least one match criterion (`key`, `keyPattern`, or `tag`) is required — calls without any return an error. Returns JSON of the registered hook entry including its assigned `id` (use that `id` with `remove_hook`).\",\n ].join(\" \"),\n {\n type: z\n .enum([\"shell\", \"http\", \"signal\"])\n .describe(\n \"Hook delivery mechanism. 'shell' runs a local command, 'http' POSTs JSON to a URL, 'signal' sends an OS signal to a named process.\",\n ),\n key: z\n .string()\n .optional()\n .describe(\n \"Trigger only on this exact key name. Pick at most one of `key` / `keyPattern` / `tag` (or combine for stricter matching).\",\n ),\n keyPattern: z\n .string()\n .optional()\n .describe(\"Trigger on any key matching this glob pattern. Examples: 'DB_*', 'STRIPE_*'.\"),\n tag: z\n .string()\n .optional()\n .describe(\n \"Trigger on any secret carrying this exact tag. Combinable with key/keyPattern as an AND filter.\",\n ),\n scope: z\n .enum([\"global\", \"project\"])\n .optional()\n .describe(\n \"Restrict the hook to secrets in this scope. Omit to fire across both global and project secrets.\",\n ),\n actions: z\n .array(z.enum([\"write\", \"delete\", \"rotate\"]))\n .optional()\n .default([\"write\", \"delete\", \"rotate\"])\n .describe(\"Which lifecycle actions trigger this hook. Defaults to all three.\"),\n command: z\n .string()\n .optional()\n .describe(\n \"Required when type='shell'. The literal shell command to run; q-ring exposes the matching key as $QRING_HOOK_KEY and action as $QRING_HOOK_ACTION.\",\n ),\n url: z\n .string()\n .optional()\n .describe(\n \"Required when type='http'. Full URL to POST a JSON body `{ id, key, scope, action, timestamp }` to (the value itself is never sent).\",\n ),\n signalTarget: z\n .string()\n .optional()\n .describe(\n \"Required when type='signal'. Either a numeric PID or a process name resolvable via `ps`.\",\n ),\n signalName: z\n .string()\n .optional()\n .default(\"SIGHUP\")\n .describe(\n \"Signal name to send (e.g. 'SIGHUP', 'SIGUSR1'). Defaults to SIGHUP, which most daemons treat as 'reload config'.\",\n ),\n description: z\n .string()\n .optional()\n .describe(\n \"Free-text human-readable description, surfaced by `list_hooks` and the dashboard.\",\n ),\n },\n toolAnnotations(\"register_hook\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"register_hook\");\n if (toolBlock) return toolBlock;\n\n if (!params.key && !params.keyPattern && !params.tag) {\n return text(\"At least one match criterion required: key, keyPattern, or tag\", true);\n }\n\n const entry = registerHook({\n type: params.type as HookType,\n match: {\n key: params.key,\n keyPattern: params.keyPattern,\n tag: params.tag,\n scope: params.scope as \"global\" | \"project\" | undefined,\n action: params.actions as HookAction[],\n },\n command: params.command,\n url: params.url,\n signal: params.signalTarget\n ? { target: params.signalTarget, signal: params.signalName }\n : undefined,\n description: params.description,\n enabled: true,\n });\n\n return text(JSON.stringify(entry, null, 2));\n },\n );\n\n server.tool(\n \"list_hooks\",\n [\n \"[hooks] Enumerate every registered lifecycle hook with its match criteria, delivery type, enabled flag, and description.\",\n \"Use to find a hook's `id` before calling `remove_hook`, audit what side effects are wired up, or diagnose why a hook did not fire.\",\n \"Read-only. Returns pretty-printed JSON array of hook entries, or 'No hooks registered' when the registry is empty.\",\n ].join(\" \"),\n {},\n toolAnnotations(\"list_hooks\"),\n async () => {\n const toolBlock = enforceToolPolicy(\"list_hooks\");\n if (toolBlock) return toolBlock;\n\n const hooks = listAllHooks();\n if (hooks.length === 0) return text(\"No hooks registered\");\n return text(JSON.stringify(hooks, null, 2));\n },\n );\n\n server.tool(\n \"remove_hook\",\n [\n \"[hooks] Detach a single lifecycle hook by its registry id so it stops firing.\",\n \"Use to retire a specific webhook/command without touching any secrets; prefer `delete_secret` to remove a credential and `tunnel_destroy` for ephemeral tunnels.\",\n \"Mutates the hook registry only — does not touch secret values, audit log, or env states. Idempotent in spirit: removing an already-absent id returns a not-found error rather than partial work. Returns 'Removed hook ID' on success.\",\n ].join(\" \"),\n {\n id: z\n .string()\n .describe(\n \"Hook id returned by `register_hook` or visible in `list_hooks` (opaque string).\",\n ),\n },\n toolAnnotations(\"remove_hook\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"remove_hook\");\n if (toolBlock) return toolBlock;\n\n const removed = removeHook(params.id);\n return text(\n removed ? `Removed hook ${params.id}` : `Hook \"${params.id}\" not found`,\n !removed,\n );\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { z } from \"zod\";\nimport { listSecrets } from \"../../core/keyring.js\";\nimport { runHealthScan } from \"../../core/agent.js\";\nimport { queryAudit } from \"../../core/observer.js\";\nimport { execCommand } from \"../../core/exec.js\";\nimport { scanCodebase } from \"../../core/scan.js\";\nimport { lintFiles } from \"../../core/linter.js\";\nimport { checkExecPolicy } from \"../../core/policy.js\";\nimport { text, opts, enforceToolPolicy, commonSchemas } from \"./_shared.js\";\n\nconst { teamId, orgId, scope, projectPath } = commonSchemas;\n\nexport function registerToolingTools(server: McpServer): void {\n server.tool(\n \"exec_with_secrets\",\n [\n \"[exec] Run a child shell command with project secrets injected as environment variables and any leaked secret values redacted from captured stdout/stderr before they return to the agent.\",\n \"Use to let an agent run a script that needs credentials (`npm run db:migrate`, `terraform plan`, `vercel deploy`) without ever putting plaintext values in the chat; prefer `env_generate` if you need to write a `.env` file to disk and `validate_secret` for upstream liveness checks.\",\n \"Spawns a real child process — has whatever side effects the command itself causes (writes, network, exec). Subject to BOTH tool policy and exec policy (allowlist/denylist). Returns a text body with `Exit code: N` then `STDOUT:` and `STDERR:` blocks; both streams are scrubbed against the secret values that were injected.\",\n ].join(\" \"),\n {\n command: z\n .string()\n .describe(\n \"Executable name or full command to run. Example: 'pnpm', 'node', '/usr/bin/env'. Must be allowed by exec policy.\",\n ),\n args: z\n .array(z.string())\n .optional()\n .describe(\n \"Positional arguments passed to `command`. Example: ['run', 'db:migrate']. Each element is passed verbatim with no extra shell parsing.\",\n ),\n keys: z\n .array(z.string())\n .optional()\n .describe(\n \"Whitelist of exact key names to inject. Omit to inject every secret in scope (subject to `tags`).\",\n ),\n tags: z\n .array(z.string())\n .optional()\n .describe(\n \"Inject only secrets carrying at least one of these tags. Combinable with `keys` as an AND filter.\",\n ),\n profile: z\n .enum([\"unrestricted\", \"restricted\", \"ci\"])\n .optional()\n .default(\"restricted\")\n .describe(\n \"Exec sandbox profile. 'restricted' (default) denies network-tool binaries (curl, wget, ssh, scp, nc, netcat, ncat) AND common interpreters/shells (python, node, deno, bun, perl, ruby, php, sh, bash, zsh) — since those could otherwise egress the injected secrets — strips proxy env vars, and caps runtime at 30s. It still is NOT a real OS sandbox (it does not restrict PATH, and some allowed binary could in principle make network calls); for genuinely untrusted commands use OS-level isolation (containers, network namespaces). 'ci' allows network and interpreters with a 300s cap and blocks a few destructive commands; 'unrestricted' inherits the full server environment. Define a custom profile in .q-ring.json to allow specific interpreters with secrets.\",\n ),\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"exec_with_secrets\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"exec_with_secrets\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const execBlock = checkExecPolicy(params.command, params.projectPath);\n if (!execBlock.allowed) {\n return text(`Policy Denied: ${execBlock.reason}`, true);\n }\n\n try {\n const result = await execCommand({\n command: params.command,\n args: params.args ?? [],\n keys: params.keys,\n tags: params.tags,\n profile: params.profile,\n scope: params.scope,\n projectPath: params.projectPath,\n source: \"mcp\",\n captureOutput: true,\n });\n\n const output: string[] = [];\n output.push(`Exit code: ${result.code}`);\n if (result.stdout) output.push(`STDOUT:\\n${result.stdout}`);\n if (result.stderr) output.push(`STDERR:\\n${result.stderr}`);\n\n return text(output.join(\"\\n\\n\"));\n } catch (err) {\n return text(`Execution failed: ${err instanceof Error ? err.message : String(err)}`, true);\n }\n },\n );\n\n server.tool(\n \"scan_codebase_for_secrets\",\n [\n \"[scan] Walk a directory tree and flag plausible hardcoded secrets using regex heuristics plus Shannon-entropy scoring on string literals.\",\n \"Use as a one-shot 'is anything leaking in this repo?' audit before commit/release; prefer `lint_files` when you already know the specific files to check (and want optional auto-fix).\",\n \"Read-only — never modifies source files. Honors `.gitignore`. Returns JSON array of `{ file, line, key, value, kind }` findings, or 'No hardcoded secrets found in the specified directory.' when clean. False positives are possible — review before treating as ground truth.\",\n ].join(\" \"),\n {\n dirPath: z\n .string()\n .describe(\n \"Directory to scan, absolute or relative to the server cwd. The scan recurses into subdirectories.\",\n ),\n },\n toolAnnotations(\"scan_codebase_for_secrets\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"scan_codebase_for_secrets\");\n if (toolBlock) return toolBlock;\n\n try {\n const results = scanCodebase(params.dirPath);\n if (results.length === 0) {\n return text(\"No hardcoded secrets found in the specified directory.\");\n }\n return text(JSON.stringify(results, null, 2));\n } catch (err) {\n return text(`Scan failed: ${err instanceof Error ? err.message : String(err)}`, true);\n }\n },\n );\n\n server.tool(\n \"lint_files\",\n [\n \"[scan] Inspect a specific list of files for hardcoded secrets and, when `fix` is true, replace each finding with `process.env.KEY` while storing the extracted value into the keyring.\",\n \"Use to migrate a known set of files (e.g. just-changed files in a pre-commit hook) into q-ring; prefer `scan_codebase_for_secrets` for a whole-tree audit and `import_dotenv` to ingest an existing .env.\",\n \"With `fix: false` this is read-only. With `fix: true` this MUTATES the listed source files in place (review with git diff!) and writes one new secret per finding to the keyring. Returns a JSON array of `{ file, line, key, value, kind }` findings, or 'No hardcoded secrets found in the specified files.'.\",\n ].join(\" \"),\n {\n files: z\n .array(z.string())\n .describe(\"Absolute or relative paths to lint. Non-existent paths surface as scan errors.\"),\n fix: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n \"If true, rewrite the source files to read `process.env.KEY` and store the extracted value in the keyring. If false (default), only report findings.\",\n ),\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"lint_files\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"lint_files\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n try {\n const results = lintFiles(params.files, {\n fix: params.fix,\n scope: params.scope as \"global\" | \"project\" | undefined,\n projectPath: params.projectPath,\n });\n if (results.length === 0) {\n return text(\"No hardcoded secrets found in the specified files.\");\n }\n return text(JSON.stringify(results, null, 2));\n } catch (err) {\n return text(`Lint failed: ${err instanceof Error ? err.message : String(err)}`, true);\n }\n },\n );\n\n server.tool(\n \"analyze_secrets\",\n [\n \"[agent] Cross-reference the secrets in scope with recent audit events to produce a usage profile and rotation/retirement suggestions.\",\n \"Use as a quarterly hygiene check or as input to a planner that decides what to rotate or delete; prefer `health_check` for decay-only triage and `audit_log` to inspect access timelines for one key.\",\n \"Read-only; uses the most recent ~500 audit events. Returns JSON `{ total, expired, stale, neverAccessed: [...], noRotationFormat: [...], mostAccessed: [{ key, reads }] }`. `neverAccessed` and `noRotationFormat` are good candidates for cleanup or for adding rotation hints.\",\n ].join(\" \"),\n {\n scope,\n projectPath,\n teamId,\n orgId,\n },\n toolAnnotations(\"analyze_secrets\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"analyze_secrets\", params.projectPath);\n if (toolBlock) return toolBlock;\n\n const o = opts(params);\n const entries = listSecrets({ ...o, silent: true });\n const audit = queryAudit({ limit: 500 });\n\n const accessMap = new Map<string, number>();\n for (const e of audit) {\n if (e.action === \"read\" && e.key) {\n accessMap.set(e.key, (accessMap.get(e.key) || 0) + 1);\n }\n }\n\n const analysis = {\n total: entries.length,\n expired: entries.filter((e) => e.decay?.isExpired).length,\n stale: entries.filter((e) => e.decay?.isStale && !e.decay?.isExpired).length,\n neverAccessed: entries\n .filter((e) => (e.envelope?.meta.accessCount ?? 0) === 0)\n .map((e) => e.key),\n noRotationFormat: entries.filter((e) => !e.envelope?.meta.rotationFormat).map((e) => e.key),\n mostAccessed: [...accessMap.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 10)\n .map(([key, count]) => ({ key, reads: count })),\n };\n\n return text(JSON.stringify(analysis, null, 2));\n },\n );\n\n // One process-scoped instance; reusing across tool invocations avoids\n // leaking listeners when the MCP client pings `status_dashboard` twice.\n let dashboardInstance: { port: number; url: string; close: () => void } | null = null;\n\n server.tool(\n \"status_dashboard\",\n [\n \"[dashboard] Start a local web dashboard (`http://127.0.0.1:PORT`) that streams live KPIs, secret tables, manifest gaps, hooks, audit events, and anomalies via Server-Sent Events.\",\n \"Use when an operator (or an agent on behalf of one) wants a richer visual surface than chat output; prefer `health_check` / `analyze_secrets` for one-shot text summaries inside the conversation.\",\n \"Side effect: binds an HTTP server on the requested port (one process-wide instance — re-running returns the existing URL instead of starting a second server). Never exposes secret values. Returns the URL string to open in a browser.\",\n ].join(\" \"),\n {\n port: z\n .number()\n .optional()\n .default(9876)\n .describe(\n \"TCP port to listen on (default 9876). Pick another port if 9876 is already in use; the call fails if binding errors.\",\n ),\n },\n toolAnnotations(\"status_dashboard\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"status_dashboard\");\n if (toolBlock) return toolBlock;\n\n if (dashboardInstance) {\n return text(`Dashboard already running at ${dashboardInstance.url}`);\n }\n\n const { startDashboardServer } = await import(\"../../core/dashboard.js\");\n dashboardInstance = startDashboardServer({ port: params.port });\n\n return text(\n `Dashboard started at ${dashboardInstance.url}\\nOpen this URL in a browser to see live quantum status. The token is required for access.`,\n );\n },\n );\n\n server.tool(\n \"agent_scan\",\n [\n \"[agent] Run a multi-project health pass that gathers decay status, audit anomalies, and `.q-ring.json` manifest gaps across one or more project paths and (optionally) auto-rotates expired secrets with freshly generated values.\",\n \"Use as the canonical 'agent maintenance loop' across a portfolio of repos; prefer `health_check` for a single read-only scope, `detect_anomalies` for audit-only triage, and `check_project` for a single-project manifest check.\",\n \"With `autoRotate=false` (default) this is read-only. With `autoRotate=true` it OVERWRITES expired secret values in the keyring with generated replacements — credential changes that may break upstream integrations until they are propagated. Subject to tool policy. Returns a JSON report of per-project findings and any rotations performed.\",\n ].join(\" \"),\n {\n autoRotate: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n \"If true, replace expired secrets with newly generated values (using each secret's `rotationFormat`/`rotationPrefix`). Only enable when intentional rotation is desired — this is destructive on the upstream side.\",\n ),\n projectPaths: z\n .array(z.string())\n .optional()\n .describe(\n \"List of absolute project roots to scan. Defaults to `[server.cwd]` when omitted.\",\n ),\n },\n toolAnnotations(\"agent_scan\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"agent_scan\");\n if (toolBlock) return toolBlock;\n\n const report = runHealthScan({\n autoRotate: params.autoRotate,\n projectPaths: params.projectPaths ?? [process.cwd()],\n });\n return text(JSON.stringify(report, null, 2));\n },\n );\n}\n","/**\n * Minimal ANSI color helpers. No dependencies.\n */\n\nconst enabled = process.stdout.isTTY !== false && !process.env.NO_COLOR;\n\nfunction wrap(code: string, text: string): string {\n return enabled ? `\\x1b[${code}m${text}\\x1b[0m` : text;\n}\n\nexport const c = {\n bold: (t: string) => wrap(\"1\", t),\n dim: (t: string) => wrap(\"2\", t),\n italic: (t: string) => wrap(\"3\", t),\n underline: (t: string) => wrap(\"4\", t),\n\n red: (t: string) => wrap(\"31\", t),\n green: (t: string) => wrap(\"32\", t),\n yellow: (t: string) => wrap(\"33\", t),\n blue: (t: string) => wrap(\"34\", t),\n magenta: (t: string) => wrap(\"35\", t),\n cyan: (t: string) => wrap(\"36\", t),\n white: (t: string) => wrap(\"37\", t),\n gray: (t: string) => wrap(\"90\", t),\n\n bgRed: (t: string) => wrap(\"41\", t),\n bgGreen: (t: string) => wrap(\"42\", t),\n bgYellow: (t: string) => wrap(\"43\", t),\n bgBlue: (t: string) => wrap(\"44\", t),\n bgMagenta: (t: string) => wrap(\"45\", t),\n bgCyan: (t: string) => wrap(\"46\", t),\n};\n\nexport function scopeColor(scope: string): string {\n return scope === \"project\" ? c.cyan(scope) : c.blue(scope);\n}\n\nexport function decayIndicator(percent: number, expired: boolean): string {\n if (expired) return c.bgRed(c.white(\" EXPIRED \"));\n if (percent >= 90) return c.red(`[decay ${percent}%]`);\n if (percent >= 75) return c.yellow(`[decay ${percent}%]`);\n if (percent > 0) return c.green(`[decay ${percent}%]`);\n return \"\";\n}\n\nexport function envBadge(env: string): string {\n switch (env) {\n case \"prod\":\n return c.bgRed(c.white(` ${env} `));\n case \"staging\":\n return c.bgYellow(c.white(` ${env} `));\n case \"dev\":\n return c.bgGreen(c.white(` ${env} `));\n case \"test\":\n return c.bgBlue(c.white(` ${env} `));\n default:\n return c.bgMagenta(c.white(` ${env} `));\n }\n}\n\nexport const SYMBOLS = {\n check: enabled ? \"\\u2713\" : \"[ok]\",\n cross: enabled ? \"\\u2717\" : \"[x]\",\n arrow: enabled ? \"\\u2192\" : \"->\",\n dot: enabled ? \"\\u2022\" : \"*\",\n lock: enabled ? \"\\u{1f512}\" : \"[locked]\",\n key: enabled ? \"\\u{1f511}\" : \"[key]\",\n link: enabled ? \"\\u{1f517}\" : \"[link]\",\n warning: enabled ? \"\\u26a0\\ufe0f\" : \"[!]\",\n clock: enabled ? \"\\u23f0\" : \"[time]\",\n shield: enabled ? \"\\u{1f6e1}\\ufe0f\" : \"[shield]\",\n zap: enabled ? \"\\u26a1\" : \"[zap]\",\n eye: enabled ? \"\\u{1f441}\\ufe0f\" : \"[eye]\",\n ghost: enabled ? \"\\u{1f47b}\" : \"[ghost]\",\n package: enabled ? \"\\u{1f4e6}\" : \"[pkg]\",\n sparkle: enabled ? \"\\u2728\" : \"[*]\",\n} as const;\n","/**\n * Quantum Agent: autonomous background monitor for secret health.\n *\n * Runs as a long-lived process that periodically:\n * - Checks for expired/stale secrets (decay monitoring)\n * - Detects access anomalies (observer analysis)\n * - Logs health reports\n * - Can trigger rotation callbacks\n *\n * Designed to run as `qring agent` or be invoked by the MCP server.\n */\n\nimport { listSecrets, setSecret } from \"./keyring.js\";\nimport { checkDecay } from \"./envelope.js\";\nimport { detectAnomalies, logAudit } from \"./observer.js\";\nimport { generateSecret } from \"./noise.js\";\nimport { fireHooks } from \"./hooks.js\";\nimport { c, SYMBOLS } from \"../utils/colors.js\";\n\nexport interface AgentConfig {\n /** Check interval in seconds (default: 60) */\n intervalSeconds: number;\n /** Auto-rotate expired secrets with generated values */\n autoRotate: boolean;\n /** Project paths to monitor */\n projectPaths: string[];\n /** Verbose output */\n verbose: boolean;\n}\n\nexport interface AgentReport {\n timestamp: string;\n totalSecrets: number;\n healthy: number;\n stale: number;\n expired: number;\n anomalies: number;\n rotated: string[];\n warnings: string[];\n}\n\nfunction defaultConfig(): AgentConfig {\n return {\n intervalSeconds: 60,\n autoRotate: false,\n projectPaths: [process.cwd()],\n verbose: false,\n };\n}\n\nexport function runHealthScan(config: Partial<AgentConfig> = {}): AgentReport {\n const cfg = { ...defaultConfig(), ...config };\n\n const report: AgentReport = {\n timestamp: new Date().toISOString(),\n totalSecrets: 0,\n healthy: 0,\n stale: 0,\n expired: 0,\n anomalies: 0,\n rotated: [],\n warnings: [],\n };\n\n // Scan global scope\n const globalEntries = listSecrets({ scope: \"global\", source: \"agent\" });\n\n // Scan project scopes\n const projectEntries = cfg.projectPaths.flatMap((pp) =>\n listSecrets({ scope: \"project\", projectPath: pp, source: \"agent\" }),\n );\n\n const allEntries = [...globalEntries, ...projectEntries];\n report.totalSecrets = allEntries.length;\n\n for (const entry of allEntries) {\n if (!entry.envelope) continue;\n\n const decay = checkDecay(entry.envelope);\n\n if (decay.isExpired) {\n report.expired++;\n report.warnings.push(\n `EXPIRED: ${entry.key} [${entry.scope}] — expired ${decay.timeRemaining}`,\n );\n\n if (cfg.autoRotate) {\n const fmt = (entry.envelope?.meta.rotationFormat ?? \"api-key\") as import(\"./noise.js\").NoiseFormat;\n const prefix = entry.envelope?.meta.rotationPrefix;\n const newValue = generateSecret({ format: fmt, prefix });\n setSecret(entry.key, newValue, {\n scope: entry.scope,\n projectPath: cfg.projectPaths[0],\n source: \"agent\",\n });\n report.rotated.push(entry.key);\n logAudit({\n action: \"write\",\n key: entry.key,\n scope: entry.scope,\n source: \"agent\",\n detail: \"auto-rotated by agent (expired)\",\n });\n fireHooks({\n action: \"rotate\",\n key: entry.key,\n scope: entry.scope,\n timestamp: new Date().toISOString(),\n source: \"agent\",\n }, entry.envelope?.meta.tags).catch(() => {});\n }\n } else if (decay.isStale) {\n report.stale++;\n report.warnings.push(\n `STALE: ${entry.key} [${entry.scope}] — ${decay.lifetimePercent}% lifetime, ${decay.timeRemaining} remaining`,\n );\n } else {\n report.healthy++;\n }\n }\n\n // Check for anomalies\n const anomalies = detectAnomalies();\n report.anomalies = anomalies.length;\n for (const a of anomalies) {\n report.warnings.push(`ANOMALY [${a.type}]: ${a.description}`);\n }\n\n return report;\n}\n\nfunction formatReport(report: AgentReport, verbose: boolean): string {\n const lines: string[] = [];\n\n lines.push(\n `${c.bold(`${SYMBOLS.shield} q-ring agent scan`)} ${c.dim(report.timestamp)}`,\n );\n lines.push(\n ` ${c.dim(\"secrets:\")} ${report.totalSecrets} ${c.green(`${SYMBOLS.check} ${report.healthy}`)} ${c.yellow(`${SYMBOLS.warning} ${report.stale}`)} ${c.red(`${SYMBOLS.cross} ${report.expired}`)} ${c.dim(`anomalies: ${report.anomalies}`)}`,\n );\n\n if (report.rotated.length > 0) {\n lines.push(\n ` ${c.cyan(`${SYMBOLS.zap} auto-rotated:`)} ${report.rotated.join(\", \")}`,\n );\n }\n\n if (verbose && report.warnings.length > 0) {\n lines.push(\"\");\n for (const w of report.warnings) {\n if (w.startsWith(\"EXPIRED\")) lines.push(` ${c.red(w)}`);\n else if (w.startsWith(\"STALE\")) lines.push(` ${c.yellow(w)}`);\n else if (w.startsWith(\"ANOMALY\")) lines.push(` ${c.magenta(w)}`);\n else lines.push(` ${w}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Run the agent as a continuous background monitor.\n */\nexport async function startAgent(config: Partial<AgentConfig> = {}): Promise<void> {\n const cfg = { ...defaultConfig(), ...config };\n\n console.log(\n `${c.bold(`${SYMBOLS.zap} q-ring agent started`)} ${c.dim(`(interval: ${cfg.intervalSeconds}s, auto-rotate: ${cfg.autoRotate})`)}`,\n );\n console.log(\n c.dim(` monitoring: global + ${cfg.projectPaths.length} project(s)`),\n );\n console.log();\n\n const scan = () => {\n const report = runHealthScan(cfg);\n console.log(formatReport(report, cfg.verbose));\n\n if (report.warnings.length > 0 || cfg.verbose) {\n console.log();\n }\n };\n\n // Initial scan\n scan();\n\n // Continuous monitoring\n const interval = setInterval(scan, cfg.intervalSeconds * 1000);\n\n // Graceful shutdown\n const shutdown = () => {\n clearInterval(interval);\n console.log(`\\n${c.dim(\"q-ring agent stopped\")}`);\n process.exit(0);\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n\n // Keep alive\n await new Promise(() => {});\n}\n","/**\n * Secure Execution & Auto-Redaction\n *\n * Runs child processes with project secrets injected into the environment.\n * Captures stdout/stderr and redacts any known secret values before they\n * are printed to the terminal or returned to the MCP agent.\n *\n * Exec profiles restrict which commands may be run, with optional\n * network and timeout controls.\n */\n\nimport { spawn } from \"node:child_process\";\nimport { StringDecoder } from \"node:string_decoder\";\nimport { Transform } from \"node:stream\";\nimport { listSecrets, getSecret, type KeyringOptions } from \"./keyring.js\";\nimport { checkDecay } from \"./envelope.js\";\nimport { checkExecPolicy, getExecMaxRuntime } from \"./policy.js\";\n\nexport interface ExecProfile {\n name: string;\n allowCommands?: string[];\n denyCommands?: string[];\n maxRuntimeSeconds?: number;\n allowNetwork?: boolean;\n stripEnvVars?: string[];\n}\n\nconst BUILTIN_PROFILES: Record<string, ExecProfile> = {\n unrestricted: { name: \"unrestricted\" },\n restricted: {\n name: \"restricted\",\n denyCommands: [\n // Network tools.\n \"curl\", \"wget\", \"ssh\", \"scp\", \"nc\", \"netcat\", \"ncat\",\n // Interpreters and shells: given the secret env vars, `python -c`,\n // `node -e`, `bash -c`, etc. can perform arbitrary network I/O and\n // exfiltrate them, defeating allowNetwork. Denied by default in\n // `restricted`; to run them with secrets use a custom profile in\n // .q-ring.json, or the `ci` / `unrestricted` profile.\n \"python\", \"python2\", \"python3\", \"node\", \"deno\", \"bun\",\n \"perl\", \"ruby\", \"php\", \"sh\", \"bash\", \"zsh\",\n ],\n maxRuntimeSeconds: 30,\n allowNetwork: false,\n stripEnvVars: [\"HTTP_PROXY\", \"HTTPS_PROXY\", \"ALL_PROXY\"],\n },\n ci: {\n name: \"ci\",\n maxRuntimeSeconds: 300,\n allowNetwork: true,\n denyCommands: [\"rm -rf /\", \"mkfs\", \"dd if=\"],\n },\n};\n\nexport function getProfile(name?: string): ExecProfile {\n if (!name) return BUILTIN_PROFILES.unrestricted;\n return BUILTIN_PROFILES[name] ?? { name };\n}\n\nexport function listProfiles(): ExecProfile[] {\n return Object.values(BUILTIN_PROFILES);\n}\n\nexport interface ExecOptions extends KeyringOptions {\n tags?: string[];\n keys?: string[];\n command: string;\n args: string[];\n /** If true, return output as string instead of piping to process.stdout */\n captureOutput?: boolean;\n /** Exec profile name (unrestricted, restricted, ci) */\n profile?: string;\n}\n\nexport interface ExecResult {\n code: number;\n stdout: string;\n stderr: string;\n}\n\n/**\n * Best-effort output redaction: replaces verbatim occurrences of known secret\n * values (>5 chars) in a child process's stdout/stderr. This is a safety net,\n * NOT a guarantee — it cannot catch secrets that the child has transformed\n * (base64/hex/URL-encoded, split across writes beyond the tail window, etc.).\n */\nexport class RedactionTransform extends Transform {\n private patterns: { value: string; replacement: string }[] = [];\n private tail: string = \"\";\n private maxLen: number = 0;\n // Decodes UTF-8 across chunk boundaries: a multi-byte character split between\n // two Buffer chunks would otherwise be corrupted to U+FFFD by chunk.toString()\n // BEFORE matching runs, letting a multi-byte secret slip through unredacted.\n // StringDecoder buffers the incomplete trailing bytes until the rest arrives.\n private decoder = new StringDecoder(\"utf8\");\n\n constructor(secretsToRedact: string[]) {\n super();\n // Only redact secrets > 5 chars to avoid destroying output\n const validSecrets = secretsToRedact.filter((s) => s.length > 5);\n // Sort by length descending to match longest first\n validSecrets.sort((a, b) => b.length - a.length);\n\n this.patterns = validSecrets.map((s) => ({\n value: s,\n replacement: \"[QRING:REDACTED]\",\n }));\n\n if (validSecrets.length > 0) {\n this.maxLen = validSecrets[0].length;\n }\n }\n\n _transform(chunk: Buffer | string, _encoding: string, callback: () => void) {\n if (this.patterns.length === 0) {\n this.push(chunk);\n return callback();\n }\n\n const decoded =\n typeof chunk === \"string\" ? chunk : this.decoder.write(chunk);\n const text = this.tail + decoded;\n let redacted = text;\n\n for (const { value, replacement } of this.patterns) {\n redacted = redacted.split(value).join(replacement);\n }\n\n if (redacted.length < this.maxLen) {\n this.tail = redacted;\n return callback();\n }\n\n const outputLen = redacted.length - this.maxLen + 1;\n const output = redacted.slice(0, outputLen);\n this.tail = redacted.slice(outputLen);\n\n this.push(output);\n callback();\n }\n\n _flush(callback: () => void) {\n // Flush any bytes the decoder is still holding (an incomplete sequence at\n // end-of-stream) along with the retained tail, then redact once more.\n let final = this.tail + this.decoder.end();\n if (final) {\n for (const { value, replacement } of this.patterns) {\n final = final.split(value).join(replacement);\n }\n this.push(final);\n }\n callback();\n }\n}\n\n/**\n * Enforce the exec policy and profile allow/deny lists for a command.\n * Shared by `qring exec` (scope-wide injection) and `qring run` (declared-only\n * injection). Throws on denial.\n */\nexport function enforceExecPolicy(\n profile: ExecProfile,\n command: string,\n args: string[],\n projectPath?: string,\n): void {\n const fullCommand = [command, ...args].join(\" \");\n\n const policyDecision = checkExecPolicy(fullCommand, projectPath);\n if (!policyDecision.allowed) {\n throw new Error(`Policy Denied: ${policyDecision.reason}`);\n }\n\n if (profile.denyCommands) {\n const denied = profile.denyCommands.find((d) => {\n const pattern = new RegExp(`(^|[\\\\s/])${d.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}(\\\\s|$)`, \"i\");\n return pattern.test(fullCommand);\n });\n if (denied) {\n throw new Error(`Exec profile \"${profile.name}\" denies command containing \"${denied}\"`);\n }\n }\n if (profile.allowCommands) {\n const allowed = profile.allowCommands.some((a) => fullCommand.startsWith(a));\n if (!allowed) {\n throw new Error(`Exec profile \"${profile.name}\" does not allow command \"${command}\"`);\n }\n }\n}\n\nexport async function execCommand(opts: ExecOptions): Promise<ExecResult> {\n const profile = getProfile(opts.profile);\n enforceExecPolicy(profile, opts.command, opts.args, opts.projectPath);\n\n const envMap: Record<string, string> = {};\n for (const [k, v] of Object.entries(process.env)) {\n if (v !== undefined) envMap[k] = v;\n }\n\n if (profile.stripEnvVars) {\n for (const key of profile.stripEnvVars) {\n delete envMap[key];\n }\n }\n\n const secretsToRedact = new Set<string>();\n\n let entries = listSecrets({\n scope: opts.scope,\n projectPath: opts.projectPath,\n source: opts.source ?? \"cli\",\n silent: true, // list silently\n });\n\n if (opts.keys?.length) {\n const keySet = new Set(opts.keys);\n entries = entries.filter((e) => keySet.has(e.key));\n }\n\n if (opts.tags?.length) {\n entries = entries.filter((e) =>\n opts.tags!.some((t) => e.envelope?.meta.tags?.includes(t)),\n );\n }\n\n for (const entry of entries) {\n if (entry.envelope) {\n const decay = checkDecay(entry.envelope);\n if (decay.isExpired) continue;\n }\n\n const val = getSecret(entry.key, {\n scope: entry.scope,\n projectPath: opts.projectPath,\n env: opts.env,\n source: opts.source ?? \"cli\",\n silent: false, // Log access for execution\n });\n\n if (val !== null) {\n envMap[entry.key] = val;\n if (val.length > 5) {\n secretsToRedact.add(val);\n }\n }\n }\n\n return spawnRedacted({\n profile,\n command: opts.command,\n args: opts.args,\n envMap,\n secretsToRedact: [...secretsToRedact],\n captureOutput: opts.captureOutput,\n projectPath: opts.projectPath,\n });\n}\n\nexport interface SpawnRedactedOptions {\n profile: ExecProfile;\n command: string;\n args: string[];\n /** Complete child environment (caller composes inheritance + injection). */\n envMap: Record<string, string>;\n /** Values to redact from the child's stdout/stderr. */\n secretsToRedact: string[];\n captureOutput?: boolean;\n /** Used only to resolve the policy-configured max runtime. */\n projectPath?: string;\n}\n\n/**\n * Spawn a child process with a fully-composed environment, enforcing the\n * profile's network restriction and runtime limit, and redacting known\n * secret values from its output.\n */\nexport function spawnRedacted(opts: SpawnRedactedOptions): Promise<ExecResult> {\n const { profile, secretsToRedact, envMap } = opts;\n const maxRuntime = profile.maxRuntimeSeconds ?? getExecMaxRuntime(opts.projectPath);\n\n return new Promise((resolve, reject) => {\n // Enforce network restrictions for profiles that disallow network access.\n const networkTools = new Set([\n \"curl\", \"wget\", \"ping\", \"nc\", \"netcat\", \"ssh\", \"telnet\", \"ftp\", \"dig\", \"nslookup\",\n ]);\n\n // Compare on the command basename so absolute paths like /usr/bin/curl are\n // still caught. (Interpreter-based egress — python -c, node -e — is out of\n // scope here; this is best-effort, not a hard sandbox.)\n const commandBase = opts.command.split(/[\\\\/]/).pop() ?? opts.command;\n\n if (profile.allowNetwork === false && networkTools.has(commandBase)) {\n const msg = `[QRING] Execution blocked: network access is disabled for profile \"${profile.name}\", command \"${opts.command}\" is considered network-related`;\n if (opts.captureOutput) {\n return resolve({ code: 126, stdout: \"\", stderr: msg });\n }\n process.stderr.write(msg + \"\\n\");\n return resolve({ code: 126, stdout: \"\", stderr: \"\" });\n }\n\n const child = spawn(opts.command, opts.args, {\n env: envMap,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: false,\n });\n\n let timedOut = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n if (maxRuntime) {\n timer = setTimeout(() => {\n timedOut = true;\n child.kill(\"SIGKILL\");\n }, maxRuntime * 1000);\n }\n\n const stdoutRedact = new RedactionTransform([...secretsToRedact]);\n const stderrRedact = new RedactionTransform([...secretsToRedact]);\n\n if (child.stdout) child.stdout.pipe(stdoutRedact);\n if (child.stderr) child.stderr.pipe(stderrRedact);\n\n let stdoutStr = \"\";\n let stderrStr = \"\";\n\n if (opts.captureOutput) {\n stdoutRedact.on(\"data\", (d) => (stdoutStr += d.toString()));\n stderrRedact.on(\"data\", (d) => (stderrStr += d.toString()));\n } else {\n stdoutRedact.pipe(process.stdout);\n stderrRedact.pipe(process.stderr);\n }\n\n child.on(\"close\", (code) => {\n if (timer) clearTimeout(timer);\n if (timedOut) {\n resolve({ code: 124, stdout: stdoutStr, stderr: stderrStr + `\\n[QRING] Process killed: exceeded ${maxRuntime}s runtime limit` });\n } else {\n resolve({ code: code ?? 0, stdout: stdoutStr, stderr: stderrStr });\n }\n });\n\n child.on(\"error\", (err) => {\n if (timer) clearTimeout(timer);\n reject(err);\n });\n });\n}\n","/**\n * Codebase Secret Scanner\n *\n * Scans a directory for hardcoded secrets using regex heuristics\n * and Shannon entropy analysis. Useful for migrating legacy codebases\n * into q-ring.\n */\n\nimport { readFileSync, readdirSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { findSecretsInLine, calculateEntropy } from \"./secrets-detect.js\";\n\nexport interface ScanResult {\n file: string;\n line: number;\n keyName: string;\n match: string;\n context: string;\n entropy: number;\n}\n\nconst IGNORE_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \".next\",\n \"dist\",\n \"build\",\n \"coverage\",\n \".cursor\",\n \"venv\",\n \"__pycache__\",\n]);\n\nconst IGNORE_EXTS = new Set([\n \".png\", \".jpg\", \".jpeg\", \".gif\", \".ico\", \".svg\", \".webp\",\n \".mp4\", \".mp3\", \".wav\", \".ogg\",\n \".pdf\", \".zip\", \".tar\", \".gz\", \".xz\",\n \".ttf\", \".woff\", \".woff2\", \".eot\",\n \".exe\", \".dll\", \".so\", \".dylib\",\n \".lock\",\n]);\n\nexport function scanCodebase(dir: string): ScanResult[] {\n const results: ScanResult[] = [];\n\n function walk(currentDir: string) {\n let entries;\n try {\n entries = readdirSync(currentDir);\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (IGNORE_DIRS.has(entry)) continue;\n\n const fullPath = join(currentDir, entry);\n let stat;\n try {\n stat = statSync(fullPath);\n } catch {\n continue;\n }\n\n if (stat.isDirectory()) {\n walk(fullPath);\n } else if (stat.isFile()) {\n const ext = fullPath.slice(fullPath.lastIndexOf(\".\")).toLowerCase();\n if (IGNORE_EXTS.has(ext) || entry.endsWith(\".lock\")) continue;\n\n let content;\n try {\n content = readFileSync(fullPath, \"utf8\");\n } catch {\n continue;\n }\n\n if (content.includes(\"\\0\")) continue;\n\n const lines = content.split(/\\r?\\n/);\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const matches = findSecretsInLine(line);\n for (const m of matches) {\n const entropy = calculateEntropy(m.value);\n const relPath = fullPath.startsWith(dir)\n ? fullPath.slice(dir.length).replace(/^[/\\\\]+/, \"\")\n : fullPath;\n\n results.push({\n file: relPath || fullPath,\n line: i + 1,\n keyName: m.varName,\n match: m.value,\n context: line.trim(),\n entropy: parseFloat(entropy.toFixed(2)),\n });\n }\n }\n }\n }\n }\n\n walk(dir);\n return results;\n}\n","/**\n * Shared heuristics for hardcoded-secret detection (scan + lint).\n * Both `scan.ts` and `linter.ts` use this module so rules stay aligned.\n */\n\n/** Same pattern for assignment-style secrets in source lines. */\nexport const SECRET_ASSIGNMENT_PATTERN =\n /((?:api_?key|secret|token|password|auth|credential|access_?key)[a-z0-9_]*)\\s*[:=]\\s*(['\"])([^'\"]+)\\2/gi;\n\nexport interface SecretMatchInLine {\n varName: string;\n value: string;\n quote: string;\n}\n\nexport function calculateEntropy(str: string): number {\n if (!str) return 0;\n const len = str.length;\n const frequencies = new Map<string, number>();\n\n for (let i = 0; i < len; i++) {\n const char = str[i];\n frequencies.set(char, (frequencies.get(char) || 0) + 1);\n }\n\n let entropy = 0;\n for (const count of frequencies.values()) {\n const p = count / len;\n entropy -= p * Math.log2(p);\n }\n\n return entropy;\n}\n\nexport function isPlaceholderValue(value: string): boolean {\n const lv = value.toLowerCase();\n return (\n lv.includes(\"example\") ||\n lv.includes(\"your_\") ||\n lv.includes(\"placeholder\") ||\n lv.includes(\"replace_me\") ||\n lv.includes(\"xxx\")\n );\n}\n\nfunction passesSecretHeuristic(value: string, entropy: number): boolean {\n return entropy > 3.5 || value.startsWith(\"sk-\") || value.startsWith(\"ghp_\");\n}\n\n/**\n * Find all secret-like assignments on one line (same behavior as the linter:\n * every match on the line is considered).\n */\nexport function findSecretsInLine(line: string): SecretMatchInLine[] {\n if (line.length > 500) return [];\n\n const out: SecretMatchInLine[] = [];\n SECRET_ASSIGNMENT_PATTERN.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = SECRET_ASSIGNMENT_PATTERN.exec(line)) !== null) {\n const varName = match[1];\n const quote = match[2];\n const value = match[3];\n\n if (value.length < 8) continue;\n if (isPlaceholderValue(value)) continue;\n\n const entropy = calculateEntropy(value);\n if (!passesSecretHeuristic(value, entropy)) continue;\n\n out.push({ varName, value, quote });\n }\n return out;\n}\n","/**\n * Secret-Aware Linter\n *\n * Scans individual files (or staged git content) for hardcoded secrets and\n * optionally rewrites them with `process.env.KEY` references, storing the\n * discovered values in q-ring.\n */\n\nimport { readFileSync, writeFileSync, existsSync } from \"node:fs\";\nimport { basename, extname } from \"node:path\";\nimport { type ScanResult } from \"./scan.js\";\nimport { setSecret, hasSecret } from \"./keyring.js\";\nimport { findSecretsInLine, calculateEntropy } from \"./secrets-detect.js\";\n\nexport interface LintResult extends ScanResult {\n fixed: boolean;\n}\n\nexport interface LintOptions {\n fix?: boolean;\n scope?: import(\"./scope.js\").Scope;\n projectPath?: string;\n}\n\nconst ENV_REF_BY_EXT: Record<string, (key: string) => string> = {\n \".ts\": (k) => `process.env.${k}`,\n \".tsx\": (k) => `process.env.${k}`,\n \".js\": (k) => `process.env.${k}`,\n \".jsx\": (k) => `process.env.${k}`,\n \".mjs\": (k) => `process.env.${k}`,\n \".cjs\": (k) => `process.env.${k}`,\n \".py\": (k) => `os.environ[\"${k}\"]`,\n \".rb\": (k) => `ENV[\"${k}\"]`,\n \".go\": (k) => `os.Getenv(\"${k}\")`,\n \".rs\": (k) => `std::env::var(\"${k}\")`,\n \".java\": (k) => `System.getenv(\"${k}\")`,\n \".kt\": (k) => `System.getenv(\"${k}\")`,\n \".cs\": (k) => `Environment.GetEnvironmentVariable(\"${k}\")`,\n \".php\": (k) => `getenv('${k}')`,\n \".sh\": (k) => `\\${${k}}`,\n \".bash\": (k) => `\\${${k}}`,\n};\n\nfunction getEnvRef(filePath: string, keyName: string): string {\n const ext = extname(filePath).toLowerCase();\n const formatter = ENV_REF_BY_EXT[ext];\n return formatter ? formatter(keyName) : `process.env.${keyName}`;\n}\n\n/**\n * Lint specific files for hardcoded secrets.\n */\nexport function lintFiles(\n files: string[],\n opts: LintOptions = {},\n): LintResult[] {\n const results: LintResult[] = [];\n\n for (const file of files) {\n if (!existsSync(file)) continue;\n\n let content: string;\n try {\n content = readFileSync(file, \"utf8\");\n } catch {\n continue;\n }\n\n if (content.includes(\"\\0\")) continue;\n\n const lines = content.split(/\\r?\\n/);\n const fixes: Array<{ line: number; original: string; replacement: string; keyName: string; value: string }> = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const matches = findSecretsInLine(line);\n\n for (const m of matches) {\n const varNameUpper = m.varName.toUpperCase();\n const entropy = calculateEntropy(m.value);\n const shouldFix = opts.fix === true;\n\n if (shouldFix) {\n const envRef = getEnvRef(file, varNameUpper);\n fixes.push({\n line: i,\n original: `${m.quote}${m.value}${m.quote}`,\n replacement: envRef,\n keyName: varNameUpper,\n value: m.value,\n });\n }\n\n results.push({\n file,\n line: i + 1,\n keyName: varNameUpper,\n match: m.value,\n context: line.trim(),\n entropy: parseFloat(entropy.toFixed(2)),\n fixed: shouldFix,\n });\n }\n }\n\n if (opts.fix && fixes.length > 0) {\n const fixLines = content.split(/\\r?\\n/);\n for (const fix of fixes.reverse()) {\n const lineIdx = fix.line;\n if (lineIdx >= 0 && lineIdx < fixLines.length) {\n fixLines[lineIdx] = fixLines[lineIdx].replace(fix.original, fix.replacement);\n }\n\n if (!hasSecret(fix.keyName, { scope: opts.scope, projectPath: opts.projectPath })) {\n setSecret(fix.keyName, fix.value, {\n scope: opts.scope ?? \"global\",\n projectPath: opts.projectPath,\n source: \"cli\",\n description: `Auto-imported from ${basename(file)}:${fix.line + 1}`,\n });\n }\n }\n\n writeFileSync(file, fixLines.join(\"\\n\"), \"utf8\");\n }\n }\n\n return results;\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { z } from \"zod\";\nimport { remember, recall, listMemory, forget } from \"../../core/memory.js\";\nimport { text, enforceToolPolicy } from \"./_shared.js\";\n\nexport function registerAgentTools(server: McpServer): void {\n server.tool(\n \"agent_remember\",\n [\n \"[agent] Persist a non-secret key/value note in encrypted, on-disk agent memory that survives across MCP sessions.\",\n \"Use to record stable agent context — last rotation date for a key, the user's deployment preferences, decisions taken in earlier sessions; do NOT use this to store secrets (use `set_secret` instead) and prefer chat scratchpad for purely transient state.\",\n \"Mutates the encrypted memory store. Idempotent: rewriting the same key with a new value simply overwrites. Returns 'Remembered \\\"KEY\\\"' on success.\",\n ].join(\" \"),\n {\n key: z\n .string()\n .describe(\n \"Memory key (free-form string). Convention: lowercase dotted namespaces, e.g. 'project.lastDeploy'.\",\n ),\n value: z\n .string()\n .describe(\n \"Plain-string value to store. JSON-stringify structured data on the caller side if needed.\",\n ),\n },\n toolAnnotations(\"agent_remember\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"agent_remember\");\n if (toolBlock) return toolBlock;\n\n remember(params.key, params.value);\n return text(`Remembered \"${params.key}\"`);\n },\n );\n\n server.tool(\n \"agent_recall\",\n [\n \"[agent] Read a value from encrypted agent memory, or list every stored key when no specific key is supplied.\",\n \"Use at the start of an agent loop to rehydrate prior context, or to look up a single remembered fact; prefer `get_project_context` for a redacted overview of secrets and `get_secret` for actual credential values.\",\n \"Read-only. With a `key` argument: returns JSON `{ ok, data: { key, value } }` or a not-found error. Without `key`: returns a JSON listing of every stored key (no values), or 'Agent memory is empty'.\",\n ].join(\" \"),\n {\n key: z\n .string()\n .optional()\n .describe(\"Memory key to read. Omit to list every stored key (without values).\"),\n },\n toolAnnotations(\"agent_recall\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"agent_recall\");\n if (toolBlock) return toolBlock;\n\n if (!params.key) {\n const entries = listMemory();\n if (entries.length === 0) return text(\"Agent memory is empty\");\n return text(JSON.stringify(entries, null, 2));\n }\n const value = recall(params.key);\n if (value === null) return text(`No memory found for \"${params.key}\"`, true);\n return text(JSON.stringify({ ok: true, data: { key: params.key, value } }, null, 2));\n },\n );\n\n server.tool(\n \"agent_forget\",\n [\n \"[agent] Permanently delete a single key from encrypted agent memory.\",\n \"Use to retract obsolete or misremembered context; prefer overwriting via `agent_remember` when you just want to update the value, and use `delete_secret` for actual credentials (which never live in agent memory).\",\n \"Destructive: there is no recycle bin. Returns 'Forgot \\\"KEY\\\"' on success or a not-found error if the key was already absent.\",\n ].join(\" \"),\n {\n key: z.string().describe(\"Memory key to delete.\"),\n },\n toolAnnotations(\"agent_forget\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"agent_forget\");\n if (toolBlock) return toolBlock;\n\n const removed = forget(params.key);\n return text(\n removed ? `Forgot \"${params.key}\"` : `No memory found for \"${params.key}\"`,\n !removed,\n );\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { toolAnnotations } from \"../tool-annotations.js\";\nimport { z } from \"zod\";\nimport {\n checkToolPolicy,\n checkKeyReadPolicy,\n checkExecPolicy,\n getPolicySummary,\n} from \"../../core/policy.js\";\nimport { text, enforceToolPolicy, commonSchemas } from \"./_shared.js\";\n\nconst { projectPath } = commonSchemas;\n\nexport function registerPolicyTools(server: McpServer): void {\n server.tool(\n \"check_policy\",\n [\n \"[policy] Ask whether a single intended action would be allowed by the project's `.q-ring.json` policy without actually performing it.\",\n \"Use as a dry-run before calling a potentially-blocked tool, attempting to read a sensitive key, or invoking `exec_with_secrets` with a non-trivial command; prefer `get_policy_summary` for a one-shot overview of the entire policy.\",\n \"Read-only. Returns JSON `{ allowed, reason?, policySource }` describing the decision. Returns an error 'Missing required parameter for the selected action type' if the matching argument for the chosen `action` is not supplied.\",\n ].join(\" \"),\n {\n action: z\n .enum([\"tool\", \"key_read\", \"exec\"])\n .describe(\n \"Which policy surface to query. 'tool' = MCP tool gate (needs `toolName`); 'key_read' = secret read gate (needs `key`); 'exec' = exec_with_secrets command gate (needs `command`).\",\n ),\n toolName: z\n .string()\n .optional()\n .describe(\"Tool id to evaluate, e.g. 'rotate_secret'. Required when `action` is 'tool'.\"),\n key: z\n .string()\n .optional()\n .describe(\"Secret key name to evaluate. Required when `action` is 'key_read'.\"),\n command: z\n .string()\n .optional()\n .describe(\n \"Command to evaluate against the exec allowlist/denylist. Required when `action` is 'exec'.\",\n ),\n projectPath,\n },\n toolAnnotations(\"check_policy\"),\n async (params) => {\n if (params.action === \"tool\" && params.toolName) {\n const d = checkToolPolicy(params.toolName, params.projectPath);\n return text(JSON.stringify(d, null, 2));\n }\n if (params.action === \"key_read\" && params.key) {\n const d = checkKeyReadPolicy(params.key, undefined, params.projectPath);\n return text(JSON.stringify(d, null, 2));\n }\n if (params.action === \"exec\" && params.command) {\n const d = checkExecPolicy(params.command, params.projectPath);\n return text(JSON.stringify(d, null, 2));\n }\n return text(\"Missing required parameter for the selected action type\", true);\n },\n );\n\n server.tool(\n \"get_policy_summary\",\n [\n \"[policy] Return a high-level summary of the project's `.q-ring.json` governance policy — counts of allow/deny rules for tools, key reads, exec commands, plus approval and rotation requirements.\",\n \"Use to orient an agent (or the user) on what guardrails are active before attempting policy-restricted actions; prefer `check_policy` for a precise per-action verdict.\",\n \"Read-only. Returns pretty-printed JSON; missing policy file returns an empty/default summary rather than an error so callers can branch on the counts.\",\n ].join(\" \"),\n {\n projectPath,\n },\n toolAnnotations(\"get_policy_summary\"),\n async (params) => {\n const toolBlock = enforceToolPolicy(\"get_policy_summary\", params.projectPath);\n if (toolBlock) return toolBlock;\n const summary = getPolicySummary(params.projectPath);\n return text(JSON.stringify(summary, null, 2));\n },\n );\n}\n","import { McpServer, ResourceTemplate } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { checkToolPolicy } from \"../core/policy.js\";\nimport {\n listAgentSessionsForAgents,\n summariseSession,\n type SessionQuery,\n} from \"../core/sessions.js\";\n\n/**\n * MCP resources exposed by the q-ring server.\n *\n * Standing rule: state an agent should *look at* is a resource, not a tool.\n * The agent session timeline is the first: `qring://sessions` lists every\n * agent session the audit chain knows about, `qring://sessions/{id}` is one\n * session's timeline.\n *\n * Both are agent surfaces, so they read through `listAgentSessionsForAgents`,\n * which strips canary trips before anything is summarised — a honeytoken must\n * never be discoverable from the agent side. They also honour the operator's\n * one switch for audit visibility: denying the `audit_log` tool in\n * `.q-ring.json` policy hides these resources too.\n */\n\nconst MIME = \"application/json\";\nconst LIST_URI = \"qring://sessions\";\n\n/** Window a resource read covers; agents don't need the whole chain. */\nconst RESOURCE_QUERY: SessionQuery = {\n since: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(),\n limit: 50,\n maxEvents: 200,\n};\n\nfunction auditVisible(): boolean {\n return checkToolPolicy(\"audit_log\").allowed;\n}\n\nexport function registerMcpResources(server: McpServer): void {\n server.registerResource(\n \"agent-sessions\",\n LIST_URI,\n {\n title: \"Agent sessions\",\n description:\n \"Audit activity folded into per-agent sessions (last 7 days): which MCP client did what, when, against which key names. Summaries only — read qring://sessions/{id} for a session's event timeline. Never contains secret values.\",\n mimeType: MIME,\n },\n async (uri) => {\n const sessions = auditVisible()\n ? listAgentSessionsForAgents(RESOURCE_QUERY).map(summariseSession)\n : [];\n return {\n contents: [{ uri: uri.href, mimeType: MIME, text: JSON.stringify({ sessions }, null, 2) }],\n };\n },\n );\n\n server.registerResource(\n \"agent-session\",\n new ResourceTemplate(\"qring://sessions/{id}\", {\n list: async () => {\n if (!auditVisible()) return { resources: [] };\n return {\n resources: listAgentSessionsForAgents(RESOURCE_QUERY).map((s) => ({\n uri: `${LIST_URI}/${s.id}`,\n name: s.wrapLabel ? `airlock: ${s.wrapLabel}` : s.agent,\n description: `${s.eventCount} events, ${s.startedAt} → ${s.endedAt}`,\n mimeType: MIME,\n })),\n };\n },\n }),\n {\n title: \"Agent session timeline\",\n description:\n \"One agent session's audit timeline, most recent event first. Key names and actions only — never secret values.\",\n mimeType: MIME,\n },\n async (uri, variables) => {\n const id = String(variables.id ?? \"\");\n const session = auditVisible()\n ? listAgentSessionsForAgents({ ...RESOURCE_QUERY, limit: undefined }).find(\n (s) => s.id === id,\n )\n : undefined;\n if (!session) throw new Error(`Session not found: ${id}`);\n return {\n contents: [{ uri: uri.href, mimeType: MIME, text: JSON.stringify(session, null, 2) }],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { registerSecretTools } from \"./tools/secrets.js\";\nimport { registerEnvironmentTools } from \"./tools/environments.js\";\nimport { registerProjectTools } from \"./tools/project.js\";\nimport { registerTunnelTools } from \"./tools/tunnel.js\";\nimport { registerTeleportTools } from \"./tools/teleport.js\";\nimport { registerAuditTools } from \"./tools/audit.js\";\nimport { registerValidationTools } from \"./tools/validation.js\";\nimport { registerHookTools } from \"./tools/hooks.js\";\nimport { registerToolingTools } from \"./tools/tooling.js\";\nimport { registerAgentTools } from \"./tools/agent.js\";\nimport { registerPolicyTools } from \"./tools/policy.js\";\nimport { registerMcpResources } from \"./resources.js\";\n\n/**\n * Register every MCP tool (and resource) on the given server.\n *\n * Tools are grouped by concern in `src/mcp/tools/*.ts`. Keep the registration\n * order stable — some MCP clients cache the tool list ordering. Resources\n * (read-only state such as the agent session timeline) live in\n * `src/mcp/resources.ts`.\n */\nexport function registerMcpTools(server: McpServer): void {\n registerMcpResources(server);\n registerSecretTools(server);\n registerEnvironmentTools(server);\n registerProjectTools(server);\n registerTunnelTools(server);\n registerTeleportTools(server);\n registerAuditTools(server);\n registerValidationTools(server);\n registerHookTools(server);\n registerToolingTools(server);\n registerAgentTools(server);\n registerPolicyTools(server);\n}\n"],"mappings":"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","names":["McpServer","z","c","opts","projectPath","server","z","z","env","opts","scope","teamId","orgId","scope","projectPath","server","z","hints","registry","opts","opts","projectPath","registry","teamId","orgId","scope","projectPath","env","server","result","z","server","z","z","randomBytes","z","z","randomBytes","teamId","orgId","scope","projectPath","server","z","z","teamId","orgId","scope","projectPath","server","z","z","teamId","orgId","scope","projectPath","server","z","registry","z","server","z","z","text","projectPath","opts","readFileSync","readFileSync","readFileSync","opts","readFileSync","teamId","orgId","scope","projectPath","server","z","z","server","z","z","projectPath","server","z","server","server","server","McpServer"]}