@vectros-ai/mcp-server 0.9.0 → 0.11.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 CHANGED
@@ -3,6 +3,105 @@
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.11.0
7
+
8
+ Refreshed to the 0.36.0 Vectros API, with clearer, more actionable errors and a
9
+ few tool-surface corrections.
10
+
11
+ ### Changed
12
+
13
+ - **Tool errors now carry the server's real reason, a typed code, and a request
14
+ id.** When a tool call fails, the result surfaces the API's own message, the
15
+ machine-readable `errorCode` (so an agent can branch on the cause — e.g.
16
+ `INSUFFICIENT_BALANCE` "top up your balance" versus `SUBSCRIPTION_LIMIT_EXCEEDED`
17
+ "upgrade your plan" on a payment-required failure, or a placement/authorization
18
+ denial), and the `requestId` to quote to support — instead of a bare HTTP status
19
+ and a generic class name.
20
+ - **`document_ingest` rejects `storeText` in text mode instead of ignoring it.**
21
+ `storeText` only applies to file uploads (it controls whether a file's extracted
22
+ text is retained). A text-ingested body is the document itself and is always
23
+ retained, so passing `storeText` alongside `text` is now refused with a clear
24
+ message rather than silently having no effect.
25
+
26
+ ### Added
27
+
28
+ - **Errors surface the 0.36.0 typed error codes.** Payment-required failures on
29
+ `rag_ask` / `document_ask` now distinguish an exhausted pre-paid balance from a
30
+ reached plan limit; a number outside the signed 64-bit range is reported as a
31
+ `400` naming the field.
32
+ - **Guidance for search-indexing failures.** `document_get` and `record_get`
33
+ descriptions explain the `indexFailure.code` that accompanies a `FAILED`
34
+ `indexStatus`, so an agent can tell content that is still partly findable
35
+ (e.g. `VECTOR_LIMIT_EXCEEDED`, keyword search still serves it) from content that
36
+ is not findable at all (`INDEXING_FAILED`).
37
+ - **Large-number guidance.** `record_create` and `document_ingest` note that every
38
+ number must fall within the signed 64-bit range and that larger whole numbers
39
+ (e.g. big external ids) should be sent as strings, which store exactly and support
40
+ exact-match lookup.
41
+
42
+ ### Fixed
43
+
44
+ - **`current_identity` / the `identity` resource describe the identity shape they
45
+ actually return.** The obsolete "the backend is still rolling this out" caveat is
46
+ gone; the extended shape (`principalType`, `principalKeyId`, `allowedActions`, and
47
+ a `dataScope` of `{ userId, scopes[] }`) is returned today.
48
+ - **`hybrid_search` gives accurate keyword-leg guidance.** When the keyword leg
49
+ matches nothing (`textLegEmpty`), the description now explains that the default
50
+ phrase match found no contiguous hit for a long query and points to shortening the
51
+ query or setting `textMode` to `AND` (precision) or `OR` (recall), rather than
52
+ prescribing a single fix.
53
+ - **`record_create` and `folder_create` describe the scope needed to receive an
54
+ existing item on a collision, not just to create one.** Both tools are
55
+ idempotent by key (`externalId` for records, `slug` for folders); the
56
+ description previously said only `records:c`/`folders:c` was required, but
57
+ being handed back the existing item on a collision is a read of that item
58
+ and separately requires `records:r`/`folders:r`. A key holding only the
59
+ create scope now gets an accurate description of the "already exists"
60
+ error it will see instead of the record.
61
+
62
+ ## 0.10.0
63
+
64
+ ### Changed (breaking)
65
+
66
+ - **Organization and client identities are now namespaces.** The tools that took
67
+ `orgId` / `clientId` now use namespaced scopes:
68
+ - `lookup_principal`: `kind` is `"user"` or a namespace (`org`, `client`, or
69
+ one you define).
70
+ - Write tools (`record_create`, `folder_create`, `folder_update`,
71
+ `document_ingest`, `document_update`): the `orgId` / `clientId` inputs are
72
+ replaced by `scopes` — an array of `namespace:value` entries, e.g.
73
+ `["org:<id>"]`.
74
+ - Read and query tools (`record_query`, `document_query`, `folder_query`,
75
+ `hybrid_search`, `rag_ask`, `list_schemas`): the `orgId` / `clientId` filters
76
+ are replaced by a single `scope` filter (`namespace:value`). `list_schemas`'s
77
+ `surface` now accepts `record`, `document`, `user`, `entity`.
78
+
79
+ ### Added
80
+
81
+ - **Automatic API-key resolution from the Vectros CLI keyring.** When
82
+ `VECTROS_API_KEY` is not set, the server now resolves its key by invoking the
83
+ `vectros` CLI credential helper (`vectros keyring show --format raw`) as a
84
+ subprocess — so a key stored once in the CLI keyring is shared by the server, agent
85
+ hooks, and scripts, instead of a plaintext copy pasted into the server's config
86
+ that silently drifts. `VECTROS_API_KEY` still takes precedence when set (behavior
87
+ unchanged), and an unset key now falls back to the keyring rather than failing
88
+ immediately. Set `VECTROS_KEYRING_ALIAS` to resolve a specific keyring entry
89
+ instead of the active one. Requires **`@vectros-ai/cli` 0.9.0+** on `PATH` (the
90
+ version the keyring itself shipped in — the helper deliberately calls no command
91
+ newer than that, so it works with an existing install); if neither an env key nor
92
+ the CLI is available, startup fails with actionable guidance naming both options.
93
+ The resolved key is held in memory only and never logged.
94
+ - **Startup says which identity it resolved, and warns when you didn't name one.**
95
+ The startup log names the keyring entry the key came from (never the key itself).
96
+ When `VECTROS_API_KEY` is unset and no `VECTROS_KEYRING_ALIAS` is given, the key
97
+ comes from whichever entry was last made active — and that log is a **warning**,
98
+ whatever key turns up: silently getting a live key (acting on real data) and
99
+ silently getting a test key (not acting on it, when you believed you were) are both
100
+ unwelcome. It is easy to reach by accident, because a blank placeholder
101
+ (`"VECTROS_API_KEY": ""` in a client config, or a Docker `-e` pass-through of an
102
+ unset var) reads as "not configured yet" but resolves like an unset key. Nothing is
103
+ blocked, and naming an entry never warns.
104
+
6
105
  ## 0.9.0
