@zackbart/connecta 0.37.1 → 0.39.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 +94 -0
- package/README.md +5 -4
- package/bin/connecta.mjs +1 -39
- package/bin/version.mjs +1 -1
- package/dist/access-tokens.js +2 -4
- package/dist/agent-identity.js +1 -1
- package/dist/agent-routes.js +231 -0
- package/dist/auth/clerk-sdk/generated.js +2 -1
- package/dist/auth/downstream-oauth/consent.js +519 -0
- package/dist/auth/downstream-oauth/grant-store.js +439 -0
- package/dist/auth/downstream-oauth/refresh-coordinator.js +562 -0
- package/dist/auth/downstream-oauth/refresh-records.js +447 -0
- package/dist/auth/downstream-oauth/sdk-hooks.js +242 -0
- package/dist/auth/downstream-oauth.js +66 -2516
- package/dist/auth/downstream-revocation.js +1 -1
- package/dist/auth/native.js +27 -0
- package/dist/auth/oauth-grant.js +24 -0
- package/dist/auth/oauth-token-response.js +1 -1
- package/dist/auth/static-oauth.js +153 -131
- package/dist/auth/vercel-agent.js +2 -1
- package/dist/auth-elicitation.js +9 -3
- package/dist/authorization-handoff.js +11 -5
- package/dist/branding.d.ts +1 -15
- package/dist/branding.js +2 -2
- package/dist/bytes.js +42 -0
- package/dist/call-admission-context.js +2 -5
- package/dist/call-recovery.js +0 -3
- package/dist/catalog-cache.js +130 -43
- package/dist/catalog-fingerprint.js +2 -18
- package/dist/catalog-policy.js +18 -0
- package/dist/catalog-service.js +285 -48
- package/dist/catalog.js +18 -2
- package/dist/config-defaults.d.ts +1 -0
- package/dist/config-defaults.js +1 -0
- package/dist/config-schema.d.ts +1 -1
- package/dist/config-schema.js +6 -2
- package/dist/config.d.ts +57 -25
- package/dist/config.js +30 -77
- package/dist/connector-caller.d.ts +1 -1
- package/dist/connector-health.js +59 -0
- package/dist/connector-status.js +117 -0
- package/dist/connectors/api-connector.d.ts +7 -2
- package/dist/connectors/api-connector.js +11 -7
- package/dist/connectors/guarded-fetch.d.ts +0 -6
- package/dist/connectors/guarded-fetch.js +1 -11
- package/dist/connectors/negotiation-cache.js +22 -4
- package/dist/connectors/remote-mcp/call.js +164 -0
- package/dist/connectors/remote-mcp/catalog.js +278 -0
- package/dist/connectors/remote-mcp/config.js +263 -0
- package/dist/connectors/remote-mcp/connection.js +671 -0
- package/dist/connectors/remote-mcp/errors.js +488 -0
- package/dist/connectors/remote-mcp/oauth.js +469 -0
- package/dist/connectors/remote-mcp/resources.js +473 -0
- package/dist/connectors/remote-mcp/runtime.js +1 -0
- package/dist/connectors/remote-mcp/transport.js +544 -0
- package/dist/connectors/remote-mcp.js +61 -2898
- package/dist/connectors/resource-uri.js +0 -4
- package/dist/credential-contract.d.ts +23 -0
- package/dist/credential-reads.js +17 -0
- package/dist/credential-verification.js +53 -0
- package/dist/credentials.d.ts +7 -0
- package/dist/credentials.js +60 -25
- package/dist/d1.d.ts +0 -89
- package/dist/d1.js +0 -34
- package/dist/describe-config.d.ts +12 -2
- package/dist/describe-config.js +2 -0
- package/dist/discovery-health.js +199 -0
- package/dist/downstream-input.js +4 -2
- package/dist/errors.d.ts +55 -17
- package/dist/errors.js +95 -41
- package/dist/execute.js +172 -125
- package/dist/executor-result.js +5 -2
- package/dist/executors/quickjs-runtime.js +2 -25
- package/dist/executors/quickjs.js +1 -1
- package/dist/guest-functions.js +83 -0
- package/dist/guest-runtime.js +63 -20
- package/dist/guest-types.d.ts +24 -10
- package/dist/http/argument-problems.js +35 -0
- package/dist/http/client.js +1 -1
- package/dist/http/errors.js +7 -6
- package/dist/http/fields.js +192 -13
- package/dist/http/hatch-response.js +73 -0
- package/dist/http/hatch.js +88 -23
- package/dist/http/json-schema.js +1 -1
- package/dist/http/node-transport.js +0 -1
- package/dist/http/oauth.js +4 -3
- package/dist/http/paging.js +6 -9
- package/dist/http/provider.js +33 -5
- package/dist/http/safety.js +9 -1
- package/dist/http/services.js +1 -8
- package/dist/http/tools.js +45 -30
- package/dist/http/vendor.js +7 -7
- package/dist/identity.js +2 -6
- package/dist/index.d.ts +1 -1
- package/dist/index.js +9 -2
- package/dist/invocation-auth.js +2 -1
- package/dist/invocation.js +21 -6
- package/dist/membership.d.ts +13 -5
- package/dist/membership.js +34 -2
- package/dist/meta-tools.js +50 -35
- package/dist/native-recovery.js +4 -16
- package/dist/native-tools.js +6 -2
- package/dist/oauth-handoff.js +2 -2
- package/dist/oauth-sealing.js +10 -0
- package/dist/operation-vocabulary.js +136 -14
- package/dist/operator-record.d.ts +2 -2
- package/dist/operator-record.js +2 -49
- package/dist/operator-ui/contract.d.ts +12 -2
- package/dist/operator-ui/generated.js +3 -3
- package/dist/operator-ui/model.d.ts +22 -1
- package/dist/program-writes.js +3 -8
- package/dist/provider-call.js +0 -7
- package/dist/provider.d.ts +1 -1
- package/dist/providers/_shared/google/kit.js +1 -6
- package/dist/providers/_shared/google/service-account.js +1 -3
- package/dist/providers/_shared/google/workspace.d.ts +1 -1
- package/dist/providers/_shared/guide.js +3 -0
- package/dist/providers/_shared/json.js +12 -0
- package/dist/providers/_shared/rest/compact-index.js +1 -1
- package/dist/providers/_shared/rest/kit.js +1 -3
- package/dist/providers/_shared/rest/operation-index.js +49 -53
- package/dist/providers/_shared/rest/value-safety.js +106 -28
- package/dist/providers/breeze/api.js +9 -8
- package/dist/providers/breeze/index.js +4 -2
- package/dist/providers/breeze/skill.generated.js +1 -1
- package/dist/providers/breeze/tools.js +7 -7
- package/dist/providers/ccb/api.js +3 -7
- package/dist/providers/ccb/index.js +7 -1
- package/dist/providers/ccb/skill.generated.js +1 -1
- package/dist/providers/ccb/tools.js +1 -6
- package/dist/providers/cloudflare/api.js +10 -3
- package/dist/providers/cloudflare/index.js +2 -1
- package/dist/providers/cloudflare/safety.js +3 -3
- package/dist/providers/cloudflare/skill.generated.js +1 -1
- package/dist/providers/docs/lib/schemas.js +24 -22
- package/dist/providers/docs/safety.js +2 -0
- package/dist/providers/docs/skill.generated.js +1 -1
- package/dist/providers/docs/tools.js +4 -14
- package/dist/providers/drive/api.js +1 -0
- package/dist/providers/drive/lib/contracts.js +8 -5
- package/dist/providers/drive/skill.generated.js +1 -1
- package/dist/providers/drive/tools.js +23 -41
- package/dist/providers/forms/api.js +1 -0
- package/dist/providers/forms/skill.generated.js +1 -1
- package/dist/providers/forms/tools.js +11 -16
- package/dist/providers/github/api.js +1 -0
- package/dist/providers/github/lib/discovery.js +1 -1
- package/dist/providers/github/skill.generated.js +1 -1
- package/dist/providers/github/tools.js +61 -17
- package/dist/providers/gmail/lib/schemas.js +60 -50
- package/dist/providers/gmail/skill.generated.js +1 -1
- package/dist/providers/gmail/tools.js +12 -26
- package/dist/providers/granola/index.js +2 -0
- package/dist/providers/granola/skill.generated.js +1 -1
- package/dist/providers/overflow/api.js +8 -4
- package/dist/providers/overflow/index.js +2 -1
- package/dist/providers/overflow/skill.generated.js +1 -1
- package/dist/providers/overflow/tools.js +3 -7
- package/dist/providers/planning-center/api.js +5 -2
- package/dist/providers/planning-center/lib/constants.d.ts +1 -1
- package/dist/providers/planning-center/lib/json-api.js +1 -9
- package/dist/providers/planning-center/skill.generated.js +1 -1
- package/dist/providers/planning-center/tools.js +2 -1
- package/dist/providers/quickbooks/safety.js +80 -39
- package/dist/providers/quickbooks/skill.generated.js +1 -1
- package/dist/providers/sheets/api.js +1 -0
- package/dist/providers/sheets/skill.generated.js +1 -1
- package/dist/providers/sheets/tools.js +14 -23
- package/dist/providers/slides/skill.generated.js +1 -1
- package/dist/providers/slides/tools.js +19 -26
- package/dist/providers/stripe/index.js +2 -1
- package/dist/providers/stripe/safety.js +2 -2
- package/dist/providers/stripe/skill.generated.js +1 -1
- package/dist/providers/tithely/api.js +5 -8
- package/dist/providers/tithely/index.js +3 -2
- package/dist/providers/tithely/skill.generated.js +1 -1
- package/dist/providers/tithely/tools.js +7 -5
- package/dist/providers/vercel/api.js +2 -7
- package/dist/providers/vercel/lib/pin.js +1 -1
- package/dist/providers/vercel/safety.js +1 -1
- package/dist/providers/vercel/skill.generated.js +1 -1
- package/dist/providers/vercel/tools.js +6 -4
- package/dist/redaction-marker.js +2 -2
- package/dist/registry.d.ts +11 -5
- package/dist/registry.js +46 -20
- package/dist/request-principal.js +1 -1
- package/dist/request-state.js +2 -2
- package/dist/routes/access-tokens.js +1 -1
- package/dist/routes/activity-disclosure.js +1 -1
- package/dist/routes/connect.js +2 -2
- package/dist/routes/credentials.js +130 -61
- package/dist/routes/dispatch.js +5 -1
- package/dist/routes/mcp.js +34 -17
- package/dist/routes/oauth-management.js +1 -1
- package/dist/routes/operator.js +6 -5
- package/dist/routes/shared.d.ts +13 -8
- package/dist/routes/shared.js +15 -9
- package/dist/routes/ui-config.js +3 -3
- package/dist/routes/ui-data.js +126 -20
- package/dist/routes/ui.js +17 -1
- package/dist/runtime/call-admission.js +1 -1
- package/dist/runtime/call.js +8 -3
- package/dist/runtime/native-storage.js +9 -0
- package/dist/runtime/request-reads.js +182 -0
- package/dist/runtime/request-scope.js +16 -0
- package/dist/runtime/settlement.js +1 -1
- package/dist/runtime/shared-read.js +2 -15
- package/dist/runtime/storage.js +12 -0
- package/dist/sent-secrets.d.ts +1 -2
- package/dist/sent-secrets.js +3 -8
- package/dist/server.js +4 -4
- package/dist/skills.js +44 -54
- package/dist/sqlite.d.ts +0 -19
- package/dist/sqlite.js +2 -83
- package/dist/storage/keys.js +69 -128
- package/dist/storage/memory.js +8 -2
- package/dist/storage/sql-native.js +27 -101
- package/dist/storage/sql.d.ts +1 -24
- package/dist/storage/sql.js +13 -14
- package/dist/storage-digest.js +32 -0
- package/dist/timeout.js +8 -0
- package/dist/tool-error.js +4 -0
- package/dist/types.d.ts +33 -0
- package/dist/url-safety.js +0 -4
- package/dist/usage-guide.js +18 -37
- package/dist/validate.d.ts +3 -0
- package/dist/validate.js +220 -158
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker.js +1 -1
- package/dist/write-outcome.js +0 -3
- package/documentation/README.md +19 -55
- package/documentation/architecture.md +436 -515
- package/documentation/auth.md +229 -88
- package/documentation/code-mode.md +201 -94
- package/documentation/deploying.md +25 -43
- package/documentation/integrating.md +18 -19
- package/documentation/meta-tools.md +225 -51
- package/documentation/migration-0.33.md +10 -6
- package/documentation/migration-0.34.md +5 -5
- package/documentation/migration-retired-layouts.md +74 -0
- package/documentation/operator-tests.md +20 -120
- package/documentation/operator-ui.md +108 -16
- package/documentation/pool-membership-upgrade.md +44 -0
- package/documentation/provider-auth-migration.md +4 -10
- package/documentation/provider-migration-0.29.md +4 -15
- package/documentation/providers.md +105 -0
- package/examples/worker/AGENTS.md +14 -16
- package/examples/worker/README.md +24 -118
- package/examples/worker/src/connecta.config.ts +1 -0
- package/guides/connecting-agents.md +9 -31
- package/guides/how-it-works.md +6 -4
- package/guides/safety-and-trust.md +4 -1
- package/package.json +19 -19
- package/templates/node/AGENTS.md +13 -12
- package/templates/node/README.md +9 -26
- package/templates/node/package.json +1 -1
- package/templates/node/src/connecta.config.ts +1 -0
- package/dist/auth/oauth-v2-migration.js +0 -135
- package/dist/provider-call-facts.d.ts +0 -115
- package/dist/provider-call.d.ts +0 -112
- package/dist/storage/d1-copy.js +0 -255
- package/dist/storage/sql-schema.d.ts +0 -6
- package/examples/worker/kv-to-d1.wrangler.jsonc +0 -26
- package/examples/worker/scripts/copy-kv-to-d1.mjs +0 -162
|
@@ -64,12 +64,9 @@ platform, proxy or adapter cap still wins. See
|
|
|
64
64
|
A Node host serving `connecta.fetch` without `listen()` has no owned sender:
|
|
65
65
|
every maintained-provider write, every reviewed POST read and every remote MCP
|
|
66
66
|
write is refused before sending. Downstream OAuth credential POSTs also require
|
|
67
|
-
that sender
|
|
68
|
-
credential POSTs used native fetch through 0.34.1. For example, an `assistant` using
|
|
67
|
+
that sender. For example, an `assistant` using
|
|
69
68
|
`vercel_api_read` to POST `/v1/registrar/domains/availability` needs that
|
|
70
|
-
transport even on a read-only endpoint.
|
|
71
|
-
entry refuses those requests before sending them. Workers use their native
|
|
72
|
-
fetch transport.
|
|
69
|
+
transport even on a read-only endpoint. Workers use their native fetch transport.
|
|
73
70
|
|
|
74
71
|
By default, Node's `listen()` handles SIGTERM and SIGINT: it stops accepting
|
|
75
72
|
connections, closes idle connections and accepted sockets without a first HTTP
|
|
@@ -81,9 +78,8 @@ keepalive before shutdown is unchanged. Its shutdown deadline defaults to ten se
|
|
|
81
78
|
(`shutdownTimeoutMs`). For example, retain the template's `listen(connecta, port)` when running it under
|
|
82
79
|
Docker Compose so `docker compose stop` uses this cleanup.
|
|
83
80
|
|
|
84
|
-
The owned Node sender connects directly by default.
|
|
85
|
-
|
|
86
|
-
proxy, set `proxy` explicitly on `listen`:
|
|
81
|
+
The owned Node sender connects directly by default. For HTTP(S) CONNECT proxy
|
|
82
|
+
egress, set `proxy` explicitly on `listen`:
|
|
87
83
|
|
|
88
84
|
```ts
|
|
89
85
|
listen(connecta, { port: 3000, proxy: "http://proxy.example.com:8080" });
|
|
@@ -108,9 +104,7 @@ replayed by the sender, including after HTTP 421, a reset or a 503. An uncertain
|
|
|
108
104
|
refresh requires authorization again; Connecta blocks the spent refresh
|
|
109
105
|
fingerprint rather than redeeming it twice. Once a refresh claim has been
|
|
110
106
|
submitted, that protection remains conservative even if proxy setup later fails.
|
|
111
|
-
Use a fresh authorization flow to reconcile.
|
|
112
|
-
fetch and needs its own host proxy policy. These credential POST requirements
|
|
113
|
-
change the native-fetch behavior of 0.34.1.
|
|
107
|
+
Use a fresh authorization flow to reconcile.
|
|
114
108
|
|
|
115
109
|
## Start on Workers
|
|
116
110
|
|
|
@@ -136,10 +130,8 @@ verified ingress behavior and the cases that still require verification.
|
|
|
136
130
|
Agents use `/agent/<pool>`, which connecta authenticates with the `cta_` token
|
|
137
131
|
alone and which ignores Access context entirely
|
|
138
132
|
([agent endpoints](./auth.md#agent-endpoints)). Behind Access, the edge must
|
|
139
|
-
let those requests through without an Access login or service token.
|
|
140
|
-
|
|
141
|
-
verified this shape on 2026-10-15. The Worker example's `alchemy.run.ts`
|
|
142
|
-
declares both applications:
|
|
133
|
+
let those requests through without an Access login or service token.
|
|
134
|
+
The Worker example's `alchemy.run.ts` declares both applications:
|
|
143
135
|
|
|
144
136
|
1. Keep the Worker-level application, whose destination is
|
|
145
137
|
`{ "type": "worker", "worker_id": "<the Worker script tag>" }`, exactly as
|
|
@@ -170,12 +162,9 @@ declares both applications:
|
|
|
170
162
|
3. Point each agent at `https://<host>/agent/<pool>` with
|
|
171
163
|
`Authorization: Bearer cta_…` and drop its `CF-Access-Client-Id` and
|
|
172
164
|
`CF-Access-Client-Secret` headers. The pool must list `"agent:<name>"`.
|
|
173
|
-
4. Verify after the change has settled.
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
responses, and in one round a 403 on a bypassed path after more than 30
|
|
177
|
-
seconds. Do not rely on a fixed wait: repeat these checks until they agree
|
|
178
|
-
for several consecutive rounds. Without credentials, `/agent/<pool>`
|
|
165
|
+
4. Verify after the change has settled. Do not rely on a fixed wait: repeat
|
|
166
|
+
these checks until they agree for several consecutive rounds. Without
|
|
167
|
+
credentials, `/agent/<pool>`
|
|
179
168
|
reaches connecta (its 401 carries `WWW-Authenticate: Bearer`, not Access's
|
|
180
169
|
403 page), while `/mcp` and `/` still get Access's refusal. Then run
|
|
181
170
|
`connecta doctor --pool <pool>` with the agent's token.
|
|
@@ -185,11 +174,8 @@ Connecta answers there only an issued token of an agent listed in the pool,
|
|
|
185
174
|
and gives every other spelling of the agent namespace a 404 before auth,
|
|
186
175
|
because Access matches `/agent/*` after resolving dot segments, folding case,
|
|
187
176
|
decoding unreserved escapes, and collapsing a leading `//`, while the Worker
|
|
188
|
-
sees the raw path.
|
|
189
|
-
|
|
190
|
-
never reads it at `/agent/*`), and Custom Domains, which use the same
|
|
191
|
-
documented hostname-and-path form but were not observed; only `workers.dev`
|
|
192
|
-
was probed. Pinning the Worker-level application's AUD on human routes is
|
|
177
|
+
sees the raw path. Connecta never reads `ctx.access` at `/agent/*`.
|
|
178
|
+
Pinning the Worker-level application's AUD on human routes is
|
|
193
179
|
recommended hardening that connecta does not yet do.
|
|
194
180
|
|
|
195
181
|
## Compose capabilities and access
|
|
@@ -221,9 +207,11 @@ existing-record migration.
|
|
|
221
207
|
|
|
222
208
|
One deployment serves one tenant and may admit several people. Node uses Clerk
|
|
223
209
|
for human auth; Access is Workers-only. With inbound auth, `maintainers` is
|
|
224
|
-
required:
|
|
225
|
-
reaches a pool that lists them in `members`: people at
|
|
226
|
-
at `/agent/<pool>`.
|
|
210
|
+
required: they receive the whole catalog at plain `/mcp` and the operator UI.
|
|
211
|
+
Everyone else reaches a pool that lists them in `members`: people at
|
|
212
|
+
`/mcp/<pool>`, agents at `/agent/<pool>`. A person in exactly one pool may also
|
|
213
|
+
use plain `/mcp`, which serves them that pool, so one client URL can be handed
|
|
214
|
+
to every person; a person in several pools must use `/mcp/<pool>`. Maintainers alone administer shared credentials, manage
|
|
227
215
|
agent tokens, and read activity; members connect their own accounts on
|
|
228
216
|
personal connectors in their pools.
|
|
229
217
|
[Auth](./auth.md#principals-visibility-and-operators) owns maintainers and members;
|
|
@@ -314,22 +302,16 @@ Bump the exact package pin, read the [changelog](../CHANGELOG.md) for every
|
|
|
314
302
|
intervening release, and apply the relevant migration before startup. `init`
|
|
315
303
|
does not merge changes into an existing deployment.
|
|
316
304
|
|
|
305
|
+
Before upgrading past 0.37.1 with pre-0.29 state, follow
|
|
306
|
+
[Retired layout migrations](./migration-retired-layouts.md). Version 0.37.1 is
|
|
307
|
+
the last bridge for KV → D1, JSON → SQLite, and OAuth layout-2 conversions.
|
|
308
|
+
|
|
317
309
|
For an existing Node deployment, add the Node entry's pinned optional peer
|
|
318
310
|
before starting the upgraded package: `npm install --save-exact undici@6.29.1`.
|
|
319
311
|
The current Node template already declares this dependency.
|
|
320
312
|
|
|
321
|
-
For
|
|
322
|
-
|
|
323
|
-
no owned sender: every maintained-provider write, every reviewed POST read and
|
|
324
|
-
every remote MCP write is refused before sending, although each worked in 0.34.1.
|
|
325
|
-
Downstream OAuth token, registration and revocation POSTs also require that
|
|
326
|
-
sender. With `listen()`, every maintained-provider request, reads included,
|
|
327
|
-
remote MCP writes and those credential POSTs use the owned sender. Configure
|
|
328
|
-
`listen(..., { proxy })` explicitly for HTTP(S) CONNECT proxy egress; ambient
|
|
329
|
-
`NODE_USE_ENV_PROXY`, `HTTP_PROXY`, `HTTPS_PROXY` and host proxy dispatchers do
|
|
330
|
-
not configure it. Remote MCP reads and OAuth discovery GETs retain native fetch
|
|
331
|
-
and need their own host proxy policy. An uncertain refresh requires fresh
|
|
332
|
-
authorization rather than replaying the spent token. See [Start on Node](#start-on-node).
|
|
313
|
+
For Node upgrades, retain the template's `listen` entrypoint and apply the
|
|
314
|
+
[Node transport and proxy requirements](#start-on-node).
|
|
333
315
|
|
|
334
316
|
Authenticated MCP bodies now default to 4 MiB through
|
|
335
317
|
`admission.requests.maxBodyBytes`; Node's separate pre-auth buffer also defaults
|
|
@@ -352,10 +334,10 @@ and [Eve agents](./meta-tools.md#eve-agents).
|
|
|
352
334
|
|
|
353
335
|
- [Provider migration for 0.35](./provider-migration-0.35.md) collects provider upgrade actions for 0.35.0, including removal of Infisical, Notion, and Mixpanel factories.
|
|
354
336
|
- [Migration to 0.34](./migration-0.34.md) covers the Overview landing page, Endpoints at `/endpoints`, default browser titles, and Workspace discovery in owner-less agent pools. No storage migration or token rotation is needed from 0.33.
|
|
337
|
+
- [Split mixed pools](./pool-membership-upgrade.md) before starting a deployment that lists people and agents together; mixed membership now throws at construction.
|
|
355
338
|
- [Migration to 0.33](./migration-0.33.md) maps every removed access option to `maintainers`, pool `members`, and `agents`, moves agents to `/agent/<pool>`, and covers pool owners, token revisions, operator contract v2 with its operator route changes, and the pre-auth listen fix.
|
|
356
339
|
- [Tokens issued before agents](./auth.md#agent-tokens-and-upgrading-from-earlier-tokens) stop admitting until each machine's token is bound once to a declared agent with `npm run adopt-token -- <token-id> <agent>` (Node) or `AccessTokenManager.adopt`, which keeps its secret. Human-bound tokens stay refused; issue those agents new tokens. Pool members name `"agent:<name>"` instead of matching token record ids.
|
|
357
|
-
- [
|
|
358
|
-
- [Worker storage from 0.28](../examples/worker/README.md#upgrading-from-028) copies KV into D1 with a one-shot migration.
|
|
340
|
+
- [Retired layout migrations](./migration-retired-layouts.md) requires completing Node JSON → SQLite, Workers KV → D1, and every OAuth layout-2 grant conversion on 0.37.1 before upgrading. The new package no longer supplies those migrations.
|
|
359
341
|
- [Worker deployments on Wrangler](../examples/worker/README.md#moving-a-wrangler-deployed-worker-to-alchemy) move to Alchemy once, adopting the Worker, D1 database, and Access applications so the script tag and Access AUD stay unchanged.
|
|
360
342
|
- [Notion, Vercel, and Cloudflare for 0.29](./provider-migration-0.29.md) records historical defaults and retained API tool names.
|
|
361
343
|
- [Executor wiring](./code-mode.md#deploy-time-capability) requires branded shipped executors or a self-managed custom executor.
|
|
@@ -57,6 +57,7 @@ const crm = remoteMcp("crm", {
|
|
|
57
57
|
});
|
|
58
58
|
const base = ["crm", "tickets"]; // the agent's lowest tier
|
|
59
59
|
// connectors: [crm, tickets], agents: ["assistant"],
|
|
60
|
+
// Agent tiers list only agents; people use a separate pool sharing base.
|
|
60
61
|
// pools: { assistant: { tools: base, members: ["agent:assistant"] } }
|
|
61
62
|
```
|
|
62
63
|
|
|
@@ -219,26 +220,11 @@ failure also reports an unknown outcome with no retry or wait advice; a proven
|
|
|
219
220
|
unsent failure retains its own recovery advice. Connector `readOnly` remains
|
|
220
221
|
optional and composes with endpoint policy.
|
|
221
222
|
|
|
222
|
-
On Node,
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
refuses remote writes before dispatch. A connector with its own `fetch` hands
|
|
226
|
-
writes to that function instead, which owns their single attempt. Downstream OAuth token, registration and
|
|
227
|
-
revocation POSTs also require the owned sender. Read calls and OAuth discovery
|
|
228
|
-
GETs keep native fetch. Workers
|
|
229
|
-
use their native fetch with manual redirects; transport failures after
|
|
223
|
+
On Node, follow the [Node transport and proxy requirements](./deploying.md#start-on-node).
|
|
224
|
+
A connector with its own `fetch` hands writes to that function, which owns their
|
|
225
|
+
single attempt. Workers use native fetch with manual redirects; failures after
|
|
230
226
|
dispatch remain unknown and non-retryable.
|
|
231
227
|
|
|
232
|
-
The owned sender connects directly by default. For HTTP(S) CONNECT proxy egress,
|
|
233
|
-
configure `listen(connecta, { port: 3000, proxy: "http://proxy.example.com:8080" })`.
|
|
234
|
-
This controls maintained-provider requests, remote MCP writes and OAuth
|
|
235
|
-
credential POSTs; it ignores `NODE_USE_ENV_PROXY`, `HTTP_PROXY`, `HTTPS_PROXY`
|
|
236
|
-
and host proxy dispatchers. Remote MCP reads and OAuth discovery GETs retain
|
|
237
|
-
native fetch and need their own host proxy policy. An uncertain refresh requires
|
|
238
|
-
fresh authorization rather than replaying the spent token. See
|
|
239
|
-
[Node startup](./deploying.md#start-on-node) for the proxy URL, credentials and
|
|
240
|
-
TLS trust rules.
|
|
241
|
-
|
|
242
228
|
Remote catalogs evolve. Discovery, direct calls, and programs enforce the
|
|
243
229
|
current annotations and `ConnectaConfig.classification` overrides. A leftover
|
|
244
230
|
`classify` option throws at construction and names that map. Provider reviews,
|
|
@@ -282,6 +268,14 @@ which binds the grant to configured API origins and manages authentication.
|
|
|
282
268
|
[Downstream OAuth on api()](./auth.md#downstream-oauth-on-api) owns a concrete
|
|
283
269
|
HTTP example and the client setup contract.
|
|
284
270
|
|
|
271
|
+
Text a handler writes for the agent that names a Connecta route, such as "call
|
|
272
|
+
authorize_connector" in an auth error, uses `ctx.routes` (`ctx.routes.authorize`,
|
|
273
|
+
`ctx.routes.read`, `ctx.routes.write`, `ctx.routes.search`, `ctx.routes.program`,
|
|
274
|
+
`ctx.routes.skills`). Connecta sets it on every context it builds to the names of
|
|
275
|
+
the surface serving the call: the meta-tool names on the default surface, and
|
|
276
|
+
the native contract's wording on a native pool. It is optional in the type, so
|
|
277
|
+
fall back to the meta names for a context built elsewhere.
|
|
278
|
+
|
|
285
279
|
Mark every side-effecting tool `readOnlyHint: false`. On a writable endpoint
|
|
286
280
|
writes use `call_destructive_tool` or a program, within the caller's grants; a
|
|
287
281
|
`readOnly` endpoint refuses them and omits them from search. Client approval is independent of
|
|
@@ -320,6 +314,11 @@ literal header credentials with personal scope. Review
|
|
|
320
314
|
[management permissions](./auth.md#management-permissions) before exposing a
|
|
321
315
|
new integration or its authentication controls.
|
|
322
316
|
|
|
317
|
+
Plain `/mcp` serves maintainers the whole catalog and every other person their
|
|
318
|
+
single pool, so one URL can serve the meta-tools to `alice` and a native pool's
|
|
319
|
+
tools to `bob`. After changing a pool's `tools`, `readOnly`, `surface` or
|
|
320
|
+
`executeCode`, check it as a member at plain `/mcp` as well as at `/mcp/<pool>`.
|
|
321
|
+
|
|
323
322
|
After editing configuration, run the deployment's typecheck and doctor, then
|
|
324
323
|
perform a bounded read. Add negative checks for target restrictions and writes
|
|
325
324
|
when authoring a handler or provider. Follow repository verification policy
|
|
@@ -346,7 +345,7 @@ check shared behavior. Provider-specific tests remain beside each provider.
|
|
|
346
345
|
|
|
347
346
|
Use [`@zackbart/connecta-eve`](https://github.com/zackbart/connecta/blob/main/packages/connecta-eve/README.md)
|
|
348
347
|
in the Eve app for an app-owned connection and endpoint instructions refreshed
|
|
349
|
-
once per turn. It requires Node 24 and Eve 0.
|
|
348
|
+
once per turn. It requires Node 24 and Eve 0.90.x, and installs separately from
|
|
350
349
|
Connecta. Follow its README for the two agent files, token environment variables,
|
|
351
350
|
optional write approval and Vercel OIDC token source. Configure the server's
|
|
352
351
|
[agent and pool membership](./auth.md#issue-rotate-or-revoke-an-agent-token)
|
|
@@ -49,7 +49,12 @@ write tools from `search_tools` results and describe, and refuses every write
|
|
|
49
49
|
call. Connector `readOnly` applies the same restriction on every endpoint; effective read-only is endpoint OR connector. Neither setting changes connector visibility or read grants. Guides
|
|
50
50
|
(`queryAnalysis.guideSummary`, `skills`, `connecta.skill`, skill
|
|
51
51
|
`resources/read`) are documentation and may name tools the endpoint refuses. The four tools with structured-only success results
|
|
52
|
-
advertise `outputSchema`.
|
|
52
|
+
advertise `outputSchema`. `search_tools`'s schema defines its typed failure,
|
|
53
|
+
including every authorization-handoff field, once under `$defs.failure`;
|
|
54
|
+
`catalogErrors[]` references it through `allOf` with `connector` required, and
|
|
55
|
+
`queryAnalysis.catalogError` references it directly. The schema declares no
|
|
56
|
+
`$schema`, and validators for drafts 4, 7, 2019-09 and 2020-12 accept the same
|
|
57
|
+
pages. The two direct-call tools omit it because their default
|
|
53
58
|
mode returns native `content`. Default-mode successes declare
|
|
54
59
|
`_meta["dev.connecta/format"]: "json" | "text"`; value mode places the value in
|
|
55
60
|
`data` and declares `format` in its complete result envelope.
|
|
@@ -134,16 +139,25 @@ Live connector probing is not a fourth: the operator pages and `/health` own it.
|
|
|
134
139
|
|
|
135
140
|
## Discovery context
|
|
136
141
|
|
|
137
|
-
The deployment-derived `execute_code` description carries a
|
|
138
|
-
inventory before any catalog search — registry order
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
142
|
+
The deployment-derived `execute_code` description carries a connector
|
|
143
|
+
inventory before any catalog search — registry order and each canonical id,
|
|
144
|
+
with no second name minted for programs. An entry adds the configured title
|
|
145
|
+
only when it says more than the id: a title whose words the id already spells,
|
|
146
|
+
such as `Google Calendar` for `google_calendar`, is dropped. Titles normalize
|
|
147
|
+
whitespace and cap at 48 UTF-8 bytes. A connector with a guide says how to
|
|
148
|
+
fetch it: `read first: skills({name:"connector:<id>"})` for a required guide,
|
|
149
|
+
`guide: skills({name:"connector:<id>"})` otherwise. For example:
|
|
150
|
+
`Connectors: crm (Customer CRM; read first: skills({name:"connector:crm"})), tickets.`
|
|
151
|
+
|
|
152
|
+
The complete line caps at 1,024 UTF-8 bytes, which names every connector of a
|
|
153
|
+
typical deployment. Past the cap, detail degrades before names do: titles are
|
|
154
|
+
dropped first, then optional guide pointers. Only when bare ids and required
|
|
155
|
+
guide pointers still exceed it do whole entries give way, in registry order, to
|
|
156
|
+
an exact `+N more` count. The inventory reads only the configured registry: no
|
|
157
|
+
catalog load, no credential probe, no live status, no capability, and no
|
|
158
|
+
replacement for canonical discovery or addressing. Search pages carry the same
|
|
159
|
+
bounded title once per connector in `connectors[<id>].title`, so choosing an
|
|
160
|
+
account or environment costs no provider read.
|
|
147
161
|
|
|
148
162
|
Read-only lookup belongs in `connecta.search` inside the program; top-level
|
|
149
163
|
`search_tools` stays for explicit catalog inspection and approval-required
|
|
@@ -171,6 +185,56 @@ read/write filter. On `approvalRequired` searches the returned discovery tool
|
|
|
171
185
|
is still a read. Hidden tools, missing grants and read-only restrictions remain
|
|
172
186
|
in force. Browsing does not consult operation vocabulary.
|
|
173
187
|
|
|
188
|
+
When a matched operation's call is fully determined, the first page also
|
|
189
|
+
carries it in `readyCalls`, so a program can call it without operation search or
|
|
190
|
+
details:
|
|
191
|
+
|
|
192
|
+
```json
|
|
193
|
+
{
|
|
194
|
+
"readyCalls": [
|
|
195
|
+
{
|
|
196
|
+
"address": "notes.notes_api_read",
|
|
197
|
+
"args": { "path": "/v1/notes" },
|
|
198
|
+
"classification": "read",
|
|
199
|
+
"summary": "List notes"
|
|
200
|
+
}
|
|
201
|
+
]
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Pass `args` unchanged to `connecta.call(address, args)` or `call_tool`. An
|
|
206
|
+
operation is fully determined only when it is a reviewed read served by the
|
|
207
|
+
hatch's `_api_read` tool itself (no named tool), uses GET, the read tool's
|
|
208
|
+
default method, and declares no path template, required parameter or required
|
|
209
|
+
body. Anything needing an id, a method choice or an argument the agent must
|
|
210
|
+
fill in stays behind `_api_search` and `_api_details`. Ready calls pass the same
|
|
211
|
+
endpoint, connector read-only, safety, hidden-tool and grant checks as the
|
|
212
|
+
vocabulary match, through a visible read tool in the caller's view. They are
|
|
213
|
+
computed offline from the construction-time index, read no account data, and
|
|
214
|
+
start no authorization.
|
|
215
|
+
|
|
216
|
+
A ready call must also be what the query names. Each path segment, and the
|
|
217
|
+
operationId without its action and version words, is one whole resource name:
|
|
218
|
+
`event_destinations` is the name "event destination", never "event". Every
|
|
219
|
+
query word other than an action (`list`, `get`, `count`, `show`, `create`,
|
|
220
|
+
`update`, `delete` and their vocabulary aliases) must belong to a resource name
|
|
221
|
+
whose words the query states in order, with singular/plural normalization and
|
|
222
|
+
the provider's declared synonyms. Version segments such as `v1` never count, and
|
|
223
|
+
a summary may supply only actions. A query with no object word gets no ready
|
|
224
|
+
call. Ready calls are omitted entirely when the top result is an exact tool name
|
|
225
|
+
or address, or a complete match on an authored tool, not the hatch's own search
|
|
226
|
+
or read tool, whose name adds nothing to the query: each of its name words is an
|
|
227
|
+
action or a query word, up to plural/singular and declared synonyms. For
|
|
228
|
+
example, `list teams` returns `list_teams` and no ready call, even when other
|
|
229
|
+
operations mention teams in their summaries, while `list projects` still offers
|
|
230
|
+
`/v10/projects` beside `list_project_env_vars`, whose name adds `env` and `vars`.
|
|
231
|
+
Each hatch offers only its top-ranked operation: a last path segment naming the
|
|
232
|
+
resource first, then the fewest resource words the query did not ask for, then
|
|
233
|
+
the shortest path. A connector offers at most one ready call and a page at most
|
|
234
|
+
three, in connector order. Later pages carry none. A ready
|
|
235
|
+
call keeps its read tool's `guideRequired` and `guideRequiredReasons`, and its
|
|
236
|
+
connector appears in `connectors`.
|
|
237
|
+
|
|
174
238
|
Vocabulary is bounded: queries at most 200 characters and eight terms; each
|
|
175
239
|
hatch caches at most 8,192 rows and 2,097,152 characters, with at most 1,024
|
|
176
240
|
characters per row and 128 query intersections. Longer queries and vocabulary
|
|
@@ -281,9 +345,11 @@ guide's first meaningful body paragraph. `required: true` is reserved for
|
|
|
281
345
|
generic API wrappers and cross-operation conventions a complete downstream
|
|
282
346
|
schema cannot express.
|
|
283
347
|
|
|
284
|
-
|
|
285
|
-
`guideSummary
|
|
286
|
-
`
|
|
348
|
+
Describe results carry a `guide: "connector:<id>"` pointer and a
|
|
349
|
+
`guideSummary`; a search page carries both once per connector in
|
|
350
|
+
`connectors[<id>]`. A matching tool row or description also carries
|
|
351
|
+
`guideRequired: true` and `guideRequiredReasons` when Connecta can prove review
|
|
352
|
+
is necessary:
|
|
287
353
|
|
|
288
354
|
| Reason | Raised by | Survives exact schema expansion |
|
|
289
355
|
| -------------------- | ------------------------------------ | -------------------------------------------------------- |
|
|
@@ -297,8 +363,17 @@ is merely told to fetch the guide first, for any reason listed. Otherwise the
|
|
|
297
363
|
bounded summary decides — connector-specific sequencing, units, pagination,
|
|
298
364
|
aliases, and generic API conventions still need the guide when they affect the
|
|
299
365
|
task, while a complete and unambiguous one-read schema proceeds directly. Guide
|
|
300
|
-
lookup
|
|
301
|
-
callers never manufacture `connector:<id>` from an
|
|
366
|
+
lookup uses an exact name returned by `skills({})`, search, describe, or the
|
|
367
|
+
`execute_code` inventory; callers never manufacture `connector:<id>` from an
|
|
368
|
+
unmarked connector. A bare connector id, such as `skills({ name: "crm" })` or
|
|
369
|
+
`connecta.skill("crm")`, also serves that connector's guide. Built-in skill
|
|
370
|
+
names stay reserved: `usage` and `investigate` always fetch the built-in skill,
|
|
371
|
+
even when a connector has that id, whose guide stays at `connector:usage` or
|
|
372
|
+
`connector:investigate`. A bare id naming a connector without a guide fails with
|
|
373
|
+
`Connector "<id>" has no usage guide.`; any other unknown name fails as an
|
|
374
|
+
unknown skill. Names containing `:`, including URIs, never fall back to a bare
|
|
375
|
+
id. MCP `skills/get` resolves names the same way; `resources/read` accepts only
|
|
376
|
+
document URIs.
|
|
302
377
|
|
|
303
378
|
A connector-scoped lexical miss keeps that connector's guide metadata under
|
|
304
379
|
`queryAnalysis`. This matters for generic wrappers whose broad tool name
|
|
@@ -307,12 +382,29 @@ disappearing with the zero-tool page.
|
|
|
307
382
|
|
|
308
383
|
Two built-in skills are byte-identical across deployments. `usage` is fetched
|
|
309
384
|
only for missing guidance or program repair, and owns program selection detail, examples, runtime
|
|
310
|
-
differences, and repair guidance; `investigate` is on-demand
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
385
|
+
differences, and repair guidance; `investigate` is domain-neutral on-demand
|
|
386
|
+
guidance for an investigation that spans several services — shared guidance,
|
|
387
|
+
not a saved workflow and not a source of deployment-specific ids. `skills`
|
|
388
|
+
lists it; the `execute_code` description does not advertise it. The always-loaded instructions and tool definitions keep
|
|
314
389
|
route selection, the fail-closed boundary, and the minimum guest syntax, so a
|
|
315
390
|
client that never fetches a skill can still write a valid first program.
|
|
391
|
+
|
|
392
|
+
The server instructions state the complete routing rule once. Some clients
|
|
393
|
+
drop server instructions, so each tool description stays sufficient for its own
|
|
394
|
+
correct use without restating that rule: `call_tool` names its scope (one
|
|
395
|
+
known-address read) and points other read work to `execute_code`;
|
|
396
|
+
`search_tools` names its scope (catalog inspection, or finding a write) and
|
|
397
|
+
points read work into a program; `execute_code` opens with the terse
|
|
398
|
+
three-route lead (`One known read: call_tool. One known write:
|
|
399
|
+
call_destructive_tool. Everything else: execute_code.`, or the read-only
|
|
400
|
+
two-route form). The `usage` skill points to those two sources instead of
|
|
401
|
+
repeating them.
|
|
402
|
+
|
|
403
|
+
Tool descriptions and output schemas carry deployment configuration only: the
|
|
404
|
+
connector inventory, budgets, the endpoint's read-only setting, and whether any
|
|
405
|
+
visible connector has a guide. No catalog outcome, call, authorization state,
|
|
406
|
+
or other live status reaches `tools/list` or the instructions, so the
|
|
407
|
+
always-loaded surface stays byte-stable for a client's prompt cache.
|
|
316
408
|
The instructions are the same on every endpoint except one addition: at
|
|
317
409
|
`/mcp/<pool>` and `/agent/<pool>`, a pool that sets a
|
|
318
410
|
[`description`](./auth.md#pools) has it appended after `This endpoint: `, so
|
|
@@ -528,8 +620,10 @@ The default cap sits under both lines with room to spare. Preview plus notice
|
|
|
528
620
|
stays under 25,000 bytes, which is under 50,000 characters for any text, because
|
|
529
621
|
a character is at least one UTF-8 byte, and under 25,000 tokens for any text,
|
|
530
622
|
because a token covers at least one byte. A `connecta.result` page is bounded by the same
|
|
531
|
-
inline byte cap, and 24,000 matches the program result boundary in
|
|
532
|
-
[code mode](./code-mode.md).
|
|
623
|
+
inline byte cap, and 24,000 matches the default program result boundary in
|
|
624
|
+
[code mode](./code-mode.md) (`execute.maxResultChars`). The `maxBytes` in
|
|
625
|
+
`nextAction` is sized so one page fits that boundary under worst-case JSON
|
|
626
|
+
escaping, capped by the call's own inline cap: 3,829 bytes by default. A deployment whose
|
|
533
627
|
clients take more can raise the cap, and one whose clients take less can lower
|
|
534
628
|
it, per connector if need be; a result between 24,000 and 50,000 bytes that
|
|
535
629
|
used to arrive whole now pages. A client that spills rather than rejects keeps
|
|
@@ -616,7 +710,7 @@ a fixed warning without storage error prose. Never repeat a write to recover out
|
|
|
616
710
|
page. Select tool rows from `page.tools`.
|
|
617
711
|
With the same schema format, schema-key option, and scoped registry, both paths
|
|
618
712
|
return identical data. Top-level search omits schemas unless requested; programs
|
|
619
|
-
default to
|
|
713
|
+
default to TypeScript signatures and schema-key metadata.
|
|
620
714
|
|
|
621
715
|
```json
|
|
622
716
|
{
|
|
@@ -625,12 +719,12 @@ default to JSON schemas and schema-key metadata.
|
|
|
625
719
|
{
|
|
626
720
|
"name": "get_ticket",
|
|
627
721
|
"address": "tickets.get_ticket",
|
|
628
|
-
"connectorTitle": "Tickets",
|
|
629
722
|
"classification": "read",
|
|
630
723
|
"schemaFormat": "json",
|
|
631
724
|
"inputSchema": { "type": "object", "properties": { "id": { "type": "string" } }, "required": ["id"] }
|
|
632
725
|
}
|
|
633
726
|
],
|
|
727
|
+
"connectors": { "tickets": { "title": "Tickets", "guide": "connector:tickets", "guideSummary": "Ticket ids and states." } },
|
|
634
728
|
"total": 1,
|
|
635
729
|
"offset": 0,
|
|
636
730
|
"limit": 8,
|
|
@@ -650,8 +744,26 @@ and connector id, never connector-supplied error text. Other failures retain
|
|
|
650
744
|
`retryAfterMs`. A scoped search also keeps its bounded failure subset under
|
|
651
745
|
`queryAnalysis.catalogError` for clients that already use it.
|
|
652
746
|
|
|
653
|
-
|
|
654
|
-
|
|
747
|
+
An unscoped search gives each connector at most 5 seconds (or
|
|
748
|
+
`discovery.probeTimeoutMs` when shorter) and ends within a 9-second discovery
|
|
749
|
+
budget. A connector that recently timed out or failed slowly is skipped for up
|
|
750
|
+
to 60 seconds: its entry keeps the recorded code with `retryable: true`,
|
|
751
|
+
`retryAfterMs`, and the message `Connector "X" was skipped because its catalog
|
|
752
|
+
lookup failed recently (CODE). Search with connector "X" to try it now.` A
|
|
753
|
+
scoped search always probes. Records are kept per owner, admitted endpoint and
|
|
754
|
+
described connector configuration. A healthy connector whose catalog always
|
|
755
|
+
takes more than 5 seconds can stay out of unscoped search; search it with
|
|
756
|
+
`connector`, or let any longer-deadline operation warm its complete catalog.
|
|
757
|
+
See [Discovery health](./architecture.md#storage-credentials-and-connectors).
|
|
758
|
+
|
|
759
|
+
Tool rows carry the address, stored classification, and tool-specific
|
|
760
|
+
`guideRequired` and `guideRequiredReasons`. Facts shared by every row of one
|
|
761
|
+
connector appear once per page in `connectors`, keyed by the connector id that
|
|
762
|
+
prefixes each row's address: the configured display `title` when present and
|
|
763
|
+
`guide` and `guideSummary` when the connector has a guide. The map names only
|
|
764
|
+
connectors with a row or ready call on this page and is omitted when none has
|
|
765
|
+
such facts.
|
|
766
|
+
Requested schemas have
|
|
655
767
|
`schemaFormat: "json"` for JSON Schema values or `schemaFormat: "text"` for
|
|
656
768
|
compact schema strings and TypeScript signatures. Compact schemas are text;
|
|
657
769
|
`inputSchema.properties` is meaningful only in JSON mode. Pagination counts
|
|
@@ -664,7 +776,19 @@ rare domain terms above ubiquitous action terms. Exact tool names and canonical
|
|
|
664
776
|
addresses rank first, so `get_issue` beats `get_issue_status` even when a
|
|
665
777
|
connector is named `issue`. Exact configured connector IDs, full display titles,
|
|
666
778
|
and recognized service names rank next. Complete lexical matches then precede
|
|
667
|
-
partial matches,
|
|
779
|
+
partial matches. Within a tier, a query whose first word outside connector names
|
|
780
|
+
is `list`, `get`, `find`, `search`, `show`, `read`, `fetch`, or `count` ranks
|
|
781
|
+
read rows before write rows; writes stay on the page. Score and catalog order
|
|
782
|
+
break the remaining ties.
|
|
783
|
+
|
|
784
|
+
A maintained provider may declare `searchSynonyms`: groups of single lowercase
|
|
785
|
+
words its users and its vendor use for the same record, such as `household`
|
|
786
|
+
and `family` for Church Community Builder. A query word then matches that
|
|
787
|
+
provider's tools and operation vocabulary through any word in its group, as an
|
|
788
|
+
ordinary whole-token match ranked below the word itself. Synonyms never widen
|
|
789
|
+
another connector's matches. Church Community Builder declares
|
|
790
|
+
`person`/`individual` and `household`/`family`; Granola declares
|
|
791
|
+
`meeting`/`note`.
|
|
668
792
|
An exact connector ID or title query browses that connector's tools, even when
|
|
669
793
|
individual tool names or descriptions mention that identity. Connector identity
|
|
670
794
|
terms that never occur in its tools need not be repeated in every tool description.
|
|
@@ -1025,28 +1149,77 @@ A remote MCP tool's advertised `inputSchema` is checked in the shared invocation
|
|
|
1025
1149
|
path before admission and provider dispatch, so a mismatch is the non-retryable
|
|
1026
1150
|
`invalid_args` identically on `call_tool`, `call_destructive_tool`,
|
|
1027
1151
|
generated-code failures, and rejected promises. The error names the connector and
|
|
1028
|
-
operation and carries
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1152
|
+
operation and carries one recovery envelope, `validation`:
|
|
1153
|
+
|
|
1154
|
+
```json
|
|
1155
|
+
{
|
|
1156
|
+
"issues": [
|
|
1157
|
+
{ "path": "/limit", "expected": "at least 5", "received": "4" },
|
|
1158
|
+
{ "path": "/mode", "expected": "one of \"fast\", \"safe\"", "received": "string" },
|
|
1159
|
+
{ "path": "/<key>", "expected": "one of the accepted keys: mode, limit" }
|
|
1160
|
+
],
|
|
1161
|
+
"acceptedKeys": ["mode", "limit"],
|
|
1162
|
+
"example": { "mode": "fast", "limit": 5 }
|
|
1163
|
+
}
|
|
1164
|
+
```
|
|
1165
|
+
|
|
1166
|
+
Every finding is listed, and the message repeats them, so one corrected call
|
|
1167
|
+
fixes them all.
|
|
1168
|
+
|
|
1169
|
+
A refusal contains only names and literals the published schema declares at
|
|
1170
|
+
non-sensitive positions, numbers allowed by the bound rule below, and fixed
|
|
1171
|
+
placeholder text. It never contains a submitted string or object key, in the
|
|
1172
|
+
message, a finding, `acceptedKeys` or the example. A position is sensitive when
|
|
1173
|
+
it or an ancestor is `writeOnly`; a named tool's input schema marks each request
|
|
1174
|
+
secret that way. API hatch findings name only the operation contract's
|
|
1175
|
+
properties and enum members, as `*_api_details` publishes them.
|
|
1176
|
+
|
|
1177
|
+
- `path` is a JSON Pointer naming declared properties and array indices. The
|
|
1178
|
+
first key the schema does not declare (a misspelled argument, a map key)
|
|
1179
|
+
reads `<key>` and ends the path, e.g. `/headers/<key>`.
|
|
1180
|
+
- `expected` states the constraint that failed, then every other constraint
|
|
1181
|
+
the position declares: bounds, property and item counts, `multipleOf`,
|
|
1182
|
+
`pattern`, `format`, `uniqueItems`, enum members, `dependentRequired`
|
|
1183
|
+
(`string (required with tags)`). A sensitive position never renders an enum,
|
|
1184
|
+
`const` or pattern literal. Each position gets one finding.
|
|
1185
|
+
- `received` is the submitted JSON type, `missing`, or, for a numeric bound at
|
|
1186
|
+
a non-sensitive position of a named tool, the submitted number.
|
|
1187
|
+
|
|
1188
|
+
At most eight findings are returned, each field clipped (path and expected 256
|
|
1189
|
+
characters, received 64), and `truncated: true` says something was omitted or
|
|
1190
|
+
clipped.
|
|
1191
|
+
|
|
1192
|
+
`example` is one valid call synthesized from the published schema and checked
|
|
1193
|
+
against the same validator. It never copies a submitted value, and a sensitive
|
|
1194
|
+
position never renders a schema literal (`enum`, `const`, `default`,
|
|
1195
|
+
`examples`). Complex or unsatisfiable schemas get `exampleUnavailable` instead.
|
|
1196
|
+
Synthesis detects recursive references and shares a 128-node work budget.
|
|
1197
|
+
Invocation uses only this schema example, never a connector's copy of the
|
|
1198
|
+
call, unless the connector states `exampleUnavailable`. API hatches
|
|
1199
|
+
(`*_api_read`, `*_api_write`) always do: their generic schema says nothing
|
|
1200
|
+
about an operation's arguments, so the reason points to the operation's
|
|
1201
|
+
`*_api_details`.
|
|
1202
|
+
|
|
1203
|
+
`acceptedKeys` names the tool's top-level arguments. `conditionalRequirements`
|
|
1204
|
+
lists known `dependentRequired` and `dependentSchemas` requirements by
|
|
1205
|
+
property name; `if`/`then`/`else` conditions are schema subtrees and are not
|
|
1206
|
+
rendered. The envelope has a 4 KiB budget:
|
|
1207
|
+
optional detail, then the example, then trailing findings are dropped whole,
|
|
1208
|
+
with `truncated: true`. A `repair` object a custom connector passes contributes
|
|
1209
|
+
its received types and schema facts. A custom connector's own findings must
|
|
1210
|
+
follow the same rule. Operator records contain only checked failure facts,
|
|
1211
|
+
never findings or examples.
|
|
1032
1212
|
|
|
1033
1213
|
`nextAction` points to discovery scoped to the same connector and tool name when
|
|
1034
1214
|
the compact schema is needed, routed like any other miss: a program to
|
|
1035
1215
|
`connecta.search`, a top-level call to `search_tools`. `retry` says to correct
|
|
1036
|
-
the listed arguments and reissue the original operation.
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
`repair`
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
Its `example` is synthesized without submitted values and checked against the
|
|
1044
|
-
same validator. Complex or unsatisfiable schemas get `exampleUnavailable`
|
|
1045
|
-
rather than an invalid example. Synthesis detects recursive references and
|
|
1046
|
-
shares a 128-node work budget. Alternative branches do not emit dependency
|
|
1047
|
-
advice unless the branch condition is known. Repair detail has a 4 KiB budget; oversized
|
|
1048
|
-
detail is withheld whole with `truncated: true`. Operator records still contain
|
|
1049
|
-
only checked failure facts, never findings or examples.
|
|
1216
|
+
the listed arguments and reissue the original operation. What the local
|
|
1217
|
+
validator declines to evaluate is [code mode](./code-mode.md#errors)'s `E8`.
|
|
1218
|
+
|
|
1219
|
+
Earlier releases returned `validation.issues[].code` (the schema keyword)
|
|
1220
|
+
and a separate `repair` object. Both are gone from responses; a custom
|
|
1221
|
+
connector may still pass `code` and `repair` to `ConnectorCallError`, which
|
|
1222
|
+
folds `repair` into `validation`.
|
|
1050
1223
|
|
|
1051
1224
|
Unknown-address errors list `configuredConnectors` from the current endpoint's
|
|
1052
1225
|
scoped registry, including an empty list when none are accessible. They never
|
|
@@ -1144,7 +1317,9 @@ its code and message for diagnostics but is `retryable: false` with
|
|
|
1144
1317
|
a program's `writes.unknown`. An HTTP refusal of the call's own write stays
|
|
1145
1318
|
known only under the refusal rules above and a complete ledger proving the
|
|
1146
1319
|
refusal covers the whole call; its recovery advice and program accounting both
|
|
1147
|
-
report failure.
|
|
1320
|
+
report failure. A `remoteMcp()` write answered with a 4xx (other than 401, 403,
|
|
1321
|
+
408 or 429) whose body is not a JSON-RPC error is unknown, never a refusal: a
|
|
1322
|
+
gateway may have answered after the server acted. Partial or unknown ledgers remain conservative. An auth failure after entering a write with
|
|
1148
1323
|
no call-owned dispatch reports an unknown outcome and requires reconciliation,
|
|
1149
1324
|
including credential refusals, static-OAuth refresh failures, and `remoteMcp()`
|
|
1150
1325
|
connect or initialize 401s before `tools/call`. A non-auth refusal before
|
|
@@ -1309,7 +1484,7 @@ window, a native `tools/list` carries a 300-second private cache hint, against
|
|
|
1309
1484
|
an hour on meta endpoints. This hint does not guarantee that a host refreshes
|
|
1310
1485
|
its cached annotations; the stale-approval race is accepted on writable pools.
|
|
1311
1486
|
|
|
1312
|
-
**Listing.** `tools/list` is one page with no cursor (Eve 0.
|
|
1487
|
+
**Listing.** `tools/list` is one page with no cursor (Eve 0.90 reads only the
|
|
1313
1488
|
first page). A pool listing more than 1,000 tools fails `tools/list` with a
|
|
1314
1489
|
JSON-RPC error asking the operator to narrow the pool; nothing is silently
|
|
1315
1490
|
dropped. A connector whose catalog cannot load is left out of that listing
|
|
@@ -1326,7 +1501,8 @@ never repeat a write; page a truncated result as its notice says. A pool
|
|
|
1326
1501
|
**Recovery.** Repair and validation fields retain the exact constraint details.
|
|
1327
1502
|
Discovery `nextAction` points to the host's tool search (`host: "search"`), with
|
|
1328
1503
|
only a `query` argument. Retry actions and retry text name the native tool,
|
|
1329
|
-
never a meta wrapper
|
|
1504
|
+
never a meta wrapper; a program on a native pool sees the same native wording
|
|
1505
|
+
in a failure it catches. An unknown name is reported as sent. Auth actions carry `authorizationUrl` or `operatorUrl`;
|
|
1330
1506
|
give the returned URL and instructions to the user or operator. Capable modern
|
|
1331
1507
|
clients may resume native auth and downstream form/URL input with the same
|
|
1332
1508
|
wire name, arguments and returned `requestState`. Changed names, targets or
|
|
@@ -1380,8 +1556,6 @@ listing, and call translation live in
|
|
|
1380
1556
|
[search tests](https://github.com/zackbart/connecta/blob/main/test/meta-tools-search.test.ts),
|
|
1381
1557
|
[call tests](https://github.com/zackbart/connecta/blob/main/test/meta-tools-call.test.ts),
|
|
1382
1558
|
[skills tests](https://github.com/zackbart/connecta/blob/main/test/skills-extension.test.ts),
|
|
1383
|
-
[native surface tests](https://github.com/zackbart/connecta/blob/main/test/native-tools.test.ts)
|
|
1384
|
-
[surface tests](https://github.com/zackbart/connecta/blob/main/test/code-first-surface.test.ts),
|
|
1385
|
-
and [pool description tests](https://github.com/zackbart/connecta/blob/main/test/pool-description.test.ts)
|
|
1559
|
+
and [native surface tests](https://github.com/zackbart/connecta/blob/main/test/native-tools.test.ts)
|
|
1386
1560
|
check the published contract. Guest parity and clause evidence are in
|
|
1387
1561
|
[code-mode verification](./code-mode.md#verification).
|