@wardby/cli 0.7.0 → 0.9.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/.env.example +5 -5
- package/README.md +6 -1
- package/deploy/local/docker-compose.quickstart-coding.yml +11 -0
- package/dist/claude-coding-worker/driver.d.ts +12 -0
- package/dist/claude-coding-worker/driver.js +29 -7
- package/dist/claude-coding-worker/main.js +5 -1
- package/dist/claude-coding-worker/sdk.js +17 -1
- package/dist/claude-plugin/command.d.ts +64 -0
- package/dist/claude-plugin/command.js +379 -0
- package/dist/cli-help.d.ts +1 -1
- package/dist/cli-help.js +2 -1
- package/dist/cli.js +71 -3
- package/dist/coding/code-host.d.ts +16 -0
- package/dist/coding/code-host.js +60 -0
- package/dist/coding/mcp-token.d.ts +12 -0
- package/dist/coding/mcp-token.js +26 -0
- package/dist/coding/protocol.js +2 -0
- package/dist/coding/redact.js +6 -1
- package/dist/coding/transcript/recorder.d.ts +5 -4
- package/dist/coding/transcript/recorder.js +3 -9
- package/dist/coding-worker/debug-trace.d.ts +3 -1
- package/dist/coding-worker/debug-trace.js +4 -2
- package/dist/coding-worker/driver.js +8 -1
- package/dist/coding-worker/main.js +5 -1
- package/dist/coding-worker/mcp-config.d.ts +27 -0
- package/dist/coding-worker/mcp-config.js +32 -0
- package/dist/coding-worker/sdk.d.ts +36 -0
- package/dist/coding-worker/sdk.js +28 -1
- package/dist/coding-worker/types.d.ts +4 -0
- package/dist/config/mcp-call-limit.d.ts +8 -0
- package/dist/config/mcp-call-limit.js +18 -0
- package/dist/config/mcp-servers.d.ts +8 -0
- package/dist/config/mcp-servers.js +12 -0
- package/dist/config/test-simulators.d.ts +10 -0
- package/dist/config/test-simulators.js +28 -0
- package/dist/config/tool-timeout.d.ts +1 -0
- package/dist/config/tool-timeout.js +18 -0
- package/dist/core/coding-mcp.d.ts +36 -0
- package/dist/core/coding-mcp.js +253 -0
- package/dist/core/coding-repository.d.ts +46 -0
- package/dist/core/coding-repository.js +92 -0
- package/dist/core/delegation-slots.d.ts +27 -0
- package/dist/core/delegation-slots.js +44 -0
- package/dist/core/dispatch.d.ts +6 -2
- package/dist/core/dispatch.js +39 -11
- package/dist/core/engine-native.d.ts +2 -0
- package/dist/core/engine-native.js +13 -0
- package/dist/core/error-code.js +2 -0
- package/dist/core/grants.d.ts +28 -3
- package/dist/core/grants.js +46 -4
- package/dist/core/host-events.js +7 -3
- package/dist/core/host-status.js +2 -2
- package/dist/core/issue-status.js +4 -3
- package/dist/core/listen-address.d.ts +10 -0
- package/dist/core/listen-address.js +14 -0
- package/dist/core/mark-ready.d.ts +1 -1
- package/dist/core/mark-ready.js +1 -1
- package/dist/core/mcp-client/client.d.ts +47 -0
- package/dist/core/mcp-client/client.js +141 -0
- package/dist/core/mcp-client/jsonrpc.d.ts +15 -0
- package/dist/core/mcp-client/jsonrpc.js +54 -0
- package/dist/core/mcp-client/results.d.ts +13 -0
- package/dist/core/mcp-client/results.js +42 -0
- package/dist/core/mcp-servers.d.ts +90 -0
- package/dist/core/mcp-servers.js +230 -0
- package/dist/core/mcp-tools.d.ts +108 -0
- package/dist/core/mcp-tools.js +287 -0
- package/dist/core/merge-order-check.js +38 -19
- package/dist/core/notification-dispatcher.js +2 -1
- package/dist/core/power-idle.d.ts +8 -2
- package/dist/core/power-idle.js +17 -3
- package/dist/core/power.d.ts +5 -0
- package/dist/core/power.js +5 -0
- package/dist/core/related-pull-requests.js +26 -10
- package/dist/core/retention-days.d.ts +5 -0
- package/dist/core/retention-days.js +14 -0
- package/dist/core/review-fix.js +2 -2
- package/dist/core/review-host-tools.js +3 -1
- package/dist/core/run-steps/config.d.ts +25 -0
- package/dist/core/run-steps/config.js +40 -0
- package/dist/core/run-steps/control-chars.d.ts +16 -0
- package/dist/core/run-steps/control-chars.js +26 -0
- package/dist/core/run-steps/detail.d.ts +32 -0
- package/dist/core/run-steps/detail.js +240 -0
- package/dist/core/run-steps/extract.d.ts +52 -0
- package/dist/core/run-steps/extract.js +467 -0
- package/dist/core/run-steps/ingress.d.ts +51 -0
- package/dist/core/run-steps/ingress.js +160 -0
- package/dist/core/run-steps/last-step.d.ts +15 -0
- package/dist/core/run-steps/last-step.js +35 -0
- package/dist/core/run-steps/native.d.ts +48 -0
- package/dist/core/run-steps/native.js +164 -0
- package/dist/core/run-steps/seen.d.ts +16 -0
- package/dist/core/run-steps/seen.js +35 -0
- package/dist/core/run-steps/summarize.d.ts +57 -0
- package/dist/core/run-steps/summarize.js +304 -0
- package/dist/core/run-steps/sweep.d.ts +21 -0
- package/dist/core/run-steps/sweep.js +41 -0
- package/dist/core/run-steps/types.d.ts +89 -0
- package/dist/core/run-steps/types.js +39 -0
- package/dist/core/run-steps/wire.d.ts +35 -0
- package/dist/core/run-steps/wire.js +47 -0
- package/dist/core/run-steps/writer.d.ts +49 -0
- package/dist/core/run-steps/writer.js +279 -0
- package/dist/core/runner.d.ts +70 -16
- package/dist/core/runner.js +296 -74
- package/dist/core/secret-broker-config.d.ts +2 -0
- package/dist/core/secret-broker-config.js +1 -1
- package/dist/core/secret-guard.d.ts +5 -2
- package/dist/core/secret-guard.js +22 -7
- package/dist/core/secrets.d.ts +11 -1
- package/dist/core/secrets.js +27 -1
- package/dist/core/serializable-retry.d.ts +18 -0
- package/dist/core/serializable-retry.js +43 -0
- package/dist/core/tool-admin.d.ts +5 -1
- package/dist/core/tool-admin.js +7 -2
- package/dist/core/tool-names.d.ts +13 -0
- package/dist/core/tool-names.js +20 -0
- package/dist/core/webhooks.d.ts +4 -0
- package/dist/core/webhooks.js +68 -49
- package/dist/core/workflow-run-events.js +2 -1
- package/dist/generated/prisma/browser.d.ts +39 -0
- package/dist/generated/prisma/client.d.ts +39 -0
- package/dist/generated/prisma/commonInputTypes.d.ts +80 -50
- package/dist/generated/prisma/enums.d.ts +6 -0
- package/dist/generated/prisma/enums.js +5 -0
- package/dist/generated/prisma/internal/class.d.ts +77 -0
- package/dist/generated/prisma/internal/class.js +4 -4
- package/dist/generated/prisma/internal/prismaNamespace.d.ts +632 -1
- package/dist/generated/prisma/internal/prismaNamespace.js +94 -3
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +98 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +94 -3
- package/dist/generated/prisma/models/Agent.d.ts +372 -1
- package/dist/generated/prisma/models/AgentMcpServer.d.ts +1412 -0
- package/dist/generated/prisma/models/AgentMcpServer.js +1 -0
- package/dist/generated/prisma/models/AgentRepository.d.ts +40 -1
- package/dist/generated/prisma/models/AuthUser.d.ts +1 -1
- package/dist/generated/prisma/models/CodingAgentProfile.d.ts +0 -7
- package/dist/generated/prisma/models/CodingProxySession.d.ts +159 -2
- package/dist/generated/prisma/models/CodingRun.d.ts +76 -1
- package/dist/generated/prisma/models/HostProvider.d.ts +2176 -0
- package/dist/generated/prisma/models/HostProvider.js +1 -0
- package/dist/generated/prisma/models/HostProviderCredential.d.ts +1285 -0
- package/dist/generated/prisma/models/HostProviderCredential.js +1 -0
- package/dist/generated/prisma/models/HostProviderOperation.d.ts +1470 -0
- package/dist/generated/prisma/models/HostProviderOperation.js +1 -0
- package/dist/generated/prisma/models/HostProviderTrustedAccount.d.ts +1145 -0
- package/dist/generated/prisma/models/HostProviderTrustedAccount.js +1 -0
- package/dist/generated/prisma/models/McpServer.d.ts +1500 -0
- package/dist/generated/prisma/models/McpServer.js +1 -0
- package/dist/generated/prisma/models/NativeGatewayCall.d.ts +39 -1
- package/dist/generated/prisma/models/Principal.d.ts +167 -0
- package/dist/generated/prisma/models/ResourceGrant.d.ts +1 -1
- package/dist/generated/prisma/models/Run.d.ts +503 -1
- package/dist/generated/prisma/models/RunStep.d.ts +1453 -0
- package/dist/generated/prisma/models/RunStep.js +1 -0
- package/dist/generated/prisma/models/Secret.d.ts +387 -0
- package/dist/generated/prisma/models/Tool.d.ts +223 -1
- package/dist/generated/prisma/models.d.ts +7 -0
- package/dist/help/search.js +12 -3
- package/dist/help-index.json +812 -52
- package/dist/import/create.js +16 -1
- package/dist/import/neutral-schema.d.ts +1 -0
- package/dist/import/neutral-schema.js +2 -0
- package/dist/mcp/auth/access.d.ts +1 -0
- package/dist/mcp/auth/grants-cli.d.ts +6 -4
- package/dist/mcp/auth/grants-cli.js +42 -3
- package/dist/mcp/auth/resource-server.d.ts +3 -1
- package/dist/mcp/auth/resource-server.js +17 -2
- package/dist/mcp/context.d.ts +6 -0
- package/dist/mcp/index.js +21 -0
- package/dist/mcp/tools/agents.js +135 -20
- package/dist/mcp/tools/grants.js +66 -28
- package/dist/mcp/tools/host-providers.d.ts +2 -0
- package/dist/mcp/tools/host-providers.js +215 -0
- package/dist/mcp/tools/mcp-servers.d.ts +26 -0
- package/dist/mcp/tools/mcp-servers.js +481 -0
- package/dist/mcp/tools/power.js +2 -2
- package/dist/mcp/tools/repositories.js +50 -10
- package/dist/mcp/tools/run-access.d.ts +7 -0
- package/dist/mcp/tools/run-access.js +14 -0
- package/dist/mcp/tools/run-steps.d.ts +16 -0
- package/dist/mcp/tools/run-steps.js +85 -0
- package/dist/mcp/tools/runs.js +186 -18
- package/dist/mcp/tools/secret-elicitation.d.ts +2 -0
- package/dist/mcp/tools/secret-elicitation.js +25 -2
- package/dist/mcp/tools/secrets.js +38 -4
- package/dist/mcp/tools/tools.d.ts +6 -4
- package/dist/mcp/tools/tools.js +40 -8
- package/dist/mcp/tools/trigger.js +28 -6
- package/dist/mcp/transport/http-limits.d.ts +2 -0
- package/dist/mcp/transport/http-limits.js +6 -2
- package/dist/mcp/webhooks/ingress.js +10 -0
- package/dist/native-worker/gateway-server.d.ts +18 -1
- package/dist/native-worker/gateway-server.js +38 -9
- package/dist/native-worker/gateway.d.ts +5 -0
- package/dist/native-worker/gateway.js +13 -1
- package/dist/native-worker/http-server.d.ts +6 -4
- package/dist/native-worker/http-server.js +53 -8
- package/dist/native-worker/ledger.d.ts +6 -2
- package/dist/native-worker/ledger.js +5 -4
- package/dist/native-worker/protocol.d.ts +1 -0
- package/dist/native-worker/protocol.js +4 -1
- package/dist/providers/coding-proxy/capability-hash.d.ts +2 -0
- package/dist/providers/coding-proxy/capability-hash.js +5 -0
- package/dist/providers/coding-proxy/mcp-route.d.ts +34 -0
- package/dist/providers/coding-proxy/mcp-route.js +166 -0
- package/dist/providers/coding-proxy/memory-ledger.d.ts +2 -0
- package/dist/providers/coding-proxy/memory-ledger.js +16 -0
- package/dist/providers/coding-proxy/prisma-ledger.d.ts +1 -0
- package/dist/providers/coding-proxy/prisma-ledger.js +36 -2
- package/dist/providers/coding-proxy/proxy.d.ts +33 -1
- package/dist/providers/coding-proxy/proxy.js +266 -75
- package/dist/providers/coding-proxy/run-step-forwarder.d.ts +42 -0
- package/dist/providers/coding-proxy/run-step-forwarder.js +206 -0
- package/dist/providers/coding-proxy/runtime.d.ts +13 -0
- package/dist/providers/coding-proxy/runtime.js +87 -4
- package/dist/providers/coding-proxy/server.d.ts +3 -0
- package/dist/providers/coding-proxy/server.js +10 -0
- package/dist/providers/coding-proxy/types.d.ts +18 -0
- package/dist/providers/engine/types.d.ts +26 -0
- package/dist/providers/executor/composition.js +5 -0
- package/dist/providers/executor/container.d.ts +47 -1
- package/dist/providers/executor/container.js +84 -8
- package/dist/providers/host-tools/invoke.d.ts +37 -0
- package/dist/providers/host-tools/invoke.js +117 -0
- package/dist/providers/host-tools/operations.d.ts +65 -0
- package/dist/providers/host-tools/operations.js +149 -0
- package/dist/providers/host-tools/registry.d.ts +79 -0
- package/dist/providers/host-tools/registry.js +362 -0
- package/dist/providers/host-tools/request-guard.d.ts +17 -0
- package/dist/providers/host-tools/request-guard.js +99 -0
- package/dist/providers/host-tools/self-test.d.ts +64 -0
- package/dist/providers/host-tools/self-test.js +142 -0
- package/dist/providers/jobs/docker-isolation.d.ts +2 -2
- package/dist/providers/jobs/docker-isolation.js +30 -8
- package/dist/providers/jobs/docker.d.ts +8 -0
- package/dist/providers/jobs/docker.js +33 -9
- package/dist/providers/jobs/kubernetes-isolation.d.ts +3 -1
- package/dist/providers/jobs/kubernetes-isolation.js +15 -2
- package/dist/providers/jobs/kubernetes.d.ts +13 -0
- package/dist/providers/jobs/kubernetes.js +28 -5
- package/dist/providers/jobs/types.d.ts +6 -0
- package/dist/providers/review-host/types.d.ts +6 -4
- package/dist/providers/review-host/types.js +1 -1
- package/dist/providers/vcs/git.d.ts +6 -2
- package/dist/providers/vcs/git.js +15 -4
- package/dist/providers/vcs/github.d.ts +2 -71
- package/dist/providers/vcs/github.js +8 -11
- package/dist/providers/vcs/index.d.ts +1 -1
- package/dist/providers/vcs/index.js +1 -1
- package/dist/providers/vcs/remote.d.ts +4 -0
- package/dist/providers/vcs/remote.js +7 -1
- package/dist/providers/vcs/routing.d.ts +12 -6
- package/dist/providers/vcs/routing.js +21 -6
- package/dist/providers/vcs/types.d.ts +71 -3
- package/dist/quickstart/index.d.ts +5 -0
- package/dist/quickstart/index.js +21 -0
- package/dist/quickstart-images.json +1 -1
- package/dist/sandbox/eval-core.d.ts +12 -2
- package/dist/sandbox/eval-core.js +20 -4
- package/dist/sandbox/host-functions.d.ts +4 -0
- package/dist/sandbox/host-functions.js +7 -2
- package/dist/sandbox/limits.d.ts +4 -1
- package/dist/sandbox/limits.js +4 -1
- package/dist/sandbox/run-in-sandbox.d.ts +6 -0
- package/dist/sandbox/run-in-sandbox.js +14 -2
- package/dist/sandbox/safe-fetch.d.ts +2 -0
- package/dist/sandbox/safe-fetch.js +1 -1
- package/dist/sandbox/secret-broker.d.ts +1 -0
- package/dist/sandbox/secret-broker.js +1 -1
- package/dist/sandbox/tool-timeout.d.ts +32 -0
- package/dist/sandbox/tool-timeout.js +52 -0
- package/dist/sandbox/user-tool.d.ts +8 -1
- package/dist/sandbox/user-tool.js +9 -3
- package/dist/serve.js +26 -18
- package/dist/viewer/api-schema.d.ts +66 -0
- package/dist/viewer/api-schema.js +31 -0
- package/dist/viewer/graph.js +2 -1
- package/dist/viewer/openapi.js +2 -1
- package/dist/viewer/run-detail.d.ts +2 -0
- package/dist/viewer/run-detail.js +26 -1
- package/dist/wardby-bin.js +5 -0
- package/docs/README.md +11 -1
- package/docs/agent-recipes.md +37 -4
- package/docs/architecture-runtime.md +1 -1
- package/docs/claude-code-plugin.md +208 -0
- package/docs/code-review-agents.md +6 -0
- package/docs/coding-agent-setup.md +94 -1
- package/docs/coding-worker-byo-images.md +4 -2
- package/docs/coding-worker-isolation.md +94 -7
- package/docs/debugging-agent-runs.md +354 -0
- package/docs/getting-started-gke.md +33 -11
- package/docs/getting-started-identity-provider.md +43 -37
- package/docs/getting-started.md +8 -0
- package/docs/host-providers.md +294 -0
- package/docs/mcp-servers.md +263 -0
- package/docs/native-sandbox.md +31 -9
- package/docs/security-deployment.md +161 -31
- package/docs/tool-secrets.md +3 -0
- package/docs/viewer-api.md +27 -12
- package/docs/viewer-api.openapi.yml +78 -2
- package/help/admin-viewer.md +5 -0
- package/help/agent-recipes.md +33 -2
- package/help/brokered-secrets.md +3 -0
- package/help/build-claude-code-image.md +1 -1
- package/help/claude-code-run-pane.md +63 -0
- package/help/deploy-gke.md +5 -0
- package/help/errors/coding-mcp-gateway-unavailable.md +46 -0
- package/help/errors/coding-mcp-pins-unavailable.md +35 -0
- package/help/errors/database-auth-invalid.md +1 -1
- package/help/errors/host-provider-error.md +40 -0
- package/help/errors/host-tool-failed.md +36 -0
- package/help/errors/mcp-call-limit.md +22 -0
- package/help/errors/mcp-call-timeout.md +22 -0
- package/help/errors/mcp-server-auth-failed.md +22 -0
- package/help/errors/mcp-server-credentials-unavailable.md +45 -0
- package/help/errors/mcp-server-error.md +28 -0
- package/help/errors/mcp-server-unreachable.md +22 -0
- package/help/errors/mcp-servers-off.md +21 -0
- package/help/errors/mcp-tool-not-allowed.md +26 -0
- package/help/errors/mcp-tool-removed.md +22 -0
- package/help/errors/mcp-unavailable.md +25 -0
- package/help/errors/native-sandbox-capacity.md +1 -1
- package/help/errors/native-sandbox-deadline-exceeded.md +1 -1
- package/help/errors/native-sandbox-docker-failed.md +1 -1
- package/help/errors/native-sandbox-gateway-error.md +1 -1
- package/help/errors/native-sandbox-gateway-unavailable.md +1 -1
- package/help/errors/native-sandbox-image-not-pinned.md +1 -1
- package/help/errors/native-sandbox-isolation-mismatch.md +1 -1
- package/help/errors/native-sandbox-network-unenforced.md +1 -1
- package/help/errors/native-sandbox-requires-catalog.md +1 -1
- package/help/errors/native-sandbox-unavailable.md +1 -1
- package/help/errors/native-sandbox-warm-delivery-failed.md +1 -1
- package/help/errors/native-sandbox-worker-exited.md +1 -1
- package/help/errors/native-sandbox-worker-lost.md +1 -1
- package/help/errors/native-sandbox-worker-unready.md +1 -1
- package/help/errors/repository-not-listed.md +36 -0
- package/help/errors/repository-required.md +36 -0
- package/help/errors/tool-timeout.md +38 -0
- package/help/host-providers.md +40 -0
- package/help/identity-and-access.md +4 -1
- package/help/low-power-mode.md +19 -8
- package/help/mcp-servers.md +73 -0
- package/help/mcp.md +9 -2
- package/help/native-capabilities.md +27 -1
- package/help/native-sandbox.md +1 -1
- package/help/operating-agents.md +16 -0
- package/help/related-pull-requests.md +7 -3
- package/help/repo-instructions-and-skills.md +3 -1
- package/help/resume-runs-locally.md +7 -0
- package/help/run-steps.md +140 -0
- package/help/stop-run.md +1 -1
- package/help/troubleshooting/coding-workers.md +9 -1
- package/help/troubleshooting/debugging-agent-runs.md +29 -0
- package/package.json +2 -1
- package/prisma/migrations/20261102000000_host_providers/migration.sql +56 -0
- package/prisma/migrations/20261104000000_coding_agent_repository_list/migration.sql +5 -0
- package/prisma/migrations/20261106000000_tool_timeout/migration.sql +4 -0
- package/prisma/migrations/20261107000000_mcp_servers/migration.sql +33 -0
- package/prisma/migrations/20261108000000_coding_mcp/migration.sql +5 -0
- package/prisma/migrations/20261109000000_task_run_index/migration.sql +3 -0
- package/prisma/migrations/20261110000000_run_steps/migration.sql +26 -0
- package/prisma/migrations/20261111000000_run_steps_viewer_notify/migration.sql +59 -0
- package/prisma/migrations/20261112000000_run_steps_detail/migration.sql +9 -0
- package/prisma/schema.prisma +211 -14
- package/scripts/git-askpass.sh +1 -1
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote MCP servers: the owner-side domain. Validates a server's URL and name, loads the owner's
|
|
3
|
+
* brokered secrets for it, builds the McpFetch that sends them (brokeredFetch over safeFetch), takes
|
|
4
|
+
* the redacted tool snapshot, and diffs snapshots. Secret values never leave this file in any output:
|
|
5
|
+
* snapshots are redacted by exact value (every encoded form) plus token shapes before they are returned.
|
|
6
|
+
*/
|
|
7
|
+
import type { PrismaClient } from "#prisma";
|
|
8
|
+
import { type McpFetch, type McpServerInfo, type McpToolEntry } from "./mcp-client/client.js";
|
|
9
|
+
import type { SecretsAccessor } from "./secrets.js";
|
|
10
|
+
import type { Logger } from "./logger.js";
|
|
11
|
+
import type { SecretCipher } from "../providers/secrets/types.js";
|
|
12
|
+
import { safeFetch } from "../sandbox/safe-fetch.js";
|
|
13
|
+
export declare class McpServerInputError extends Error {
|
|
14
|
+
constructor(message: string);
|
|
15
|
+
}
|
|
16
|
+
/** What the server's owner (or an admin) sees when a stored secret of the server can't be decrypted. */
|
|
17
|
+
export declare const CREDENTIALS_UNAVAILABLE_MESSAGE = "The MCP server's credentials can't be decrypted on this server. Check that every Wardby process (control plane, scheduler, native gateway) uses the same SECRET_APP_KEY, or set the secret again.";
|
|
18
|
+
/**
|
|
19
|
+
* A server's brokered secret exists but its stored value can't be decrypted (another
|
|
20
|
+
* SECRET_APP_KEY, a key-id mismatch, a corrupt ciphertext). Not an input problem: the message is
|
|
21
|
+
* fixed and never carries the cipher's error, the ciphertext or a value.
|
|
22
|
+
*/
|
|
23
|
+
export declare class McpCredentialsUnavailableError extends Error {
|
|
24
|
+
/** Empty while a server is being registered (it has no id yet). */
|
|
25
|
+
readonly serverId: string;
|
|
26
|
+
readonly serverName: string;
|
|
27
|
+
readonly secretName: string;
|
|
28
|
+
readonly code = "mcp_server_credentials_unavailable";
|
|
29
|
+
constructor(
|
|
30
|
+
/** Empty while a server is being registered (it has no id yet). */
|
|
31
|
+
serverId: string, serverName: string, secretName: string);
|
|
32
|
+
}
|
|
33
|
+
/** The one operator line for an undecryptable server secret: ids and names only, never the cipher's error text. */
|
|
34
|
+
export declare function logCredentialsUnavailable(log: Pick<Logger, "warn">, error: McpCredentialsUnavailableError): void;
|
|
35
|
+
export interface McpServerRow {
|
|
36
|
+
id: string;
|
|
37
|
+
ownerId: string;
|
|
38
|
+
name: string;
|
|
39
|
+
url: string;
|
|
40
|
+
secretNames: string[];
|
|
41
|
+
}
|
|
42
|
+
/** Validates a server URL: https, no userinfo, no fragment, default port; returns the normalised string. */
|
|
43
|
+
export declare function normaliseServerUrl(raw: string): string;
|
|
44
|
+
export declare function assertServerName(name: string): void;
|
|
45
|
+
/** The tool name the model sees: `<server>__<tool>` with any other character mapped to `_`. */
|
|
46
|
+
export declare function exposedToolName(serverName: string, toolName: string): string;
|
|
47
|
+
/** A server's saved tool list (toolSnapshot); anything but an array reads as empty. */
|
|
48
|
+
export declare function snapshotOf(server: {
|
|
49
|
+
toolSnapshot: unknown;
|
|
50
|
+
}): McpToolEntry[];
|
|
51
|
+
/** Exposed names of allowed tools; a name too long to expose is left out (refused at attach anyway). */
|
|
52
|
+
export declare function exposedNames(serverName: string, allowedTools: readonly string[]): string[];
|
|
53
|
+
/** Added, removed and changed (description or schema) tool names between two snapshots; order-independent. */
|
|
54
|
+
export declare function diffSnapshots(before: McpToolEntry[], after: McpToolEntry[]): {
|
|
55
|
+
added: string[];
|
|
56
|
+
removed: string[];
|
|
57
|
+
changed: string[];
|
|
58
|
+
};
|
|
59
|
+
/** Redacts every secret value of this server (exact, every encoded and escaped form) plus token shapes. */
|
|
60
|
+
export declare function redactForServer(text: string, values: string[]): string;
|
|
61
|
+
/** The same error with its message redacted; an McpClientError keeps its code, any other keeps its name. */
|
|
62
|
+
export declare function redactError(error: unknown, values: string[]): Error;
|
|
63
|
+
type SecretDb = Pick<PrismaClient, "secret">;
|
|
64
|
+
/**
|
|
65
|
+
* Loads the owner's secrets for the server; each must exist, be owned by ownerId, be brokered, and list
|
|
66
|
+
* the URL's host (McpServerInputError otherwise). A stored value that can't be decrypted throws
|
|
67
|
+
* McpCredentialsUnavailableError.
|
|
68
|
+
*/
|
|
69
|
+
export declare function loadServerSecrets(db: SecretDb, cipher: Pick<SecretCipher, "decrypt">, server: McpServerRow): Promise<{
|
|
70
|
+
accessor: SecretsAccessor;
|
|
71
|
+
values: string[];
|
|
72
|
+
}>;
|
|
73
|
+
/** The McpFetch for one server: brokeredFetch over safeFetch with the timeout and signal; text body, lower-case headers. */
|
|
74
|
+
export declare function serverFetch(server: McpServerRow, accessor: SecretsAccessor, options: {
|
|
75
|
+
timeoutMs: number;
|
|
76
|
+
fetchImpl?: typeof safeFetch;
|
|
77
|
+
}): McpFetch;
|
|
78
|
+
/** initialize + listTools + close; the result is redacted (as JSON text) before it is returned. */
|
|
79
|
+
export declare function fetchSnapshot(server: McpServerRow, deps: {
|
|
80
|
+
db: SecretDb;
|
|
81
|
+
cipher: Pick<SecretCipher, "decrypt">;
|
|
82
|
+
fetchImpl?: typeof safeFetch;
|
|
83
|
+
timeoutMs?: number;
|
|
84
|
+
}): Promise<{
|
|
85
|
+
serverInfo: McpServerInfo;
|
|
86
|
+
tools: McpToolEntry[];
|
|
87
|
+
}>;
|
|
88
|
+
/** For the secret delete guard: names of the owner's MCP servers whose secretNames include the secret. */
|
|
89
|
+
export declare function mcpServersUsingSecret(db: Pick<PrismaClient, "mcpServer">, ownerId: string, secretName: string): Promise<string[]>;
|
|
90
|
+
export {};
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { redactTokenShapedValues } from "../coding/protocol.js";
|
|
2
|
+
import { McpClientError, McpHttpClient, } from "./mcp-client/client.js";
|
|
3
|
+
import { parseSecretBrokerConfig } from "./secret-broker-config.js";
|
|
4
|
+
import { redactExactSecretValues, withEscapedForms } from "./secret-spans.js";
|
|
5
|
+
import { brokeredFetch } from "../sandbox/brokered-fetch.js";
|
|
6
|
+
import { safeFetch } from "../sandbox/safe-fetch.js";
|
|
7
|
+
import { consoleRedactionValues, encodedForms } from "../sandbox/secret-broker.js";
|
|
8
|
+
export class McpServerInputError extends Error {
|
|
9
|
+
constructor(message) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = "McpServerInputError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/** What the server's owner (or an admin) sees when a stored secret of the server can't be decrypted. */
|
|
15
|
+
export const CREDENTIALS_UNAVAILABLE_MESSAGE = "The MCP server's credentials can't be decrypted on this server. Check that every Wardby process (control plane, scheduler, native gateway) uses the same SECRET_APP_KEY, or set the secret again.";
|
|
16
|
+
/**
|
|
17
|
+
* A server's brokered secret exists but its stored value can't be decrypted (another
|
|
18
|
+
* SECRET_APP_KEY, a key-id mismatch, a corrupt ciphertext). Not an input problem: the message is
|
|
19
|
+
* fixed and never carries the cipher's error, the ciphertext or a value.
|
|
20
|
+
*/
|
|
21
|
+
export class McpCredentialsUnavailableError extends Error {
|
|
22
|
+
serverId;
|
|
23
|
+
serverName;
|
|
24
|
+
secretName;
|
|
25
|
+
code = "mcp_server_credentials_unavailable";
|
|
26
|
+
constructor(
|
|
27
|
+
/** Empty while a server is being registered (it has no id yet). */
|
|
28
|
+
serverId, serverName, secretName) {
|
|
29
|
+
super(CREDENTIALS_UNAVAILABLE_MESSAGE);
|
|
30
|
+
this.serverId = serverId;
|
|
31
|
+
this.serverName = serverName;
|
|
32
|
+
this.secretName = secretName;
|
|
33
|
+
this.name = "McpCredentialsUnavailableError";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** The one operator line for an undecryptable server secret: ids and names only, never the cipher's error text. */
|
|
37
|
+
export function logCredentialsUnavailable(log, error) {
|
|
38
|
+
log.warn({
|
|
39
|
+
reason: "mcp_secret_decrypt_failed",
|
|
40
|
+
...(error.serverId !== "" ? { serverId: error.serverId } : {}),
|
|
41
|
+
serverName: error.serverName,
|
|
42
|
+
secretName: error.secretName,
|
|
43
|
+
}, "MCP server secret could not be decrypted");
|
|
44
|
+
}
|
|
45
|
+
const SERVER_NAME = /^[a-z0-9][a-z0-9_-]{0,31}$/;
|
|
46
|
+
const EXPOSED_NAME = /^[A-Za-z0-9_-]{1,64}$/;
|
|
47
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
48
|
+
/** Validates a server URL: https, no userinfo, no fragment, default port; returns the normalised string. */
|
|
49
|
+
export function normaliseServerUrl(raw) {
|
|
50
|
+
let url;
|
|
51
|
+
try {
|
|
52
|
+
url = new URL(raw);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
throw new McpServerInputError("The MCP server URL is not a valid URL.");
|
|
56
|
+
}
|
|
57
|
+
if (url.protocol !== "https:")
|
|
58
|
+
throw new McpServerInputError("The MCP server URL must use https.");
|
|
59
|
+
if (url.username !== "" || url.password !== "")
|
|
60
|
+
throw new McpServerInputError("The MCP server URL must not contain a username or password; use a brokered secret.");
|
|
61
|
+
if (url.hash !== "")
|
|
62
|
+
throw new McpServerInputError("The MCP server URL must not contain a fragment (#).");
|
|
63
|
+
if (url.port !== "")
|
|
64
|
+
throw new McpServerInputError("The MCP server URL must use the default https port (443).");
|
|
65
|
+
return url.href;
|
|
66
|
+
}
|
|
67
|
+
export function assertServerName(name) {
|
|
68
|
+
if (!SERVER_NAME.test(name)) {
|
|
69
|
+
throw new McpServerInputError("The MCP server name must be 1-32 characters: lower-case letters, digits, _ or -, starting with a letter or digit.");
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** The tool name the model sees: `<server>__<tool>` with any other character mapped to `_`. */
|
|
73
|
+
export function exposedToolName(serverName, toolName) {
|
|
74
|
+
const name = `${serverName}__${toolName}`.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
75
|
+
if (!EXPOSED_NAME.test(name)) {
|
|
76
|
+
throw new McpServerInputError(`The tool name "${name.slice(0, 40)}..." is longer than 64 characters once prefixed.`);
|
|
77
|
+
}
|
|
78
|
+
return name;
|
|
79
|
+
}
|
|
80
|
+
/** A server's saved tool list (toolSnapshot); anything but an array reads as empty. */
|
|
81
|
+
export function snapshotOf(server) {
|
|
82
|
+
return Array.isArray(server.toolSnapshot) ? server.toolSnapshot : [];
|
|
83
|
+
}
|
|
84
|
+
/** Exposed names of allowed tools; a name too long to expose is left out (refused at attach anyway). */
|
|
85
|
+
export function exposedNames(serverName, allowedTools) {
|
|
86
|
+
return allowedTools.flatMap((tool) => {
|
|
87
|
+
try {
|
|
88
|
+
return [exposedToolName(serverName, tool)];
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/** Added, removed and changed (description or schema) tool names between two snapshots; order-independent. */
|
|
96
|
+
export function diffSnapshots(before, after) {
|
|
97
|
+
const old = new Map(before.map((t) => [t.name, t]));
|
|
98
|
+
const next = new Map(after.map((t) => [t.name, t]));
|
|
99
|
+
const added = [...next.keys()].filter((n) => !old.has(n)).sort();
|
|
100
|
+
const removed = [...old.keys()].filter((n) => !next.has(n)).sort();
|
|
101
|
+
const changed = [...next.keys()].filter((n) => old.has(n) && canonical(old.get(n)) !== canonical(next.get(n))).sort();
|
|
102
|
+
return { added, removed, changed };
|
|
103
|
+
}
|
|
104
|
+
function canonical(value) {
|
|
105
|
+
return JSON.stringify(value, (_key, v) => v !== null && typeof v === "object" && !Array.isArray(v)
|
|
106
|
+
? Object.fromEntries(Object.entries(v).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)))
|
|
107
|
+
: v);
|
|
108
|
+
}
|
|
109
|
+
/** Redacts every secret value of this server (exact, every encoded and escaped form) plus token shapes. */
|
|
110
|
+
export function redactForServer(text, values) {
|
|
111
|
+
const forms = withEscapedForms(values.flatMap(encodedForms)).sort((a, b) => b.length - a.length);
|
|
112
|
+
return redactTokenShapedValues(redactExactSecretValues(text, [...values, ...forms]));
|
|
113
|
+
}
|
|
114
|
+
/** The same error with its message redacted; an McpClientError keeps its code, any other keeps its name. */
|
|
115
|
+
export function redactError(error, values) {
|
|
116
|
+
const message = redactForServer(error instanceof Error ? error.message : "The MCP server call failed.", values);
|
|
117
|
+
if (error instanceof McpClientError)
|
|
118
|
+
return new McpClientError(error.code, message);
|
|
119
|
+
if (error instanceof McpServerInputError)
|
|
120
|
+
return new McpServerInputError(message);
|
|
121
|
+
// Its message is fixed and carries no value: keep it (and its ids) as it is.
|
|
122
|
+
if (error instanceof McpCredentialsUnavailableError)
|
|
123
|
+
return error;
|
|
124
|
+
const out = new Error(message);
|
|
125
|
+
if (error instanceof Error)
|
|
126
|
+
out.name = error.name;
|
|
127
|
+
return out;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Loads the owner's secrets for the server; each must exist, be owned by ownerId, be brokered, and list
|
|
131
|
+
* the URL's host (McpServerInputError otherwise). A stored value that can't be decrypted throws
|
|
132
|
+
* McpCredentialsUnavailableError.
|
|
133
|
+
*/
|
|
134
|
+
export async function loadServerSecrets(db, cipher, server) {
|
|
135
|
+
const host = new URL(server.url).hostname.toLowerCase();
|
|
136
|
+
const entries = new Map();
|
|
137
|
+
const values = new Set();
|
|
138
|
+
for (const name of server.secretNames) {
|
|
139
|
+
const stored = await db.secret.findUnique({
|
|
140
|
+
where: { ownerId_name: { ownerId: server.ownerId, name } },
|
|
141
|
+
select: { ciphertext: true, broker: true },
|
|
142
|
+
});
|
|
143
|
+
if (!stored)
|
|
144
|
+
throw new McpServerInputError(`Secret "${name}" was not found among your secrets.`);
|
|
145
|
+
if (stored.broker === null || stored.broker === undefined)
|
|
146
|
+
throw new McpServerInputError(`Secret "${name}" is not brokered; set its broker config first (set_secret_broker).`);
|
|
147
|
+
let broker;
|
|
148
|
+
try {
|
|
149
|
+
broker = parseSecretBrokerConfig(stored.broker);
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
throw new McpServerInputError(`Secret "${name}" has a broker config that cannot be read; set it again.`);
|
|
153
|
+
}
|
|
154
|
+
if (!broker.hosts.includes(host))
|
|
155
|
+
throw new McpServerInputError(`Secret "${name}" is not brokered to host ${host}; add it to the secret's hosts.`);
|
|
156
|
+
let value;
|
|
157
|
+
try {
|
|
158
|
+
value = await cipher.decrypt(stored.ciphertext);
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
// The cipher's error is dropped: it is not an input problem, and its text is not ours to pass on.
|
|
162
|
+
throw new McpCredentialsUnavailableError(server.id, server.name, name);
|
|
163
|
+
}
|
|
164
|
+
const entry = { value, broker };
|
|
165
|
+
entries.set(name, entry);
|
|
166
|
+
for (const v of withEscapedForms(consoleRedactionValues(entry)))
|
|
167
|
+
values.add(v);
|
|
168
|
+
}
|
|
169
|
+
const accessor = {
|
|
170
|
+
get: async () => {
|
|
171
|
+
throw new Error("secret_brokered: this secret is brokered; it is never readable");
|
|
172
|
+
},
|
|
173
|
+
resolve: async (name) => entries.get(name),
|
|
174
|
+
};
|
|
175
|
+
return { accessor, values: [...values] };
|
|
176
|
+
}
|
|
177
|
+
/** The McpFetch for one server: brokeredFetch over safeFetch with the timeout and signal; text body, lower-case headers. */
|
|
178
|
+
export function serverFetch(server, accessor, options) {
|
|
179
|
+
return async (request, signal) => {
|
|
180
|
+
const response = (await brokeredFetch({
|
|
181
|
+
url: server.url,
|
|
182
|
+
init: { method: request.method, headers: request.headers, body: request.body },
|
|
183
|
+
secretNames: server.secretNames,
|
|
184
|
+
secrets: accessor,
|
|
185
|
+
fetchImpl: options.fetchImpl ?? safeFetch,
|
|
186
|
+
policy: { timeoutMs: options.timeoutMs, signal },
|
|
187
|
+
redactFromConsole: () => { },
|
|
188
|
+
}));
|
|
189
|
+
return {
|
|
190
|
+
status: response.status,
|
|
191
|
+
headers: Object.fromEntries(Object.entries(response.headers).map(([k, v]) => [k.toLowerCase(), v])),
|
|
192
|
+
body: Buffer.from(response.bodyBase64, "base64").toString("utf8"),
|
|
193
|
+
};
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
/** initialize + listTools + close; the result is redacted (as JSON text) before it is returned. */
|
|
197
|
+
export async function fetchSnapshot(server, deps) {
|
|
198
|
+
const timeoutMs = deps.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
199
|
+
const { accessor, values } = await loadServerSecrets(deps.db, deps.cipher, server);
|
|
200
|
+
const client = new McpHttpClient({
|
|
201
|
+
fetch: serverFetch(server, accessor, { timeoutMs, fetchImpl: deps.fetchImpl }),
|
|
202
|
+
signal: AbortSignal.timeout(timeoutMs * 3),
|
|
203
|
+
});
|
|
204
|
+
let raw;
|
|
205
|
+
try {
|
|
206
|
+
const serverInfo = await client.initialize();
|
|
207
|
+
raw = { serverInfo, tools: await client.listTools() };
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
throw redactError(error, values);
|
|
211
|
+
}
|
|
212
|
+
finally {
|
|
213
|
+
await client.close().catch(() => { });
|
|
214
|
+
}
|
|
215
|
+
const redacted = redactForServer(JSON.stringify(raw), values);
|
|
216
|
+
try {
|
|
217
|
+
return JSON.parse(redacted);
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
throw new McpServerInputError("The MCP server's tool list could not be saved safely.");
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/** For the secret delete guard: names of the owner's MCP servers whose secretNames include the secret. */
|
|
224
|
+
export async function mcpServersUsingSecret(db, ownerId, secretName) {
|
|
225
|
+
const rows = await db.mcpServer.findMany({
|
|
226
|
+
where: { ownerId, secretNames: { has: secretName } },
|
|
227
|
+
select: { name: true },
|
|
228
|
+
});
|
|
229
|
+
return rows.map((r) => r.name).sort();
|
|
230
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A native run's remote MCP tools: the load step pins the agent's attached, allowed tools
|
|
3
|
+
* (loadMcpToolPins), the runner offers them as built-ins (mcpToolDefs), and every call runs on the
|
|
4
|
+
* control plane through handleMcpTool. The pin decides only which tools the model sees for this
|
|
5
|
+
* run; each call re-checks the live attachment, that the agent's owner may still use the server (owns
|
|
6
|
+
* it or holds use on it), and uses the live server row (URL, secrets). A pin carries no URL (a query
|
|
7
|
+
* string can carry a token), secret names or owner id: pins are saved in the run's step results.
|
|
8
|
+
*
|
|
9
|
+
* Secret values never leave: results and errors are redacted against the server's secrets (every
|
|
10
|
+
* encoded form) plus token shapes, the log line carries no arguments, bodies or URL, and
|
|
11
|
+
* mcpNamedSecretValues feeds the run's own redaction (secret-guard.ts loadAgentSecretValues).
|
|
12
|
+
*/
|
|
13
|
+
import type { PrismaClient } from "#prisma";
|
|
14
|
+
import type { Logger } from "./logger.js";
|
|
15
|
+
import type { LoadedTool } from "../providers/engine/types.js";
|
|
16
|
+
import type { SecretCipher } from "../providers/secrets/types.js";
|
|
17
|
+
import type { safeFetch } from "../sandbox/safe-fetch.js";
|
|
18
|
+
/** One MCP tool as the load step pins it. */
|
|
19
|
+
export interface McpToolPin {
|
|
20
|
+
/** The name the model sees: `<server name>__<tool name>`. */
|
|
21
|
+
exposedName: string;
|
|
22
|
+
/** The name the server knows. */
|
|
23
|
+
toolName: string;
|
|
24
|
+
serverId: string;
|
|
25
|
+
serverName: string;
|
|
26
|
+
/** Only when the attachment sets one. */
|
|
27
|
+
callTimeoutMs?: number;
|
|
28
|
+
definition: {
|
|
29
|
+
description: string;
|
|
30
|
+
inputSchema: Record<string, unknown>;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export declare const DEFAULT_MCP_CALL_TIMEOUT_MS = 30000;
|
|
34
|
+
/** What a grantee's run sees when the server owner's credentials can't be loaded. */
|
|
35
|
+
export declare const SHARED_CREDENTIALS_MESSAGE = "The MCP server's credentials can't be used; ask its owner to check it.";
|
|
36
|
+
/**
|
|
37
|
+
* A Codex coding agent runs shell commands that can read the run's MCP token, so it may use only tools
|
|
38
|
+
* the server marks read-only (annotations.readOnlyHint === true in the saved tool list).
|
|
39
|
+
*/
|
|
40
|
+
export declare function isMarkedReadOnly(entry: {
|
|
41
|
+
annotations?: Record<string, unknown>;
|
|
42
|
+
} | undefined): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Whether a coding provider gets the Codex read-only rule. Fails closed: anything but exactly
|
|
45
|
+
* "claude-code" (Codex, an unknown value, or a coding agent with no profile) counts as Codex. A run
|
|
46
|
+
* is judged by the provider it was dispatched with (CodingRun.provider), never the agent's current
|
|
47
|
+
* profile, which can change between dispatch and launch.
|
|
48
|
+
*/
|
|
49
|
+
export declare function isCodexCoding(provider: string | null | undefined): boolean;
|
|
50
|
+
type McpToolsDb = Pick<PrismaClient, "agentMcpServer" | "secret" | "resourceGrant">;
|
|
51
|
+
/** Redaction reads attachments and secrets only: it covers every attached server, usable or not. */
|
|
52
|
+
type McpSecretsDb = Pick<PrismaClient, "agentMcpServer" | "secret">;
|
|
53
|
+
export interface McpToolPinOptions {
|
|
54
|
+
/**
|
|
55
|
+
* Pin only tools the server marks read-only: the caller sets it for a Codex coding run, from the
|
|
56
|
+
* provider the run was dispatched with (isCodexCoding(run.provider)). Native runs leave it unset.
|
|
57
|
+
*/
|
|
58
|
+
readOnlyOnly?: boolean;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Builds pins for an agent's attachments: allowed tools present in the snapshot only, from servers the
|
|
62
|
+
* agent's owner may still use (owns, or holds use on); none when the mode is off.
|
|
63
|
+
*/
|
|
64
|
+
export declare function loadMcpToolPins(db: Pick<PrismaClient, "agentMcpServer" | "resourceGrant">, agentId: string, options?: McpToolPinOptions): Promise<McpToolPin[]>;
|
|
65
|
+
/**
|
|
66
|
+
* The pins whose exposed name no other tool of the run uses. Attach refuses clashes; this covers a
|
|
67
|
+
* name that became a built-in (or an attached tool) later: the MCP tool is left out, with a warning.
|
|
68
|
+
*/
|
|
69
|
+
export declare function withoutClashingPins(pins: readonly McpToolPin[], otherNames: readonly string[], log: Pick<Logger, "warn">): McpToolPin[];
|
|
70
|
+
export declare function mcpToolDefs(pins: readonly McpToolPin[]): LoadedTool[];
|
|
71
|
+
export interface McpToolContext {
|
|
72
|
+
db: McpToolsDb;
|
|
73
|
+
cipher: Pick<SecretCipher, "decrypt">;
|
|
74
|
+
/** The agent whose attachment is re-checked on every call. */
|
|
75
|
+
agentId: string;
|
|
76
|
+
/** The run, for the per-call log line. */
|
|
77
|
+
runId: string;
|
|
78
|
+
/** The run's stop signal: aborting it stops a call in flight. */
|
|
79
|
+
signal: AbortSignal;
|
|
80
|
+
/** A sandboxed run's session deadline; the call's time limit never runs past it. */
|
|
81
|
+
deadlineAt?: Date;
|
|
82
|
+
/**
|
|
83
|
+
* Refuse any tool the live tool list doesn't mark read-only: set by the coding gateway for a Codex
|
|
84
|
+
* run, from the run's dispatched provider (isCodexCoding(codingRun.provider)). Native runs leave it unset.
|
|
85
|
+
*/
|
|
86
|
+
readOnlyOnly?: boolean;
|
|
87
|
+
fetchImpl?: typeof safeFetch;
|
|
88
|
+
log: Pick<Logger, "info" | "warn">;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Never throws. Re-checks the live attachment, validates the arguments, runs initialize → tools/call →
|
|
92
|
+
* close under the time limit, and returns the redacted result text or a JSON error. One log line per call.
|
|
93
|
+
*/
|
|
94
|
+
export declare function handleMcpTool(pin: McpToolPin, argsJson: string, ctx: McpToolContext): Promise<string>;
|
|
95
|
+
export interface NamedMcpSecretValues {
|
|
96
|
+
/** `mcp:<server name>/<secret name>`. */
|
|
97
|
+
name: string;
|
|
98
|
+
values: string[];
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Every secret value of every server attached to the agent, named `mcp:<server>/<secret>`, in
|
|
102
|
+
* every form the server's own redaction looks for. A secret that no longer exists has no value to
|
|
103
|
+
* leak and is skipped; a read that fails rejects (callers fail closed).
|
|
104
|
+
*/
|
|
105
|
+
export declare function mcpNamedSecretValues(db: McpSecretsDb, cipher: Pick<SecretCipher, "decrypt">, agentId: string): Promise<NamedMcpSecretValues[]>;
|
|
106
|
+
/** Secret values for every attached server of this agent (for run-text masking and gateway cause checks). */
|
|
107
|
+
export declare function mcpSecretValuesForAgent(db: McpSecretsDb, cipher: Pick<SecretCipher, "decrypt">, agentId: string): Promise<string[]>;
|
|
108
|
+
export {};
|