@zackbart/connecta 0.30.0 → 0.32.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 +66 -0
- package/README.md +21 -16
- package/bin/connecta.mjs +1 -0
- package/bin/version.mjs +1 -1
- package/dist/auth-elicitation.js +1 -1
- package/dist/call-recovery.js +25 -0
- package/dist/catalog-service.js +7 -2
- package/dist/config-schema.d.ts +14 -7
- package/dist/config-schema.js +29 -10
- package/dist/config-value-sources.js +6 -3
- package/dist/config.d.ts +26 -8
- package/dist/config.js +38 -16
- package/dist/connector-access.d.ts +2 -1
- package/dist/connectors/guarded-fetch.d.ts +18 -1
- package/dist/connectors/guarded-fetch.js +21 -2
- package/dist/describe-config.d.ts +6 -3
- package/dist/describe-config.js +3 -2
- package/dist/errors.d.ts +3 -1
- package/dist/errors.js +1 -0
- package/dist/execute.js +16 -14
- package/dist/index.js +4 -3
- package/dist/invocation.js +39 -4
- package/dist/meta-tools.js +17 -19
- package/dist/operator-record.d.ts +2 -2
- package/dist/operator-record.js +2 -0
- package/dist/operator-ui/contract.d.ts +5 -4
- package/dist/operator-ui/generated.js +2 -2
- package/dist/operator-ui/model.d.ts +1 -1
- package/dist/operator-ui/view.d.ts +9 -0
- package/dist/operator-ui/view.js +12 -0
- package/dist/program-writes.js +4 -49
- package/dist/provider.d.ts +6 -5
- package/dist/provider.js +3 -4
- package/dist/providers/_shared/google/workspace.js +1 -1
- package/dist/providers/_shared/rest/dispatch.js +41 -0
- package/dist/providers/_shared/rest/operation-index.d.ts +133 -0
- package/dist/providers/_shared/rest/operation-index.js +527 -0
- package/dist/providers/_shared/rest/tools.d.ts +141 -0
- package/dist/providers/_shared/rest/tools.js +569 -0
- package/dist/providers/_shared/rest/value-safety.d.ts +151 -0
- package/dist/providers/_shared/rest/value-safety.js +580 -0
- package/dist/providers/breeze/skill.generated.js +2 -2
- package/dist/providers/cloudflare/graphql.js +385 -0
- package/dist/providers/cloudflare/index.d.ts +47 -51
- package/dist/providers/cloudflare/index.js +188 -1997
- package/dist/providers/cloudflare/openapi.generated.js +3347 -0
- package/dist/providers/cloudflare/rest.d.ts +37 -0
- package/dist/providers/cloudflare/rest.js +1056 -0
- package/dist/providers/cloudflare/skill.generated.js +7 -4
- package/dist/providers/cloudflare/value-safety.js +1247 -0
- package/dist/providers/docs/index.d.ts +1 -1
- package/dist/providers/docs/index.js +2 -2
- package/dist/providers/drive/index.d.ts +1 -1
- package/dist/providers/drive/index.js +1 -1
- package/dist/providers/forms/index.d.ts +1 -1
- package/dist/providers/forms/index.js +2 -2
- package/dist/providers/github/skill.generated.js +2 -2
- package/dist/providers/gmail/index.d.ts +1 -1
- package/dist/providers/gmail/index.js +274 -23
- package/dist/providers/gmail/skill.generated.js +2 -2
- package/dist/providers/linear/index.js +1 -1
- package/dist/providers/mixpanel/index.d.ts +27 -12
- package/dist/providers/mixpanel/index.js +58 -6
- package/dist/providers/mixpanel/operations.js +20 -0
- package/dist/providers/mixpanel/rest.js +603 -0
- package/dist/providers/mixpanel/skill.generated.js +3 -2
- package/dist/providers/mixpanel/value-safety.js +16 -0
- package/dist/providers/notion/index.d.ts +35 -31
- package/dist/providers/notion/index.js +76 -1499
- package/dist/providers/notion/openapi.generated.js +75 -0
- package/dist/providers/notion/rest.d.ts +24 -0
- package/dist/providers/notion/rest.js +1186 -0
- package/dist/providers/notion/skill.generated.js +5 -4
- package/dist/providers/notion/value-safety.js +31 -0
- package/dist/providers/planning-center/index.d.ts +27 -0
- package/dist/providers/planning-center/index.js +286 -24
- package/dist/providers/planning-center/skill.generated.js +24 -4
- package/dist/providers/sheets/index.d.ts +1 -1
- package/dist/providers/sheets/index.js +3 -3
- package/dist/providers/slides/index.d.ts +1 -1
- package/dist/providers/slides/index.js +3 -3
- package/dist/providers/stripe/index.d.ts +26 -20
- package/dist/providers/stripe/index.js +103 -130
- package/dist/providers/stripe/openapi.generated.js +649 -0
- package/dist/providers/stripe/rest.d.ts +14 -0
- package/dist/providers/stripe/rest.js +395 -0
- package/dist/providers/stripe/skill.generated.js +7 -5
- package/dist/providers/stripe/value-safety.js +705 -0
- package/dist/providers/vercel/index.d.ts +31 -22
- package/dist/providers/vercel/index.js +96 -853
- package/dist/providers/vercel/openapi.generated.js +456 -0
- package/dist/providers/vercel/rest.d.ts +20 -0
- package/dist/providers/vercel/rest.js +1002 -0
- package/dist/providers/vercel/skill.generated.js +4 -5
- package/dist/providers/vercel/value-safety.js +328 -0
- package/dist/providers/wispr-flow/index.d.ts +14 -0
- package/dist/providers/wispr-flow/index.js +117 -0
- package/dist/providers/wispr-flow/skill.generated.js +8 -0
- package/dist/routes/mcp.js +30 -10
- package/dist/routes/operator.js +14 -7
- package/dist/routes/ui-config.js +2 -2
- package/dist/server.js +3 -0
- package/dist/skills.js +5 -4
- package/dist/tool-safety.js +13 -5
- package/dist/types.d.ts +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/ui.js +1 -1
- package/dist/usage-guide.js +3 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/write-outcome.js +47 -0
- package/documentation/README.md +1 -0
- package/documentation/architecture.md +155 -28
- package/documentation/auth.md +86 -27
- package/documentation/code-mode.md +81 -72
- package/documentation/deploying.md +10 -5
- package/documentation/integrating.md +72 -9
- package/documentation/meta-tools.md +52 -38
- package/documentation/operating.md +11 -8
- package/documentation/operator-tests.md +2 -3
- package/documentation/operator-ui.md +9 -3
- package/documentation/provider-auth-migration.md +308 -0
- package/documentation/provider-migration-0.29.md +18 -6
- package/examples/worker/AGENTS.md +5 -0
- package/examples/worker/README.md +2 -2
- package/examples/worker/src/connecta.config.ts +5 -0
- package/package.json +7 -2
- package/templates/node/AGENTS.md +6 -4
- package/templates/node/README.md +6 -4
- package/templates/node/package.json +1 -1
- package/templates/node/src/connecta.config.ts +5 -0
- package/dist/providers/vercel/mcp-ownership.js +0 -212
- package/dist/tool-safety.d.ts +0 -9
|
@@ -35,7 +35,7 @@ const tracker = linear("tracker", {
|
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
Linear defaults to OAuth; its read-only endpoint requests only the downstream
|
|
38
|
-
read scope. That is separate from Connecta
|
|
38
|
+
read scope. That is separate from a Connecta `readOnly` endpoint. Read the
|
|
39
39
|
[Linear skill](https://github.com/zackbart/connecta/blob/main/src/providers/linear/SKILL.md)
|
|
40
40
|
and [factory options](https://github.com/zackbart/connecta/blob/main/src/providers/linear/index.ts)
|
|
41
41
|
for API-key framing, workspace instructions, and admission choices.
|
|
@@ -49,11 +49,73 @@ mapping from admitted identity to the downstream account; a request must not
|
|
|
49
49
|
choose its own account. Gmail never sends mail, and Drive never permanently
|
|
50
50
|
deletes files.
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
Wispr Flow uses OAuth only through `wisprFlow()` from
|
|
53
|
+
`@zackbart/connecta/providers/wispr-flow`. It reaches the authorized account's
|
|
54
|
+
Notetaker content, with personal and work accounts holding separate data.
|
|
55
|
+
Its [provider guide](https://github.com/zackbart/connecta/blob/main/src/providers/wispr-flow/SKILL.md)
|
|
56
|
+
owns account access, search limits, transcript permissions and paging. The
|
|
57
|
+
reviewed classification includes task writes listed in Claude's directory even
|
|
58
|
+
though Wispr's public help describes read-only access; discover the account's
|
|
59
|
+
actual tools before assuming those writes exist.
|
|
60
|
+
|
|
61
|
+
Stripe requires `auth`: `{ type: "oauth" }` reaches Stripe's hosted MCP
|
|
62
|
+
server, and `{ type: "apiKey" }` with `mode` reaches Connecta's REST connector
|
|
63
|
+
with an operator-managed key. Notion requires `auth` the same way:
|
|
64
|
+
`{ type: "oauth" }` acts as the signed-in user over Notion's hosted MCP, and
|
|
65
|
+
`{ type: "token" }` acts as an internal integration over Connecta's REST
|
|
66
|
+
connector. Cloudflare requires `auth` too: `{ type: "oauth" }` reaches its
|
|
67
|
+
hosted MCP server, and `{ type: "apiToken" }` or `{ type: "globalApiKey" }`
|
|
68
|
+
reaches Connecta's REST connector, with an optional `pin` of accounts and zones
|
|
69
|
+
(required for a Global API Key unless `unpinned: true`). Vercel requires `auth`
|
|
70
|
+
as well: `{ type: "oauth" }` reaches Vercel's hosted MCP server, and
|
|
71
|
+
`{ type: "token" }` with an optional `teamId` reaches Connecta's REST connector
|
|
72
|
+
with an operator-managed access token. Vercel admits only reviewed and approved
|
|
73
|
+
MCP clients to its hosted server, an operational gate outside Connecta. See the
|
|
74
|
+
[provider auth migration](./provider-auth-migration.md).
|
|
75
|
+
To use both implementations of one provider, configure two connector ids with
|
|
76
|
+
independent credentials.
|
|
77
|
+
|
|
78
|
+
Planning Center's `excludeApps` removes whole products from a connection, for
|
|
79
|
+
example `planningCenter("pco", { purpose, excludeApps: ["giving"] })` for a
|
|
80
|
+
deployment that keeps agents away from donor and financial data. Excluded
|
|
81
|
+
products lose their named tools, guide text, and version pins, and the
|
|
82
|
+
`pco_api_get` and `pco_api_mutate` hatches refuse their paths before sending.
|
|
83
|
+
The check reads the exact URL the transport would fetch, and while any product
|
|
84
|
+
is excluded a hatch path must be literal: dot segments, empty segments,
|
|
85
|
+
backslashes, whitespace, and percent-encoded `/`, `\`, `?`, `#`, or `%` are
|
|
86
|
+
refused rather than normalized.
|
|
87
|
+
|
|
88
|
+
Exclusion also closes the routes through which the excluded product's data is
|
|
89
|
+
reachable through another product. While any product is excluded the connection removes
|
|
90
|
+
`list_lists`, `list_list_people`, and `run_list` and refuses every People list,
|
|
91
|
+
list result, rule, and condition, by path or `include`, because a list's
|
|
92
|
+
conditions can draw on any product, such as a donor list built from Giving
|
|
93
|
+
donations, and lists can depend on other lists. Planning Center publishes a
|
|
94
|
+
list's conditions, but a reliable check would have to follow every nested list,
|
|
95
|
+
so the connection does not attempt one. It refuses webhook event and delivery
|
|
96
|
+
payloads, since a payload can carry any product's records, and every change to
|
|
97
|
+
an existing webhook subscription by id, since the id does not name its product.
|
|
98
|
+
A new subscription must name a reachable product's event. People cannot be
|
|
99
|
+
excluded.
|
|
100
|
+
|
|
101
|
+
What exclusion guarantees is that agents reach none of the excluded product's
|
|
102
|
+
endpoints, no live cross-product query such as a People list, and no webhook
|
|
103
|
+
payload or change to an existing subscription. It does not hide records that the church's own
|
|
104
|
+
automations or staff have copied into a reachable product. A
|
|
105
|
+
[Giving automation](https://help.planningcenter.com/en/144355-automations-in-giving.html)
|
|
106
|
+
can add first-time donors to a People workflow, and those workflow cards stay
|
|
107
|
+
readable, as do donor details recorded in notes, custom fields, or form
|
|
108
|
+
answers. Those are People data once written, so the connection does not refuse
|
|
109
|
+
them by guessing at their origin.
|
|
110
|
+
|
|
111
|
+
For a hard boundary, give the connection a personal access token belonging to a
|
|
112
|
+
Planning Center user with No Access in the excluded product. Planning Center
|
|
113
|
+
sets permissions per product for each user, does not grant Giving to
|
|
114
|
+
organization administrators automatically, and lets People workflows be shared
|
|
115
|
+
per workflow; a token carries its user's permissions, so Planning Center itself
|
|
116
|
+
refuses what that user cannot see. `excludeApps` is defense in depth on top of
|
|
117
|
+
that boundary: it narrows what Connecta exposes, not what the token can do
|
|
118
|
+
elsewhere.
|
|
57
119
|
|
|
58
120
|
## Another remote MCP server
|
|
59
121
|
|
|
@@ -126,9 +188,10 @@ which binds the grant to configured API origins and manages authentication.
|
|
|
126
188
|
[Downstream OAuth on api()](./auth.md#downstream-oauth-on-api) owns a concrete
|
|
127
189
|
HTTP example and the client setup contract.
|
|
128
190
|
|
|
129
|
-
Mark every side-effecting tool `readOnlyHint: false`. On
|
|
130
|
-
writes use `call_destructive_tool
|
|
131
|
-
|
|
191
|
+
Mark every side-effecting tool `readOnlyHint: false`. On a writable endpoint
|
|
192
|
+
writes use `call_destructive_tool` or a program, within the caller's grants; a
|
|
193
|
+
`readOnly` endpoint refuses them and omits them from search. Client approval is independent of
|
|
194
|
+
tool definition. Use declared output
|
|
132
195
|
schemas when known; runtime observations cannot replace them.
|
|
133
196
|
|
|
134
197
|
## Separate ownership from visibility
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Connecta keeps one small tool surface in model context and resolves downstream
|
|
4
4
|
tools behind it. `search_tools` finds addresses, the call tools enforce the
|
|
5
|
-
stored classification, `execute_code` runs programs
|
|
5
|
+
stored classification, `execute_code` runs programs on a writable or read-only endpoint, and `connecta.result` inside programs
|
|
6
6
|
pages bounded results.
|
|
7
7
|
|
|
8
8
|
This guide is the contract an MCP client sees. The in-program `connecta.*` API
|
|
@@ -31,10 +31,13 @@ configuration adds a seventh or removes one, so a client's cached tool list
|
|
|
31
31
|
never depends on the storage behind the deployment. There was an eighth,
|
|
32
32
|
`resume_execution`, while programs paused at writes; it left with pausing
|
|
33
33
|
([#672](https://github.com/zackbart/connecta/issues/672)). `execute_code`
|
|
34
|
-
is annotated `readOnlyHint: true, destructiveHint: false` on a
|
|
35
|
-
endpoint, and `readOnlyHint: false, destructiveHint: true` on a
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
is annotated `readOnlyHint: true, destructiveHint: false` on a read-only
|
|
35
|
+
endpoint, and `readOnlyHint: false, destructiveHint: true` on a writable one.
|
|
36
|
+
Approval belongs to the client. A read-only endpoint keeps all six tools, omits
|
|
37
|
+
write tools from `search_tools` results and describe, and refuses every write
|
|
38
|
+
call; `readOnly` never changes connector visibility or read grants. Guides
|
|
39
|
+
(`queryAnalysis.guideSummary`, `skills`, `connecta.skill`, skill
|
|
40
|
+
`resources/read`) are documentation and may name tools the endpoint refuses. The four tools with structured-only success results
|
|
38
41
|
advertise `outputSchema`. The two direct-call tools omit it because their default
|
|
39
42
|
mode returns native `content`. Default-mode successes declare
|
|
40
43
|
`_meta["dev.connecta/format"]: "json" | "text"`; value mode places the value in
|
|
@@ -70,9 +73,11 @@ credentials, logs, or raw error text.
|
|
|
70
73
|
|
|
71
74
|
Connecta's discovery tools carry read-only hints. `authorize_connector`
|
|
72
75
|
requests interactive authentication changes; `call_destructive_tool` sends
|
|
73
|
-
writes and is annotated destructive. `execute_code`
|
|
74
|
-
|
|
75
|
-
program
|
|
76
|
+
writes and is annotated destructive. `execute_code` states whether the endpoint
|
|
77
|
+
is read-only or writable in its description and annotations. On a writable
|
|
78
|
+
endpoint the client may approve the whole program as a write. On a read-only
|
|
79
|
+
endpoint, the `call_tool`, `call_destructive_tool`, and `search_tools`
|
|
80
|
+
descriptions say so too; `call_destructive_tool` still runs reads there. `call_destructive_tool.reason` is dropped before
|
|
76
81
|
anything runs.
|
|
77
82
|
|
|
78
83
|
## Routing between the call surfaces
|
|
@@ -93,12 +98,16 @@ page the completed direct-call result or oversized program return with
|
|
|
93
98
|
`connecta.result` after the write runs once. Sampling or slicing a write's output
|
|
94
99
|
inside the program can still discard the answer.
|
|
95
100
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
`
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
On a writable endpoint the same program discovers and dispatches writes, capped
|
|
102
|
+
by `execute.maxWrites`, and `call_destructive_tool` sends one known write. On a
|
|
103
|
+
read-only endpoint nothing writes: `search_tools`, `connecta.search`, and
|
|
104
|
+
`connecta.describe` omit write tools as if the connector lacked them, and
|
|
105
|
+
every write call through `call_tool`, `call_destructive_tool`, or a program is
|
|
106
|
+
refused before validation or dispatch with `read_only_endpoint`,
|
|
107
|
+
`retryable: false`, and no `nextAction`. Connector guides are not filtered and
|
|
108
|
+
may still name such a write. No route on that endpoint writes; the agent
|
|
109
|
+
reports it. Connecta
|
|
110
|
+
never pauses, replays, or approves a program.
|
|
102
111
|
|
|
103
112
|
Both search routes return the flat page specified under
|
|
104
113
|
[lexical discovery](#lexical-discovery), using the catalog's shared output schema.
|
|
@@ -129,14 +138,14 @@ Read-only lookup belongs in `connecta.search` inside the program; top-level
|
|
|
129
138
|
`search_tools` stays for explicit catalog inspection and approval-required
|
|
130
139
|
discovery. Both take the same arguments.
|
|
131
140
|
|
|
132
|
-
| Argument | What it does
|
|
133
|
-
| ------------------ |
|
|
134
|
-
| `query` | two to four action/object terms; empty or whitespace-only browses
|
|
135
|
-
| `connector` | scopes to one id, loading that catalog alone instead of fanning out across every configured connector. Set it when the integration is obvious, omit it when the right one is genuinely ambiguous
|
|
136
|
-
| `safety` | `"readOnly"` selects stored `read` verdicts; `"approvalRequired"` selects stored `write` verdicts; omitted or `"all"` selects both. Each row carries `classification: "read" \| "write"`. These legacy filter names do not describe
|
|
137
|
-
| `limit` / `offset` | page the ranked results; omit `limit` initially so the default eight-result page stays small
|
|
138
|
-
| `includeSchemas` | `"compact"` for the rendered routing view, `"json"` for the exact schema, `"typescript"` for a function signature ([below](#typescript-signatures))
|
|
139
|
-
| `fullDescriptions` | unabridged tool purposes, at the obvious cost
|
|
141
|
+
| Argument | What it does |
|
|
142
|
+
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
143
|
+
| `query` | two to four action/object terms; empty or whitespace-only browses |
|
|
144
|
+
| `connector` | scopes to one id, loading that catalog alone instead of fanning out across every configured connector. Set it when the integration is obvious, omit it when the right one is genuinely ambiguous |
|
|
145
|
+
| `safety` | `"readOnly"` selects stored `read` verdicts; `"approvalRequired"` selects stored `write` verdicts; omitted or `"all"` selects both. Each row carries `classification: "read" \| "write"`. These legacy filter names do not describe client approval policy; a read-only endpoint has no write rows. |
|
|
146
|
+
| `limit` / `offset` | page the ranked results; omit `limit` initially so the default eight-result page stays small |
|
|
147
|
+
| `includeSchemas` | `"compact"` for the rendered routing view, `"json"` for the exact schema, `"typescript"` for a function signature ([below](#typescript-signatures)) |
|
|
148
|
+
| `fullDescriptions` | unabridged tool purposes, at the obvious cost |
|
|
140
149
|
|
|
141
150
|
Neither `connector` nor `safety` grants authority or changes invocation
|
|
142
151
|
admission; they select what discovery shows and nothing else.
|
|
@@ -381,7 +390,7 @@ caught catalog-load errors, unknown-tool failures, and recovery messages that
|
|
|
381
390
|
list visible connectors or local guides. Returns with no downstream calls still
|
|
382
391
|
require matching identity, origin and endpoint, current auth, and pool membership. A page must
|
|
383
392
|
match those bindings and pass current auth, connector/tool grants, pool membership,
|
|
384
|
-
and
|
|
393
|
+
and read-only checks. Old entries lacking bindings fail closed. A random UUID is a
|
|
385
394
|
handle, never an access grant.
|
|
386
395
|
|
|
387
396
|
New entries store UTF-8 bytes in a base64 envelope split across storage keys,
|
|
@@ -512,13 +521,10 @@ format: "text", text }`. The page size is clamped to the original call's inline
|
|
|
512
521
|
cap and a 32 KiB program bridge ceiling, with UTF-8 alignment and forward progress. Reassemble inside the sandbox;
|
|
513
522
|
returning pages unchanged can hit the program result cap. The admitted subject
|
|
514
523
|
and principal, endpoint/pool, request origin, connector, and tool bindings must
|
|
515
|
-
match. The host rechecks current access and
|
|
516
|
-
read-only endpoint cannot read a write stash.
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
usable bounded preview. It says paging is unavailable and the write already
|
|
520
|
-
ran; it carries no result handle or recovery action and stores no unreachable
|
|
521
|
-
stash. Write paging remains available on trusted endpoints.
|
|
524
|
+
match. The host rechecks current access and whether the endpoint is read-only
|
|
525
|
+
before returning each page; a read-only endpoint cannot read a write stash.
|
|
526
|
+
Caller arguments select no partition. A read-only endpoint never runs a write,
|
|
527
|
+
so every write result it could page came from a writable endpoint.
|
|
522
528
|
|
|
523
529
|
A refused stash write cannot undo a downstream success. Direct calls and program returns produce
|
|
524
530
|
a paging-unavailable notice, without a handle or recovery action. A write's
|
|
@@ -820,10 +826,11 @@ attempted tool name; an unknown tool scopes the same query to the connector that
|
|
|
820
826
|
answered. The suggested route follows the route the caller took:
|
|
821
827
|
`tool: "search_tools"` for a top-level call, `function: "connecta.search"` with
|
|
822
828
|
the same arguments when the miss happened inside `execute_code`, which has no
|
|
823
|
-
way to call a tool. `call_tool` reaching an unannotated,
|
|
824
|
-
destructive tool returns `
|
|
825
|
-
|
|
826
|
-
|
|
829
|
+
way to call a tool. On a writable endpoint, `call_tool` reaching an unannotated,
|
|
830
|
+
write-capable, or destructive tool returns `destructive_tool_requires_approval`
|
|
831
|
+
with `nextAction` for `call_destructive_tool` and the canonical address. On a
|
|
832
|
+
read-only endpoint every write path returns `read_only_endpoint` with no
|
|
833
|
+
`nextAction`. Nothing is executed by these records.
|
|
827
834
|
|
|
828
835
|
`connecta.describe` keeps its failures inline instead, so one miss cannot
|
|
829
836
|
discard the other schemas; each failed entry carries a human `error`, typed
|
|
@@ -924,13 +931,20 @@ scoped registry, including an empty list when none are accessible. They never
|
|
|
924
931
|
list connectors from another pool or identity's grants.
|
|
925
932
|
|
|
926
933
|
A write that times out after dispatch returns `write_outcome_unknown` with
|
|
927
|
-
`retryable: false` and an agent-only `uncertainCall: { address, args?, argsOmitted?, argsRedacted? }`.
|
|
928
|
-
No write is automatically replayed. `
|
|
934
|
+
`retryable: false` and an agent-only `uncertainCall: { address, args?, argsOmitted?, argsRedacted?, recovery? }`.
|
|
935
|
+
No write is automatically replayed. `recovery` carries facts the connector
|
|
936
|
+
recorded before dispatch (`src/call-recovery.ts`), such as the `idempotencyKey`
|
|
937
|
+
a REST connector generated; a deliberate retry that reuses it with the exact
|
|
938
|
+
original arguments cannot repeat the write while the vendor retains the key
|
|
939
|
+
(Stripe may prune v1 keys after 24 hours). After that, look the object up before
|
|
940
|
+
retrying. When a connector recorded such facts, any other dispatched write whose
|
|
941
|
+
outcome is unknown (a lost response body, a 5xx) also carries `uncertainCall`
|
|
942
|
+
with them under its own code, and program write accounting keeps it. `args` may be partial reconciliation context
|
|
929
943
|
with `argsRedacted: true`. A withheld echo or arguments over the 512-byte budget
|
|
930
944
|
carry `argsOmitted: true`; sensitive or unresolved schemas also carry
|
|
931
945
|
`argsRedacted: true`. When `args` is absent or redacted, use the original
|
|
932
|
-
arguments if reconciliation requires another call. A timeout before dispatch remains `timeout`.
|
|
933
|
-
|
|
946
|
+
arguments if reconciliation requires another call. A timeout before dispatch remains `timeout`.
|
|
947
|
+
Program write accounting keeps this detail even if the guest catches the
|
|
934
948
|
failure or returns early. Multiple uncertain writes use `uncertainCalls`,
|
|
935
949
|
bounded to ten calls with `uncertainCallsTruncated` when more exist.
|
|
936
950
|
|
|
@@ -15,14 +15,17 @@ instructions and `skills` usage guide for deployment-specific context.
|
|
|
15
15
|
| ------------------------------------------------------------------ | --------------------------------------------------------- |
|
|
16
16
|
| One known read, with usable arguments and a small result | `call_tool` |
|
|
17
17
|
| Discover a tool, chain calls, combine services, or reduce a result | `execute_code` |
|
|
18
|
-
| One write on a
|
|
18
|
+
| One known write on a writable endpoint | `call_destructive_tool` |
|
|
19
19
|
| Obtain connector instructions | `skills` with the returned guide name |
|
|
20
20
|
| Start a required authentication handoff | `authorize_connector`, using the returned recovery action |
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
controls approval.
|
|
22
|
+
Whether the endpoint is read-only or writable is part of its tool
|
|
23
|
+
descriptions. On a writable endpoint, programs and `call_destructive_tool` may
|
|
24
|
+
write within the caller's grants, and `execute_code` is annotated as a write;
|
|
25
|
+
the client controls approval. On a read-only endpoint, search and describe omit
|
|
26
|
+
write tools and every write call is refused with `read_only_endpoint`, even one
|
|
27
|
+
a connector guide names; tell the user rather than looking for another route. Never change pool, identity, or `readOnly` to work
|
|
28
|
+
around a refusal.
|
|
26
29
|
[Routing between the call surfaces](./meta-tools.md#routing-between-the-call-surfaces)
|
|
27
30
|
owns the full decision rules.
|
|
28
31
|
|
|
@@ -35,9 +38,9 @@ failed catalog or a service outside the caller's grants.
|
|
|
35
38
|
|
|
36
39
|
For normal reads, keep discovery, calls, and reduction in one program when the
|
|
37
40
|
schemas suffice; return the answer rather than catalog matches. Use top-level
|
|
38
|
-
`search_tools` for catalog inspection or to
|
|
39
|
-
endpoint, then dispatch
|
|
40
|
-
|
|
41
|
+
`search_tools` for catalog inspection or to find one known write on a writable
|
|
42
|
+
endpoint, then dispatch it with `call_destructive_tool`. An unfamiliar read
|
|
43
|
+
result may return a bounded sample for inspection before the next program.
|
|
41
44
|
|
|
42
45
|
Use the exact returned `address`, including punctuation. A TypeScript signature
|
|
43
46
|
is guidance for writing JavaScript; do not paste types into executable code.
|
|
@@ -72,9 +72,8 @@ gh run download RUN_ID --name operator-linux-snapshots \
|
|
|
72
72
|
|
|
73
73
|
The workflow uploads all generated baselines and never commits them. Review the
|
|
74
74
|
images and changed files, commit the intentional changes, and push again. The
|
|
75
|
-
normal CI browser job must compare and pass against that commit.
|
|
76
|
-
|
|
77
|
-
before the workflow reaches main. Later updates use `workflow_dispatch`.
|
|
75
|
+
normal CI browser job must compare and pass against that commit. Snapshot
|
|
76
|
+
updates run only through `workflow_dispatch`.
|
|
78
77
|
|
|
79
78
|
On a matching Linux runner, `npm ci`, install Chromium with the command above,
|
|
80
79
|
then run `npm run test:browser:snapshots`. The normal command is
|
|
@@ -42,7 +42,9 @@ from `connecta/ui`. `src/operator-ui/contract.ts` is also the browser's type
|
|
|
42
42
|
source. The response has `schemaVersion: 1`, `config`, `configSources`, `live`, and `you`.
|
|
43
43
|
`config` is the construction-time `describeConfig()` snapshot, filtered to
|
|
44
44
|
visible connectors, granted tools, classification overrides, and admitted
|
|
45
|
-
pools.
|
|
45
|
+
pools. `config.hasGrant` reports whether deployment code configures a grant for
|
|
46
|
+
plain `/mcp`; Access displays that fact and Config includes its provenance.
|
|
47
|
+
Pool tools are the intersection with the caller's identity grants.
|
|
46
48
|
`configSources` labels each serialized leaf as `default` or `config`, based on
|
|
47
49
|
option presence rather than equality with the default. Factory descriptions carry
|
|
48
50
|
relative `optionSources` paths so resolved module and transport defaults retain
|
|
@@ -52,6 +54,10 @@ ids and pool names and are filtered after disclosure; hidden values leave no
|
|
|
52
54
|
provenance keys. It contains no source code or credential material.
|
|
53
55
|
Every response is private, `no-store` JSON. Only GET is allowed, with the
|
|
54
56
|
same auth gate and identity partition as `/ui/data` and `/ui/connectors/:id`.
|
|
57
|
+
These catalog reads, activity reads, and connector auth routes also require
|
|
58
|
+
admission through the default `/mcp` grant. Refusals return private JSON 404s;
|
|
59
|
+
there is no per-pool UI view. Public HTML shells and static assets carry no
|
|
60
|
+
catalog data. Access-token management retains its interactive permission gate.
|
|
55
61
|
|
|
56
62
|
`live.connectors` carries status and problem codes, complete registry tools
|
|
57
63
|
with their final read/write classification, catalog age in milliseconds, and
|
|
@@ -69,7 +75,7 @@ personal connectors to the caller's activity identity. Each retained fact
|
|
|
69
75
|
copies a validated timestamp and outcome only. A null call means unknown or
|
|
70
76
|
absent in that window, not proof of no calls. `live.activity` distinguishes
|
|
71
77
|
available, unconfigured, forbidden, and unavailable history. `you` names no
|
|
72
|
-
identity or auth material; it reports grants, root and admitted-
|
|
78
|
+
identity or auth material; it reports grants, whether the root and admitted pools are read-only,
|
|
73
79
|
and effective activity, token, and per-connector auth permissions.
|
|
74
80
|
|
|
75
81
|
`connecta doctor --config` fetches this authenticated contract and prints only
|
|
@@ -112,7 +118,7 @@ id and typed actor when available, otherwise a fresh id and system actor. No
|
|
|
112
118
|
names, descriptions or schemas enter the event. Private catalog changes require
|
|
113
119
|
a matching principal owner even when the connector uses shared auth. Empty credential declarations
|
|
114
120
|
report `credential_required` before running a connector status or catalog probe.
|
|
115
|
-
The Access adapter reports inbound provider kinds, admitted pools, grants,
|
|
121
|
+
The Access adapter reports inbound provider kinds, admitted pools, grants, read-only endpoints
|
|
116
122
|
and endpoint setup; token controls retain their existing permission gate.
|
|
117
123
|
Configuration remains in deployment code. The UI mutates only credentials,
|
|
118
124
|
OAuth connections and client tokens through the existing routes.
|