@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/cli-http.mjs CHANGED
@@ -3,7 +3,7 @@
3
3
  // src/server.ts
4
4
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
5
5
 
6
- // ../../node_modules/@vectros-ai/sdk/dist/index.mjs
6
+ // node_modules/@vectros-ai/sdk/dist/index.mjs
7
7
  var __defProp = Object.defineProperty;
8
8
  var __export = (target, all) => {
9
9
  for (var name in all)
@@ -4613,7 +4613,7 @@ var DocumentsClient = class {
4613
4613
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/documents");
4614
4614
  }
4615
4615
  /**
4616
- * 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.
4616
+ * 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.
4617
4617
  *
4618
4618
  * @param {Vectros.IngestDocumentRequest} request
4619
4619
  * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -4939,25 +4939,29 @@ var DocumentsClient = class {
4939
4939
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "PATCH", "/v1/documents/{id}");
4940
4940
  }
4941
4941
  /**
4942
- * 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.
4942
+ * 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.
4943
4943
  *
4944
4944
  * @param {Vectros.LookupDocumentsRequest} request
4945
4945
  * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
4946
4946
  *
4947
+ * @throws {@link Vectros.BadRequestError}
4948
+ *
4947
4949
  * @example
4948
4950
  * await client.documents.lookupDocuments({
4949
4951
  * type: "invoice",
4950
4952
  * field: "po_number",
4951
4953
  * value: "PO-1001",
4952
4954
  * prefix: "PO-2024",
4953
- * startFrom: "550e8400-e29b-41d4-a716-446655440000"
4955
+ * startFrom: "550e8400-e29b-41d4-a716-446655440000",
4956
+ * userId: "550e8400-e29b-41d4-a716-446655440000",
4957
+ * scope: "org:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
4954
4958
  * })
4955
4959
  */
4956
4960
  lookupDocuments(request, requestOptions) {
4957
4961
  return HttpResponsePromise.fromPromise(this.__lookupDocuments(request, requestOptions));
4958
4962
  }
4959
4963
  async __lookupDocuments(request, requestOptions) {
4960
- const { type: type_, field, value, from: from_, to, prefix, startFrom, limit, order } = request;
4964
+ const { type: type_, field, value, from: from_, to, prefix, startFrom, limit, order, userId, scope } = request;
4961
4965
  const _queryParams = {
4962
4966
  type: type_,
4963
4967
  field,
@@ -4967,7 +4971,9 @@ var DocumentsClient = class {
4967
4971
  prefix,
4968
4972
  startFrom,
4969
4973
  limit,
4970
- order: order != null ? order : void 0
4974
+ order: order != null ? order : void 0,
4975
+ userId,
4976
+ scope
4971
4977
  };
4972
4978
  const _authRequest = await this._options.authProvider.getAuthRequest();
4973
4979
  const _headers = mergeHeaders(
@@ -4993,11 +4999,16 @@ var DocumentsClient = class {
4993
4999
  return { data: _response.body, rawResponse: _response.rawResponse };
4994
5000
  }
4995
5001
  if (_response.error.reason === "status-code") {
4996
- throw new VectrosError({
4997
- statusCode: _response.error.statusCode,
4998
- body: _response.error.body,
4999
- rawResponse: _response.rawResponse
5000
- });
5002
+ switch (_response.error.statusCode) {
5003
+ case 400:
5004
+ throw new BadRequestError(_response.error.body, _response.rawResponse);
5005
+ default:
5006
+ throw new VectrosError({
5007
+ statusCode: _response.error.statusCode,
5008
+ body: _response.error.body,
5009
+ rawResponse: _response.rawResponse
5010
+ });
5011
+ }
5001
5012
  }
5002
5013
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/documents/lookup");
5003
5014
  }
@@ -5365,7 +5376,7 @@ var FoldersClient = class {
5365
5376
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/folders");
5366
5377
  }
5367
5378
  /**
5368
- * 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.
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 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.
5369
5380
  *
5370
5381
  * @param {Vectros.CreateFolderRequest} request
5371
5382
  * @param {FoldersClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -5823,7 +5834,7 @@ var IdentityClient = class {
5823
5834
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/entities/{namespace}");
5824
5835
  }
5825
5836
  /**
5826
- * 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.
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 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.
5827
5838
  *
5828
5839
  * @param {Vectros.CreateEntityRequest} request
5829
5840
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -6267,7 +6278,7 @@ var IdentityClient = class {
6267
6278
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/namespaces/{namespace}");
6268
6279
  }
6269
6280
  /**
6270
- * 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.
6281
+ * 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.
6271
6282
  *
6272
6283
  * @param {Vectros.UpdateNamespaceRequest} request
6273
6284
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -6280,7 +6291,8 @@ var IdentityClient = class {
6280
6291
  * await client.identity.updateNamespace({
6281
6292
  * namespace: "team",
6282
6293
  * body: {
6283
- * namespace: "team"
6294
+ * namespace: "team",
6295
+ * specificityRank: 1500
6284
6296
  * }
6285
6297
  * })
6286
6298
  */
@@ -6445,7 +6457,7 @@ var IdentityClient = class {
6445
6457
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/namespaces");
6446
6458
  }
6447
6459
  /**
6448
- * 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.
6460
+ * 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.
6449
6461
  *
6450
6462
  * @param {Vectros.NamespaceRequest} request
6451
6463
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -6456,7 +6468,8 @@ var IdentityClient = class {
6456
6468
  *
6457
6469
  * @example
6458
6470
  * await client.identity.registerNamespace({
6459
- * namespace: "team"
6471
+ * namespace: "team",
6472
+ * specificityRank: 1500
6460
6473
  * })
6461
6474
  */
6462
6475
  registerNamespace(request, requestOptions) {
@@ -6573,7 +6586,7 @@ var IdentityClient = class {
6573
6586
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/users");
6574
6587
  }
6575
6588
  /**
6576
- * 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.
6589
+ * 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.
6577
6590
  *
6578
6591
  * @param {Vectros.CreateUserRequest} request
6579
6592
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -7444,7 +7457,7 @@ var RecordsClient = class {
7444
7457
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/records");
7445
7458
  }
7446
7459
  /**
7447
- * 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.
7460
+ * 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.
7448
7461
  *
7449
7462
  * @param {Vectros.CreateRecordRequest} request
7450
7463
  * @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -8035,6 +8048,8 @@ var SchemasClient = class {
8035
8048
  * @param {Vectros.ListSchemasRequest} request
8036
8049
  * @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
8037
8050
  *
8051
+ * @throws {@link Vectros.BadRequestError}
8052
+ *
8038
8053
  * @example
8039
8054
  * await client.schemas.listSchemas({
8040
8055
  * userId: "550e8400-e29b-41d4-a716-446655440000",
@@ -8081,16 +8096,21 @@ var SchemasClient = class {
8081
8096
  return { data: _response.body, rawResponse: _response.rawResponse };
8082
8097
  }
8083
8098
  if (_response.error.reason === "status-code") {
8084
- throw new VectrosError({
8085
- statusCode: _response.error.statusCode,
8086
- body: _response.error.body,
8087
- rawResponse: _response.rawResponse
8088
- });
8099
+ switch (_response.error.statusCode) {
8100
+ case 400:
8101
+ throw new BadRequestError(_response.error.body, _response.rawResponse);
8102
+ default:
8103
+ throw new VectrosError({
8104
+ statusCode: _response.error.statusCode,
8105
+ body: _response.error.body,
8106
+ rawResponse: _response.rawResponse
8107
+ });
8108
+ }
8089
8109
  }
8090
8110
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/schemas");
8091
8111
  }
8092
8112
  /**
8093
- * 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.
8113
+ * 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.
8094
8114
  *
8095
8115
  * @param {Vectros.CreateSchemaRequest} request
8096
8116
  * @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -8234,7 +8254,7 @@ var SchemasClient = class {
8234
8254
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/schemas/{id}");
8235
8255
  }
8236
8256
  /**
8237
- * 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.
8257
+ * 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.
8238
8258
  *
8239
8259
  * @param {Vectros.UpdateSchemaRequest} request
8240
8260
  * @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -8303,7 +8323,7 @@ var SchemasClient = class {
8303
8323
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "PUT", "/v1/schemas/{id}");
8304
8324
  }
8305
8325
  /**
8306
- * 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.
8326
+ * 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.
8307
8327
  *
8308
8328
  * @param {Vectros.DeleteSchemaRequest} request
8309
8329
  * @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -8605,8 +8625,8 @@ function warnOnSuboptimalKey(key, log) {
8605
8625
 
8606
8626
  // src/build-info.ts
8607
8627
  var BUILD_INFO = {
8608
- mcpServer: true ? "0.11.0" : "dev",
8609
- sdk: true ? "0.36.0" : "dev"
8628
+ mcpServer: true ? "0.12.0" : "dev",
8629
+ sdk: true ? "0.37.0" : "dev"
8610
8630
  };
8611
8631
 
8612
8632
  // src/log.ts
@@ -9118,14 +9138,14 @@ var record_query_default = recordQuery;
9118
9138
  import { z as z3 } from "zod";
9119
9139
 
9120
9140
  // src/tools/resolve-external-id.ts
9121
- function validateSelector(sel, entity) {
9141
+ function validateSelector(sel, entity, fieldName) {
9122
9142
  const hasId = sel.id !== void 0 && sel.id !== "";
9123
9143
  const hasExt = sel.externalId !== void 0 && sel.externalId !== "";
9124
9144
  if (hasId && hasExt) {
9125
- return `Provide either id or externalId (not both) to identify the ${entity}.`;
9145
+ return `Provide either ${fieldName} or externalId (not both) to identify the ${entity}.`;
9126
9146
  }
9127
9147
  if (!hasId && !hasExt) {
9128
- return `Provide id, or externalId + type, to identify the ${entity}.`;
9148
+ return `Provide ${fieldName}, or externalId + type, to identify the ${entity}.`;
9129
9149
  }
9130
9150
  if (hasExt && (sel.type === void 0 || sel.type === "")) {
9131
9151
  return "type is required when selecting by externalId (externalId is unique within a type).";
@@ -9133,7 +9153,7 @@ function validateSelector(sel, entity) {
9133
9153
  return void 0;
9134
9154
  }
9135
9155
  async function resolveRecordIdByExternalId(client, sel) {
9136
- const err = validateSelector(sel, "record");
9156
+ const err = validateSelector(sel, "record", "id");
9137
9157
  if (err) return { error: err };
9138
9158
  if (sel.id) return { id: sel.id };
9139
9159
  const page = await client.records.lookupRecordsByBody({
@@ -9149,7 +9169,7 @@ async function resolveRecordIdByExternalId(client, sel) {
9149
9169
  return { id: items[0].id };
9150
9170
  }
9151
9171
  async function resolveDocumentIdByExternalId(client, sel) {
9152
- const err = validateSelector(sel, "document");
9172
+ const err = validateSelector(sel, "document", "documentId");
9153
9173
  if (err) return { error: err };
9154
9174
  if (sel.id) return { id: sel.id };
9155
9175
  const page = await client.documents.lookupDocumentsByBody({