@vectros-ai/mcp-server 0.11.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/dist/index.js CHANGED
@@ -42,7 +42,7 @@ module.exports = __toCommonJS(index_exports);
42
42
  // src/server.ts
43
43
  var import_server = require("@modelcontextprotocol/sdk/server/index.js");
44
44
 
45
- // ../../node_modules/@vectros-ai/sdk/dist/index.mjs
45
+ // node_modules/@vectros-ai/sdk/dist/index.mjs
46
46
  var __defProp2 = Object.defineProperty;
47
47
  var __export2 = (target, all) => {
48
48
  for (var name in all)
@@ -4652,7 +4652,7 @@ var DocumentsClient = class {
4652
4652
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/documents");
4653
4653
  }
4654
4654
  /**
4655
- * 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.
4655
+ * 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.
4656
4656
  *
4657
4657
  * @param {Vectros.IngestDocumentRequest} request
4658
4658
  * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -4978,25 +4978,29 @@ var DocumentsClient = class {
4978
4978
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "PATCH", "/v1/documents/{id}");
4979
4979
  }
4980
4980
  /**
4981
- * 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.
4981
+ * 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.
4982
4982
  *
4983
4983
  * @param {Vectros.LookupDocumentsRequest} request
4984
4984
  * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
4985
4985
  *
4986
+ * @throws {@link Vectros.BadRequestError}
4987
+ *
4986
4988
  * @example
4987
4989
  * await client.documents.lookupDocuments({
4988
4990
  * type: "invoice",
4989
4991
  * field: "po_number",
4990
4992
  * value: "PO-1001",
4991
4993
  * prefix: "PO-2024",
4992
- * startFrom: "550e8400-e29b-41d4-a716-446655440000"
4994
+ * startFrom: "550e8400-e29b-41d4-a716-446655440000",
4995
+ * userId: "550e8400-e29b-41d4-a716-446655440000",
4996
+ * scope: "org:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
4993
4997
  * })
4994
4998
  */
4995
4999
  lookupDocuments(request, requestOptions) {
4996
5000
  return HttpResponsePromise.fromPromise(this.__lookupDocuments(request, requestOptions));
4997
5001
  }
4998
5002
  async __lookupDocuments(request, requestOptions) {
4999
- const { type: type_, field, value, from: from_, to, prefix, startFrom, limit, order } = request;
5003
+ const { type: type_, field, value, from: from_, to, prefix, startFrom, limit, order, userId, scope } = request;
5000
5004
  const _queryParams = {
5001
5005
  type: type_,
5002
5006
  field,
@@ -5006,7 +5010,9 @@ var DocumentsClient = class {
5006
5010
  prefix,
5007
5011
  startFrom,
5008
5012
  limit,
5009
- order: order != null ? order : void 0
5013
+ order: order != null ? order : void 0,
5014
+ userId,
5015
+ scope
5010
5016
  };
5011
5017
  const _authRequest = await this._options.authProvider.getAuthRequest();
5012
5018
  const _headers = mergeHeaders(
@@ -5032,11 +5038,16 @@ var DocumentsClient = class {
5032
5038
  return { data: _response.body, rawResponse: _response.rawResponse };
5033
5039
  }
5034
5040
  if (_response.error.reason === "status-code") {
5035
- throw new VectrosError({
5036
- statusCode: _response.error.statusCode,
5037
- body: _response.error.body,
5038
- rawResponse: _response.rawResponse
5039
- });
5041
+ switch (_response.error.statusCode) {
5042
+ case 400:
5043
+ throw new BadRequestError(_response.error.body, _response.rawResponse);
5044
+ default:
5045
+ throw new VectrosError({
5046
+ statusCode: _response.error.statusCode,
5047
+ body: _response.error.body,
5048
+ rawResponse: _response.rawResponse
5049
+ });
5050
+ }
5040
5051
  }
5041
5052
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/documents/lookup");
5042
5053
  }
@@ -5404,7 +5415,7 @@ var FoldersClient = class {
5404
5415
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/folders");
5405
5416
  }
5406
5417
  /**
5407
- * 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.
5418
+ * 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.
5408
5419
  *
5409
5420
  * @param {Vectros.CreateFolderRequest} request
5410
5421
  * @param {FoldersClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -5862,7 +5873,7 @@ var IdentityClient = class {
5862
5873
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/entities/{namespace}");
5863
5874
  }
5864
5875
  /**
5865
- * 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.
5876
+ * 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.
5866
5877
  *
5867
5878
  * @param {Vectros.CreateEntityRequest} request
5868
5879
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -6306,7 +6317,7 @@ var IdentityClient = class {
6306
6317
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/namespaces/{namespace}");
6307
6318
  }
6308
6319
  /**
6309
- * 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.
6320
+ * 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.
6310
6321
  *
6311
6322
  * @param {Vectros.UpdateNamespaceRequest} request
6312
6323
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -6319,7 +6330,8 @@ var IdentityClient = class {
6319
6330
  * await client.identity.updateNamespace({
6320
6331
  * namespace: "team",
6321
6332
  * body: {
6322
- * namespace: "team"
6333
+ * namespace: "team",
6334
+ * specificityRank: 1500
6323
6335
  * }
6324
6336
  * })
6325
6337
  */
@@ -6484,7 +6496,7 @@ var IdentityClient = class {
6484
6496
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/namespaces");
6485
6497
  }
6486
6498
  /**
6487
- * 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.
6499
+ * 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.
6488
6500
  *
6489
6501
  * @param {Vectros.NamespaceRequest} request
6490
6502
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -6495,7 +6507,8 @@ var IdentityClient = class {
6495
6507
  *
6496
6508
  * @example
6497
6509
  * await client.identity.registerNamespace({
6498
- * namespace: "team"
6510
+ * namespace: "team",
6511
+ * specificityRank: 1500
6499
6512
  * })
6500
6513
  */
6501
6514
  registerNamespace(request, requestOptions) {
@@ -6612,7 +6625,7 @@ var IdentityClient = class {
6612
6625
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/users");
6613
6626
  }
6614
6627
  /**
6615
- * 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.
6628
+ * 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.
6616
6629
  *
6617
6630
  * @param {Vectros.CreateUserRequest} request
6618
6631
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -7483,7 +7496,7 @@ var RecordsClient = class {
7483
7496
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/records");
7484
7497
  }
7485
7498
  /**
7486
- * 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.
7499
+ * 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.
7487
7500
  *
7488
7501
  * @param {Vectros.CreateRecordRequest} request
7489
7502
  * @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -8074,6 +8087,8 @@ var SchemasClient = class {
8074
8087
  * @param {Vectros.ListSchemasRequest} request
8075
8088
  * @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
8076
8089
  *
8090
+ * @throws {@link Vectros.BadRequestError}
8091
+ *
8077
8092
  * @example
8078
8093
  * await client.schemas.listSchemas({
8079
8094
  * userId: "550e8400-e29b-41d4-a716-446655440000",
@@ -8120,16 +8135,21 @@ var SchemasClient = class {
8120
8135
  return { data: _response.body, rawResponse: _response.rawResponse };
8121
8136
  }
8122
8137
  if (_response.error.reason === "status-code") {
8123
- throw new VectrosError({
8124
- statusCode: _response.error.statusCode,
8125
- body: _response.error.body,
8126
- rawResponse: _response.rawResponse
8127
- });
8138
+ switch (_response.error.statusCode) {
8139
+ case 400:
8140
+ throw new BadRequestError(_response.error.body, _response.rawResponse);
8141
+ default:
8142
+ throw new VectrosError({
8143
+ statusCode: _response.error.statusCode,
8144
+ body: _response.error.body,
8145
+ rawResponse: _response.rawResponse
8146
+ });
8147
+ }
8128
8148
  }
8129
8149
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/schemas");
8130
8150
  }
8131
8151
  /**
8132
- * 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:w` scope; only legal schema changes are applied — migration-locked changes are rejected). Requires the `schemas:w` scope.
8152
+ * 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.
8133
8153
  *
8134
8154
  * @param {Vectros.CreateSchemaRequest} request
8135
8155
  * @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -8273,7 +8293,7 @@ var SchemasClient = class {
8273
8293
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/schemas/{id}");
8274
8294
  }
8275
8295
  /**
8276
- * 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:w` scope.
8296
+ * 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.
8277
8297
  *
8278
8298
  * @param {Vectros.UpdateSchemaRequest} request
8279
8299
  * @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -8342,7 +8362,7 @@ var SchemasClient = class {
8342
8362
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "PUT", "/v1/schemas/{id}");
8343
8363
  }
8344
8364
  /**
8345
- * 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:w` scope.
8365
+ * 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.
8346
8366
  *
8347
8367
  * @param {Vectros.DeleteSchemaRequest} request
8348
8368
  * @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -8639,8 +8659,8 @@ function warnOnSuboptimalKey(key, log) {
8639
8659
 
8640
8660
  // src/build-info.ts
8641
8661
  var BUILD_INFO = {
8642
- mcpServer: true ? "0.11.0" : "dev",
8643
- sdk: true ? "0.36.0" : "dev"
8662
+ mcpServer: true ? "0.12.0" : "dev",
8663
+ sdk: true ? "0.37.0" : "dev"
8644
8664
  };
8645
8665
 
8646
8666
  // src/log.ts
@@ -9152,14 +9172,14 @@ var record_query_default = recordQuery;
9152
9172
  var import_zod3 = require("zod");
9153
9173
 
9154
9174
  // src/tools/resolve-external-id.ts
9155
- function validateSelector(sel, entity) {
9175
+ function validateSelector(sel, entity, fieldName) {
9156
9176
  const hasId = sel.id !== void 0 && sel.id !== "";
9157
9177
  const hasExt = sel.externalId !== void 0 && sel.externalId !== "";
9158
9178
  if (hasId && hasExt) {
9159
- return `Provide either id or externalId (not both) to identify the ${entity}.`;
9179
+ return `Provide either ${fieldName} or externalId (not both) to identify the ${entity}.`;
9160
9180
  }
9161
9181
  if (!hasId && !hasExt) {
9162
- return `Provide id, or externalId + type, to identify the ${entity}.`;
9182
+ return `Provide ${fieldName}, or externalId + type, to identify the ${entity}.`;
9163
9183
  }
9164
9184
  if (hasExt && (sel.type === void 0 || sel.type === "")) {
9165
9185
  return "type is required when selecting by externalId (externalId is unique within a type).";
@@ -9167,7 +9187,7 @@ function validateSelector(sel, entity) {
9167
9187
  return void 0;
9168
9188
  }
9169
9189
  async function resolveRecordIdByExternalId(client, sel) {
9170
- const err = validateSelector(sel, "record");
9190
+ const err = validateSelector(sel, "record", "id");
9171
9191
  if (err) return { error: err };
9172
9192
  if (sel.id) return { id: sel.id };
9173
9193
  const page = await client.records.lookupRecordsByBody({
@@ -9183,7 +9203,7 @@ async function resolveRecordIdByExternalId(client, sel) {
9183
9203
  return { id: items[0].id };
9184
9204
  }
9185
9205
  async function resolveDocumentIdByExternalId(client, sel) {
9186
- const err = validateSelector(sel, "document");
9206
+ const err = validateSelector(sel, "document", "documentId");
9187
9207
  if (err) return { error: err };
9188
9208
  if (sel.id) return { id: sel.id };
9189
9209
  const page = await client.documents.lookupDocumentsByBody({