7
106
 
8
107
  ### Added
package/README.md CHANGED
@@ -213,7 +213,7 @@ available.
213
213
 
214
214
  | Tool | What it does |
215
215
  |---|---|
216
- | `current_identity` | Describe the credential: tenantId, environment, principalType, and (where surfaced) allowedActions + dataScope. |
216
+ | `current_identity` | Describe the credential: tenantId, environment, principalType, principalKeyId, and (for scoped credentials) allowedActions + dataScope. |
217
217
  | `lookup_principal` | Resolve a user / org / client by your own `externalId` (→ its Vectros UUID, for the ownership filters) or by a schema lookup field. Read-only. |
218
218
  | `version_history` | Read the audit/version trail (CREATE/UPDATE/DELETE, with actor + diff) for one record or document. Read-only. |
219
219
 
@@ -242,7 +242,7 @@ Two read-only resources for ambient context (no tool call required):
242
242
  Use a **scoped permanent API key** (`ssk_*`), not a root key (`sk_*`).
243
243
 
244
244
  A scoped key is bound to a narrowed `AccessProfile` — e.g. read-only
245
- across one `orgId`. If your MCP install is compromised, the blast
245
+ across one org scope (`scope:org`). If your MCP install is compromised, the blast
246
246
  radius is whatever the profile allows, not the whole tenant. The
247
247
  server emits a `warn` log line on startup when you pass a wildcard
248
248
  `sk_*` for exactly this reason.
@@ -259,11 +259,42 @@ AccessProfile for MCP") for least-privilege credential setup — the
259
259
  `vectros bootstrap` flow provisions a scoped `ssk_*` key and its AccessProfile
260
260
  in one command.
261
261
 
