@zackbart/connecta 0.34.1 → 0.35.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/CHANGELOG.md +363 -0
- package/README.md +62 -106
- package/SECURITY.md +3 -2
- package/bin/connecta.mjs +41 -16
- package/bin/version.mjs +1 -1
- package/dist/access-tokens.d.ts +2 -1
- package/dist/access-tokens.js +66 -30
- package/dist/activity.d.ts +1 -1
- package/dist/activity.js +2 -0
- package/dist/agent-config.d.ts +23 -0
- package/dist/agent-config.js +59 -0
- package/dist/agent-description.js +16 -0
- package/dist/agent-identity.js +4 -4
- package/dist/agent-observation.js +39 -0
- package/dist/auth/clerk-sdk/client.d.ts +2 -0
- package/dist/auth/clerk-sdk/generated.js +554 -563
- package/dist/auth/clerk-transport.js +70 -3
- package/dist/auth/clerk.d.ts +13 -0
- package/dist/auth/clerk.js +653 -246
- package/dist/auth/cloudflare-access.js +46 -42
- package/dist/auth/downstream-client-metadata.js +2 -2
- package/dist/auth/downstream-oauth.js +2051 -1160
- package/dist/auth/downstream-revocation.js +88 -88
- package/dist/auth/native-call.js +20 -0
- package/dist/auth/native.js +184 -0
- package/dist/auth/oauth-start-reset.js +11 -5
- package/dist/auth/oauth-token-response.js +121 -102
- package/dist/auth/oauth-v2-migration.js +97 -78
- package/dist/auth/renewable-grant.js +10 -0
- package/dist/auth/static-oauth.js +663 -271
- package/dist/auth/vercel-agent.js +266 -0
- package/dist/auth-admission.js +204 -0
- package/dist/auth-elicitation.js +350 -241
- package/dist/authorization-handoff.js +164 -90
- package/dist/call-admission-context.js +3 -10
- package/dist/call-admission.js +2 -0
- package/dist/call-classification.js +9 -0
- package/dist/call-recovery.js +32 -13
- package/dist/canonical-json.js +8 -0
- package/dist/catalog-cache.js +369 -213
- package/dist/catalog-service.js +659 -530
- package/dist/catalog.js +5 -1
- package/dist/concurrency.js +0 -25
- package/dist/config-defaults.d.ts +1 -0
- package/dist/config-defaults.js +1 -0
- package/dist/config-schema.d.ts +3 -1
- package/dist/config-schema.js +13 -3
- package/dist/config.d.ts +40 -6
- package/dist/config.js +40 -26
- package/dist/connector-caller.d.ts +4 -0
- package/dist/connector-caller.js +17 -4
- package/dist/connectors/api-connector.d.ts +12 -7
- package/dist/connectors/api-connector.js +142 -56
- package/dist/connectors/guarded-fetch.d.ts +51 -17
- package/dist/connectors/guarded-fetch.js +215 -121
- package/dist/connectors/negotiation-cache.js +20 -10
- package/dist/connectors/remote-mcp.d.ts +10 -30
- package/dist/connectors/remote-mcp.js +955 -563
- package/dist/d1.js +10 -243
- package/dist/derived-context.js +5 -0
- package/dist/describe-config.d.ts +3 -1
- package/dist/describe-config.js +2 -0
- package/dist/downstream-input.js +347 -260
- package/dist/errors.d.ts +87 -6
- package/dist/errors.js +114 -4
- package/dist/execute.js +87 -50
- package/dist/executor-admission.js +3 -0
- package/dist/executors/quickjs.js +163 -112
- package/dist/guarded-transport.js +50 -0
- package/dist/guest-runtime.js +1 -1
- package/dist/http/client.js +439 -0
- package/dist/http/errors.js +558 -0
- package/dist/http/fields.js +49 -0
- package/dist/http/hatch-paging.js +318 -0
- package/dist/http/hatch.js +1279 -0
- package/dist/http/json-schema.js +267 -0
- package/dist/http/node-transport.js +241 -0
- package/dist/http/oauth.js +162 -0
- package/dist/http/paging.js +228 -0
- package/dist/http/provider.js +221 -0
- package/dist/http/safety.js +82 -0
- package/dist/http/services.js +79 -0
- package/dist/http/tools.js +383 -0
- package/dist/http/vendor-index.js +138 -0
- package/dist/http/vendor.js +448 -0
- package/dist/http/write-request.js +66 -0
- package/dist/http-policy.d.ts +11 -0
- package/dist/http-policy.js +45 -0
- package/dist/inbound-credential.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +4 -0
- package/dist/invocation-auth.js +30 -19
- package/dist/invocation.js +218 -85
- package/dist/mcp-result.js +0 -4
- package/dist/membership.d.ts +4 -0
- package/dist/meta-output.js +1 -1
- package/dist/meta-tools.js +531 -406
- package/dist/native-recovery.js +52 -0
- package/dist/native-tools.js +382 -0
- package/dist/node.d.ts +4 -3
- package/dist/node.js +45 -8
- package/dist/oauth-handoff.js +177 -104
- package/dist/oauth-partition.js +6 -20
- package/dist/oauth-sealing.js +6 -7
- package/dist/operation-vocabulary.js +101 -0
- package/dist/operator-record.d.ts +2 -2
- package/dist/operator-record.js +17 -4
- package/dist/operator-ui/agents.d.ts +5 -4
- package/dist/operator-ui/agents.js +17 -7
- package/dist/operator-ui/config-summary.js +5 -4
- package/dist/operator-ui/connection-map.js +7 -5
- package/dist/operator-ui/contract.d.ts +7 -3
- package/dist/operator-ui/endpoints.js +4 -13
- package/dist/operator-ui/fix-prompts.d.ts +1 -1
- package/dist/operator-ui/fix-prompts.js +0 -8
- package/dist/operator-ui/generated.js +3 -3
- package/dist/operator-ui/model.d.ts +2 -3
- package/dist/operator-ui/overview.js +5 -2
- package/dist/operator-ui/setup-commands.js +0 -4
- package/dist/operator-ui/view.d.ts +2 -25
- package/dist/operator-ui/view.js +2 -76
- package/dist/program-writes.js +47 -26
- package/dist/provider-call-facts.d.ts +115 -0
- package/dist/provider-call-facts.js +182 -0
- package/dist/provider-call.d.ts +112 -0
- package/dist/provider-call.js +271 -0
- package/dist/provider.d.ts +65 -31
- package/dist/provider.js +116 -39
- package/dist/providers/_shared/google/hatch.js +91 -0
- package/dist/providers/_shared/google/kit.js +537 -0
- package/dist/providers/_shared/google/result-size.js +15 -2
- package/dist/providers/_shared/google/service-account.d.ts +2 -1
- package/dist/providers/_shared/google/service-account.js +8 -4
- package/dist/providers/_shared/google/workspace.d.ts +6 -210
- package/dist/providers/_shared/google/workspace.js +6 -425
- package/dist/providers/_shared/rest/compact-index.js +86 -0
- package/dist/providers/_shared/rest/dispatch.js +3 -23
- package/dist/providers/_shared/rest/kit.js +546 -0
- package/dist/providers/_shared/rest/operation-index.js +230 -14
- package/dist/providers/_shared/rest/response-media.js +11 -0
- package/dist/providers/_shared/rest/tools.js +101 -78
- package/dist/providers/_shared/rest/value-safety.js +353 -195
- package/dist/providers/_shared/sensitive-fields.js +27 -0
- package/dist/providers/breeze/api.js +584 -0
- package/dist/providers/breeze/index.d.ts +1 -3
- package/dist/providers/breeze/index.js +67 -1420
- package/dist/providers/breeze/openapi.generated.js +60 -0
- package/dist/providers/breeze/skill.generated.js +2 -6
- package/dist/providers/breeze/tools.js +696 -0
- package/dist/providers/ccb/api.js +496 -0
- package/dist/providers/ccb/index.d.ts +15 -37
- package/dist/providers/ccb/index.js +77 -1702
- package/dist/providers/ccb/lib/constants.d.ts +34 -0
- package/dist/providers/ccb/lib/constants.js +74 -0
- package/dist/providers/ccb/lib/guide.js +9 -0
- package/dist/providers/ccb/lib/verdicts.js +387 -0
- package/dist/providers/ccb/openapi.generated.js +397 -0
- package/dist/providers/ccb/safety.js +295 -0
- package/dist/providers/ccb/skill.generated.js +2 -6
- package/dist/providers/ccb/tools.js +853 -0
- package/dist/providers/cloudflare/api.js +1066 -0
- package/dist/providers/cloudflare/index.d.ts +5 -22
- package/dist/providers/cloudflare/index.js +79 -197
- package/dist/providers/cloudflare/lib/config.d.ts +16 -0
- package/dist/providers/cloudflare/lib/config.js +2 -0
- package/dist/providers/cloudflare/lib/discovery.js +29 -0
- package/dist/providers/cloudflare/{graphql.js → lib/graphql.js} +1 -1
- package/dist/providers/cloudflare/lib/hatch.js +103 -0
- package/dist/providers/cloudflare/lib/path-bounds.js +28 -0
- package/dist/providers/cloudflare/lib/response-media.js +75 -0
- package/dist/providers/cloudflare/openapi.generated.js +4 -3
- package/dist/providers/cloudflare/{value-safety.js → safety.js} +487 -0
- package/dist/providers/cloudflare/skill.generated.js +2 -10
- package/dist/providers/cloudflare/tools.js +360 -0
- package/dist/providers/docs/api.js +51 -0
- package/dist/providers/docs/index.d.ts +1 -12
- package/dist/providers/docs/index.js +53 -1165
- package/dist/providers/docs/lib/constants.d.ts +18 -0
- package/dist/providers/docs/lib/constants.js +18 -0
- package/dist/providers/docs/lib/discovery.js +26 -0
- package/dist/providers/docs/lib/requests.js +48 -0
- package/dist/providers/docs/lib/schemas.js +168 -0
- package/dist/providers/docs/openapi.generated.js +16 -0
- package/dist/providers/docs/safety.js +54 -0
- package/dist/providers/docs/skill.generated.js +2 -6
- package/dist/providers/docs/tools.js +802 -0
- package/dist/providers/drive/api.js +177 -0
- package/dist/providers/drive/index.d.ts +1 -12
- package/dist/providers/drive/index.js +38 -1448
- package/dist/providers/drive/lib/constants.d.ts +6 -0
- package/dist/providers/drive/lib/constants.js +6 -0
- package/dist/providers/drive/lib/contracts.js +532 -0
- package/dist/providers/drive/lib/hatch.js +197 -0
- package/dist/providers/drive/openapi.generated.js +77 -0
- package/dist/providers/drive/safety.js +90 -0
- package/dist/providers/drive/skill.generated.js +2 -6
- package/dist/providers/drive/tools.js +1290 -0
- package/dist/providers/forms/api.js +71 -0
- package/dist/providers/forms/index.d.ts +1 -12
- package/dist/providers/forms/index.js +49 -1145
- package/dist/providers/forms/lib/constants.d.ts +14 -0
- package/dist/providers/forms/lib/constants.js +19 -0
- package/dist/providers/forms/lib/hatch.js +72 -0
- package/dist/providers/forms/openapi.generated.js +23 -0
- package/dist/providers/forms/safety.js +34 -0
- package/dist/providers/forms/skill.generated.js +2 -8
- package/dist/providers/forms/tools.js +1024 -0
- package/dist/providers/github/api.js +150 -0
- package/dist/providers/github/index.d.ts +4 -5
- package/dist/providers/github/index.js +30 -87
- package/dist/providers/github/{auth.d.ts → lib/auth.d.ts} +5 -3
- package/dist/providers/github/{auth.js → lib/auth.js} +40 -43
- package/dist/providers/github/lib/discovery.js +132 -0
- package/dist/providers/github/lib/operations.js +58 -0
- package/dist/providers/github/{scope.d.ts → lib/scope.d.ts} +2 -0
- package/dist/providers/github/{scope.js → lib/scope.js} +25 -1
- package/dist/providers/github/openapi.generated.js +1216 -0
- package/dist/providers/github/safety.js +216 -0
- package/dist/providers/github/skill.generated.js +2 -5
- package/dist/providers/github/tools.js +506 -0
- package/dist/providers/gmail/api.js +114 -0
- package/dist/providers/gmail/index.d.ts +1 -12
- package/dist/providers/gmail/index.js +73 -1621
- package/dist/providers/gmail/lib/constants.d.ts +13 -0
- package/dist/providers/gmail/lib/constants.js +16 -0
- package/dist/providers/gmail/lib/index.js +173 -0
- package/dist/providers/gmail/lib/schemas.js +176 -0
- package/dist/providers/gmail/lib/threading.js +120 -0
- package/dist/providers/gmail/openapi.generated.js +92 -0
- package/dist/providers/gmail/safety.js +21 -0
- package/dist/providers/gmail/skill.generated.js +2 -6
- package/dist/providers/gmail/tools.js +1435 -0
- package/dist/providers/overflow/api.js +1008 -0
- package/dist/providers/overflow/index.d.ts +1 -17
- package/dist/providers/overflow/index.js +60 -1488
- package/dist/providers/overflow/skill.generated.js +2 -5
- package/dist/providers/overflow/tools.js +873 -0
- package/dist/providers/planning-center/api.js +467 -0
- package/dist/providers/planning-center/index.d.ts +4 -35
- package/dist/providers/planning-center/index.js +69 -2445
- package/dist/providers/planning-center/lib/constants.d.ts +58 -0
- package/dist/providers/planning-center/lib/constants.js +83 -0
- package/dist/providers/planning-center/lib/discovery.js +40 -0
- package/dist/providers/planning-center/lib/guide.js +39 -0
- package/dist/providers/planning-center/lib/json-api.js +83 -0
- package/dist/providers/planning-center/lib/verdicts.js +1758 -0
- package/dist/providers/planning-center/openapi.generated.js +1764 -0
- package/dist/providers/planning-center/safety.js +188 -0
- package/dist/providers/planning-center/skill.generated.js +2 -27
- package/dist/providers/planning-center/tools.js +1010 -0
- package/dist/providers/sheets/api.js +133 -0
- package/dist/providers/sheets/index.d.ts +4 -16
- package/dist/providers/sheets/index.js +61 -1172
- package/dist/providers/sheets/lib/constants.d.ts +14 -0
- package/dist/providers/sheets/lib/constants.js +14 -0
- package/dist/providers/sheets/lib/hatch.js +163 -0
- package/dist/providers/sheets/lib/requests.js +105 -0
- package/dist/providers/sheets/lib/schemas.js +138 -0
- package/dist/providers/sheets/openapi.generated.js +30 -0
- package/dist/providers/sheets/safety.js +27 -0
- package/dist/providers/sheets/skill.generated.js +2 -7
- package/dist/providers/sheets/tools.js +734 -0
- package/dist/providers/slides/api.js +147 -0
- package/dist/providers/slides/index.d.ts +2 -10
- package/dist/providers/slides/index.js +48 -2555
- package/dist/providers/slides/lib/constants.d.ts +11 -0
- package/dist/providers/slides/lib/constants.js +11 -0
- package/dist/providers/slides/lib/requests.js +60 -0
- package/dist/providers/slides/lib/schemas.js +565 -0
- package/dist/providers/slides/openapi.generated.js +18 -0
- package/dist/providers/slides/skill.generated.js +2 -6
- package/dist/providers/slides/tools.js +1968 -0
- package/dist/providers/stripe/api.js +401 -0
- package/dist/providers/stripe/index.d.ts +5 -27
- package/dist/providers/stripe/index.js +74 -210
- package/dist/providers/stripe/lib/config.d.ts +4 -0
- package/dist/providers/stripe/lib/config.js +2 -0
- package/dist/providers/stripe/openapi.generated.js +4 -3
- package/dist/providers/stripe/{value-safety.js → safety.js} +5 -5
- package/dist/providers/stripe/skill.generated.js +2 -11
- package/dist/providers/stripe/tools.js +77 -0
- package/dist/providers/tithely/api.js +531 -0
- package/dist/providers/tithely/index.d.ts +17 -0
- package/dist/providers/tithely/index.js +86 -965
- package/dist/providers/tithely/skill.generated.js +2 -5
- package/dist/providers/tithely/tools.js +426 -0
- package/dist/providers/vercel/api.js +551 -0
- package/dist/providers/vercel/index.d.ts +9 -25
- package/dist/providers/vercel/index.js +66 -260
- package/dist/providers/vercel/lib/config.d.ts +2 -0
- package/dist/providers/vercel/lib/config.js +2 -0
- package/dist/providers/vercel/lib/index.js +117 -0
- package/dist/providers/vercel/lib/logs.js +100 -0
- package/dist/providers/vercel/lib/pin.js +270 -0
- package/dist/providers/vercel/openapi.generated.js +10 -5
- package/dist/providers/vercel/{value-safety.js → safety.js} +247 -38
- package/dist/providers/vercel/skill.generated.js +2 -7
- package/dist/providers/vercel/tools.js +642 -0
- package/dist/redaction-identity.js +47 -0
- package/dist/redaction-marker.js +125 -0
- package/dist/registry.d.ts +21 -15
- package/dist/registry.js +409 -376
- package/dist/routes/access-tokens.js +1 -1
- package/dist/routes/actor-labels.js +1 -1
- package/dist/routes/connect.js +1 -1
- package/dist/routes/dispatch.js +103 -0
- package/dist/routes/mcp.js +170 -79
- package/dist/routes/oauth.js +3 -1
- package/dist/routes/operator.js +2 -2
- package/dist/routes/shared.d.ts +5 -4
- package/dist/routes/shared.js +244 -177
- package/dist/routes/skills.js +10 -8
- package/dist/routes/ui-config.js +27 -3
- package/dist/routes/ui-data.js +21 -20
- package/dist/routes/ui.js +1 -1
- package/dist/runtime/call-admission.js +0 -26
- package/dist/runtime/call-entry.js +30 -0
- package/dist/runtime/call.js +556 -0
- package/dist/runtime/connector-scope.js +7 -0
- package/dist/runtime/credential-probe.js +34 -0
- package/dist/runtime/executor.js +40 -0
- package/dist/runtime/native-storage.js +63 -0
- package/dist/runtime/registry.js +27 -0
- package/dist/runtime/request-scope.js +72 -0
- package/dist/runtime/run.js +15 -7
- package/dist/runtime/shared-read.js +34 -5
- package/dist/runtime/storage.js +34 -21
- package/dist/sent-secrets.d.ts +194 -37
- package/dist/sent-secrets.js +1743 -340
- package/dist/server.js +5 -56
- package/dist/skills.js +322 -222
- package/dist/sqlite.js +15 -14
- package/dist/storage/d1-copy.js +255 -0
- package/dist/storage/d1-driver.js +15 -0
- package/dist/storage/keys.js +28 -0
- package/dist/storage/sql-driver.js +88 -0
- package/dist/storage/sql-native.js +544 -0
- package/dist/storage/sql-schema.d.ts +6 -0
- package/dist/storage/sql-schema.js +15 -0
- package/dist/storage/sql.d.ts +14 -20
- package/dist/storage/sql.js +29 -535
- package/dist/timeout.js +0 -26
- package/dist/tool-safety.js +20 -10
- package/dist/types.d.ts +7 -109
- package/dist/upward.js +3 -0
- package/dist/usage-guide.js +3 -1
- package/dist/validate.d.ts +4 -2
- package/dist/validate.js +86 -9
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker.js +312 -292
- package/dist/workspace-subject.js +5 -1
- package/dist/write-outcome.js +454 -34
- package/documentation/README.md +27 -7
- package/documentation/architecture.md +2547 -226
- package/documentation/auth.md +821 -98
- package/documentation/code-mode.md +49 -16
- package/documentation/deploying.md +164 -20
- package/documentation/hosted-mcp-migration.md +460 -0
- package/documentation/integrating.md +129 -144
- package/documentation/meta-tools.md +409 -32
- package/documentation/operating.md +27 -3
- package/documentation/operator-tests.md +3 -0
- package/documentation/operator-ui.md +68 -45
- package/documentation/provider-auth-migration.md +16 -63
- package/documentation/provider-migration-0.29.md +10 -5
- package/documentation/provider-migration-0.35.md +975 -0
- package/documentation/providers.md +965 -0
- package/examples/worker/AGENTS.md +23 -9
- package/examples/worker/README.md +254 -135
- package/examples/worker/alchemy.run.ts +116 -0
- package/examples/worker/gitignore +10 -0
- package/examples/worker/src/connecta.config.ts +23 -21
- package/examples/worker/wrangler.jsonc +14 -5
- package/guides/connecting-agents.md +157 -0
- package/guides/how-it-works.md +156 -0
- package/guides/safety-and-trust.md +153 -0
- package/package.json +27 -46
- package/templates/node/.env.example +3 -0
- package/templates/node/README.md +22 -2
- package/templates/node/docker-compose.yml +1 -0
- package/templates/node/package.json +3 -2
- package/templates/node/src/connecta.config.ts +8 -0
- package/dist/catalog-drift.d.ts +0 -138
- package/dist/catalog-drift.js +0 -578
- package/dist/providers/_shared/request-token.js +0 -83
- package/dist/providers/_shared/rest/operation-index.d.ts +0 -133
- package/dist/providers/_shared/rest/tools.d.ts +0 -141
- package/dist/providers/_shared/rest/value-safety.d.ts +0 -201
- package/dist/providers/basecamp/index.d.ts +0 -45
- package/dist/providers/basecamp/index.js +0 -997
- package/dist/providers/basecamp/skill.generated.js +0 -9
- package/dist/providers/cloudflare/rest.d.ts +0 -37
- package/dist/providers/cloudflare/rest.js +0 -1097
- package/dist/providers/github/hosted.js +0 -218
- package/dist/providers/github/rest.js +0 -321
- package/dist/providers/infisical/index.d.ts +0 -7
- package/dist/providers/infisical/index.js +0 -713
- package/dist/providers/infisical/skill.generated.js +0 -8
- package/dist/providers/intercom/index.d.ts +0 -24
- package/dist/providers/intercom/index.js +0 -121
- package/dist/providers/intercom/skill.generated.js +0 -8
- package/dist/providers/linear/index.d.ts +0 -55
- package/dist/providers/linear/index.js +0 -537
- package/dist/providers/linear/skill.generated.js +0 -8
- package/dist/providers/mixpanel/index.d.ts +0 -59
- package/dist/providers/mixpanel/index.js +0 -472
- package/dist/providers/mixpanel/operations.js +0 -20
- package/dist/providers/mixpanel/rest.js +0 -603
- package/dist/providers/mixpanel/skill.generated.js +0 -10
- package/dist/providers/mixpanel/value-safety.js +0 -16
- package/dist/providers/notion/index.d.ts +0 -67
- package/dist/providers/notion/index.js +0 -368
- package/dist/providers/notion/openapi.generated.js +0 -75
- package/dist/providers/notion/rest.d.ts +0 -24
- package/dist/providers/notion/rest.js +0 -1226
- package/dist/providers/notion/skill.generated.js +0 -11
- package/dist/providers/notion/value-safety.js +0 -56
- package/dist/providers/revenuecat/index.d.ts +0 -51
- package/dist/providers/revenuecat/index.js +0 -697
- package/dist/providers/revenuecat/skill.generated.js +0 -11
- package/dist/providers/stripe/rest.d.ts +0 -14
- package/dist/providers/stripe/rest.js +0 -402
- package/dist/providers/vercel/rest.d.ts +0 -20
- package/dist/providers/vercel/rest.js +0 -1020
- package/dist/providers/wispr-flow/index.d.ts +0 -14
- package/dist/providers/wispr-flow/index.js +0 -117
- package/dist/providers/wispr-flow/skill.generated.js +0 -8
- /package/dist/providers/github/{key.js → lib/key.js} +0 -0
package/README.md
CHANGED
|
@@ -2,137 +2,93 @@
|
|
|
2
2
|
|
|
3
3
|
**One connection between your agent and the services you choose.**
|
|
4
4
|
|
|
5
|
-
Connecta puts
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
## How it works
|
|
5
|
+
Connecta puts the services your agent needs behind one connection. It uses
|
|
6
|
+
**Model Context Protocol (MCP)**, a standard that lets AI apps use tools.
|
|
7
|
+
You run Connecta and choose what each agent may access.
|
|
9
8
|
|
|
10
9
|
```mermaid
|
|
11
10
|
flowchart LR
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Sandbox["Sandbox<br/>runs the agent's short programs"]
|
|
16
|
-
Keys["Credentials<br/>stay on the server"]
|
|
11
|
+
Agents["Agent apps and people"] --> Pools
|
|
12
|
+
subgraph Connecta["Your Connecta server"]
|
|
13
|
+
Pools["Pools<br/>which tools each caller can use"] --> Checks["Access checks<br/>reads · changes · secrets"]
|
|
17
14
|
end
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Connecta <--> Yours["Any remote MCP server<br/>or HTTP API"]
|
|
22
|
-
|
|
23
|
-
style Connecta fill:#e0e7ff,stroke:#4338ca,color:#1e1b4b,stroke-width:2px
|
|
15
|
+
Checks --> Stripe
|
|
16
|
+
Checks --> Google["Google Workspace"]
|
|
17
|
+
Checks --> Other["Other services"]
|
|
24
18
|
```
|
|
25
19
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
20
|
+
A tool is an action, such as finding a ticket or updating a record. The agent
|
|
21
|
+
can call one action directly or combine several in a short program inside
|
|
22
|
+
Connecta. The program can return a small answer instead of every record.
|
|
23
|
+
Connecta supplies the service credentials, so the agent doesn't need them.
|
|
29
24
|
|
|
30
25
|
## What you can connect
|
|
31
26
|
|
|
32
|
-
Maintained connections: <!-- providers:start -->
|
|
33
|
-
Plus any remote MCP server or HTTP API you describe.
|
|
34
|
-
|
|
35
|
-
## Who can use it
|
|
27
|
+
Maintained connections: <!-- providers:start -->Breeze ChMS, Church Community Builder, Cloudflare, GitHub, Gmail, Google Docs, Google Drive, Google Forms, Google Sheets, Google Slides, Overflow, Planning Center, Stripe, Tithe.ly, and Vercel<!-- providers:end -->.
|
|
36
28
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
| How they prove it | Sign in: Clerk (Node) or Cloudflare Access (Workers) | One token Connecta issues to that agent |
|
|
41
|
-
| Their own logins | Yes, on personal connections | No. An agent uses accounts you assign it |
|
|
29
|
+
You can also connect another hosted MCP tool server, or describe an API
|
|
30
|
+
Connecta should call. Hosted connections use the server's current tools;
|
|
31
|
+
maintained integrations come with tools built by Connecta.
|
|
42
32
|
|
|
43
|
-
|
|
44
|
-
and manage credentials and agent tokens. Everyone else reaches only the pools
|
|
45
|
-
they are listed in.
|
|
33
|
+
## What it protects
|
|
46
34
|
|
|
47
|
-
|
|
35
|
+
| Boundary | What Connecta does |
|
|
36
|
+
| ---------------- | ------------------------------------------------------------------------------------------------------------------------- |
|
|
37
|
+
| Access | A pool limits the tools its members can reach. |
|
|
38
|
+
| Writes | For tools marked as writes, once a change is sent, Connecta won't automatically send it again. |
|
|
39
|
+
| Secrets | Known secrets are redacted from agent output. Enable the credential vault to encrypt stored credentials and OAuth tokens. |
|
|
40
|
+
| Read-only access | Read-only endpoints hide writes and refuse attempts to call them. |
|
|
48
41
|
|
|
49
|
-
|
|
50
|
-
|
|
42
|
+
Read-only protection and single-attempt writes depend on truthful tool labels.
|
|
43
|
+
The AI app using Connecta decides when to ask for approval; a writable pool
|
|
44
|
+
can write unattended. [Safety and trust](./guides/safety-and-trust.md)
|
|
45
|
+
explains these boundaries and their limits.
|
|
51
46
|
|
|
52
|
-
|
|
53
|
-
flowchart LR
|
|
54
|
-
Maint["Maintainer<br/>(signs in)"] --> Main["/mcp<br/>every tool"]
|
|
55
|
-
Bob["Bob<br/>(signs in)"] --> Team["/mcp/team<br/>CRM + tickets"]
|
|
56
|
-
Bot["assistant agent<br/>(token)"] --> AgentPool["/agent/assistant<br/>CRM + tickets"]
|
|
47
|
+
## Try it in three steps
|
|
57
48
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
```
|
|
49
|
+
You'll need somewhere to run Connecta and permission to connect the service
|
|
50
|
+
accounts you choose. Creating the project is the start of setup; account
|
|
51
|
+
connections and access rules still need configuring.
|
|
62
52
|
|
|
63
|
-
|
|
64
|
-
outside a pool gets the same "not found" as a pool that doesn't exist, and
|
|
65
|
-
someone in two pools uses two addresses: pools never merge.
|
|
53
|
+
1. **Create a deployment.** Start with the Node template:
|
|
66
54
|
|
|
67
|
-
|
|
55
|
+
```sh
|
|
56
|
+
npx @zackbart/connecta init my-connecta
|
|
57
|
+
cd my-connecta
|
|
58
|
+
npm install
|
|
59
|
+
```
|
|
68
60
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
61
|
+
2. **Choose services and access.** Your operator—the person or team running
|
|
62
|
+
Connecta—can use a coding assistant as a setup agent. Give that assistant
|
|
63
|
+
the [operator documentation](./documentation/README.md). It configures
|
|
64
|
+
services, enables the credential vault, connects accounts, and starts
|
|
65
|
+
the server with the access rules you choose.
|
|
66
|
+
3. **Connect your AI app.** This app is the MCP client: it uses Connecta's
|
|
67
|
+
tools on your agent's behalf. Give it the pool address and authentication
|
|
68
|
+
method supplied by your operator. [Connecting agents](./guides/connecting-agents.md)
|
|
69
|
+
explains what to ask for; the [deployment guide](./documentation/deploying.md)
|
|
70
|
+
has runnable steps.
|
|
73
71
|
|
|
74
72
|
```mermaid
|
|
75
73
|
flowchart LR
|
|
76
|
-
|
|
77
|
-
Group["Chat of team members"] --> TeamTier["/agent/assistant-team<br/>shared tools"]
|
|
78
|
-
Leads["Chat of leads only"] --> LeadsTier["/agent/assistant-leads<br/>shared tools + billing"]
|
|
79
|
-
Alice["One-on-one<br/>with Alice"] --> PA["/agent/assistant-alice<br/>her tier + her accounts"]
|
|
80
|
-
|
|
81
|
-
Base -.-> TeamTier -.-> LeadsTier
|
|
82
|
-
|
|
83
|
-
style Base fill:#e0e7ff,stroke:#4338ca,color:#1e1b4b
|
|
84
|
-
style TeamTier fill:#e0e7ff,stroke:#4338ca,color:#1e1b4b
|
|
85
|
-
style LeadsTier fill:#e0e7ff,stroke:#4338ca,color:#1e1b4b
|
|
86
|
-
style PA fill:#dcfce7,stroke:#15803d,color:#14532d
|
|
74
|
+
Create["1 · Create"] --> Configure["2 · Choose services + access"] --> Connect["3 · Connect your AI app"]
|
|
87
75
|
```
|
|
88
76
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
the people cleared for it. [Organizing an agent's pools](./documentation/auth.md#organizing-an-agents-pools)
|
|
93
|
-
has the full layout.
|
|
77
|
+
The package is `@zackbart/connecta` (`npm install @zackbart/connecta`). Run it
|
|
78
|
+
on Node, in Docker, or on Cloudflare Workers. The
|
|
79
|
+
[deployment guide](./documentation/deploying.md#choose-a-deployment) covers each.
|
|
94
80
|
|
|
95
|
-
|
|
81
|
+
## Read a little more
|
|
96
82
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
-
|
|
100
|
-
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
## Reads and writes
|
|
105
|
-
|
|
106
|
-
Every endpoint is writable or read-only, and you choose explicitly. A
|
|
107
|
-
read-only endpoint hides write tools and refuses every write. You can also make
|
|
108
|
-
one connection read-only across all endpoints. On a writable
|
|
109
|
-
one, your agent's host decides what to approve.
|
|
110
|
-
|
|
111
|
-
## Where it runs
|
|
112
|
-
|
|
113
|
-
Node or Docker (Clerk sign-in, SQLite) or Cloudflare Workers (Cloudflare
|
|
114
|
-
Access, D1). Both serve the same agent tools. An optional operator UI shows
|
|
115
|
-
a connection map, endpoints, connectors, and activity; integrations and access
|
|
116
|
-
still change only in deployment code.
|
|
117
|
-
|
|
118
|
-
## Getting started
|
|
119
|
-
|
|
120
|
-
Give your agent the [agent documentation](./documentation/README.md) and ask
|
|
121
|
-
it to set up Connecta with the integrations you want, where to run it, and who
|
|
122
|
-
should have access.
|
|
83
|
+
| Guide | What you'll understand |
|
|
84
|
+
| --------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
85
|
+
| [How it works](./guides/how-it-works.md) | Connectors, pools, people, and how a call reaches a service. |
|
|
86
|
+
| [Connecting agents](./guides/connecting-agents.md) | Agent tokens, Vercel identity, and the optional Eve helper. |
|
|
87
|
+
| [Safety and trust](./guides/safety-and-trust.md) | Uncertain changes, secrets, read-only access, and your responsibilities. |
|
|
88
|
+
| [Operator documentation](./documentation/README.md) | Setup, feature availability, upgrades, and exact contracts. |
|
|
123
89
|
|
|
124
90
|
<a id="existing-client-tokens"></a>
|
|
125
91
|
|
|
126
|
-
Upgrading?
|
|
127
|
-
[
|
|
128
|
-
|
|
129
|
-
## Status
|
|
130
|
-
|
|
131
|
-
Built for its author's deployments first and published openly. Breaking
|
|
132
|
-
changes are expected before 1.0. See the [changelog](./CHANGELOG.md) and
|
|
133
|
-
[security policy](./SECURITY.md).
|
|
134
|
-
|
|
135
|
-
[Principles](https://github.com/zackbart/connecta/blob/main/PRINCIPLES.md) ·
|
|
136
|
-
[Decision records](https://github.com/zackbart/connecta/tree/main/decisions) ·
|
|
137
|
-
[Planned work](https://github.com/zackbart/connecta/issues) (a plan is not a
|
|
138
|
-
shipped feature)
|
|
92
|
+
Upgrading? Follow the [upgrade guide](./documentation/deploying.md#upgrade-an-existing-deployment).
|
|
93
|
+
Breaking changes are expected before 1.0. See the [changelog](./CHANGELOG.md)
|
|
94
|
+
and [security policy](./SECURITY.md).
|
package/SECURITY.md
CHANGED
|
@@ -17,8 +17,9 @@ findings are reviewed for reachability and recorded when an upstream package has
|
|
|
17
17
|
not yet released a compatible fix.
|
|
18
18
|
|
|
19
19
|
The MCP TypeScript SDK 2.x packages and Effect are exact-pinned. Effect is the
|
|
20
|
-
runtime core, and its
|
|
21
|
-
|
|
20
|
+
runtime core, and its `effect/http`, `effect/http-api`, and `effect/sql` area
|
|
21
|
+
modules carry `@stability unstable` within the 4.x LTS line, so its pin moves
|
|
22
|
+
in a dedicated upgrade. The split client and server packages no longer
|
|
22
23
|
install Hono or `@hono/node-server`, so the temporary root-project override
|
|
23
24
|
used with SDK 1.x is gone. A dependency bump must pass `pnpm run release:check`
|
|
24
25
|
and the Node/Workers runtime suites before a pin moves.
|
package/bin/connecta.mjs
CHANGED
|
@@ -244,32 +244,57 @@ async function doctor() {
|
|
|
244
244
|
fetch: doctorFetch,
|
|
245
245
|
});
|
|
246
246
|
let negotiatedVersion;
|
|
247
|
+
let native = false;
|
|
248
|
+
let executeCode = true;
|
|
247
249
|
try {
|
|
248
250
|
await client.connect(transport);
|
|
249
251
|
negotiatedVersion = client.getNegotiatedProtocolVersion();
|
|
250
252
|
const listed = await client.listTools({}, { timeout: DOCTOR_TIMEOUT_MS });
|
|
251
253
|
const actual = listed.tools.map((tool) => tool.name).sort();
|
|
252
|
-
const
|
|
253
|
-
|
|
254
|
+
const surface = listed.tools.find((tool) => tool.name === "skills")?._meta?.["dev.connecta/surface"];
|
|
255
|
+
native = surface?.surface === "native";
|
|
256
|
+
executeCode = !native || surface.executeCode === true;
|
|
257
|
+
if (native && surface.catalogErrors?.length)
|
|
258
|
+
throw new Error(
|
|
259
|
+
`Native catalogs unavailable: ${surface.catalogErrors.join(", ")}. Inspect connector status and authentication.`,
|
|
260
|
+
);
|
|
261
|
+
const expected = native
|
|
262
|
+
? ["skills", executeCode ? "execute_code" : "read_result"].sort()
|
|
263
|
+
: [...META_TOOL_NAMES].sort();
|
|
264
|
+
if (
|
|
265
|
+
native
|
|
266
|
+
? expected.some((name) => !actual.includes(name)) ||
|
|
267
|
+
[
|
|
268
|
+
"search_tools",
|
|
269
|
+
"call_tool",
|
|
270
|
+
"call_destructive_tool",
|
|
271
|
+
"authorize_connector",
|
|
272
|
+
executeCode ? "read_result" : "execute_code",
|
|
273
|
+
].some((name) => actual.includes(name))
|
|
274
|
+
: JSON.stringify(actual) !== JSON.stringify(expected)
|
|
275
|
+
) {
|
|
254
276
|
throw new Error(
|
|
255
277
|
`Unexpected MCP surface. Expected ${expected.join(", ")}; received ` +
|
|
256
278
|
`${Array.isArray(actual) ? actual.join(", ") : "no tool list"}.`,
|
|
257
279
|
);
|
|
258
280
|
}
|
|
259
281
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
const executionResult = executed.structuredContent ?? JSON.parse(executed.content?.[0]?.text ?? "null");
|
|
269
|
-
if (executed.isError || executionResult?.result !== 42) {
|
|
270
|
-
throw new Error(
|
|
271
|
-
`${executorName ? `${executorName} execution` : "execute_code"} check ` + `failed: ${JSON.stringify(executed)}`,
|
|
282
|
+
if (executeCode) {
|
|
283
|
+
const executed = await client.callTool(
|
|
284
|
+
{
|
|
285
|
+
name: "execute_code",
|
|
286
|
+
arguments: { code: "async () => 42" },
|
|
287
|
+
},
|
|
288
|
+
undefined,
|
|
289
|
+
{ timeout: DOCTOR_TIMEOUT_MS },
|
|
272
290
|
);
|
|
291
|
+
const executionResult = executed.structuredContent ?? JSON.parse(executed.content?.[0]?.text ?? "null");
|
|
292
|
+
if (executed.isError || executionResult?.result !== 42) {
|
|
293
|
+
throw new Error(
|
|
294
|
+
`${executorName ? `${executorName} execution` : "execute_code"} check ` +
|
|
295
|
+
`failed: ${JSON.stringify(executed)}`,
|
|
296
|
+
);
|
|
297
|
+
}
|
|
273
298
|
}
|
|
274
299
|
} finally {
|
|
275
300
|
await client.close();
|
|
@@ -277,8 +302,8 @@ async function doctor() {
|
|
|
277
302
|
|
|
278
303
|
console.log(
|
|
279
304
|
`Connecta doctor passed: ${health.connectors} connector(s), ` +
|
|
280
|
-
`${executorName ? `${executorName} executed` : "code executed"}, ` +
|
|
281
|
-
`prescribed ${META_TOOL_NAMES.length}-tool surface, MCP ${negotiatedVersion}, package ${CONNECTA_VERSION}.`,
|
|
305
|
+
`${executeCode ? (executorName ? `${executorName} executed` : "code executed") : "code disabled"}, ` +
|
|
306
|
+
`${native ? "native tool surface" : `prescribed ${META_TOOL_NAMES.length}-tool surface`}, MCP ${negotiatedVersion}, package ${CONNECTA_VERSION}.`,
|
|
282
307
|
);
|
|
283
308
|
}
|
|
284
309
|
|
package/bin/version.mjs
CHANGED
package/dist/access-tokens.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { InboundAuth, KVStorage } from "./types.js";
|
|
2
2
|
import type { AccessTokensModule } from "./module-contracts.js";
|
|
3
|
+
import { type AgentConfig } from "./agent-config.js";
|
|
3
4
|
/**
|
|
4
5
|
* One declared agent's token slot as management sees it. Never secret
|
|
5
6
|
* material. `revision` is opaque: it changes on every commit to the slot and
|
|
@@ -69,7 +70,7 @@ export declare class AccessTokenManager {
|
|
|
69
70
|
private readonly agents;
|
|
70
71
|
private readonly agentOrder;
|
|
71
72
|
constructor(storage: KVStorage, options?: {
|
|
72
|
-
agents?: readonly
|
|
73
|
+
agents?: readonly AgentConfig[];
|
|
73
74
|
});
|
|
74
75
|
private declared;
|
|
75
76
|
private read;
|
package/dist/access-tokens.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import { withAuthenticationDeadline } from "./auth-admission.js";
|
|
1
2
|
import { authorizationCredential, isMachineCredential } from "./inbound-credential.js";
|
|
2
|
-
import { assertKnownOptions, ConfigError, optionsOf } from "./config-schema.js";
|
|
3
|
+
import { assertKnownOptions, ConfigError, optionsOf, readPlain } from "./config-schema.js";
|
|
3
4
|
import { routeAccessTokens } from "./routes/access-tokens.js";
|
|
4
5
|
import { validIdentityReference } from "./identity.js";
|
|
5
6
|
import { accessTokenKeys } from "./storage/keys.js";
|
|
6
|
-
import { AGENT_NAMESPACE, agentSubjectId,
|
|
7
|
+
import { AGENT_NAMESPACE, agentSubjectId, isAgentName, trustAgentProvider } from "./agent-identity.js";
|
|
8
|
+
import { keepErrorName } from "./redaction-identity.js";
|
|
9
|
+
import { agentConfig } from "./agent-config.js";
|
|
10
|
+
import { authCall, authCatch, authFlow, authInvoke, authMethod, authOwnMethod, authStorage, registerAuthMethod, } from "./auth/native.js";
|
|
11
|
+
import { runEdge } from "./runtime/run.js";
|
|
7
12
|
const TOKEN_PREFIX = "cta_";
|
|
8
13
|
const TOKEN_BYTES = 32;
|
|
9
14
|
const TOKEN_VALUE_RE = /^cta_[A-Za-z0-9_-]{43}$/;
|
|
@@ -31,6 +36,7 @@ export class AccessTokenError extends Error {
|
|
|
31
36
|
this.code = code;
|
|
32
37
|
}
|
|
33
38
|
}
|
|
39
|
+
keepErrorName(AccessTokenError, "AccessTokenError");
|
|
34
40
|
/** What each operation tells its caller when its outcome cannot be settled. */
|
|
35
41
|
const UNKNOWN = {
|
|
36
42
|
rotate: "Rotation outcome unknown: no secret was returned, so rotate again for a replacement",
|
|
@@ -251,8 +257,10 @@ export class AccessTokenManager {
|
|
|
251
257
|
throw new Error("accessTokens requires storage that implements list and compareAndSet " +
|
|
252
258
|
"(d1Storage, sqliteStorage, or memoryStorage)");
|
|
253
259
|
}
|
|
254
|
-
const
|
|
255
|
-
|
|
260
|
+
const input = readPlain(options.agents ?? [], "agents", agentConfig);
|
|
261
|
+
if (input.unknown.length)
|
|
262
|
+
throw new ConfigError("agents contains unknown declaration options.");
|
|
263
|
+
const agents = agentConfig.parse(input.value, "agents").map((agent) => agent.name);
|
|
256
264
|
this.agentOrder = Object.freeze([...agents]);
|
|
257
265
|
this.agents = new Set(agents);
|
|
258
266
|
this.auth = trustAgentProvider({
|
|
@@ -270,7 +278,7 @@ export class AccessTokenManager {
|
|
|
270
278
|
return undefined;
|
|
271
279
|
}
|
|
272
280
|
},
|
|
273
|
-
authorize: (request) => this
|
|
281
|
+
authorize: authMethod((request) => authCatch(authInvoke(this, "authorize", [request]), unauthorized)),
|
|
274
282
|
});
|
|
275
283
|
}
|
|
276
284
|
declared(name) {
|
|
@@ -779,31 +787,59 @@ export class AccessTokenManager {
|
|
|
779
787
|
.sort((a, b) => a.createdAt.localeCompare(b.createdAt))
|
|
780
788
|
.map(({ id, name, createdAt }) => ({ id, name, createdAt }));
|
|
781
789
|
}
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
790
|
+
authorize(request) {
|
|
791
|
+
return runEdge(authOwnMethod(AccessTokenManager.prototype, this, "authorize", [request]));
|
|
792
|
+
}
|
|
793
|
+
static {
|
|
794
|
+
registerAuthMethod(AccessTokenManager.prototype, "authorize", function (request) {
|
|
795
|
+
return authFlow(function* () {
|
|
796
|
+
const credential = authorizationCredential(request);
|
|
797
|
+
const token = credential.kind === "bearer" ? credential.token : undefined;
|
|
798
|
+
if (!token || !TOKEN_VALUE_RE.test(token))
|
|
799
|
+
return unauthorized();
|
|
800
|
+
return (yield authCall(withAuthenticationDeadline, [
|
|
801
|
+
request,
|
|
802
|
+
authMethod((signal) => {
|
|
803
|
+
return authFlow(function* () {
|
|
804
|
+
signal.throwIfAborted();
|
|
805
|
+
const hash = (yield authCall(hashToken, [token]));
|
|
806
|
+
signal.throwIfAborted();
|
|
807
|
+
const lookupRaw = (yield authStorage(this.storage, "get", [lookupKey(hash)]));
|
|
808
|
+
signal.throwIfAborted();
|
|
809
|
+
if (!lookupRaw)
|
|
810
|
+
return unauthorized();
|
|
811
|
+
const lookup = parseLookup(lookupRaw);
|
|
812
|
+
if (!lookup)
|
|
813
|
+
return unauthorized();
|
|
814
|
+
const recordRaw = ID_RE.test(lookup.id)
|
|
815
|
+
? (yield authStorage(this.storage, "get", [recordKey(lookup.id)]))
|
|
816
|
+
: null;
|
|
817
|
+
const record = recordRaw ? parseRecord(recordRaw) : null;
|
|
818
|
+
if (record && record.id !== lookup.id)
|
|
819
|
+
throw new Error("Stored access token id mismatch");
|
|
820
|
+
signal.throwIfAborted();
|
|
821
|
+
if (!record ||
|
|
822
|
+
record.revokedAt ||
|
|
823
|
+
record.tokenHash !== hash ||
|
|
824
|
+
record.tokenPrefix !== token.slice(0, 12)) {
|
|
825
|
+
return unauthorized();
|
|
826
|
+
}
|
|
827
|
+
// The slot is the authority: a surviving lookup or record it does not
|
|
828
|
+
// name is inert. Human-bound and unbound records, and agents no longer in
|
|
829
|
+
// code, refuse exactly as an unknown token does.
|
|
830
|
+
if (record.principal || record.agent === undefined || !this.agents.has(record.agent))
|
|
831
|
+
return unauthorized();
|
|
832
|
+
const slotRaw = (yield authStorage(this.storage, "get", [slotKey(record.agent)]));
|
|
833
|
+
const slot = slotRaw === null ? null : parseSlot(slotRaw, record.agent);
|
|
834
|
+
signal.throwIfAborted();
|
|
835
|
+
if (slot?.state !== "issued" || slot.tokenId !== record.id)
|
|
836
|
+
return unauthorized();
|
|
837
|
+
return { ok: true, subjectId: agentSubjectId(record.agent), agent: record.agent };
|
|
838
|
+
}.bind(this));
|
|
839
|
+
}),
|
|
840
|
+
]));
|
|
841
|
+
}.bind(this));
|
|
842
|
+
}, AccessTokenManager.prototype.authorize);
|
|
807
843
|
}
|
|
808
844
|
}
|
|
809
845
|
const ACCESS_TOKENS_OPTIONS = optionsOf()({});
|
package/dist/activity.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { Logger } from "./types.js";
|
|
|
5
5
|
export declare function activityClientFact(value: unknown, field: "name" | "version"): string | undefined;
|
|
6
6
|
/** Stored package versions use a bounded release-version grammar, including prereleases. */
|
|
7
7
|
export declare function activityPackageVersion(value: unknown): string | undefined;
|
|
8
|
-
export type ActivityCallSource = "catalog_refresh" | "call_tool" | "call_destructive_tool" | "batch_call" | "execute_code" | "resume_execution";
|
|
8
|
+
export type ActivityCallSource = "catalog_refresh" | "native" | "call_tool" | "call_destructive_tool" | "batch_call" | "execute_code" | "resume_execution";
|
|
9
9
|
export type ActivityOutcome = "success" | "error" | "timeout" | "cancelled" | "paused" | "approved";
|
|
10
10
|
/** Read-only history: how much one `resume_execution` approved (#672). */
|
|
11
11
|
export type ActivityApproval = "call" | "tool";
|
package/dist/activity.js
CHANGED
|
@@ -3,6 +3,7 @@ import { assertKnownOptions, keys, optionsOf } from "./config-schema.js";
|
|
|
3
3
|
import { routeActivity } from "./routes/activity.js";
|
|
4
4
|
import { boundedEchoText, classificationCode } from "./errors.js";
|
|
5
5
|
import { failureRecord, logFailure } from "./operator-record.js";
|
|
6
|
+
import { keepErrorName } from "./redaction-identity.js";
|
|
6
7
|
/**
|
|
7
8
|
* How long an identity field may be before the store stops believing it.
|
|
8
9
|
*
|
|
@@ -91,6 +92,7 @@ export class InvalidActivityCursorError extends Error {
|
|
|
91
92
|
super("invalid activity cursor");
|
|
92
93
|
}
|
|
93
94
|
}
|
|
95
|
+
keepErrorName(InvalidActivityCursorError, "InvalidActivityCursorError");
|
|
94
96
|
/**
|
|
95
97
|
* Best-effort by design: activity storage can never change a tool result.
|
|
96
98
|
* Workers attach async sinks to waitUntil; synchronous sinks such as Analytics
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type Field } from "./config-schema.js";
|
|
2
|
+
type VercelEnvironment = "production" | "preview" | "development";
|
|
3
|
+
/** Vercel workload binding: immutable team_ ID; prefer a prj_ project ID. */
|
|
4
|
+
interface VercelAgentCredential {
|
|
5
|
+
team: string;
|
|
6
|
+
project: string;
|
|
7
|
+
environments?: readonly VercelEnvironment[] | undefined;
|
|
8
|
+
}
|
|
9
|
+
/** A string keeps the existing token-only declaration. */
|
|
10
|
+
export type AgentConfig = string | {
|
|
11
|
+
name: string;
|
|
12
|
+
vercel: VercelAgentCredential;
|
|
13
|
+
};
|
|
14
|
+
export interface ResolvedAgent {
|
|
15
|
+
readonly name: string;
|
|
16
|
+
readonly vercel?: {
|
|
17
|
+
readonly team: string;
|
|
18
|
+
readonly project: string;
|
|
19
|
+
readonly environments: readonly VercelEnvironment[];
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export declare const agentConfig: Field<readonly AgentConfig[], readonly ResolvedAgent[], true>;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { assertAgentNames } from "./agent-identity.js";
|
|
2
|
+
import { array, ConfigError, object, opaque, required, text } from "./config-schema.js";
|
|
3
|
+
const segment = (kind) => required(opaque({
|
|
4
|
+
check(value, path) {
|
|
5
|
+
const pattern = kind === "team" ? /^team_[A-Za-z0-9]+(?![\s\S])/ : /^[A-Za-z0-9._-]+(?![\s\S])/;
|
|
6
|
+
if (typeof value !== "string" || value.length > 128 || !pattern.test(value)) {
|
|
7
|
+
throw new ConfigError(`${path} must be ${kind === "team" ? "an immutable Vercel team_ ID" : "an exact Vercel project ID or name"}.`);
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
}));
|
|
11
|
+
const environments = opaque({
|
|
12
|
+
check(value, path) {
|
|
13
|
+
if (!Array.isArray(value) ||
|
|
14
|
+
value.length === 0 ||
|
|
15
|
+
value.some((env) => !["production", "preview", "development"].includes(env)) ||
|
|
16
|
+
new Set(value).size !== value.length) {
|
|
17
|
+
throw new ConfigError(`${path} must list unique production, preview or development environments.`);
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
resolve: (value) => Object.freeze([...(value ?? ["production"])]),
|
|
21
|
+
});
|
|
22
|
+
const declaration = object({
|
|
23
|
+
name: required(text()),
|
|
24
|
+
vercel: required(object({ team: segment("team"), project: segment("project"), environments })),
|
|
25
|
+
});
|
|
26
|
+
const entry = {
|
|
27
|
+
...declaration,
|
|
28
|
+
optional: false,
|
|
29
|
+
parse: (value, path) => (typeof value === "string" ? Object.freeze({ name: value }) : declaration.parse(value, path)),
|
|
30
|
+
absent: (path) => {
|
|
31
|
+
throw new ConfigError(`${path} must declare an agent.`);
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
const list = array(entry);
|
|
35
|
+
export const agentConfig = {
|
|
36
|
+
...list,
|
|
37
|
+
parse(value, path) {
|
|
38
|
+
const agents = list.parse(value, path);
|
|
39
|
+
assertAgentNames(agents.map((agent) => agent.name), path);
|
|
40
|
+
for (let i = 0; i < agents.length; i++) {
|
|
41
|
+
const a = agents[i].vercel;
|
|
42
|
+
if (!a)
|
|
43
|
+
continue;
|
|
44
|
+
for (const prior of agents.slice(0, i)) {
|
|
45
|
+
const b = prior.vercel;
|
|
46
|
+
// A project name and an ID can designate the same project. Refuse possible
|
|
47
|
+
// overlap rather than let declaration order select another identity.
|
|
48
|
+
if (b &&
|
|
49
|
+
a.team === b.team &&
|
|
50
|
+
(a.project === b.project || a.project.startsWith("prj_") !== b.project.startsWith("prj_")) &&
|
|
51
|
+
a.environments.some((env) => b.environments.includes(env))) {
|
|
52
|
+
throw new ConfigError(`${path}[${i}].vercel overlaps another agent's workload binding.`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return agents;
|
|
57
|
+
},
|
|
58
|
+
absent: () => Object.freeze([]),
|
|
59
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const empty = Object.freeze([]);
|
|
2
|
+
const descriptions = new WeakMap();
|
|
3
|
+
export function registerAgentDescriptions(config, agents, tokens) {
|
|
4
|
+
if (descriptions.has(config))
|
|
5
|
+
return;
|
|
6
|
+
descriptions.set(config, Object.freeze(agents.map((agent) => Object.freeze({
|
|
7
|
+
name: agent.name,
|
|
8
|
+
credentialTypes: Object.freeze([
|
|
9
|
+
...(tokens ? ["access_token"] : []),
|
|
10
|
+
...(agent.vercel ? ["vercel_oidc"] : []),
|
|
11
|
+
]),
|
|
12
|
+
}))));
|
|
13
|
+
}
|
|
14
|
+
export function agentDescriptions(config) {
|
|
15
|
+
return descriptions.get(config) ?? empty;
|
|
16
|
+
}
|
package/dist/agent-identity.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Code-declared agents (#837): the names deployment code lists in `agents`,
|
|
2
|
-
// the identity an admitted agent carries, and the
|
|
3
|
-
// assert it. Pure, so core reads it without reaching
|
|
2
|
+
// the identity an admitted agent carries, and the built-in providers trusted
|
|
3
|
+
// to assert it. Pure, so core reads it without reaching credential modules.
|
|
4
4
|
import { ConfigError } from "./config-schema.js";
|
|
5
5
|
/** Agent names: lowercase letters, digits, `_` and `-`. */
|
|
6
6
|
const AGENT_NAME_RE = /^[a-z0-9_-]+$/u;
|
|
@@ -36,12 +36,12 @@ export function assertAgentNames(value, path) {
|
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
38
|
const agentProviders = new WeakSet();
|
|
39
|
-
/** Mark
|
|
39
|
+
/** Mark a built-in credential adapter as trusted to assert `agent`. */
|
|
40
40
|
export function trustAgentProvider(provider) {
|
|
41
41
|
agentProviders.add(provider);
|
|
42
42
|
return provider;
|
|
43
43
|
}
|
|
44
|
-
/** Whether `provider` is
|
|
44
|
+
/** Whether `provider` is a trusted built-in agent credential adapter. */
|
|
45
45
|
export function assertsAgents(provider) {
|
|
46
46
|
return agentProviders.has(provider);
|
|
47
47
|
}
|