@vectros-ai/mcp-server 0.16.0 → 0.17.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 +161 -0
- package/README.md +83 -10
- package/dist/cli-http.js +1390 -302
- package/dist/cli-http.js.map +1 -1
- package/dist/cli-http.mjs +1401 -313
- package/dist/cli-http.mjs.map +1 -1
- package/dist/cli.js +1390 -302
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +1401 -313
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1390 -302
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1401 -313
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,167 @@
|
|
|
3
3
|
All notable changes to `@vectros-ai/mcp-server` are documented here.
|
|
4
4
|
This project adheres to [Semantic Versioning](https://semver.org).
|
|
5
5
|
|
|
6
|
+
## 0.17.0 — 2026-09-07
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- **`record_batch_write`** — create or upsert up to 50 structured records in one call,
|
|
11
|
+
wrapping `POST /v1/records/batch` (API 0.43.0: previously a `501` stub, now live).
|
|
12
|
+
Use it instead of N `record_create` round-trips when you hold several records.
|
|
13
|
+
Items may mix types, and each one goes through the same schema validation,
|
|
14
|
+
`externalId` idempotency, unique-field enforcement and `records:c:<type>` scope
|
|
15
|
+
check as a single create, applied per item against that item's own type — a batch
|
|
16
|
+
is not a way to write a type your credential could not write one at a time.
|
|
17
|
+
`atomicity: "all_or_nothing"` commits every item in one transaction and writes
|
|
18
|
+
nothing at all if any item fails, which is a better failure shape for an agent than
|
|
19
|
+
a loop of creates that half-succeeds; the default `best_effort` writes each item
|
|
20
|
+
independently. The item vocabulary deliberately mirrors `record_create` (`type` +
|
|
21
|
+
`fields`), so nothing new has to be learned to use it.
|
|
22
|
+
|
|
23
|
+
**The call reports success whenever the batch was *processed* — including when
|
|
24
|
+
every item failed.** That is the endpoint's own contract, so the tool does not
|
|
25
|
+
fake an error result; read the per-item `results` (matched to what you sent by
|
|
26
|
+
`index`) and the `succeeded`/`failed` counts. Per-item `status` carries two values
|
|
27
|
+
beyond the ordinary outcomes, and they call for different remedies:
|
|
28
|
+
`forbidden` (your credential lacked the scope or ownership that item needed — fix
|
|
29
|
+
the credential, not the item) and `not_committed` (this item was fine, but an
|
|
30
|
+
`all_or_nothing` batch was aborted by a different one).
|
|
31
|
+
|
|
32
|
+
- **`record_query` can list by `folderId`, and serve the account-wide `recent` feed.**
|
|
33
|
+
Two list-mode selectors the API has carried on `GET /v1/records` for many releases
|
|
34
|
+
but this tool never exposed: `folderId` lists every record filed in a folder
|
|
35
|
+
regardless of type (combine with `type` for one type within one folder), and
|
|
36
|
+
`recent: true` returns the recently-updated feed across all types — the only way to
|
|
37
|
+
read records without naming a type. `record_create` has always accepted `folderId`,
|
|
38
|
+
so until now a record could be filed into a folder and never listed back out of it.
|
|
39
|
+
|
|
40
|
+
This matters more from 0.43.0 on, because `folder_delete` now refuses a folder that
|
|
41
|
+
still holds records and the supported way to find them is exactly this call.
|
|
42
|
+
`type` is consequently optional now: a lookup (`field`) still requires it, a list
|
|
43
|
+
with no selector at all is refused, and `recent` is refused alongside
|
|
44
|
+
`type`/`folderId`/`userId`/`scope` rather than silently ignoring them the way the
|
|
45
|
+
API does.
|
|
46
|
+
|
|
47
|
+
- **`scopeFilters` on `hybrid_search` and `rag_ask`** — narrow a search or a RAG
|
|
48
|
+
retrieval by more than one ownership dimension at once, e.g.
|
|
49
|
+
`["org:<id>", "client:<id>"]` for one specific client within one specific org.
|
|
50
|
+
Something `scope` alone could not express, for a credential whose access spans
|
|
51
|
+
several dimensions. Mutually exclusive with `scope`; passing both is refused
|
|
52
|
+
locally with a message naming both fields, rather than spending a round trip on
|
|
53
|
+
the API's own rejection.
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
|
|
57
|
+
- **`folder_delete` now states its emptiness precondition** — the folder must contain
|
|
58
|
+
no documents, **no records**, and no sub-folders, and the description says how to clear
|
|
59
|
+
each: a document can be moved out or deleted, a record can only be deleted (nothing on
|
|
60
|
+
this surface moves one), and a sub-folder cannot be re-parented, so nesting must be
|
|
61
|
+
cleared innermost-first. The description previously named only protected folders, so
|
|
62
|
+
the most common way this call fails read as impossible.
|
|
63
|
+
|
|
64
|
+
**API 0.43.0 widened the refusal, and it lands harder on this server than on most
|
|
65
|
+
callers.** The old guard saw sub-folders and *file-backed* documents only — it was blind
|
|
66
|
+
to *text-ingested* documents and to records, and a delete that hit one of those returned
|
|
67
|
+
success while orphaning the contents behind a folder id that no longer resolved.
|
|
68
|
+
Text-inline ingest is `document_ingest`'s default path, so folders this server filled are
|
|
69
|
+
precisely the ones whose deletes used to succeed and now do not.
|
|
70
|
+
|
|
71
|
+
One consequence worth planning for: the emptiness check counts **everything** in the
|
|
72
|
+
folder, including items the calling credential cannot read. A scoped credential can be
|
|
73
|
+
refused by content it has no way to enumerate, so a refusal that contradicts your own
|
|
74
|
+
listing is expected rather than a bug.
|
|
75
|
+
- **`rag_ask`'s `truncationWarning` now carries `truncatedCount` and `noContentCount`**,
|
|
76
|
+
and its `reason` can be `no_groundable_content` or `context_window_budget_and_no_content`
|
|
77
|
+
as well as `context_window_budget`. Results can be dropped before the prompt is built
|
|
78
|
+
for two independent reasons — not fitting the context window, or having no groundable
|
|
79
|
+
text at all — and these separate them. Inherited from the API with no code change here;
|
|
80
|
+
noted because it is new data an agent sees.
|
|
81
|
+
- **`hybrid_search`'s ARCHIVED note now covers records, and stops claiming an absolute.**
|
|
82
|
+
It said ARCHIVED *documents* never appear in results, which read as an asymmetry implying
|
|
83
|
+
archived records still match — they do not, and have refused to index since API 0.35.
|
|
84
|
+
API 0.43.0 additionally fixed two document write paths that could silently re-index an
|
|
85
|
+
already-archived document. But it deliberately does **not** sweep items already stranded
|
|
86
|
+
in that state: they stay searchable until written to again. So "never appear" was a false
|
|
87
|
+
absolute, and the description now names the repair — re-send `status: "ARCHIVED"` on the
|
|
88
|
+
item — instead of implying the case cannot arise.
|
|
89
|
+
- **A search hit's returned `createdAt` is documented as the INDEX timestamp.** It is the moment
|
|
90
|
+
the item entered the search index — the same moment it was created in the common case, but later
|
|
91
|
+
for anything re-indexed since — so it should not be reported to a user as the creation time; fetch
|
|
92
|
+
the item with `document_get`/`record_get` for that. The `createdAfter`/`createdBefore` FILTERS are a
|
|
93
|
+
separate thing and are unchanged: they filter on the item's true creation time, which does not move
|
|
94
|
+
when it is re-indexed, with a bounded allowance that lets an item matched on its FIRST index be
|
|
95
|
+
checked against its index time instead (clock skew between creating and indexing).
|
|
96
|
+
- **`folder_delete` no longer implies a record cannot be moved.** It said a record must be deleted
|
|
97
|
+
because it cannot be re-filed. The API supports re-filing one (`folderId` is patchable); it is
|
|
98
|
+
*this server* that does not expose it — `record_update` has no `folderId` argument. As written, an
|
|
99
|
+
agent clearing a folder could have deleted partner data where a move was available, then reported
|
|
100
|
+
that a move was impossible. It now names the gap as this server's and says to move the record
|
|
101
|
+
through the API/SDK rather than deleting it here.
|
|
102
|
+
- **`record_batch_write` no longer claims duplicate `externalId`s within one batch are refused.**
|
|
103
|
+
That holds under `atomicity: "all_or_nothing"` only. Under the default `best_effort` each item is
|
|
104
|
+
written independently, so a second item carrying the same `externalId` matches what the first just
|
|
105
|
+
wrote and reports `updated` — a duplicated key silently collapses two rows into one, counted as a
|
|
106
|
+
success. Both modes are now described.
|
|
107
|
+
- **`record_create` / `record_batch_write`: `scopes` is bounded by `data_scope`, not by identity.**
|
|
108
|
+
Both said the values "must come from the credential's own identity". The platform states the
|
|
109
|
+
opposite: identity supplies the DEFAULT when you state none and does not limit which value you may
|
|
110
|
+
state; each entry must fall inside the `data_scope` of a granting clause. The old wording would
|
|
111
|
+
stop an agent setting a scope it was entitled to set.
|
|
112
|
+
- **`record_query` rejects `folderId`/`recent` on a lookup** instead of ignoring them, matching the
|
|
113
|
+
existing guard for lookup arguments passed without `field`.
|
|
114
|
+
- **Bundled `@vectros-ai/sdk` repinned to the 0.43.0 line.**
|
|
115
|
+
|
|
116
|
+
### Notes
|
|
117
|
+
|
|
118
|
+
- **A root `sk_*` key can no longer file into a non-`default` app context.** As of API
|
|
119
|
+
0.43.0, a `folderId` / `parentFolderId` — or a document's `schemaId` — belonging to
|
|
120
|
+
another context is refused with a uniform `400`, on `document_ingest`,
|
|
121
|
+
`document_update`, `record_create`, `record_update` and `folder_create`. Those calls
|
|
122
|
+
previously succeeded, but never coherently: a root key's writes are stamped
|
|
123
|
+
`default`, so the row landed in `default` while its folder or schema lived elsewhere.
|
|
124
|
+
Existing rows are unaffected. Use a scoped key bound to the target context — the
|
|
125
|
+
credential this server recommends anyway. See README § Recommended credential.
|
|
126
|
+
- **A `filters` clause on `status` means something different for records now.** Records
|
|
127
|
+
no longer publish their lifecycle `status` into the search index (API 0.43.0), so on
|
|
128
|
+
`hybrid_search` / `rag_ask` a `status` filter matches a schema's own `status` field
|
|
129
|
+
where one is declared, and nothing where none is — it no longer collides with the
|
|
130
|
+
platform's lifecycle value. Record schemas can now use `status` as a filterable field
|
|
131
|
+
of their own.
|
|
132
|
+
- **0.43.0 capabilities this server deliberately does not expose:** stored scripts and
|
|
133
|
+
synchronous script execution, trigger rules, trigger-failure history, and usage
|
|
134
|
+
reporting. The reasoning is in README § What this server deliberately doesn't expose
|
|
135
|
+
— briefly: authoring stored code is a design-time act rather than a data-plane one;
|
|
136
|
+
declaring a trigger rule grants live authority; trigger-failure and usage reporting
|
|
137
|
+
are operational questions for a person, not mid-task tool calls; and synchronous
|
|
138
|
+
script execution has a failure surface (an undetermined-outcome run, and an
|
|
139
|
+
idempotency key a tool call has no natural identity for) that needs a deliberate
|
|
140
|
+
design rather than a thin wrapper.
|
|
141
|
+
|
|
142
|
+
## 0.16.1 — 2026-08-27
|
|
143
|
+
|
|
144
|
+
### Fixed
|
|
145
|
+
|
|
146
|
+
- **Claude Code setup docs: restart-to-load + Windows npx-resolution caveats.**
|
|
147
|
+
The "Configure manually (Claude Code)" section now covers three real
|
|
148
|
+
friction points found in dogfooding: a session already open when the
|
|
149
|
+
server is added needs a full quit + reopen (not just re-selecting the
|
|
150
|
+
tab); the `/mcp` panel shows the connector marketplace, not local stdio
|
|
151
|
+
servers, so it can't confirm the server loaded; and config resolves off
|
|
152
|
+
the git common root, so a linked worktree needs adding/opening from the
|
|
153
|
+
same project as its main repo. Also documents a Windows-specific trap: a
|
|
154
|
+
scoped-registry override for `@vectros-ai` in `.npmrc` can silently
|
|
155
|
+
resolve `npx -y @vectros-ai/mcp-server` to an unexpected internal build
|
|
156
|
+
that isn't guaranteed to run there — pin an explicit version if the
|
|
157
|
+
plain command fails to start.
|
|
158
|
+
- **`current_identity`'s `granted_capabilities` note now lists all five named capabilities.**
|
|
159
|
+
The tool description and the `identity` resource both listed only four
|
|
160
|
+
(`member-lifecycle` / `forensic-read` / `context-directory-read` / `delegate-mint`); the
|
|
161
|
+
platform's fifth, `delegate-principal-stamp`, is now named alongside them.
|
|
162
|
+
|
|
163
|
+
### Changed
|
|
164
|
+
|
|
165
|
+
- Bundled `@vectros-ai/sdk` refreshed to the current release's staging build.
|
|
166
|
+
|
|
6
167
|
## 0.16.0 — 2026-08-27
|
|
7
168
|
|
|
8
169
|
### Added
|
package/README.md
CHANGED
|
@@ -166,17 +166,32 @@ claude mcp add vectros -e VECTROS_API_KEY=ssk_live_... -- npx -y @vectros-ai/mcp
|
|
|
166
166
|
```
|
|
167
167
|
|
|
168
168
|
Add `-e VECTROS_API_BASE_URL=https://api.staging.vectros.ai` for a non-production
|
|
169
|
-
environment.
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
169
|
+
environment.
|
|
170
|
+
|
|
171
|
+
**Load it into a session by restarting.** A Claude Code session that was
|
|
172
|
+
already open when you added the server won't pick it up mid-session — fully
|
|
173
|
+
quit and reopen the project (not just re-select the tab). The `/mcp` panel
|
|
174
|
+
shows the connector marketplace, not locally-configured stdio servers, so it
|
|
175
|
+
won't confirm the server is loaded — ask the agent to call a Vectros tool
|
|
176
|
+
instead. Config is keyed by the **git common root**, so a linked worktree
|
|
177
|
+
resolves to its main repo's `.mcp.json` — add and open from the same project.
|
|
178
|
+
|
|
179
|
+
> **Windows note:** if your `.npmrc` (or a global npm config) points the
|
|
180
|
+
> `@vectros-ai` scope at a private registry, a bare `npx -y @vectros-ai/mcp-server`
|
|
181
|
+
> can resolve an unexpected internal build there instead of the public
|
|
182
|
+
> release — and an internal build is not guaranteed to run on Windows. If the
|
|
183
|
+
> command above fails to start, either remove the scoped-registry override
|
|
184
|
+
> for a plain `npx` run, or pin an explicit version (`npx -y
|
|
185
|
+
> @vectros-ai/mcp-server@<version>`) known to work.
|
|
186
|
+
|
|
187
|
+
## Tools (23 tools)
|
|
173
188
|
|
|
174
189
|
**Search & RAG**
|
|
175
190
|
|
|
176
191
|
| Tool | What it does |
|
|
177
192
|
|---|---|
|
|
178
|
-
| `hybrid_search` | Hybrid BM25 + dense search across the tenant's indexed content (records + documents). Narrow by ownership, folder, type, metadata filters, a created date window, and keyword-precision (`textMode`) / relevance floors. Returns the indexed projection of each hit. |
|
|
179
|
-
| `rag_ask` | Ask a question grounded against the indexed corpus. Scope retrieval (ownership / folder / type / metadata filters / date window) and steer generation (`instructions` / `temperature`). Streaming generation aggregated; progress notifications keep the call alive for the generation window. |
|
|
193
|
+
| `hybrid_search` | Hybrid BM25 + dense search across the tenant's indexed content (records + documents). Narrow by ownership (`scope` for one dimension, `scopeFilters` for several at once — e.g. one client within one org), folder, type, metadata filters, a created date window, and keyword-precision (`textMode`) / relevance floors. Returns the indexed projection of each hit. |
|
|
194
|
+
| `rag_ask` | Ask a question grounded against the indexed corpus. Scope retrieval (ownership — `scope` or multi-dimension `scopeFilters` — / folder / type / metadata filters / date window) and steer generation (`instructions` / `temperature`). Streaming generation aggregated; progress notifications keep the call alive for the generation window. |
|
|
180
195
|
| `document_ask` | Ask a question grounded against a single document. Same aggregation + progress-notification shape as `rag_ask`. |
|
|
181
196
|
|
|
182
197
|
**Records** (structured, schema-validated data)
|
|
@@ -184,10 +199,11 @@ available.
|
|
|
184
199
|
| Tool | What it does |
|
|
185
200
|
|---|---|
|
|
186
201
|
| `list_schemas` | List the record-schema catalog the credential can see (filter by `surface` or resolve one by `recordType`). Makes `record_query` / `record_create` discoverable. |
|
|
187
|
-
| `record_query` | Query records by lookup field — equality (`value`), range, or prefix, with `asc`/`desc` ordering and an optional `sortFrom`/`sortTo` window — or list mode (
|
|
202
|
+
| `record_query` | Query records by lookup field — equality (`value`), range, or prefix, with `asc`/`desc` ordering and an optional `sortFrom`/`sortTo` window — or list mode, choosing one of `type`, `folderId` (every record in a folder, any type — combine with `type` to narrow), or `recent` (the account-wide recently-updated feed across all types), then optionally filtering the first two by ownership. Also supports composite equality across 2-3 fields (`values`), but only against a lookup the *schema* declares over those fields together (see `list_schemas`) — not any two fields you pick. |
|
|
188
203
|
| `record_get` | Fetch one record by id, including its full payload (large payloads truncated to protect the agent context window). |
|
|
189
204
|
| `record_batch_get` | Fetch several records by id (1-100) in one call, each with its full payload. Returns `missingIds` for any requested id you can't access, since the API silently omits them. |
|
|
190
205
|
| `record_create` | Create a record of a given type; idempotent by `externalId`; optional per-record `indexMode`. |
|
|
206
|
+
| `record_batch_write` | Create or upsert up to 50 records in one call, instead of N `record_create` round-trips. Items may mix types and are validated and scope-checked individually. `atomicity: all_or_nothing` commits them as one transaction (nothing is written if any item fails); the default `best_effort` writes each independently. Reports success whenever the batch was *processed* — read the per-item `results`, not just the absence of an error. |
|
|
191
207
|
| `record_update` | Patch a record's payload (deep-merged; `null` deletes a key); optimistic concurrency via `expectedVersion`. |
|
|
192
208
|
| `record_delete` | Permanently delete a record by id (leaves a tombstone). |
|
|
193
209
|
|
|
@@ -208,17 +224,17 @@ available.
|
|
|
208
224
|
| `folder_query` | Get a folder by id, or list folders (a parent's children for tree navigation, or a flat tenant list; paginated via `nextCursor`). |
|
|
209
225
|
| `folder_create` | Create a folder. |
|
|
210
226
|
| `folder_update` | Update a folder's name / description / ownership (merge-patch; optimistic concurrency via `expectedVersion`; folders cannot be re-parented). |
|
|
211
|
-
| `folder_delete` | Delete a folder. |
|
|
227
|
+
| `folder_delete` | Delete a folder. It must be empty first — no documents, no records, and no sub-folders — and a context root is protected outright. |
|
|
212
228
|
|
|
213
229
|
**Identity & history**
|
|
214
230
|
|
|
215
231
|
| Tool | What it does |
|
|
216
232
|
|---|---|
|
|
217
|
-
| `current_identity` | Describe the credential: tenantId, environment, principalType, principalKeyId, principalLabel, and (for scoped credentials) allowedActions + dataScope. Does **not** yet include `granted_capabilities` (`member-lifecycle` / `forensic-read` / `context-directory-read` / `delegate-mint`) — a separate reach dimension a scope clause can carry
|
|
233
|
+
| `current_identity` | Describe the credential: tenantId, environment, principalType, principalKeyId, principalLabel, and (for scoped credentials) allowedActions + dataScope. Does **not** yet include `granted_capabilities` (`member-lifecycle` / `forensic-read` / `context-directory-read` / `delegate-mint`, as of API 0.40.0, joined by `delegate-principal-stamp` in 0.42.0) — a separate reach dimension a scope clause can carry that `/v1/ping` doesn't report yet, so allowedActions + dataScope may understate a credential's true reach. Also reports this server's own version and the bundled SDK version (`mcpServerVersion`, `sdkVersion`). |
|
|
218
234
|
| `lookup_principal` | Resolve a user, or an identity entity in a namespace (`org`/`client`/any namespace you registered), by your own `externalId` (→ its Vectros UUID, for the ownership filters) or by a schema lookup field. Pass `contextId` to target a specific app context for a context-owned namespace. Read-only. |
|
|
219
235
|
| `version_history` | Read the audit/version trail (CREATE/UPDATE/DELETE, with actor + diff) for one record or document. Read-only. |
|
|
220
236
|
|
|
221
|
-
All
|
|
237
|
+
All 23 tools wrap published Vectros HTTP API endpoints. JSON
|
|
222
238
|
responses are what the agent sees as tool output. Per-call cost
|
|
223
239
|
surfaces via the `usage` field on inference responses.
|
|
224
240
|
|
|
@@ -260,6 +276,20 @@ AccessProfile for MCP") for least-privilege credential setup — the
|
|
|
260
276
|
`vectros bootstrap` flow provisions a scoped `ssk_*` key and its AccessProfile
|
|
261
277
|
in one command.
|
|
262
278
|
|
|
279
|
+
> **A root `sk_*` can no longer file into another app context, as of API 0.43.0.**
|
|
280
|
+
> If you run this server on a root key and a tool call names a `folderId` /
|
|
281
|
+
> `parentFolderId` — or a `schemaId` on a document — belonging to a context other
|
|
282
|
+
> than `default`, it is now refused with a uniform `400 "Folder not found"` /
|
|
283
|
+
> `"Schema not found"`. This affects `document_ingest`, `document_update`,
|
|
284
|
+
> `record_create`, `record_update` and `folder_create`, and it is a change in
|
|
285
|
+
> outcome: those calls used to succeed. They never did what they appeared to,
|
|
286
|
+
> though — a root key's writes are always stamped `default`, so the row landed in
|
|
287
|
+
> `default` while its folder or schema lived elsewhere, permanently invisible to
|
|
288
|
+
> the context that owned them. Existing rows written the old way are untouched and
|
|
289
|
+
> still readable, updatable and deletable. The fix is the same scoped key
|
|
290
|
+
> recommended above: one bound to the target context can file into it and always
|
|
291
|
+
> could.
|
|
292
|
+
|
|
263
293
|
## Credential resolution
|
|
264
294
|
|
|
265
295
|
The server resolves its API key from the first source that yields one:
|
|
@@ -363,6 +393,49 @@ const server = new VectrosMCPServer({
|
|
|
363
393
|
await server.connect(createStdioTransport());
|
|
364
394
|
```
|
|
365
395
|
|
|
396
|
+
## What this server deliberately doesn't expose
|
|
397
|
+
|
|
398
|
+
This is a decision, not a backlog. An MCP server is a tool surface handed to an
|
|
399
|
+
autonomous caller, so a capability the API offers is not automatically a tool —
|
|
400
|
+
each one has to earn its place on an agent's surface.
|
|
401
|
+
|
|
402
|
+
The line is the **data plane**: records, documents, folders and search are here in
|
|
403
|
+
full. Anything that grants or administers authority is not, and neither is the
|
|
404
|
+
design-time layer that defines the data model.
|
|
405
|
+
|
|
406
|
+
- **Stored scripts** (`/v1/scripts` — push, list, fetch, delete). A stored script is
|
|
407
|
+
code, not data. Authoring it is a design-time act, the same reason schema mutation
|
|
408
|
+
lives in the CLI rather than here: an agent that can write the code that later runs
|
|
409
|
+
under your credential is a different proposition from one that can write records.
|
|
410
|
+
- **Synchronous script execution** (`POST /v1/scripts/execute`, the `scripts:x` scope).
|
|
411
|
+
The closer call of the two, and excluded on operational grounds rather than reach —
|
|
412
|
+
a `scripts:x:<name>` grant is a deliberately narrow, per-script permission, and an
|
|
413
|
+
ordinary scoped key can hold it. What an agent handles badly is the failure surface:
|
|
414
|
+
a run whose outcome cannot be determined returns `500 EXECUTION_OUTCOME_UNKNOWN` with
|
|
415
|
+
writes that may or may not have committed, which is not something a caller resolves
|
|
416
|
+
by retrying — it has to go and look. Getting a retry right also means reusing an
|
|
417
|
+
`Idempotency-Key` across attempts, and a tool call has no natural retry identity, so
|
|
418
|
+
an agent re-invoking after a timeout would silently run the script a second time.
|
|
419
|
+
Exposing this well needs a deliberate design for those two things, not a thin wrapper.
|
|
420
|
+
Until then, run scripts from a caller that can handle them — the API, the SDK, or the
|
|
421
|
+
CLI.
|
|
422
|
+
- **Trigger rules** (`/v1/triggers`). Declaring a rule grants authority — a rule's
|
|
423
|
+
`scopes`/`roleIds` are live, and declaring one is scope-monotonicity-checked like
|
|
424
|
+
any other authority-granting surface. Minting authority is not an agent action.
|
|
425
|
+
- **Trigger failure history** (`GET /v1/trigger-failures`) and **usage/billing**
|
|
426
|
+
(`GET /v1/usage`). Both are read-only, and both are operational rather than
|
|
427
|
+
data-plane — they describe how your automation and your account are behaving, not
|
|
428
|
+
what your content says. That is a question for the developer portal or the CLI,
|
|
429
|
+
where a person is looking at it, rather than a tool an agent reaches for mid-task.
|
|
430
|
+
- **Identity, access and credential administration** — users, access profiles,
|
|
431
|
+
roles, app contexts, issuer registrations, and scoped-key minting. Unchanged
|
|
432
|
+
since launch: identity CRUD stays off the agent tool surface by design.
|
|
433
|
+
`lookup_principal` resolves an identifier to an id and does nothing else.
|
|
434
|
+
- **Compliance operations** (erasure, export). Same reason.
|
|
435
|
+
|
|
436
|
+
If one of these belongs on your agent's surface, that's worth telling us — the
|
|
437
|
+
line is drawn on purpose and can be redrawn with a reason.
|
|
438
|
+
|
|
366
439
|
## What this server doesn't do (yet)
|
|
367
440
|
|
|
368
441
|
- **No prompts capability** — `/rag` and `/ingest_pdf` slash-command
|