262
+ ## Credential resolution
263
+
264
+ The server resolves its API key from the first source that yields one:
265
+
266
+ 1. **`VECTROS_API_KEY`** — always wins when set.
267
+ 2. **The `vectros` CLI keyring** — if the key is unset and
268
+ [`@vectros-ai/cli`](https://www.npmjs.com/package/@vectros-ai/cli) **0.9.0+** is on
269
+ your `PATH`, the server runs `vectros keyring show --format raw` as a subprocess
270
+ and uses the key it prints. By default that is your **active** identity; set
271
+ `VECTROS_KEYRING_ALIAS` to pick a specific entry. This is the same pattern as
272
+ `git credential` / `docker-credential-*` / `aws credential_process`: the key
273
+ lives in one place, and the server, your scripts, and your agent hooks all read
274
+ it from there instead of each keeping a plaintext copy that drifts.
275
+ 3. **Neither** — startup fails with a message naming both options.
276
+
277
+ The resolved key is held in memory and never logged. Startup logs which alias it
278
+ resolved (not the key), so you can tell at a glance which identity the server is
279
+ running as — `vectros keyring doctor` shows the same view.
280
+
281
+ > **Startup warns when it picks an identity you didn't name.** If `VECTROS_API_KEY`
282
+ > is unset and no `VECTROS_KEYRING_ALIAS` is set, the server falls back to your
283
+ > **active** keyring entry and logs a warning — it is running as whatever identity
284
+ > `vectros switch` last selected, which may be a `ssk_live_*` key acting on real data
285
+ > or a `ssk_test_*` one that isn't. Either can be an unwelcome surprise, because a
286
+ > blank placeholder (`"VECTROS_API_KEY": ""` in a client config, or `-e VECTROS_API_KEY`
287
+ > passing through an unset var in Docker) reads as "not configured yet" but resolves
288
+ > like an unset key. Nothing is blocked — name an entry with `VECTROS_KEYRING_ALIAS`,
289
+ > or set `VECTROS_API_KEY`, and the warning goes away. `vectros keyring doctor` shows
290
+ > which entry is active and which of your keys are live.
291
+
262
292
  ## Environment variables
263
293
 
264
294
  | Var | Required | Default | Purpose |
265
295
  |---|---|---|---|
266
- | `VECTROS_API_KEY` | **yes** | — | Vectros API key. Accepts `sk_*` / `ssk_*` / `st_*`; `ssk_*` recommended. |
296
+ | `VECTROS_API_KEY` | no\* | — | Vectros API key. Accepts `sk_*` / `ssk_*` / `st_*`; `ssk_*` recommended. \*Required **unless** the `vectros` CLI is installed with a usable keyring entry — see [Credential resolution](#credential-resolution). Takes precedence when set. |
297
+ | `VECTROS_KEYRING_ALIAS` | no | (the active entry) | Resolve this `vectros` keyring entry instead of the active one. Ignored when `VECTROS_API_KEY` is set. |
267
298
  | `VECTROS_API_BASE_URL` | no | `https://api.vectros.ai` | Override for staging or other envs. Validated: must be `https://` (or `http://` to localhost) and an official `*.vectros.ai` host. |
268
299
  | `VECTROS_ALLOW_INSECURE_BASE_URL` | no | — | Set `1` to bypass the base-URL allow-list (e.g. a trusted local proxy). **Not recommended** — sends your key to an unvalidated host; logs a warning. |
269
300
  | `VECTROS_MCP_INGEST_ROOT` | no | process cwd | Directory `document_ingest`'s `filePath` mode is jailed to. Paths escaping it (traversal/absolute/symlink) or matching a sensitive pattern are rejected. |
@@ -310,7 +341,7 @@ Health probe lives at `GET /healthz` (always unauthenticated, k8s
310
341
  readiness-friendly).
311
342
 
312
343
  Current limitation: the server uses one upstream credential per process
313
- (the env `VECTROS_API_KEY`). Per-request credential override via the
344
+ (the key resolved at startup). Per-request credential override via the
314
345
  incoming Authorization header is a planned enhancement. For now, deploy one
315
346
  server per credential boundary you want.
316
347