@vectros-ai/mcp-server 0.10.0 → 0.12.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 +85 -0
- package/README.md +1 -1
- package/dist/cli-http.js +105 -51
- package/dist/cli-http.js.map +1 -1
- package/dist/cli-http.mjs +105 -51
- package/dist/cli-http.mjs.map +1 -1
- package/dist/cli.js +105 -51
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +105 -51
- package/dist/cli.mjs.map +1 -1
- package/dist/index.js +105 -51
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +105 -51
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,91 @@
|
|
|
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.12.0
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
|
|
10
|
+
- **`document_get`/`document_update` selector errors now name the right parameter.**
|
|
11
|
+
Calling either tool with a bad or missing selector previously told you to
|
|
12
|
+
"provide `id`" — but their actual parameter is `documentId`; `id` isn't
|
|
13
|
+
recognized at all. A caller reasonably assuming symmetry with `record_get`
|
|
14
|
+
(which genuinely does use `id`) got an error message that appeared to confirm
|
|
15
|
+
the wrong fix. Both selector-validation messages now say `documentId`;
|
|
16
|
+
`record_get`/`record_update` are unchanged (their parameter really is `id`).
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- **`hybrid_search` results now carry `externalId` per hit, and the response
|
|
21
|
+
includes `hasMore`.** `externalId` lets you correlate a hit back to your own
|
|
22
|
+
record/document identity without a follow-up lookup (null if the item was
|
|
23
|
+
ingested without one, or indexed before this field existed). `hasMore` tells
|
|
24
|
+
you explicitly whether more results are available past the current page.
|
|
25
|
+
- **The `textLegEmpty` diagnostic no longer fires on every non-empty TEXT-mode
|
|
26
|
+
search.** It's based on each hit's keyword-relevance score, which the API
|
|
27
|
+
previously reported as `0` for every TEXT-mode result regardless of actual
|
|
28
|
+
relevance; TEXT-mode now returns a real, meaningful score, so the diagnostic
|
|
29
|
+
only fires when the keyword leg genuinely contributed nothing.
|
|
30
|
+
- **Dependency maintenance** — repinned the bundled `@vectros-ai/sdk` to `0.37.0`
|
|
31
|
+
(additive `basedOn` schema customization, `specificityRank` on namespaces, and
|
|
32
|
+
the search/RAG response fields above). The server bundles the SDK into its
|
|
33
|
+
published output, so this is a rebuild against the current SDK.
|
|
34
|
+
|
|
35
|
+
## 0.11.0
|
|
36
|
+
|
|
37
|
+
Refreshed to the 0.36.0 Vectros API, with clearer, more actionable errors and a
|
|
38
|
+
few tool-surface corrections.
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
- **Tool errors now carry the server's real reason, a typed code, and a request
|
|
43
|
+
id.** When a tool call fails, the result surfaces the API's own message, the
|
|
44
|
+
machine-readable `errorCode` (so an agent can branch on the cause — e.g.
|
|
45
|
+
`INSUFFICIENT_BALANCE` "top up your balance" versus `SUBSCRIPTION_LIMIT_EXCEEDED`
|
|
46
|
+
"upgrade your plan" on a payment-required failure, or a placement/authorization
|
|
47
|
+
denial), and the `requestId` to quote to support — instead of a bare HTTP status
|
|
48
|
+
and a generic class name.
|
|
49
|
+
- **`document_ingest` rejects `storeText` in text mode instead of ignoring it.**
|
|
50
|
+
`storeText` only applies to file uploads (it controls whether a file's extracted
|
|
51
|
+
text is retained). A text-ingested body is the document itself and is always
|
|
52
|
+
retained, so passing `storeText` alongside `text` is now refused with a clear
|
|
53
|
+
message rather than silently having no effect.
|
|
54
|
+
|
|
55
|
+
### Added
|
|
56
|
+
|
|
57
|
+
- **Errors surface the 0.36.0 typed error codes.** Payment-required failures on
|
|
58
|
+
`rag_ask` / `document_ask` now distinguish an exhausted pre-paid balance from a
|
|
59
|
+
reached plan limit; a number outside the signed 64-bit range is reported as a
|
|
60
|
+
`400` naming the field.
|
|
61
|
+
- **Guidance for search-indexing failures.** `document_get` and `record_get`
|
|
62
|
+
descriptions explain the `indexFailure.code` that accompanies a `FAILED`
|
|
63
|
+
`indexStatus`, so an agent can tell content that is still partly findable
|
|
64
|
+
(e.g. `VECTOR_LIMIT_EXCEEDED`, keyword search still serves it) from content that
|
|
65
|
+
is not findable at all (`INDEXING_FAILED`).
|
|
66
|
+
- **Large-number guidance.** `record_create` and `document_ingest` note that every
|
|
67
|
+
number must fall within the signed 64-bit range and that larger whole numbers
|
|
68
|
+
(e.g. big external ids) should be sent as strings, which store exactly and support
|
|
69
|
+
exact-match lookup.
|
|
70
|
+
|
|
71
|
+
### Fixed
|
|
72
|
+
|
|
73
|
+
- **`current_identity` / the `identity` resource describe the identity shape they
|
|
74
|
+
actually return.** The obsolete "the backend is still rolling this out" caveat is
|
|
75
|
+
gone; the extended shape (`principalType`, `principalKeyId`, `allowedActions`, and
|
|
76
|
+
a `dataScope` of `{ userId, scopes[] }`) is returned today.
|
|
77
|
+
- **`hybrid_search` gives accurate keyword-leg guidance.** When the keyword leg
|
|
78
|
+
matches nothing (`textLegEmpty`), the description now explains that the default
|
|
79
|
+
phrase match found no contiguous hit for a long query and points to shortening the
|
|
80
|
+
query or setting `textMode` to `AND` (precision) or `OR` (recall), rather than
|
|
81
|
+
prescribing a single fix.
|
|
82
|
+
- **`record_create` and `folder_create` describe the scope needed to receive an
|
|
83
|
+
existing item on a collision, not just to create one.** Both tools are
|
|
84
|
+
idempotent by key (`externalId` for records, `slug` for folders); the
|
|
85
|
+
description previously said only `records:c`/`folders:c` was required, but
|
|
86
|
+
being handed back the existing item on a collision is a read of that item
|
|
87
|
+
and separately requires `records:r`/`folders:r`. A key holding only the
|
|
88
|
+
create scope now gets an accurate description of the "already exists"
|
|
89
|
+
error it will see instead of the record.
|
|
90
|
+
|
|
6
91
|
## 0.10.0
|
|
7
92
|
|
|
8
93
|
### Changed (breaking)
|
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 (
|
|
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
|
|
package/dist/cli-http.js
CHANGED
|
@@ -61,6 +61,7 @@ __export(api_exports, {
|
|
|
61
61
|
FileUploadRequest: () => FileUploadRequest,
|
|
62
62
|
ForbiddenError: () => ForbiddenError,
|
|
63
63
|
IdentityLookupRequest: () => IdentityLookupRequest,
|
|
64
|
+
IndexFailure: () => IndexFailure,
|
|
64
65
|
InternalServerError: () => InternalServerError,
|
|
65
66
|
ListEntitiesRequestOrder: () => ListEntitiesRequestOrder,
|
|
66
67
|
ListUsersRequestOrder: () => ListUsersRequestOrder,
|
|
@@ -582,6 +583,17 @@ var IdentityLookupRequest;
|
|
|
582
583
|
Desc: "desc"
|
|
583
584
|
};
|
|
584
585
|
})(IdentityLookupRequest || (IdentityLookupRequest = {}));
|
|
586
|
+
var IndexFailure;
|
|
587
|
+
((IndexFailure2) => {
|
|
588
|
+
IndexFailure2.Code = {
|
|
589
|
+
SourceUnavailable: "SOURCE_UNAVAILABLE",
|
|
590
|
+
TextIndexFailed: "TEXT_INDEX_FAILED",
|
|
591
|
+
EmbeddingFailed: "EMBEDDING_FAILED",
|
|
592
|
+
IndexingFailed: "INDEXING_FAILED",
|
|
593
|
+
VectorLimitExceeded: "VECTOR_LIMIT_EXCEEDED",
|
|
594
|
+
Internal: "INTERNAL"
|
|
595
|
+
};
|
|
596
|
+
})(IndexFailure || (IndexFailure = {}));
|
|
585
597
|
var ModelDataVersionResponse;
|
|
586
598
|
((ModelDataVersionResponse2) => {
|
|
587
599
|
ModelDataVersionResponse2.ChangeType = {
|
|
@@ -4098,7 +4110,7 @@ var AuthClient = class {
|
|
|
4098
4110
|
);
|
|
4099
4111
|
}
|
|
4100
4112
|
/**
|
|
4101
|
-
* Creates a short-lived JWT bearer token restricted to specific actions and, optionally, to a particular user
|
|
4113
|
+
* Creates a short-lived JWT bearer token restricted to specific actions and, optionally, to a particular user or identity entity (in any namespace). Use this to hand a narrowly-scoped credential to a browser or downstream service so it never sees your root API key. Only callable with a root API key (`sk_*`).
|
|
4102
4114
|
*
|
|
4103
4115
|
* @param {Vectros.TokenRequest} request
|
|
4104
4116
|
* @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -4315,7 +4327,7 @@ var ComplianceClient = class {
|
|
|
4315
4327
|
this._options = normalizeClientOptionsWithAuth(options);
|
|
4316
4328
|
}
|
|
4317
4329
|
/**
|
|
4318
|
-
* Submits a right-to-erasure request for a single end-subject (a user,
|
|
4330
|
+
* Submits a right-to-erasure request for a single end-subject (a user, or an identity entity in any namespace). Erasure removes exactly the data the subject solely owns across the declared contexts, plus the subject's identity and lookup rows. It never touches another account's data and never cascades into another subject's data. The request is asynchronous: it returns 202 with a `requestId`; poll `GET /v1/erasure-requests/{id}` until the job completes to obtain the completion certificate. Requires a root API key — a scoped credential is rejected with 403.
|
|
4319
4331
|
*
|
|
4320
4332
|
* @param {Vectros.ErasureRequest} request
|
|
4321
4333
|
* @param {ComplianceClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -4624,7 +4636,7 @@ var DocumentsClient = class {
|
|
|
4624
4636
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/documents");
|
|
4625
4637
|
}
|
|
4626
4638
|
/**
|
|
4627
|
-
* Creates a document from a raw text string and queues it for asynchronous indexing so it becomes searchable. Optionally supply an `externalId` to make the create idempotent — if a document with the same `externalId` already exists in your context, that existing document is returned unchanged instead of a duplicate being created. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing document was returned) tells the two apart. To overwrite an existing document's content instead of returning it unchanged, set `?upsert=true` (this also requires the `documents:u` scope). Requires the `documents:c` scope.
|
|
4639
|
+
* Creates a document from a raw text string and queues it for asynchronous indexing so it becomes searchable. Optionally supply an `externalId` to make the create idempotent — if a document with the same `externalId` already exists in your context, that existing document is returned unchanged instead of a duplicate being created. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing document was returned) tells the two apart. To overwrite an existing document's content instead of returning it unchanged, set `?upsert=true` (this also requires the `documents:u` scope). Requires the `documents:c` scope to create. Being returned the existing document on a collision is a read of that document's data and additionally requires the `documents:r` scope — a credential holding `documents:c` alone receives a `400` ("already exists") on collision instead of the document.
|
|
4628
4640
|
*
|
|
4629
4641
|
* @param {Vectros.IngestDocumentRequest} request
|
|
4630
4642
|
* @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -4950,25 +4962,29 @@ var DocumentsClient = class {
|
|
|
4950
4962
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "PATCH", "/v1/documents/{id}");
|
|
4951
4963
|
}
|
|
4952
4964
|
/**
|
|
4953
|
-
* Finds documents of a given type by field value. Supported fields: `externalId` (the document's first-class external identifier — no schema declaration required) and any field declared as a lookup field on the bound schema. A lookup on a sensitive field is rejected here because the value would appear in the URL query string; use POST /v1/documents/lookup (the request-body variant) for a sensitive field instead. Results are paginated: set `limit` for the page size and feed the returned `nextCursor` back as `startFrom` to fetch the next page. The response is a `{data, nextCursor}` envelope. Requires the `documents:r` scope.
|
|
4965
|
+
* Finds documents of a given type by field value. Supported fields: `externalId` (the document's first-class external identifier — no schema declaration required) and any field declared as a lookup field on the bound schema. A lookup on a sensitive field is rejected here because the value would appear in the URL query string; use POST /v1/documents/lookup (the request-body variant) for a sensitive field instead. `type`'s schema resolves with basedOn-aware shadowing: your own `userId`- or `scope`-owned variant if you have one, otherwise the shared base — for a scoped credential the owner is always your own token identity; `userId`/`scope` here only apply as an explicit owner selector for a root API key. Results are paginated: set `limit` for the page size and feed the returned `nextCursor` back as `startFrom` to fetch the next page. The response is a `{data, nextCursor}` envelope. Requires the `documents:r` scope.
|
|
4954
4966
|
*
|
|
4955
4967
|
* @param {Vectros.LookupDocumentsRequest} request
|
|
4956
4968
|
* @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
4957
4969
|
*
|
|
4970
|
+
* @throws {@link Vectros.BadRequestError}
|
|
4971
|
+
*
|
|
4958
4972
|
* @example
|
|
4959
4973
|
* await client.documents.lookupDocuments({
|
|
4960
4974
|
* type: "invoice",
|
|
4961
4975
|
* field: "po_number",
|
|
4962
4976
|
* value: "PO-1001",
|
|
4963
4977
|
* prefix: "PO-2024",
|
|
4964
|
-
* startFrom: "550e8400-e29b-41d4-a716-446655440000"
|
|
4978
|
+
* startFrom: "550e8400-e29b-41d4-a716-446655440000",
|
|
4979
|
+
* userId: "550e8400-e29b-41d4-a716-446655440000",
|
|
4980
|
+
* scope: "org:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
|
|
4965
4981
|
* })
|
|
4966
4982
|
*/
|
|
4967
4983
|
lookupDocuments(request, requestOptions) {
|
|
4968
4984
|
return HttpResponsePromise.fromPromise(this.__lookupDocuments(request, requestOptions));
|
|
4969
4985
|
}
|
|
4970
4986
|
async __lookupDocuments(request, requestOptions) {
|
|
4971
|
-
const { type: type_, field, value, from: from_, to, prefix, startFrom, limit, order } = request;
|
|
4987
|
+
const { type: type_, field, value, from: from_, to, prefix, startFrom, limit, order, userId, scope } = request;
|
|
4972
4988
|
const _queryParams = {
|
|
4973
4989
|
type: type_,
|
|
4974
4990
|
field,
|
|
@@ -4978,7 +4994,9 @@ var DocumentsClient = class {
|
|
|
4978
4994
|
prefix,
|
|
4979
4995
|
startFrom,
|
|
4980
4996
|
limit,
|
|
4981
|
-
order: order != null ? order : void 0
|
|
4997
|
+
order: order != null ? order : void 0,
|
|
4998
|
+
userId,
|
|
4999
|
+
scope
|
|
4982
5000
|
};
|
|
4983
5001
|
const _authRequest = await this._options.authProvider.getAuthRequest();
|
|
4984
5002
|
const _headers = mergeHeaders(
|
|
@@ -5004,11 +5022,16 @@ var DocumentsClient = class {
|
|
|
5004
5022
|
return { data: _response.body, rawResponse: _response.rawResponse };
|
|
5005
5023
|
}
|
|
5006
5024
|
if (_response.error.reason === "status-code") {
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5025
|
+
switch (_response.error.statusCode) {
|
|
5026
|
+
case 400:
|
|
5027
|
+
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
5028
|
+
default:
|
|
5029
|
+
throw new VectrosError({
|
|
5030
|
+
statusCode: _response.error.statusCode,
|
|
5031
|
+
body: _response.error.body,
|
|
5032
|
+
rawResponse: _response.rawResponse
|
|
5033
|
+
});
|
|
5034
|
+
}
|
|
5012
5035
|
}
|
|
5013
5036
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/documents/lookup");
|
|
5014
5037
|
}
|
|
@@ -5376,7 +5399,7 @@ var FoldersClient = class {
|
|
|
5376
5399
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/folders");
|
|
5377
5400
|
}
|
|
5378
5401
|
/**
|
|
5379
|
-
* Creates a folder to organize your documents and records. If `parentFolderId` is omitted, the folder is created under your context's default root folder. Folder creation is idempotent by (slug + parent): if a folder with the same slug already exists under the same parent, that existing folder is returned unchanged instead of a duplicate being created. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing folder was returned) tells the two apart. To overwrite an existing folder's mutable fields instead of returning it unchanged, set `?upsert=true` (this also requires the `folders:u` scope). Requires the `folders:c` scope.
|
|
5402
|
+
* Creates a folder to organize your documents and records. If `parentFolderId` is omitted, the folder is created under your context's default root folder. Folder creation is idempotent by (slug + parent): if a folder with the same slug already exists under the same parent, that existing folder is returned unchanged instead of a duplicate being created. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing folder was returned) tells the two apart. To overwrite an existing folder's mutable fields instead of returning it unchanged, set `?upsert=true` (this also requires the `folders:u` scope). Requires the `folders:c` scope to create. Being returned the existing folder on a collision is a read of that folder's data and additionally requires the `folders:r` scope — a credential holding `folders:c` alone receives a `400` ("already exists") on collision instead of the folder.
|
|
5380
5403
|
*
|
|
5381
5404
|
* @param {Vectros.CreateFolderRequest} request
|
|
5382
5405
|
* @param {FoldersClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -5834,7 +5857,7 @@ var IdentityClient = class {
|
|
|
5834
5857
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/entities/{namespace}");
|
|
5835
5858
|
}
|
|
5836
5859
|
/**
|
|
5837
|
-
* Creates a new entity in the given namespace. This call is idempotent on `externalId` within the namespace: if an entity with the same `externalId` already exists, the existing record is returned instead of creating a duplicate (`created: false`, HTTP 200). To overwrite an existing entity's content instead of returning it unchanged, set `?upsert=true` (also requires the `entities:u:<namespace>` scope). The namespace must be entity-backed (`org`/`client`, or registered via `POST /v1/namespaces`). Requires the `entities:c:<namespace>` scope.
|
|
5860
|
+
* Creates a new entity in the given namespace. This call is idempotent on `externalId` within the namespace: if an entity with the same `externalId` already exists, the existing record is returned instead of creating a duplicate (`created: false`, HTTP 200). To overwrite an existing entity's content instead of returning it unchanged, set `?upsert=true` (also requires the `entities:u:<namespace>` scope). The namespace must be entity-backed (`org`/`client`, or registered via `POST /v1/namespaces`). Requires the `entities:c:<namespace>` scope to create. Being returned the existing entity on a collision is a read of that entity's data and additionally requires the `entities:r:<namespace>` scope — a credential holding `entities:c:<namespace>` alone receives a `400` ("already in use") on collision instead of the entity.
|
|
5838
5861
|
*
|
|
5839
5862
|
* @param {Vectros.CreateEntityRequest} request
|
|
5840
5863
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -6278,7 +6301,7 @@ var IdentityClient = class {
|
|
|
6278
6301
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/namespaces/{namespace}");
|
|
6279
6302
|
}
|
|
6280
6303
|
/**
|
|
6281
|
-
* Updates the mutable fields (`entityBacked`, `defaultSchemaId`) of a registered namespace. The namespace name itself is immutable. Requires a root API key. The reserved built-ins cannot be updated.
|
|
6304
|
+
* Updates the mutable fields (`entityBacked`, `defaultSchemaId`, `specificityRank`) of a registered namespace. The namespace name itself is immutable. Requires a root API key. The reserved built-ins cannot be updated.
|
|
6282
6305
|
*
|
|
6283
6306
|
* @param {Vectros.UpdateNamespaceRequest} request
|
|
6284
6307
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -6291,7 +6314,8 @@ var IdentityClient = class {
|
|
|
6291
6314
|
* await client.identity.updateNamespace({
|
|
6292
6315
|
* namespace: "team",
|
|
6293
6316
|
* body: {
|
|
6294
|
-
* namespace: "team"
|
|
6317
|
+
* namespace: "team",
|
|
6318
|
+
* specificityRank: 1500
|
|
6295
6319
|
* }
|
|
6296
6320
|
* })
|
|
6297
6321
|
*/
|
|
@@ -6456,7 +6480,7 @@ var IdentityClient = class {
|
|
|
6456
6480
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/namespaces");
|
|
6457
6481
|
}
|
|
6458
6482
|
/**
|
|
6459
|
-
* Registers a new scope namespace and declares whether its values resolve to identity entities (`entityBacked`). Requires a root API key. The reserved names `org` and `client` are built in and cannot be registered.
|
|
6483
|
+
* Registers a new scope namespace and declares whether its values resolve to identity entities (`entityBacked`). Also requires `specificityRank`, an explicit, account-unique position in the specificity order used to break recordType schema-resolution ties. Requires a root API key. The reserved names `org` and `client` are built in and cannot be registered.
|
|
6460
6484
|
*
|
|
6461
6485
|
* @param {Vectros.NamespaceRequest} request
|
|
6462
6486
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -6467,7 +6491,8 @@ var IdentityClient = class {
|
|
|
6467
6491
|
*
|
|
6468
6492
|
* @example
|
|
6469
6493
|
* await client.identity.registerNamespace({
|
|
6470
|
-
* namespace: "team"
|
|
6494
|
+
* namespace: "team",
|
|
6495
|
+
* specificityRank: 1500
|
|
6471
6496
|
* })
|
|
6472
6497
|
*/
|
|
6473
6498
|
registerNamespace(request, requestOptions) {
|
|
@@ -6584,7 +6609,7 @@ var IdentityClient = class {
|
|
|
6584
6609
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/users");
|
|
6585
6610
|
}
|
|
6586
6611
|
/**
|
|
6587
|
-
* Creates a user identity in your account. The operation is idempotent on `externalId`: if a user with the same `externalId` already exists, the existing record is returned instead of creating a duplicate. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing user was returned) tells the two apart. To overwrite an existing user's mutable fields (email, status, payload, schema binding) instead of returning it unchanged, set `?upsert=true` (this also requires the `users:u` scope). Requires the `users:c` scope.
|
|
6612
|
+
* Creates a user identity in your account. The operation is idempotent on `externalId`: if a user with the same `externalId` already exists, the existing record is returned instead of creating a duplicate. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing user was returned) tells the two apart. To overwrite an existing user's mutable fields (email, status, payload, schema binding) instead of returning it unchanged, set `?upsert=true` (this also requires the `users:u` scope). Requires the `users:c` scope to create. Being returned the existing user on a collision is a read of that user's data and additionally requires the `users:r` scope — a credential holding `users:c` alone receives a `400` ("already exists") on collision instead of the user.
|
|
6588
6613
|
*
|
|
6589
6614
|
* @param {Vectros.CreateUserRequest} request
|
|
6590
6615
|
* @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -7455,7 +7480,7 @@ var RecordsClient = class {
|
|
|
7455
7480
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/records");
|
|
7456
7481
|
}
|
|
7457
7482
|
/**
|
|
7458
|
-
* Creates a new record of a given type. The `payload` is validated against that type's schema before the record is stored. Identify the type by sending `typeName`, `schemaId`, or both (they must agree); if you send only `schemaId`, the type is taken from that schema. Optionally supply an `externalId` to make the create idempotent — if a record with the same `externalId` already exists in your context, that existing record is returned unchanged instead of a duplicate being created. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing record was returned) tells the two apart. To overwrite an existing record's content instead of returning it unchanged, set `?upsert=true` (this also requires the `records:u:<type>` scope). Requires the `records:c:<type>` scope.
|
|
7483
|
+
* Creates a new record of a given type. The `payload` is validated against that type's schema before the record is stored. Identify the type by sending `typeName`, `schemaId`, or both (they must agree); if you send only `schemaId`, the type is taken from that schema. Optionally supply an `externalId` to make the create idempotent — if a record with the same `externalId` already exists in your context, that existing record is returned unchanged instead of a duplicate being created. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing record was returned) tells the two apart. To overwrite an existing record's content instead of returning it unchanged, set `?upsert=true` (this also requires the `records:u:<type>` scope). Requires the `records:c:<type>` scope to create. Being returned the existing record on a collision is a read of that record's data and additionally requires the `records:r:<type>` scope — a credential holding `records:c:<type>` alone receives a `400` ("already exists") on collision instead of the record.
|
|
7459
7484
|
*
|
|
7460
7485
|
* @param {Vectros.CreateRecordRequest} request
|
|
7461
7486
|
* @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -8046,6 +8071,8 @@ var SchemasClient = class {
|
|
|
8046
8071
|
* @param {Vectros.ListSchemasRequest} request
|
|
8047
8072
|
* @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
8048
8073
|
*
|
|
8074
|
+
* @throws {@link Vectros.BadRequestError}
|
|
8075
|
+
*
|
|
8049
8076
|
* @example
|
|
8050
8077
|
* await client.schemas.listSchemas({
|
|
8051
8078
|
* userId: "550e8400-e29b-41d4-a716-446655440000",
|
|
@@ -8092,16 +8119,21 @@ var SchemasClient = class {
|
|
|
8092
8119
|
return { data: _response.body, rawResponse: _response.rawResponse };
|
|
8093
8120
|
}
|
|
8094
8121
|
if (_response.error.reason === "status-code") {
|
|
8095
|
-
|
|
8096
|
-
|
|
8097
|
-
|
|
8098
|
-
|
|
8099
|
-
|
|
8122
|
+
switch (_response.error.statusCode) {
|
|
8123
|
+
case 400:
|
|
8124
|
+
throw new BadRequestError(_response.error.body, _response.rawResponse);
|
|
8125
|
+
default:
|
|
8126
|
+
throw new VectrosError({
|
|
8127
|
+
statusCode: _response.error.statusCode,
|
|
8128
|
+
body: _response.error.body,
|
|
8129
|
+
rawResponse: _response.rawResponse
|
|
8130
|
+
});
|
|
8131
|
+
}
|
|
8100
8132
|
}
|
|
8101
8133
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/schemas");
|
|
8102
8134
|
}
|
|
8103
8135
|
/**
|
|
8104
|
-
* Defines a new record type with optional field definitions, validation rules, and lookup indexes. Idempotent by `typeName` within the same ownership scope: re-creating an existing `typeName` returns the existing schema rather than failing. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing schema was returned) tells the two apart. To reconcile an existing schema to the submitted shape instead of returning it unchanged, set `?upsert=true` (this also requires the `schemas:
|
|
8136
|
+
* Defines a new record type with optional field definitions, validation rules, and lookup indexes. Idempotent by `typeName` within the same ownership scope: re-creating an existing `typeName` returns the existing schema rather than failing. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing schema was returned) tells the two apart. To reconcile an existing schema to the submitted shape instead of returning it unchanged, set `?upsert=true` (this also requires the `schemas:u` scope; only legal schema changes are applied — migration-locked changes are rejected). Requires the `schemas:c` scope to create. Being returned the existing schema on a collision is a read of that schema's data and additionally requires the `schemas:r` scope — a credential holding `schemas:c` alone receives a `400` ("already in use") on collision instead of the schema.
|
|
8105
8137
|
*
|
|
8106
8138
|
* @param {Vectros.CreateSchemaRequest} request
|
|
8107
8139
|
* @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -8245,7 +8277,7 @@ var SchemasClient = class {
|
|
|
8245
8277
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/schemas/{id}");
|
|
8246
8278
|
}
|
|
8247
8279
|
/**
|
|
8248
|
-
* Updates a record schema. Fields you omit are preserved; `typeName` is immutable and cannot be changed. Collection fields (`fields`, `lookupFields`, `renderHints`, `capabilities`) are replaced in full when supplied. Requires the `schemas:
|
|
8280
|
+
* Updates a record schema. Fields you omit are preserved; `typeName` is immutable and cannot be changed. Collection fields (`fields`, `lookupFields`, `renderHints`, `capabilities`) are replaced in full when supplied. Requires the `schemas:u` scope.
|
|
8249
8281
|
*
|
|
8250
8282
|
* @param {Vectros.UpdateSchemaRequest} request
|
|
8251
8283
|
* @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -8314,7 +8346,7 @@ var SchemasClient = class {
|
|
|
8314
8346
|
return handleNonStatusCodeError(_response.error, _response.rawResponse, "PUT", "/v1/schemas/{id}");
|
|
8315
8347
|
}
|
|
8316
8348
|
/**
|
|
8317
|
-
* Permanently deletes a record schema. The request is refused with 409 if records of this type still exist — delete those records first, since every record must reference a live schema. Requires the `schemas:
|
|
8349
|
+
* Permanently deletes a record schema. The request is refused with 409 if records of this type still exist — delete those records first, since every record must reference a live schema. A lineage base (a schema other schemas declare `basedOn`) also cannot be deleted while any such variant still exists — delete the variant schema(s) first. Requires the `schemas:d` scope.
|
|
8318
8350
|
*
|
|
8319
8351
|
* @param {Vectros.DeleteSchemaRequest} request
|
|
8320
8352
|
* @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -8611,8 +8643,8 @@ function warnOnSuboptimalKey(key, log) {
|
|
|
8611
8643
|
|
|
8612
8644
|
// src/build-info.ts
|
|
8613
8645
|
var BUILD_INFO = {
|
|
8614
|
-
mcpServer: true ? "0.
|
|
8615
|
-
sdk: true ? "0.
|
|
8646
|
+
mcpServer: true ? "0.12.0" : "dev",
|
|
8647
|
+
sdk: true ? "0.37.0" : "dev"
|
|
8616
8648
|
};
|
|
8617
8649
|
|
|
8618
8650
|
// src/log.ts
|
|
@@ -8816,31 +8848,45 @@ async function consumeStream(stream, onProgress) {
|
|
|
8816
8848
|
}
|
|
8817
8849
|
|
|
8818
8850
|
// src/tools/errors.ts
|
|
8851
|
+
function asErrorBody(body) {
|
|
8852
|
+
if (body && typeof body === "object") return body;
|
|
8853
|
+
return void 0;
|
|
8854
|
+
}
|
|
8819
8855
|
function toolError(toolName, err, docPointer) {
|
|
8820
8856
|
let summary = `${toolName} failed`;
|
|
8821
8857
|
let detail = String(err);
|
|
8858
|
+
let errorCode;
|
|
8859
|
+
let requestId;
|
|
8822
8860
|
if (err instanceof StreamError) {
|
|
8823
8861
|
summary = `${toolName} stream error`;
|
|
8824
8862
|
detail = err.message;
|
|
8825
8863
|
} else if (err instanceof Error) {
|
|
8826
8864
|
const e = err;
|
|
8827
8865
|
detail = e.message;
|
|
8866
|
+
const body = asErrorBody(e.body);
|
|
8867
|
+
if (body) {
|
|
8868
|
+
if (typeof body.message === "string" && body.message.trim().length > 0) detail = body.message;
|
|
8869
|
+
if (typeof body.errorCode === "string" && body.errorCode.length > 0) errorCode = body.errorCode;
|
|
8870
|
+
if (typeof body.requestId === "string" && body.requestId.length > 0) requestId = body.requestId;
|
|
8871
|
+
}
|
|
8828
8872
|
if (e.statusCode) {
|
|
8829
|
-
summary = `${toolName} failed: HTTP ${e.statusCode}`;
|
|
8873
|
+
summary = `${toolName} failed: HTTP ${e.statusCode}${errorCode ? ` (${errorCode})` : ""}`;
|
|
8830
8874
|
} else if (e.name && e.name !== "Error") {
|
|
8831
8875
|
summary = `${toolName} failed: ${e.name}`;
|
|
8832
8876
|
}
|
|
8833
8877
|
}
|
|
8834
|
-
const
|
|
8878
|
+
const trailer = (errorCode ? `
|
|
8879
|
+
errorCode: ${errorCode}` : "") + (requestId ? `
|
|
8880
|
+
requestId: ${requestId}` : "") + (docPointer ? `
|
|
8835
8881
|
|
|
8836
|
-
See: ${docPointer}` : "";
|
|
8882
|
+
See: ${docPointer}` : "");
|
|
8837
8883
|
return {
|
|
8838
8884
|
isError: true,
|
|
8839
8885
|
content: [
|
|
8840
8886
|
{
|
|
8841
8887
|
type: "text",
|
|
8842
8888
|
text: `${summary}
|
|
8843
|
-
${detail}${
|
|
8889
|
+
${detail}${trailer}`
|
|
8844
8890
|
}
|
|
8845
8891
|
]
|
|
8846
8892
|
};
|
|
@@ -8917,7 +8963,7 @@ var inputSchema = {
|
|
|
8917
8963
|
var hybridSearch = ({ client, log }) => ({
|
|
8918
8964
|
name: "hybrid_search",
|
|
8919
8965
|
title: "Hybrid search",
|
|
8920
|
-
description:
|
|
8966
|
+
description: 'Search your tenant\'s indexed content (documents + structured records) using hybrid BM25 + dense ranking. Returns up to `limit` results (default 3, max 50 \u2014 raise it in one call when you can accept the larger result) with citations and surrounding context for grounding follow-up reasoning. Narrow with contentTypes/typeName/filters, ownership (userId/scope), folder scope, a created date window, keyword precision (textMode OR/AND/PHRASE), relevance floors (minSimilarity/minTextRelevance), uniqueDocuments, and requireComplete (fail closed on a degraded backend). Tenant-isolated; the caller\'s scoped key fully constrains which content is visible. ARCHIVED (soft-retracted) documents never appear in results \u2014 fetch them by id via document_get, or restore them via document_update. To stay within the agent context window each hit returns its matched chunkText + a short snippet by default; set includeContext:true for the broader surrounding passage. If the whole result would be too large it is truncated to the top hits (truncated:true). totalResults is the full matching pool and hasMore:true means results remain past this page \u2014 raise limit or advance offset to fetch them. textLegEmpty:true flags that the keyword (BM25) leg matched nothing (all textScores 0) \u2014 typically the default PHRASE mode finding no contiguous match for a long natural-language query. Loosen the keyword leg: shorten the query to its key terms, or set textMode "AND" (all terms, higher precision) or "OR" (any term, broad recall).',
|
|
8921
8967
|
inputSchema,
|
|
8922
8968
|
handler: async (args) => {
|
|
8923
8969
|
const limit = args.limit ?? MCP_DEFAULT_LIMIT;
|
|
@@ -9110,14 +9156,14 @@ var record_query_default = recordQuery;
|
|
|
9110
9156
|
var import_zod3 = require("zod");
|
|
9111
9157
|
|
|
9112
9158
|
// src/tools/resolve-external-id.ts
|
|
9113
|
-
function validateSelector(sel, entity) {
|
|
9159
|
+
function validateSelector(sel, entity, fieldName) {
|
|
9114
9160
|
const hasId = sel.id !== void 0 && sel.id !== "";
|
|
9115
9161
|
const hasExt = sel.externalId !== void 0 && sel.externalId !== "";
|
|
9116
9162
|
if (hasId && hasExt) {
|
|
9117
|
-
return `Provide either
|
|
9163
|
+
return `Provide either ${fieldName} or externalId (not both) to identify the ${entity}.`;
|
|
9118
9164
|
}
|
|
9119
9165
|
if (!hasId && !hasExt) {
|
|
9120
|
-
return `Provide
|
|
9166
|
+
return `Provide ${fieldName}, or externalId + type, to identify the ${entity}.`;
|
|
9121
9167
|
}
|
|
9122
9168
|
if (hasExt && (sel.type === void 0 || sel.type === "")) {
|
|
9123
9169
|
return "type is required when selecting by externalId (externalId is unique within a type).";
|
|
@@ -9125,7 +9171,7 @@ function validateSelector(sel, entity) {
|
|
|
9125
9171
|
return void 0;
|
|
9126
9172
|
}
|
|
9127
9173
|
async function resolveRecordIdByExternalId(client, sel) {
|
|
9128
|
-
const err = validateSelector(sel, "record");
|
|
9174
|
+
const err = validateSelector(sel, "record", "id");
|
|
9129
9175
|
if (err) return { error: err };
|
|
9130
9176
|
if (sel.id) return { id: sel.id };
|
|
9131
9177
|
const page = await client.records.lookupRecordsByBody({
|
|
@@ -9141,7 +9187,7 @@ async function resolveRecordIdByExternalId(client, sel) {
|
|
|
9141
9187
|
return { id: items[0].id };
|
|
9142
9188
|
}
|
|
9143
9189
|
async function resolveDocumentIdByExternalId(client, sel) {
|
|
9144
|
-
const err = validateSelector(sel, "document");
|
|
9190
|
+
const err = validateSelector(sel, "document", "documentId");
|
|
9145
9191
|
if (err) return { error: err };
|
|
9146
9192
|
if (sel.id) return { id: sel.id };
|
|
9147
9193
|
const page = await client.documents.lookupDocumentsByBody({
|
|
@@ -9169,7 +9215,7 @@ var inputSchema3 = {
|
|
|
9169
9215
|
var recordGet = ({ client, log }) => ({
|
|
9170
9216
|
name: "record_get",
|
|
9171
9217
|
title: "Get a record by id or externalId",
|
|
9172
|
-
description: "Fetch a single structured record, including the full payload. Select it EITHER by its Vectros `id` (e.g. from record_query / hybrid_search) OR by your own `externalId` + `type` \u2014 the same key you passed to record_create, resolved for you (no manual record_query lookup needed). Very large payloads are truncated to protect the agent context window.",
|
|
9218
|
+
description: "Fetch a single structured record, including the full payload. Select it EITHER by its Vectros `id` (e.g. from record_query / hybrid_search) OR by your own `externalId` + `type` \u2014 the same key you passed to record_create, resolved for you (no manual record_query lookup needed). Very large payloads are truncated to protect the agent context window. The response carries the record's processing `indexStatus`; when it is FAILED an `indexFailure.code` explains whether the content is still searchable (e.g. VECTOR_LIMIT_EXCEEDED keeps keyword search vs INDEXING_FAILED = not findable at all) \u2014 branch on the `code`, not the message.",
|
|
9173
9219
|
inputSchema: inputSchema3,
|
|
9174
9220
|
handler: async (args) => {
|
|
9175
9221
|
const id = args.id;
|
|
@@ -9207,7 +9253,7 @@ var import_zod4 = require("zod");
|
|
|
9207
9253
|
var inputSchema4 = {
|
|
9208
9254
|
type: import_zod4.z.string().min(1, "type is required").describe('Record type / schema name (e.g. "task"). Must match an existing schema \u2014 see list_schemas.'),
|
|
9209
9255
|
fields: import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()).describe(
|
|
9210
|
-
"The record payload \u2014 a JSON object of field\u2192value, validated against the type schema. Call list_schemas to learn required fields, types, and enum values."
|
|
9256
|
+
"The record payload \u2014 a JSON object of field\u2192value, validated against the type schema. Call list_schemas to learn required fields, types, and enum values. Every number must fall within the signed 64-bit range (a value outside it, or with >38 significant digits, is refused with a 400 naming the field) \u2014 send a larger whole number (e.g. a big external id) as a STRING, which stores it exactly and supports exact-match lookup."
|
|
9211
9257
|
),
|
|
9212
9258
|
externalId: import_zod4.z.string().optional().describe(
|
|
9213
9259
|
"Stable caller-supplied id. Immutable; unique per type. Re-creating with the same externalId returns the existing record (idempotent) \u2014 use it to make creates safely retryable."
|
|
@@ -9225,7 +9271,7 @@ var inputSchema4 = {
|
|
|
9225
9271
|
var recordCreate = ({ client, log }) => ({
|
|
9226
9272
|
name: "record_create",
|
|
9227
9273
|
title: "Create a record",
|
|
9228
|
-
description: "Create a structured record of a given type. Provide `type` and `fields` (the payload, validated against the type schema \u2014 call list_schemas first to learn required fields and enums). Idempotent by `externalId`. Requires the key to allow records:c.",
|
|
9274
|
+
description: "Create a structured record of a given type. Provide `type` and `fields` (the payload, validated against the type schema \u2014 call list_schemas first to learn required fields and enums). Idempotent by `externalId`. Requires the key to allow records:c (and records:r to receive the existing record on a collision).",
|
|
9229
9275
|
inputSchema: inputSchema4,
|
|
9230
9276
|
handler: async (args) => {
|
|
9231
9277
|
const type = args.type;
|
|
@@ -9583,7 +9629,7 @@ function isNotAvailable(err) {
|
|
|
9583
9629
|
var documentGet = ({ client, log }) => ({
|
|
9584
9630
|
name: "document_get",
|
|
9585
9631
|
title: "Get document metadata (and optionally text)",
|
|
9586
|
-
description: "Fetch metadata for a single document \u2014 select it by its Vectros `documentId` OR by your own `externalId` + `type` (resolved for you). Pass `includeText: true` to also fetch the text body (capped at ~8K tokens; `truncated: true` flag if cut). Text is available for every text-ingested document and for file-ingested documents unless they were uploaded with `storeText: false` (extracted text discarded after indexing) \u2014 then `textAvailable: false` is set; the original file is still retrievable via `includeDownloadUrl`. Pass `includeDownloadUrl: true` to also get a short-lived presigned `downloadUrl` for the original file (file-backed documents only). Returns the full document metadata, including its lifecycle `status` (ACTIVE, or ARCHIVED when soft-retracted from search \u2014 restorable via document_update) and its processing `indexStatus`.",
|
|
9632
|
+
description: "Fetch metadata for a single document \u2014 select it by its Vectros `documentId` OR by your own `externalId` + `type` (resolved for you). Pass `includeText: true` to also fetch the text body (capped at ~8K tokens; `truncated: true` flag if cut). Text is available for every text-ingested document and for file-ingested documents unless they were uploaded with `storeText: false` (extracted text discarded after indexing) \u2014 then `textAvailable: false` is set; the original file is still retrievable via `includeDownloadUrl`. Pass `includeDownloadUrl: true` to also get a short-lived presigned `downloadUrl` for the original file (file-backed documents only). Returns the full document metadata, including its lifecycle `status` (ACTIVE, or ARCHIVED when soft-retracted from search \u2014 restorable via document_update) and its processing `indexStatus`. When `indexStatus` is FAILED the response also carries `indexFailure` with a machine-readable `code` telling you whether the content is still findable \u2014 e.g. TEXT_INDEX_FAILED / VECTOR_LIMIT_EXCEEDED (one leg still serves it) vs INDEXING_FAILED (not findable by search at all). Branch on `code`, not on the message.",
|
|
9587
9633
|
inputSchema: inputSchema10,
|
|
9588
9634
|
handler: async (args) => {
|
|
9589
9635
|
const documentId = args.documentId;
|
|
@@ -9917,7 +9963,7 @@ var inputSchema15 = {
|
|
|
9917
9963
|
var folderCreate = ({ client, log }) => ({
|
|
9918
9964
|
name: "folder_create",
|
|
9919
9965
|
title: "Create a folder",
|
|
9920
|
-
description: "Create a folder to organize documents and records. Pass `parentId` to nest it (create-only \u2014 folders cannot be moved later). Idempotent by `slug` within the parent. Requires the key to allow folders:c.",
|
|
9966
|
+
description: "Create a folder to organize documents and records. Pass `parentId` to nest it (create-only \u2014 folders cannot be moved later). Idempotent by `slug` within the parent. Requires the key to allow folders:c (and folders:r to receive the existing folder on a collision).",
|
|
9921
9967
|
inputSchema: inputSchema15,
|
|
9922
9968
|
handler: async (args) => {
|
|
9923
9969
|
try {
|
|
@@ -10016,7 +10062,7 @@ var inputSchema18 = {
|
|
|
10016
10062
|
var currentIdentity = ({ log, apiKey, environment }) => ({
|
|
10017
10063
|
name: "current_identity",
|
|
10018
10064
|
title: "Current identity (tenant + principal scope)",
|
|
10019
|
-
description: "Describe the credential the MCP server is operating under. Returns tenantId, environment (staging|production), principalType (root_key|scoped_key|token), principalKeyId, and (for scoped
|
|
10065
|
+
description: "Describe the credential the MCP server is operating under. Returns tenantId, environment (staging|production), principalType (root_key|scoped_key|token), principalKeyId, principalLabel, and (for scoped credentials) allowedActions plus dataScope \u2014 the credential's reach as { userId, scopes[] }, where each scope is a `namespace:value` string (e.g. \"org:<uuid>\"). Use this when the user asks 'what can you do here?' or 'what tenant am I in?'. Calls GET /v1/ping under the hood.",
|
|
10020
10066
|
inputSchema: inputSchema18,
|
|
10021
10067
|
handler: async () => {
|
|
10022
10068
|
try {
|
|
@@ -10114,7 +10160,7 @@ var inputSchema19 = {
|
|
|
10114
10160
|
"Index strategy. HYBRID (BM25 + dense, default; best for general retrieval), SEMANTIC (dense only; concept-driven queries), TEXT (BM25 only; exact-match / keyword), NONE (store-only / archival \u2014 retrievable by id and structured-field lookup but never in search results). Omit to inherit the bound schema's default."
|
|
10115
10161
|
),
|
|
10116
10162
|
externalId: import_zod18.z.string().optional().describe(
|
|
10117
|
-
|
|
10163
|
+
'Stable caller-supplied id. Immutable; unique per type within your context. Re-ingesting with the same externalId returns the existing document (idempotent) instead of creating a duplicate \u2014 use it to make ingests safely retryable and as the key other records reference. Mirrors record_create. Receiving the existing document back is a read of it and needs documents:r in addition to documents:c; a create-only key gets an "already exists" error instead of the document.'
|
|
10118
10164
|
),
|
|
10119
10165
|
upsert: import_zod18.z.boolean().optional().describe(
|
|
10120
10166
|
"When true, re-ingesting an existing externalId OVERWRITES that document and re-indexes the new body (text mode) / re-uploads and re-indexes the new file (file mode), instead of returning the existing one unchanged. This is the curation/re-sync primitive: edit a source, re-ingest with upsert:true, and the search index reflects the new content. Requires the documents:u scope. IMPORTANT: pass the SAME schemaId (and type) you used originally \u2014 externalId is unique WITHIN a type, so omitting schemaId resolves in the untyped namespace and mints a duplicate instead of updating. The response `created` flag confirms which happened (created:true = a new document was minted)."
|
|
@@ -10123,12 +10169,12 @@ var inputSchema19 = {
|
|
|
10123
10169
|
"Bind this document to a record schema. When set, `payload` is validated against the schema and its lookup fields become directly queryable via document_query (records parity). Resolve a schema id from its type via list_schemas. Omit for an untyped document."
|
|
10124
10170
|
),
|
|
10125
10171
|
payload: import_zod18.z.record(import_zod18.z.string(), import_zod18.z.unknown()).optional().describe(
|
|
10126
|
-
"The document's structured data \u2014 a flat key/value object. With `schemaId`, declared fields are validated and lookup fields indexed; undeclared keys pass through as free-form and are searchable via the hybrid_search `filters` param. Without a schema it is stored as free-form metadata."
|
|
10172
|
+
"The document's structured data \u2014 a flat key/value object. With `schemaId`, declared fields are validated and lookup fields indexed; undeclared keys pass through as free-form and are searchable via the hybrid_search `filters` param. Without a schema it is stored as free-form metadata. Every number must fall within the signed 64-bit range \u2014 send a larger whole number as a STRING (stored exactly, exact-match lookup), else the ingest is refused with a 400 naming the field."
|
|
10127
10173
|
),
|
|
10128
10174
|
// Inline text mode (mutually exclusive with filePath):
|
|
10129
10175
|
text: import_zod18.z.string().min(1).optional().describe("Text body to ingest inline. Mutually exclusive with filePath. Either text or filePath is required."),
|
|
10130
10176
|
storeText: import_zod18.z.boolean().optional().describe(
|
|
10131
|
-
"Whether the
|
|
10177
|
+
"FILE MODE ONLY. Whether the uploaded file's EXTRACTED text is retained after indexing (default true), fixed at ingest. true keeps the extracted text retrievable via document_get(includeText:true) and usable by document_ask; false discards it once indexing completes \u2014 search still works and the original file remains downloadable, but includeText returns textAvailable:false and document_ask is unavailable. NOT accepted with `text`: a text-ingested body is the document itself and is ALWAYS retained, so the backend has no storeText knob on the text path \u2014 passing it with `text` is rejected rather than silently ignored."
|
|
10132
10178
|
),
|
|
10133
10179
|
// File upload mode (mutually exclusive with text; stdio-transport-only):
|
|
10134
10180
|
filePath: import_zod18.z.string().min(1).optional().describe(
|
|
@@ -10145,7 +10191,7 @@ var inputSchema19 = {
|
|
|
10145
10191
|
var documentIngest = ({ client, log, transport, ingestRoot }) => ({
|
|
10146
10192
|
name: "document_ingest",
|
|
10147
10193
|
title: "Ingest a new document (text body or file upload)",
|
|
10148
|
-
description: "Create a new document in your Vectros tenant. Two modes:\n \u2022 Text mode: pass `text` (string body). Single-call. Use for crawled content, notes, generated text.\n \u2022 File mode: pass `filePath` (local path on the MCP server's host machine). STDIO-TRANSPORT ONLY \u2014 rejected on HTTP transport. MCP server reads the bytes, requests a presigned upload URL, and PUTs them. Returns when the upload is accepted (indexStatus: PENDING_INDEX); poll with `document_get` until indexStatus is INDEXED.\nEither `text` or `filePath` must be present; both is an error. Idempotent by `externalId` (re-ingest returns the existing document, not a duplicate). To UPDATE an existing document instead \u2014 re-index an edited body \u2014 pass `upsert:true` with the same `externalId` (and the same `schemaId`); this is the re-sync primitive for keeping a knowledge base current. Pass `schemaId` + `payload` for a typed, lookup-queryable document (records parity). indexMode defaults to HYBRID for untyped documents (omit to inherit a bound schema's default). storeText
|
|
10194
|
+
description: "Create a new document in your Vectros tenant. Two modes:\n \u2022 Text mode: pass `text` (string body). Single-call. Use for crawled content, notes, generated text.\n \u2022 File mode: pass `filePath` (local path on the MCP server's host machine). STDIO-TRANSPORT ONLY \u2014 rejected on HTTP transport. MCP server reads the bytes, requests a presigned upload URL, and PUTs them. Returns when the upload is accepted (indexStatus: PENDING_INDEX); poll with `document_get` until indexStatus is INDEXED.\nEither `text` or `filePath` must be present; both is an error. Idempotent by `externalId` (re-ingest returns the existing document, not a duplicate \u2014 requires documents:r in addition to documents:c, since being handed the existing document is a read of it). To UPDATE an existing document instead \u2014 re-index an edited body \u2014 pass `upsert:true` with the same `externalId` (and the same `schemaId`); this is the re-sync primitive for keeping a knowledge base current. Pass `schemaId` + `payload` for a typed, lookup-queryable document (records parity). indexMode defaults to HYBRID for untyped documents (omit to inherit a bound schema's default). storeText is a FILE-MODE knob (default true): false discards the uploaded file's extracted text after indexing (search + file download keep working; text retrieval and document_ask do not). Text-mode bodies are always retained, so storeText is not accepted with `text`.",
|
|
10149
10195
|
inputSchema: inputSchema19,
|
|
10150
10196
|
handler: async (args) => {
|
|
10151
10197
|
const title = args.title;
|
|
@@ -10182,6 +10228,14 @@ var documentIngest = ({ client, log, transport, ingestRoot }) => ({
|
|
|
10182
10228
|
)
|
|
10183
10229
|
);
|
|
10184
10230
|
}
|
|
10231
|
+
if (text && args.storeText !== void 0) {
|
|
10232
|
+
return toolError(
|
|
10233
|
+
"document_ingest",
|
|
10234
|
+
new Error(
|
|
10235
|
+
"`storeText` is not supported with `text` \u2014 a text-ingested body is the document itself and is always retained; the text path has no storeText control. Omit it (text mode), or use `filePath` mode where storeText:false discards the uploaded file's extracted text after indexing."
|
|
10236
|
+
)
|
|
10237
|
+
);
|
|
10238
|
+
}
|
|
10185
10239
|
const common = {
|
|
10186
10240
|
folderId: args.folderId,
|
|
10187
10241
|
payload: args.payload,
|
|
@@ -10486,7 +10540,7 @@ var identityResource = ({ log, apiKey, environment }) => ({
|
|
|
10486
10540
|
name: "identity",
|
|
10487
10541
|
uri: "vectros://identity",
|
|
10488
10542
|
title: "Current identity (tenant + principal scope)",
|
|
10489
|
-
description: "The tenant + principal scope the MCP server is authenticated as. Returns the same payload as the `current_identity` tool: status, environment, principalType, principalKeyId, and (for scoped
|
|
10543
|
+
description: "The tenant + principal scope the MCP server is authenticated as. Returns the same payload as the `current_identity` tool: status, tenantId, environment, principalType, principalKeyId, principalLabel, and (for scoped credentials) allowedActions + dataScope ({ userId, scopes[] }). The /v1/ping backing call ships this extended shape today.",
|
|
10490
10544
|
mimeType: "application/json",
|
|
10491
10545
|
read: async () => {
|
|
10492
10546
|
const identity = await resolveIdentity({ log, apiKey, environment });
|