@zackbart/connecta 0.15.1 → 0.16.1
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/AGENTS.md +40 -20
- package/CHANGELOG.md +653 -0
- package/README.md +25 -5
- package/bin/connecta.mjs +44 -3
- package/dist/access-tokens.d.ts +0 -1
- package/dist/access-tokens.js +0 -1
- package/dist/activity.d.ts +50 -2
- package/dist/activity.js +34 -1
- package/dist/apps-shell.d.ts +0 -1
- package/dist/apps-shell.js +0 -1
- package/dist/auth/bearer.d.ts +0 -1
- package/dist/auth/bearer.js +0 -1
- package/dist/auth/clerk.d.ts +0 -1
- package/dist/auth/clerk.js +45 -9
- package/dist/auth/downstream-oauth.d.ts +0 -1
- package/dist/auth/downstream-oauth.js +0 -1
- package/dist/call-admission.d.ts +0 -1
- package/dist/call-admission.js +0 -1
- package/dist/catalog-drift.d.ts +99 -0
- package/dist/catalog-drift.js +251 -0
- package/dist/catalog-fingerprint.d.ts +0 -1
- package/dist/catalog-fingerprint.js +0 -1
- package/dist/catalog-limits.d.ts +0 -1
- package/dist/catalog-limits.js +0 -1
- package/dist/catalog-service.d.ts +0 -1
- package/dist/catalog-service.js +41 -5
- package/dist/catalog.d.ts +11 -1
- package/dist/catalog.js +20 -1
- package/dist/concurrency.d.ts +0 -1
- package/dist/concurrency.js +0 -1
- package/dist/connector-scope.d.ts +0 -1
- package/dist/connector-scope.js +0 -1
- package/dist/connectors/api.d.ts +29 -21
- package/dist/connectors/api.js +45 -19
- package/dist/connectors/guarded-fetch.d.ts +106 -0
- package/dist/connectors/guarded-fetch.js +289 -0
- package/dist/connectors/remote-mcp.d.ts +0 -1
- package/dist/connectors/remote-mcp.js +0 -1
- package/dist/credentials.d.ts +0 -1
- package/dist/credentials.js +0 -1
- package/dist/errors.d.ts +30 -3
- package/dist/errors.js +1 -1
- package/dist/execute.d.ts +0 -1
- package/dist/execute.js +0 -1
- package/dist/executor-admission.d.ts +11 -1
- package/dist/executor-admission.js +28 -1
- package/dist/executor-result.d.ts +0 -1
- package/dist/executor-result.js +0 -1
- package/dist/executors/quickjs-child.d.ts +0 -1
- package/dist/executors/quickjs-child.js +0 -1
- package/dist/executors/quickjs-protocol.d.ts +0 -1
- package/dist/executors/quickjs-protocol.js +0 -1
- package/dist/executors/quickjs-runtime.d.ts +0 -1
- package/dist/executors/quickjs-runtime.js +0 -1
- package/dist/executors/quickjs.d.ts +0 -1
- package/dist/executors/quickjs.js +2 -1
- package/dist/favicon.d.ts +0 -1
- package/dist/favicon.js +0 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +24 -7
- package/dist/invocation.d.ts +0 -1
- package/dist/invocation.js +0 -1
- package/dist/json-schema.d.ts +0 -1
- package/dist/json-schema.js +0 -1
- package/dist/mcp-result.d.ts +0 -1
- package/dist/mcp-result.js +0 -1
- package/dist/meta-tools.d.ts +0 -1
- package/dist/meta-tools.js +0 -1
- package/dist/node.d.ts +0 -1
- package/dist/node.js +0 -1
- package/dist/operator-ui/generated.d.ts +2 -3
- package/dist/operator-ui/generated.js +3 -4
- package/dist/operator-ui/model.d.ts +10 -1
- package/dist/operator-ui/model.js +0 -1
- package/dist/operator-ui/view.d.ts +167 -0
- package/dist/operator-ui/view.js +270 -0
- package/dist/providers/cloudflare.d.ts +0 -1
- package/dist/providers/cloudflare.js +261 -299
- package/dist/providers/linear.d.ts +26 -5
- package/dist/providers/linear.js +32 -61
- package/dist/providers/mixpanel.d.ts +35 -4
- package/dist/providers/mixpanel.js +53 -79
- package/dist/providers/notion.d.ts +0 -1
- package/dist/providers/notion.js +87 -42
- package/dist/providers/stripe.d.ts +13 -1
- package/dist/providers/stripe.js +31 -60
- package/dist/registry.d.ts +34 -2
- package/dist/registry.js +85 -5
- package/dist/retired-toolkits.d.ts +0 -1
- package/dist/retired-toolkits.js +0 -1
- package/dist/routes/access-tokens.d.ts +0 -1
- package/dist/routes/access-tokens.js +0 -1
- package/dist/routes/activity.d.ts +0 -1
- package/dist/routes/activity.js +0 -1
- package/dist/routes/credentials.d.ts +0 -1
- package/dist/routes/credentials.js +0 -1
- package/dist/routes/mcp.d.ts +0 -1
- package/dist/routes/mcp.js +0 -1
- package/dist/routes/oauth.d.ts +0 -1
- package/dist/routes/oauth.js +0 -1
- package/dist/routes/shared.d.ts +2 -1
- package/dist/routes/shared.js +0 -1
- package/dist/routes/ui.d.ts +0 -1
- package/dist/routes/ui.js +0 -1
- package/dist/server.d.ts +0 -1
- package/dist/server.js +11 -1
- package/dist/skills.d.ts +0 -1
- package/dist/skills.js +0 -1
- package/dist/storage/file.d.ts +0 -1
- package/dist/storage/file.js +0 -1
- package/dist/storage/memory.d.ts +0 -1
- package/dist/storage/memory.js +0 -1
- package/dist/timeout.d.ts +0 -1
- package/dist/timeout.js +0 -1
- package/dist/tool-safety.d.ts +0 -1
- package/dist/tool-safety.js +0 -1
- package/dist/types.d.ts +45 -1
- package/dist/types.js +0 -1
- package/dist/ui.d.ts +0 -1
- package/dist/ui.js +13 -137
- package/dist/validate.d.ts +13 -15
- package/dist/validate.js +24 -11
- package/dist/version.d.ts +1 -2
- package/dist/version.js +1 -2
- package/documentation/architecture.md +186 -5
- package/documentation/auth.md +11 -0
- package/documentation/call-admission.md +142 -6
- package/documentation/cloudflare.md +92 -10
- package/documentation/code-first-exploration.md +2 -2
- package/documentation/code-mode.md +14 -14
- package/documentation/connector-guides.md +172 -5
- package/documentation/connectors.md +89 -0
- package/documentation/linear.md +20 -2
- package/documentation/mcp-ui-design.md +2 -2
- package/documentation/meta-tools.md +7 -1
- package/documentation/mixpanel.md +42 -9
- package/documentation/notion.md +23 -2
- package/documentation/operations.md +325 -5
- package/documentation/operator-ui.md +120 -5
- package/documentation/provider-audit.md +160 -0
- package/documentation/provider-conventions.md +667 -0
- package/documentation/request-admission.md +167 -5
- package/documentation/rich-output-design.md +1 -2
- package/documentation/stripe.md +15 -0
- package/documentation/upgrading.md +454 -0
- package/ethos.md +14 -9
- package/examples/worker/README.md +102 -12
- package/examples/worker/src/index.ts +46 -1
- package/examples/worker/wrangler.jsonc +14 -1
- package/package.json +10 -6
- package/templates/node/.dockerignore +10 -0
- package/templates/node/.env.example +40 -3
- package/templates/node/AGENTS.md +16 -1
- package/templates/node/Dockerfile +49 -0
- package/templates/node/README.md +117 -2
- package/templates/node/docker-compose.yml +39 -0
- package/templates/node/package.json +1 -1
- package/templates/node/src/file-activity.ts +182 -0
- package/templates/node/src/index.ts +80 -4
- package/assets/connecta-clay-hero.png +0 -0
- package/dist/access-tokens.d.ts.map +0 -1
- package/dist/access-tokens.js.map +0 -1
- package/dist/activity.d.ts.map +0 -1
- package/dist/activity.js.map +0 -1
- package/dist/apps-shell.d.ts.map +0 -1
- package/dist/apps-shell.js.map +0 -1
- package/dist/auth/bearer.d.ts.map +0 -1
- package/dist/auth/bearer.js.map +0 -1
- package/dist/auth/clerk.d.ts.map +0 -1
- package/dist/auth/clerk.js.map +0 -1
- package/dist/auth/downstream-oauth.d.ts.map +0 -1
- package/dist/auth/downstream-oauth.js.map +0 -1
- package/dist/call-admission.d.ts.map +0 -1
- package/dist/call-admission.js.map +0 -1
- package/dist/catalog-fingerprint.d.ts.map +0 -1
- package/dist/catalog-fingerprint.js.map +0 -1
- package/dist/catalog-limits.d.ts.map +0 -1
- package/dist/catalog-limits.js.map +0 -1
- package/dist/catalog-service.d.ts.map +0 -1
- package/dist/catalog-service.js.map +0 -1
- package/dist/catalog.d.ts.map +0 -1
- package/dist/catalog.js.map +0 -1
- package/dist/concurrency.d.ts.map +0 -1
- package/dist/concurrency.js.map +0 -1
- package/dist/connector-scope.d.ts.map +0 -1
- package/dist/connector-scope.js.map +0 -1
- package/dist/connectors/api.d.ts.map +0 -1
- package/dist/connectors/api.js.map +0 -1
- package/dist/connectors/remote-mcp.d.ts.map +0 -1
- package/dist/connectors/remote-mcp.js.map +0 -1
- package/dist/credentials.d.ts.map +0 -1
- package/dist/credentials.js.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js.map +0 -1
- package/dist/execute.d.ts.map +0 -1
- package/dist/execute.js.map +0 -1
- package/dist/executor-admission.d.ts.map +0 -1
- package/dist/executor-admission.js.map +0 -1
- package/dist/executor-result.d.ts.map +0 -1
- package/dist/executor-result.js.map +0 -1
- package/dist/executors/quickjs-child.d.ts.map +0 -1
- package/dist/executors/quickjs-child.js.map +0 -1
- package/dist/executors/quickjs-protocol.d.ts.map +0 -1
- package/dist/executors/quickjs-protocol.js.map +0 -1
- package/dist/executors/quickjs-runtime.d.ts.map +0 -1
- package/dist/executors/quickjs-runtime.js.map +0 -1
- package/dist/executors/quickjs.d.ts.map +0 -1
- package/dist/executors/quickjs.js.map +0 -1
- package/dist/favicon.d.ts.map +0 -1
- package/dist/favicon.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/invocation.d.ts.map +0 -1
- package/dist/invocation.js.map +0 -1
- package/dist/json-schema.d.ts.map +0 -1
- package/dist/json-schema.js.map +0 -1
- package/dist/mcp-result.d.ts.map +0 -1
- package/dist/mcp-result.js.map +0 -1
- package/dist/meta-tools.d.ts.map +0 -1
- package/dist/meta-tools.js.map +0 -1
- package/dist/node.d.ts.map +0 -1
- package/dist/node.js.map +0 -1
- package/dist/operator-ui/generated.d.ts.map +0 -1
- package/dist/operator-ui/generated.js.map +0 -1
- package/dist/operator-ui/model.d.ts.map +0 -1
- package/dist/operator-ui/model.js.map +0 -1
- package/dist/providers/cloudflare.d.ts.map +0 -1
- package/dist/providers/cloudflare.js.map +0 -1
- package/dist/providers/linear.d.ts.map +0 -1
- package/dist/providers/linear.js.map +0 -1
- package/dist/providers/mixpanel.d.ts.map +0 -1
- package/dist/providers/mixpanel.js.map +0 -1
- package/dist/providers/notion.d.ts.map +0 -1
- package/dist/providers/notion.js.map +0 -1
- package/dist/providers/stripe.d.ts.map +0 -1
- package/dist/providers/stripe.js.map +0 -1
- package/dist/registry.d.ts.map +0 -1
- package/dist/registry.js.map +0 -1
- package/dist/retired-toolkits.d.ts.map +0 -1
- package/dist/retired-toolkits.js.map +0 -1
- package/dist/routes/access-tokens.d.ts.map +0 -1
- package/dist/routes/access-tokens.js.map +0 -1
- package/dist/routes/activity.d.ts.map +0 -1
- package/dist/routes/activity.js.map +0 -1
- package/dist/routes/credentials.d.ts.map +0 -1
- package/dist/routes/credentials.js.map +0 -1
- package/dist/routes/mcp.d.ts.map +0 -1
- package/dist/routes/mcp.js.map +0 -1
- package/dist/routes/oauth.d.ts.map +0 -1
- package/dist/routes/oauth.js.map +0 -1
- package/dist/routes/shared.d.ts.map +0 -1
- package/dist/routes/shared.js.map +0 -1
- package/dist/routes/ui.d.ts.map +0 -1
- package/dist/routes/ui.js.map +0 -1
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/skills.d.ts.map +0 -1
- package/dist/skills.js.map +0 -1
- package/dist/storage/file.d.ts.map +0 -1
- package/dist/storage/file.js.map +0 -1
- package/dist/storage/memory.d.ts.map +0 -1
- package/dist/storage/memory.js.map +0 -1
- package/dist/timeout.d.ts.map +0 -1
- package/dist/timeout.js.map +0 -1
- package/dist/tool-safety.d.ts.map +0 -1
- package/dist/tool-safety.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/ui.d.ts.map +0 -1
- package/dist/ui.js.map +0 -1
- package/dist/validate.d.ts.map +0 -1
- package/dist/validate.js.map +0 -1
- package/dist/version.d.ts.map +0 -1
- package/dist/version.js.map +0 -1
- package/examples/node/README.md +0 -52
- package/examples/node/src/index.ts +0 -71
- package/src/access-tokens.ts +0 -289
- package/src/activity.ts +0 -234
- package/src/apps-shell.ts +0 -370
- package/src/auth/bearer.ts +0 -61
- package/src/auth/clerk.ts +0 -553
- package/src/auth/downstream-oauth.ts +0 -575
- package/src/call-admission.ts +0 -521
- package/src/catalog-fingerprint.ts +0 -52
- package/src/catalog-limits.ts +0 -11
- package/src/catalog-service.ts +0 -1153
- package/src/catalog.ts +0 -790
- package/src/concurrency.ts +0 -39
- package/src/connector-scope.ts +0 -66
- package/src/connectors/api.ts +0 -159
- package/src/connectors/remote-mcp.ts +0 -1090
- package/src/credentials.ts +0 -428
- package/src/errors.ts +0 -364
- package/src/execute.ts +0 -1406
- package/src/executor-admission.ts +0 -328
- package/src/executor-result.ts +0 -107
- package/src/executors/quickjs-child.ts +0 -172
- package/src/executors/quickjs-protocol.ts +0 -99
- package/src/executors/quickjs-runtime.ts +0 -470
- package/src/executors/quickjs.ts +0 -776
- package/src/favicon.ts +0 -53
- package/src/index.ts +0 -666
- package/src/invocation.ts +0 -655
- package/src/json-schema.ts +0 -11
- package/src/mcp-result.ts +0 -43
- package/src/meta-tools.ts +0 -1607
- package/src/node.ts +0 -206
- package/src/operator-ui/browser.css +0 -423
- package/src/operator-ui/browser.ts +0 -1281
- package/src/operator-ui/generated.ts +0 -4
- package/src/operator-ui/model.ts +0 -111
- package/src/providers/cloudflare.ts +0 -3999
- package/src/providers/linear.ts +0 -302
- package/src/providers/mixpanel.ts +0 -229
- package/src/providers/notion.ts +0 -1879
- package/src/providers/stripe.ts +0 -307
- package/src/registry.ts +0 -1085
- package/src/retired-toolkits.ts +0 -14
- package/src/routes/access-tokens.ts +0 -115
- package/src/routes/activity.ts +0 -215
- package/src/routes/credentials.ts +0 -254
- package/src/routes/mcp.ts +0 -429
- package/src/routes/oauth.ts +0 -322
- package/src/routes/shared.ts +0 -247
- package/src/routes/ui.ts +0 -152
- package/src/server.ts +0 -195
- package/src/skills.ts +0 -271
- package/src/storage/file.ts +0 -123
- package/src/storage/memory.ts +0 -44
- package/src/timeout.ts +0 -84
- package/src/tool-safety.ts +0 -15
- package/src/types.ts +0 -523
- package/src/ui.ts +0 -744
- package/src/validate.ts +0 -387
- package/src/version.ts +0 -7
|
@@ -111,6 +111,11 @@ export const connecta = createConnecta({
|
|
|
111
111
|
All three are ordinary `Connector` instances by the time the registry sees
|
|
112
112
|
them. Nothing in the list is privileged by how it was authored.
|
|
113
113
|
|
|
114
|
+
What a maintained connection owes an agent is written down rather than
|
|
115
|
+
inherited from whoever wrote it last:
|
|
116
|
+
[provider conventions](./provider-conventions.md), one set for hand-written
|
|
117
|
+
HTTP surfaces and one for hosted-MCP proxies.
|
|
118
|
+
|
|
114
119
|
Maintained provider guides:
|
|
115
120
|
|
|
116
121
|
- [Cloudflare](./cloudflare.md)
|
|
@@ -119,6 +124,90 @@ Maintained provider guides:
|
|
|
119
124
|
- [Notion](./notion.md)
|
|
120
125
|
- [Stripe](./stripe.md)
|
|
121
126
|
|
|
127
|
+
## The `api()` construction contract
|
|
128
|
+
|
|
129
|
+
`api()` is the path every custom integration takes, and whatever it accepts is
|
|
130
|
+
what an agent eventually reads. Three things are refused at construction rather
|
|
131
|
+
than discovered in production
|
|
132
|
+
([#340](https://github.com/zackbart/connecta/issues/340)):
|
|
133
|
+
|
|
134
|
+
- **A tool with no description.** Discovery has nothing else to route on, and a
|
|
135
|
+
guess costs a call.
|
|
136
|
+
- **A tool with no explicit boolean `annotations.readOnlyHint`.** `true`
|
|
137
|
+
declares a read and admits the tool to `call_tool` and `execute_code`;
|
|
138
|
+
`false` declares work that crosses `call_destructive_tool`, where the host
|
|
139
|
+
can ask a human. Connecta never infers the classification from a tool name,
|
|
140
|
+
description, schema, HTTP method, or the other annotations — an unclassified
|
|
141
|
+
tool is a bug in the deployment, not a puzzle to solve.
|
|
142
|
+
- **An `inputSchema` the validator cannot compile.** Declaring one is optional;
|
|
143
|
+
declaring one that cannot be enforced is not. A schema that only reveals
|
|
144
|
+
itself on first use — an unresolvable `$ref`, say — fails that call as
|
|
145
|
+
non-retryable `invalid_args` rather than forwarding raw arguments to the
|
|
146
|
+
handler. `validateArgs: false` still opts out of enforcement for deployments
|
|
147
|
+
that want loose coercion; it does not opt out of the schema being real.
|
|
148
|
+
|
|
149
|
+
None of this reaches a proxied catalog: hosted-MCP tools arrive as their
|
|
150
|
+
downstream wrote them, and an unannotated or contradictory one stays
|
|
151
|
+
fail-closed onto `call_destructive_tool`. The contract binds the surfaces we
|
|
152
|
+
write, not the catalogs we relay.
|
|
153
|
+
|
|
154
|
+
## The guarded fetch transport
|
|
155
|
+
|
|
156
|
+
Every hand-written HTTP surface re-derives the same safety machinery, and two
|
|
157
|
+
of them had already derived it slightly differently. `src/connectors/guarded-fetch.ts`
|
|
158
|
+
is that machinery extracted once ([#341](https://github.com/zackbart/connecta/issues/341)):
|
|
159
|
+
one `guardedFetch({ provider, baseUrl, headers, maxResponseBytes, authenticate })`
|
|
160
|
+
factory returning the transport a connector sends every request through.
|
|
161
|
+
|
|
162
|
+
What it owns is mechanical and provider-independent:
|
|
163
|
+
|
|
164
|
+
- **Confinement.** A request path is provider-relative, carries no query or
|
|
165
|
+
fragment, and is re-checked against the base origin and path prefix *after*
|
|
166
|
+
`new URL` normalization — because normalization is how a path escapes a
|
|
167
|
+
prefix, not something to trust before it.
|
|
168
|
+
- **Construction.** Query parameters are encoded rather than concatenated, a
|
|
169
|
+
JSON body is serialized with the `Content-Type` to match, and a pre-framed
|
|
170
|
+
body gets none, so `fetch` still picks the multipart boundary.
|
|
171
|
+
- **Credential forwarding.** `authenticate` is called once per request and its
|
|
172
|
+
headers are applied last; a request header wearing one of their names is
|
|
173
|
+
refused rather than allowed to shadow it. A 3xx is refused outright — a
|
|
174
|
+
redirect is an instruction to re-send the credential to whatever origin the
|
|
175
|
+
`Location` names, and a confinement a redirect can undo was never one.
|
|
176
|
+
- **Bounded reads.** `maxResponseBytes` is required, not defaulted: what counts
|
|
177
|
+
as an absurd response is a fact about the API, not about HTTP. A declared
|
|
178
|
+
`Content-Length` past the ceiling fails before a byte is read, and a
|
|
179
|
+
streaming body is abandoned at the ceiling rather than buffered past it.
|
|
180
|
+
- **Normalization.** An unreachable provider becomes a retryable `unavailable`
|
|
181
|
+
instead of whatever `TypeError` the runtime threw, and `ctx.signal` rides
|
|
182
|
+
every request.
|
|
183
|
+
|
|
184
|
+
What it deliberately does not own is meaning. It never reads a status code and
|
|
185
|
+
never invents an authentication scheme: the provider's `authenticate` callback
|
|
186
|
+
supplies the headers, and the provider's mapper turns one `GuardedResponse`
|
|
187
|
+
into a result or a typed failure. That split is not fastidiousness. Notion's
|
|
188
|
+
403 means a capability the integration was never granted — re-authorizing
|
|
189
|
+
cannot fix it — while Cloudflare's means a token scope, and the two want
|
|
190
|
+
opposite next moves. A helper that guessed would be wrong for one of them.
|
|
191
|
+
|
|
192
|
+
Cloudflare and Notion both run on it. Their existing suites carried over
|
|
193
|
+
unchanged, which proves the migration kept the behavior those suites cover —
|
|
194
|
+
not that nothing changed. Three things did, and the changelog names them: a
|
|
195
|
+
3xx is refused where both providers used to follow it, both now fail past
|
|
196
|
+
their byte ceiling, and `cloudflare()`'s `baseUrl` is validated at
|
|
197
|
+
construction. Each suite gained one test for the ceiling, because the one
|
|
198
|
+
guard the helper was written to add is the one a provider's own mapper can
|
|
199
|
+
most easily disarm: a bare `catch` around `response.json()` swallows the
|
|
200
|
+
transport's refusal along with a parse error, and turns a response nobody was
|
|
201
|
+
allowed to read into an empty success. A mapper re-throws
|
|
202
|
+
`ConnectorCallError` and swallows only what it recognizes.
|
|
203
|
+
|
|
204
|
+
It is **not exported this release**: the two migrations proved the shape
|
|
205
|
+
preserves behavior for connectors that already had this machinery, not that it
|
|
206
|
+
is the right shape for an author starting from nothing, and an unexported
|
|
207
|
+
symbol costs nothing to reshape while a published one is a promise.
|
|
208
|
+
The provider audit ([#342](https://github.com/zackbart/connecta/issues/342))
|
|
209
|
+
supplies the third caller that would settle it.
|
|
210
|
+
|
|
122
211
|
## MCP version skew
|
|
123
212
|
|
|
124
213
|
Connecta deliberately sits between protocol generations
|
package/documentation/linear.md
CHANGED
|
@@ -11,6 +11,7 @@ import { linear } from "@zackbart/connecta/providers/linear";
|
|
|
11
11
|
const tracker = linear("product_tracker", {
|
|
12
12
|
title: "Product issue tracking",
|
|
13
13
|
purpose: "Issue and project planning for the platform team",
|
|
14
|
+
access: "read-write",
|
|
14
15
|
instructions: "File bugs into the Platform team unless the request names another.",
|
|
15
16
|
});
|
|
16
17
|
```
|
|
@@ -23,13 +24,21 @@ cannot change the connector's safety classification.
|
|
|
23
24
|
|
|
24
25
|
## Access modes
|
|
25
26
|
|
|
26
|
-
Linear publishes two hosted endpoints, and `access` selects between them
|
|
27
|
+
Linear publishes two hosted endpoints, and `access` selects between them. It is
|
|
28
|
+
**required**, with no default:
|
|
27
29
|
|
|
28
30
|
| `access` | Endpoint | OAuth scopes |
|
|
29
31
|
| --- | --- | --- |
|
|
30
|
-
| `"read-write"`
|
|
32
|
+
| `"read-write"` | `https://mcp.linear.app/mcp` | `read`, `write` |
|
|
31
33
|
| `"read-only"` | `https://mcp.linear.app/mcp/readonly` | `read` |
|
|
32
34
|
|
|
35
|
+
There is no safe default to pick. Defaulting to `"read-write"` hands a
|
|
36
|
+
deployment write access it never asked for; defaulting to `"read-only"` turns a
|
|
37
|
+
deployment that does write into one whose every write fails at Linear — at
|
|
38
|
+
runtime, where no agent can repair it. So the operator declares which one this
|
|
39
|
+
is, and a deployment that forgot fails at construction with a message naming
|
|
40
|
+
both options.
|
|
41
|
+
|
|
33
42
|
Read-only is not a client-side filter. The endpoint advertises the `read` scope
|
|
34
43
|
alone, so the token minted for it cannot reach Linear's write APIs — a stronger
|
|
35
44
|
guarantee than any annotation Connecta applies. A deployment that only reports
|
|
@@ -63,6 +72,7 @@ also accepts a bearer token or a personal API key passed directly in the
|
|
|
63
72
|
```ts
|
|
64
73
|
linear("automation_tracker", {
|
|
65
74
|
purpose: "Headless release reporting",
|
|
75
|
+
access: "read-only",
|
|
66
76
|
auth: {
|
|
67
77
|
type: "headers",
|
|
68
78
|
headers: { Authorization: env.LINEAR_API_KEY },
|
|
@@ -130,6 +140,7 @@ one. An operator who knows their workspace can supply one explicitly:
|
|
|
130
140
|
```ts
|
|
131
141
|
linear("product_tracker", {
|
|
132
142
|
purpose: "Issue and project planning for the platform team",
|
|
143
|
+
access: "read-write",
|
|
133
144
|
callAdmission: {
|
|
134
145
|
rules: [
|
|
135
146
|
{ budget: { kind: "rolling-window", maxCalls: 1_000, windowMs: 3_600_000 } },
|
|
@@ -141,3 +152,10 @@ linear("product_tracker", {
|
|
|
141
152
|
A budget-only rule needs no queue. If you add `maxConcurrency` you are asking
|
|
142
153
|
for a queue, and the admission controller then requires the rest of the queue
|
|
143
154
|
settings at construction.
|
|
155
|
+
|
|
156
|
+
## Conventions
|
|
157
|
+
|
|
158
|
+
This connection is audited against
|
|
159
|
+
[the provider conventions](./provider-conventions.md). Its verdict per
|
|
160
|
+
convention, including every recorded exception, is the Linear section of
|
|
161
|
+
[the provider audit](./provider-audit.md).
|
|
@@ -375,8 +375,8 @@ buy a guarantee the protocol already gives away.
|
|
|
375
375
|
source carries the `srcdoc` and sandbox attributes and contains no
|
|
376
376
|
message-forwarding path from the inner frame to the host.
|
|
377
377
|
- `U1`–`U11` fold into `code-mode.md`, the `execute_code` description documents
|
|
378
|
-
`connecta.ui`, and the
|
|
379
|
-
[
|
|
378
|
+
`connecta.ui`, and the suite takes its row in the
|
|
379
|
+
[test map](./operations.md#the-test-map).
|
|
380
380
|
- `npm run check` passes.
|
|
381
381
|
|
|
382
382
|
The implementation issue (#277) carries these as acceptance criteria.
|
|
@@ -229,7 +229,13 @@ results explain that no single tool covered every term and recommend splitting
|
|
|
229
229
|
distinct intents. A true negative says that no matching capability is
|
|
230
230
|
configured and recommends refining, connector-scoping, or browsing; when a
|
|
231
231
|
connector catalog was unavailable, the response includes
|
|
232
|
-
`unavailableConnectorCount` instead of making that stronger claim. A
|
|
232
|
+
`unavailableConnectorCount` instead of making that stronger claim. A no-match
|
|
233
|
+
query whose terms name a configured connector's `id` or `title` never makes it
|
|
234
|
+
either: connector identity is not in the lexical index — indexing it would move
|
|
235
|
+
ranking for every query that already matches tools — so instead the guidance on
|
|
236
|
+
an unscoped miss names up to three such connectors by ID and sends the caller
|
|
237
|
+
to a scoped browse. Identity affects that one sentence and nothing else: no
|
|
238
|
+
ranking, no result, and no new field. A search
|
|
233
239
|
explicitly scoped to that unavailable connector also receives `catalogError` —
|
|
234
240
|
the bounded classified failure (`code`, `message`, `retryable`, and any
|
|
235
241
|
`retryAfterMs`) so the caller can tell a transient outage from one a deployment
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Import `mixpanel()` independently from
|
|
4
4
|
`@zackbart/connecta/providers/mixpanel`. It wraps Mixpanel's hosted MCP server
|
|
5
|
-
with regional endpoint selection, OAuth by default, a
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
with regional endpoint selection, OAuth by default, a task-oriented usage
|
|
6
|
+
guide, and a vetted safety classification. It adds no provider dependency and
|
|
7
|
+
is not reachable from Connecta's root entry.
|
|
8
8
|
|
|
9
9
|
```ts
|
|
10
10
|
import { mixpanel } from "@zackbart/connecta/providers/mixpanel";
|
|
@@ -25,6 +25,12 @@ connector's safety classification.
|
|
|
25
25
|
|
|
26
26
|
`region` accepts `"us"` (the default), `"eu"`, or `"in"` and selects the
|
|
27
27
|
corresponding [official hosted endpoint](https://docs.mixpanel.com/docs/mcp#mcp-server-urls).
|
|
28
|
+
A project lives in exactly one residency, so the region also decides what this
|
|
29
|
+
connection can see at all: a question pointed at the wrong one comes back empty
|
|
30
|
+
rather than wrong, which reads as the project having no data. That makes it a
|
|
31
|
+
routing fact, so it rides the default `title` (`Mixpanel (us)`, `Mixpanel
|
|
32
|
+
(eu)`, `Mixpanel (in)`) and opens the usage guide — `search_tools` renders a
|
|
33
|
+
connector's title and guide summary and never its description.
|
|
28
34
|
OAuth is the recommended default and keeps each connector instance's flow and
|
|
29
35
|
tokens in its connector-scoped storage. Mixpanel service accounts are also
|
|
30
36
|
supported with an explicit header override:
|
|
@@ -68,9 +74,36 @@ approval copy the host shows a human.
|
|
|
68
74
|
Experiments and Feature Flags — 15 of the 63 classified tools — are Mixpanel
|
|
69
75
|
beta surfaces. Expect their names and schemas to move faster than the rest.
|
|
70
76
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
+
## Rate limits
|
|
78
|
+
|
|
79
|
+
Mixpanel meters its MCP server **per user per hour**, shared with everything
|
|
80
|
+
else that credential does. Connecta's counter is per runtime, not per user, and
|
|
81
|
+
the two cannot be reconciled in either direction: one runtime serving several
|
|
82
|
+
users under-counts, and several Worker isolates or Node processes sharing one
|
|
83
|
+
credential each admit a full budget. A hardcoded ceiling would therefore either
|
|
84
|
+
throttle a healthy deployment or fail to protect a busy one, so this connection
|
|
85
|
+
declares **no call-admission budget by default**. An operator who knows the
|
|
86
|
+
account can supply one explicitly:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
mixpanel("product_analytics", {
|
|
90
|
+
purpose: "Product and growth decisions for the production app",
|
|
91
|
+
callAdmission: {
|
|
92
|
+
rules: [
|
|
93
|
+
{ budget: { kind: "rolling-window", maxCalls: 300, windowMs: 3_600_000 } },
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
A budget-only rule needs no queue. If you add `maxConcurrency` you are asking
|
|
100
|
+
for a queue, and the admission controller then requires the rest of the queue
|
|
101
|
+
settings at construction. Discovery traffic is outside connector call admission
|
|
102
|
+
either way and still needs restrained use.
|
|
103
|
+
|
|
104
|
+
## Conventions
|
|
105
|
+
|
|
106
|
+
This connection is audited against
|
|
107
|
+
[the provider conventions](./provider-conventions.md). Its verdict per
|
|
108
|
+
convention, including every recorded exception, is the Mixpanel section of
|
|
109
|
+
[the provider audit](./provider-audit.md).
|
package/documentation/notion.md
CHANGED
|
@@ -166,7 +166,7 @@ should do next, and two of Notion's are easy to mistranslate.
|
|
|
166
166
|
| 400 (`validation_error`, `invalid_json`, `invalid_request`, `missing_version`, …) | `invalid_args` | every documented 400 is a malformed request |
|
|
167
167
|
| 401 `unauthorized` | `auth_required` | the token is missing or invalid |
|
|
168
168
|
| 403 `restricted_resource` | `connector_call_failed`, non-retryable | **not** `auth_required` |
|
|
169
|
-
| 404 `object_not_found` | `connector_call_failed`, non-retryable | overloaded
|
|
169
|
+
| 404 `object_not_found` | `connector_call_failed`, non-retryable | overloaded — deliberately **not** `not_found`; see below |
|
|
170
170
|
| 409 `conflict_error` | `unavailable`, retryable | Notion says to retry |
|
|
171
171
|
| 429 `rate_limited` | `rate_limited` + `retryAfterMs` | `Retry-After` seconds → ms |
|
|
172
172
|
| 529 `service_overload` | `unavailable` + `retryAfterMs` | back off like a 429 |
|
|
@@ -184,7 +184,12 @@ whose message says an operator must change it in Notion.
|
|
|
184
184
|
object that does not exist and for one that exists but has not been shared with
|
|
185
185
|
the integration, and it will not say which. The message says both, because
|
|
186
186
|
treating it as deletion is exactly how an agent concludes a page is gone when
|
|
187
|
-
it was simply never shared.
|
|
187
|
+
it was simply never shared. This is why the row above does not use `not_found`,
|
|
188
|
+
which exists precisely to say "it is not there": the qualifier on that code
|
|
189
|
+
([H11](./provider-conventions.md#h11--errors-are-mapped-to-what-the-caller-does-next))
|
|
190
|
+
is that the provider must tell absence apart from a permission gap, and Notion
|
|
191
|
+
does not. A program that skipped this id as missing would be right about half
|
|
192
|
+
the time, which is the half that matters.
|
|
188
193
|
|
|
189
194
|
## Rate limiting
|
|
190
195
|
|
|
@@ -231,3 +236,19 @@ block updates or deletes, no page moves. Those are all real Notion endpoints
|
|
|
231
236
|
and all deliberately absent: this is a deliberate tool surface, not a mirror of
|
|
232
237
|
the API. Anything missing is reachable through a custom `api()` connector
|
|
233
238
|
beside this one, which remains a first-class path.
|
|
239
|
+
|
|
240
|
+
There is also **no guarded raw-REST escape hatch** — no `notion_api_get`, no
|
|
241
|
+
`notion_api_mutate`. The convention that permits one
|
|
242
|
+
([H14](./provider-conventions.md#h14--a-named-tool-must-beat-the-escape-hatch-and-the-escape-hatch-splits-by-safety))
|
|
243
|
+
also permits a small provider to have none, provided it says so, and Notion's
|
|
244
|
+
public API is finite and slow-moving enough that a named surface can cover it.
|
|
245
|
+
The usage guide says it too, because an agent that assumes a hatch exists
|
|
246
|
+
spends a search proving it does not: absent from the tool list means absent
|
|
247
|
+
from this connection, not hidden behind a generic call.
|
|
248
|
+
|
|
249
|
+
## Conventions
|
|
250
|
+
|
|
251
|
+
This connection is audited against
|
|
252
|
+
[the provider conventions](./provider-conventions.md). Its verdict per
|
|
253
|
+
convention, including every recorded exception, is the Notion section of
|
|
254
|
+
[the provider audit](./provider-audit.md).
|