@vectros-ai/mcp-server 0.7.0 → 0.10.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)
@@ -18,7 +18,6 @@ __export(api_exports, {
18
18
  BatchWriteRequest: () => BatchWriteRequest,
19
19
  BatchWriteResult: () => BatchWriteResult,
20
20
  ChatMessage: () => ChatMessage,
21
- ClientRequest: () => ClientRequest,
22
21
  ConflictError: () => ConflictError,
23
22
  ContentDeltaEvent: () => ContentDeltaEvent,
24
23
  ContentTooLargeError: () => ContentTooLargeError,
@@ -27,6 +26,7 @@ __export(api_exports, {
27
26
  DocumentRequest: () => DocumentRequest,
28
27
  DocumentResponse: () => DocumentResponse,
29
28
  DoneEvent: () => DoneEvent,
29
+ EntityRequest: () => EntityRequest,
30
30
  ErasureCertificate: () => ErasureCertificate,
31
31
  ErasureRequest: () => ErasureRequest,
32
32
  ErasureRequestResponse: () => ErasureRequestResponse,
@@ -39,15 +39,13 @@ __export(api_exports, {
39
39
  ForbiddenError: () => ForbiddenError,
40
40
  IdentityLookupRequest: () => IdentityLookupRequest,
41
41
  InternalServerError: () => InternalServerError,
42
- ListClientsRequestOrder: () => ListClientsRequestOrder,
43
- ListOrgsRequestOrder: () => ListOrgsRequestOrder,
42
+ ListEntitiesRequestOrder: () => ListEntitiesRequestOrder,
44
43
  ListUsersRequestOrder: () => ListUsersRequestOrder,
45
44
  LookupDocumentsRequestOrder: () => LookupDocumentsRequestOrder,
46
45
  LookupRecordsRequestOrder: () => LookupRecordsRequestOrder,
47
46
  ModelDataVersionResponse: () => ModelDataVersionResponse,
48
47
  NotFoundError: () => NotFoundError,
49
48
  NotImplementedError: () => NotImplementedError,
50
- OrgRequest: () => OrgRequest,
51
49
  PaymentRequiredError: () => PaymentRequiredError,
52
50
  PingResponse: () => PingResponse,
53
51
  RagSearch: () => RagSearch,
@@ -288,11 +286,6 @@ var UnauthorizedError = class extends VectrosError {
288
286
  var auth_exports = {};
289
287
  var ErasureRequest;
290
288
  ((ErasureRequest2) => {
291
- ErasureRequest2.SubjectType = {
292
- User: "user",
293
- Client: "client",
294
- Org: "org"
295
- };
296
289
  ErasureRequest2.AuditDisposition = {
297
290
  RetainRedacted: "retain-redacted",
298
291
  Purge: "purge"
@@ -304,11 +297,6 @@ var ExportRequest;
304
297
  Tenant: "tenant",
305
298
  Subject: "subject"
306
299
  };
307
- ExportRequest2.SubjectType = {
308
- User: "user",
309
- Client: "client",
310
- Org: "org"
311
- };
312
300
  ExportRequest2.Format = {
313
301
  Ndjson: "ndjson"
314
302
  };
@@ -347,15 +335,10 @@ var LookupDocumentsRequestOrder = {
347
335
  var folders_exports = {};
348
336
  var identity_exports = {};
349
337
  __export(identity_exports, {
350
- ListClientsRequestOrder: () => ListClientsRequestOrder,
351
- ListOrgsRequestOrder: () => ListOrgsRequestOrder,
338
+ ListEntitiesRequestOrder: () => ListEntitiesRequestOrder,
352
339
  ListUsersRequestOrder: () => ListUsersRequestOrder
353
340
  });
354
- var ListClientsRequestOrder = {
355
- Asc: "asc",
356
- Desc: "desc"
357
- };
358
- var ListOrgsRequestOrder = {
341
+ var ListEntitiesRequestOrder = {
359
342
  Asc: "asc",
360
343
  Desc: "desc"
361
344
  };
@@ -454,13 +437,6 @@ var ChatMessage;
454
437
  Assistant: "assistant"
455
438
  };
456
439
  })(ChatMessage || (ChatMessage = {}));
457
- var ClientRequest;
458
- ((ClientRequest2) => {
459
- ClientRequest2.Status = {
460
- Active: "ACTIVE",
461
- Suspended: "SUSPENDED"
462
- };
463
- })(ClientRequest || (ClientRequest = {}));
464
440
  var ContentDeltaEvent;
465
441
  ((ContentDeltaEvent2) => {
466
442
  ContentDeltaEvent2.Event = {
@@ -515,6 +491,13 @@ var DoneEvent;
515
491
  Done: "done"
516
492
  };
517
493
  })(DoneEvent || (DoneEvent = {}));
494
+ var EntityRequest;
495
+ ((EntityRequest2) => {
496
+ EntityRequest2.Status = {
497
+ Active: "ACTIVE",
498
+ Suspended: "SUSPENDED"
499
+ };
500
+ })(EntityRequest || (EntityRequest = {}));
518
501
  var ErasureCertificate;
519
502
  ((ErasureCertificate2) => {
520
503
  ErasureCertificate2.AuditDisposition = {
@@ -530,11 +513,6 @@ var ErasureRequestResponse;
530
513
  Completed: "completed",
531
514
  Failed: "failed"
532
515
  };
533
- ErasureRequestResponse2.SubjectType = {
534
- User: "user",
535
- Client: "client",
536
- Org: "org"
537
- };
538
516
  })(ErasureRequestResponse || (ErasureRequestResponse = {}));
539
517
  var ErrorEvent;
540
518
  ((ErrorEvent2) => {
@@ -560,11 +538,6 @@ var ExportRequestResponse;
560
538
  Tenant: "tenant",
561
539
  Subject: "subject"
562
540
  };
563
- ExportRequestResponse2.SubjectType = {
564
- User: "user",
565
- Client: "client",
566
- Org: "org"
567
- };
568
541
  })(ExportRequestResponse || (ExportRequestResponse = {}));
569
542
  var FieldDef;
570
543
  ((FieldDef2) => {
@@ -578,13 +551,6 @@ var FieldDef;
578
551
  Object: "object",
579
552
  Reference: "reference"
580
553
  };
581
- FieldDef2.TargetSurface = {
582
- Record: "record",
583
- Document: "document",
584
- User: "user",
585
- Org: "org",
586
- Client: "client"
587
- };
588
554
  })(FieldDef || (FieldDef = {}));
589
555
  var IdentityLookupRequest;
590
556
  ((IdentityLookupRequest2) => {
@@ -601,13 +567,6 @@ var ModelDataVersionResponse;
601
567
  Delete: "DELETE"
602
568
  };
603
569
  })(ModelDataVersionResponse || (ModelDataVersionResponse = {}));
604
- var OrgRequest;
605
- ((OrgRequest2) => {
606
- OrgRequest2.Status = {
607
- Active: "ACTIVE",
608
- Suspended: "SUSPENDED"
609
- };
610
- })(OrgRequest || (OrgRequest = {}));
611
570
  var PingResponse;
612
571
  ((PingResponse2) => {
613
572
  PingResponse2.Environment = {
@@ -637,11 +596,6 @@ var RagSearch;
637
596
  })(RagSearch || (RagSearch = {}));
638
597
  var ReadAccessLogResponse;
639
598
  ((ReadAccessLogResponse2) => {
640
- ReadAccessLogResponse2.SubjectType = {
641
- User: "user",
642
- Client: "client",
643
- Org: "org"
644
- };
645
599
  ReadAccessLogResponse2.Action = {
646
600
  Read: "read",
647
601
  List: "list",
@@ -652,6 +606,10 @@ var ReadAccessLogResponse;
652
606
  })(ReadAccessLogResponse || (ReadAccessLogResponse = {}));
653
607
  var RecordRequest;
654
608
  ((RecordRequest2) => {
609
+ RecordRequest2.Status = {
610
+ Active: "ACTIVE",
611
+ Archived: "ARCHIVED"
612
+ };
655
613
  RecordRequest2.IndexMode = {
656
614
  Hybrid: "HYBRID",
657
615
  Semantic: "SEMANTIC",
@@ -661,6 +619,10 @@ var RecordRequest;
661
619
  })(RecordRequest || (RecordRequest = {}));
662
620
  var RecordResponse;
663
621
  ((RecordResponse2) => {
622
+ RecordResponse2.Status = {
623
+ Active: "ACTIVE",
624
+ Archived: "ARCHIVED"
625
+ };
664
626
  RecordResponse2.IndexStatus = {
665
627
  PendingIndex: "PENDING_INDEX",
666
628
  Indexed: "INDEXED",
@@ -703,8 +665,7 @@ var SchemaRequest;
703
665
  Record: "record",
704
666
  Document: "document",
705
667
  User: "user",
706
- Org: "org",
707
- Client: "client"
668
+ Entity: "entity"
708
669
  };
709
670
  })(AllowedSurfaces = SchemaRequest2.AllowedSurfaces || (SchemaRequest2.AllowedSurfaces = {}));
710
671
  })(SchemaRequest || (SchemaRequest = {}));
@@ -727,8 +688,7 @@ var SchemaResponse;
727
688
  Record: "record",
728
689
  Document: "document",
729
690
  User: "user",
730
- Org: "org",
731
- Client: "client"
691
+ Entity: "entity"
732
692
  };
733
693
  })(AllowedSurfaces = SchemaResponse2.AllowedSurfaces || (SchemaResponse2.AllowedSurfaces = {}));
734
694
  })(SchemaResponse || (SchemaResponse = {}));
@@ -2283,7 +2243,7 @@ function withNoOpAuthProvider(options) {
2283
2243
  authProvider: new NoOpAuthProvider()
2284
2244
  };
2285
2245
  }
2286
- function handleNonStatusCodeError(error, rawResponse, method, path) {
2246
+ function handleNonStatusCodeError(error, rawResponse, method, path2) {
2287
2247
  switch (error.reason) {
2288
2248
  case "non-json":
2289
2249
  throw new VectrosError({
@@ -2297,7 +2257,7 @@ function handleNonStatusCodeError(error, rawResponse, method, path) {
2297
2257
  rawResponse
2298
2258
  });
2299
2259
  case "timeout":
2300
- throw new VectrosTimeoutError(`Timeout exceeded when calling ${method} ${path}.`, {
2260
+ throw new VectrosTimeoutError(`Timeout exceeded when calling ${method} ${path2}.`, {
2301
2261
  cause: error.cause
2302
2262
  });
2303
2263
  case "unknown":
@@ -2369,7 +2329,7 @@ var AuthClient = class {
2369
2329
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/auth/jwks");
2370
2330
  }
2371
2331
  /**
2372
- * Returns a page of per-subject PHI read-access rows: who read which subject's PHI, when, against which record, and whether any sensitive value was actually revealed in plaintext. Metadata only — never the PHI itself. This is the disclosure-accounting surface from which a covered entity derives its HIPAA §164.528 accounting of disclosures. Provide at least one query axis: a subject (`subjectType` + `subjectId`, plus optional `clientId`) within a `contextId` for the primary accounting query; `resourceId` within a `contextId` for 'who read this record'; `callerKeyId` for 'what did this credential read' (account-wide forensic); or `contextId` alone to enumerate a whole context. `from`/`to` bound the time window. Results are scoped to your account, derived from your token — never from input. Requires the `access-log:r` scope.
2332
+ * Returns a page of per-subject PHI read-access rows: who read which subject's PHI, when, against which record, and whether any sensitive value was actually revealed in plaintext. Metadata only — never the PHI itself. This is the disclosure-accounting surface from which a covered entity derives its HIPAA §164.528 accounting of disclosures. Provide at least one query axis: a subject (`subjectType` + `subjectId`) within a `contextId` for the primary accounting query; `resourceId` within a `contextId` for 'who read this record'; `callerKeyId` for 'what did this credential read' (account-wide forensic); or `contextId` alone to enumerate a whole context. `from`/`to` bound the time window. Results are scoped to your account, derived from your token — never from input. Requires the `access-log:r` scope.
2373
2333
  *
2374
2334
  * @param {Vectros.GetAccessLogRequest} request
2375
2335
  * @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -2382,7 +2342,6 @@ var AuthClient = class {
2382
2342
  * subjectType: "user",
2383
2343
  * subjectId: "user_abc123",
2384
2344
  * contextId: "ctx_intake",
2385
- * clientId: "client_xyz789",
2386
2345
  * action: "read",
2387
2346
  * callerKeyId: "key_abc123",
2388
2347
  * resourceType: "intake_form",
@@ -2397,7 +2356,6 @@ var AuthClient = class {
2397
2356
  subjectType,
2398
2357
  subjectId,
2399
2358
  contextId,
2400
- clientId,
2401
2359
  from: from_,
2402
2360
  to,
2403
2361
  action,
@@ -2412,7 +2370,6 @@ var AuthClient = class {
2412
2370
  subjectType,
2413
2371
  subjectId,
2414
2372
  contextId,
2415
- clientId,
2416
2373
  from: from_,
2417
2374
  to,
2418
2375
  action,
@@ -2846,7 +2803,7 @@ var AuthClient = class {
2846
2803
  );
2847
2804
  }
2848
2805
  /**
2849
- * Creates a new access profile under the given app context. This call is idempotent by `principalId`: if a profile with the same `principalId` already exists, the existing profile is returned (with status 200) instead of creating a duplicate. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing profile was returned) tells the two apart. To overwrite an existing profile's `scopes`/`roleId`, `identityOverrides`, and `status` instead of returning it unchanged, set `?upsert=true` (this also requires the `profiles:u` scope). You must provide exactly one of `scopes` (an inline list of scopes) or `roleId` (a reference to a role); supplying both, or neither, is rejected. `identityOverrides` may set only `orgId` and `clientId`; any other key (including the account identifier or `userId`) is rejected. If you use a scoped credential, the profile's effective scopes may not exceed your own; a root API key (`sk_`) is exempt. Requires the `profiles:c` scope.
2806
+ * Creates a new access profile under the given app context. This call is idempotent by `principalId`: if a profile with the same `principalId` already exists, the existing profile is returned (with status 200) instead of creating a duplicate. The response's `created` field (and the HTTP status — 201 when created, 200 when an existing profile was returned) tells the two apart. To overwrite an existing profile's `scopes`/`roleId`, `identityOverrides`, and `status` instead of returning it unchanged, set `?upsert=true` (this also requires the `profiles:u` scope). You must provide exactly one of `scopes` (an inline list of scopes) or `roleId` (a reference to a role); supplying both, or neither, is rejected. `identityOverrides` is keyed by ownership namespace in `scope:<namespace>` form — `scope:org` and `scope:client` for the reserved namespaces, or any namespace you have registered — and may name at most two; any other key (including the account identifier or `userId`) is rejected. If you use a scoped credential, the profile's effective scopes may not exceed your own; a root API key (`sk_`) is exempt. Requires the `profiles:c` scope.
2850
2807
  *
2851
2808
  * @param {Vectros.CreateAccessProfileRequest} request
2852
2809
  * @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -3135,7 +3092,7 @@ var AuthClient = class {
3135
3092
  * roleId: "engineering-member",
3136
3093
  * name: "Engineering Team Member",
3137
3094
  * scopes: [{
3138
- * allowed_actions: ["read", "write"]
3095
+ * allowed_actions: ["records:cru", "search:r"]
3139
3096
  * }]
3140
3097
  * }
3141
3098
  * })
@@ -3683,7 +3640,7 @@ var AuthClient = class {
3683
3640
  * roleId: "engineering-member",
3684
3641
  * name: "Engineering Team Member",
3685
3642
  * scopes: [{
3686
- * allowed_actions: ["read", "write"]
3643
+ * allowed_actions: ["records:cru", "search:r"]
3687
3644
  * }]
3688
3645
  * }
3689
3646
  * })
@@ -4136,7 +4093,7 @@ var AuthClient = class {
4136
4093
  * "userId": "550e8400-e29b-41d4-a716-446655440000"
4137
4094
  * },
4138
4095
  * dataScope: {
4139
- * "orgId": ["6ba7b810-9dad-11d1-80b4-00c04fd430c8"]
4096
+ * "scope:org": ["6ba7b810-9dad-11d1-80b4-00c04fd430c8"]
4140
4097
  * }
4141
4098
  * },
4142
4099
  * expiresInSeconds: 3600
@@ -4586,7 +4543,7 @@ var DocumentsClient = class {
4586
4543
  this._options = normalizeClientOptionsWithAuth(options);
4587
4544
  }
4588
4545
  /**
4589
- * Returns a paginated list of your documents, optionally filtered by folder (`folderId`) and/or owner (`userId`, `orgId`, or `clientId`). The response is a `{data, nextCursor}` envelope; pass `nextCursor` back as `startFrom` to fetch the next page. Requires the `documents:r` scope.
4546
+ * Returns a paginated list of your documents, optionally filtered by folder (`folderId`) and/or owner (`userId` or `scope`). The response is a `{data, nextCursor}` envelope; pass `nextCursor` back as `startFrom` to fetch the next page. Requires the `documents:r` scope.
4590
4547
  *
4591
4548
  * @param {Vectros.ListDocumentsRequest} request
4592
4549
  * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -4594,8 +4551,7 @@ var DocumentsClient = class {
4594
4551
  * @example
4595
4552
  * await client.documents.listDocuments({
4596
4553
  * userId: "550e8400-e29b-41d4-a716-446655440000",
4597
- * orgId: "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
4598
- * clientId: "f47ac10b-58cc-4372-a567-0e02b2c3d479",
4554
+ * scope: "group:eng-team",
4599
4555
  * folderId: "f47ac10b-58cc-4372-a567-0e02b2c3d479",
4600
4556
  * startFrom: "doc_prev123"
4601
4557
  * })
@@ -4604,11 +4560,10 @@ var DocumentsClient = class {
4604
4560
  return HttpResponsePromise.fromPromise(this.__listDocuments(request, requestOptions));
4605
4561
  }
4606
4562
  async __listDocuments(request = {}, requestOptions) {
4607
- const { userId, orgId, clientId, folderId, startFrom, limit } = request;
4563
+ const { userId, scope, folderId, startFrom, limit } = request;
4608
4564
  const _queryParams = {
4609
4565
  userId,
4610
- orgId,
4611
- clientId,
4566
+ scope,
4612
4567
  folderId,
4613
4568
  startFrom,
4614
4569
  limit
@@ -4666,9 +4621,10 @@ var DocumentsClient = class {
4666
4621
  return HttpResponsePromise.fromPromise(this.__ingestDocument(request, requestOptions));
4667
4622
  }
4668
4623
  async __ingestDocument(request, requestOptions) {
4669
- const { upsert, body: _body } = request;
4624
+ const { upsert, allowClear, body: _body } = request;
4670
4625
  const _queryParams = {
4671
- upsert
4626
+ upsert,
4627
+ allowClear
4672
4628
  };
4673
4629
  const _authRequest = await this._options.authProvider.getAuthRequest();
4674
4630
  const _headers = mergeHeaders(
@@ -4792,7 +4748,10 @@ var DocumentsClient = class {
4792
4748
  return HttpResponsePromise.fromPromise(this.__updateDocument(request, requestOptions));
4793
4749
  }
4794
4750
  async __updateDocument(request, requestOptions) {
4795
- const { id, body: _body } = request;
4751
+ const { id, allowClear, body: _body } = request;
4752
+ const _queryParams = {
4753
+ allowClear
4754
+ };
4796
4755
  const _authRequest = await this._options.authProvider.getAuthRequest();
4797
4756
  const _headers = mergeHeaders(
4798
4757
  _authRequest.headers,
@@ -4807,7 +4766,7 @@ var DocumentsClient = class {
4807
4766
  method: "PUT",
4808
4767
  headers: _headers,
4809
4768
  contentType: "application/json",
4810
- queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
4769
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
4811
4770
  requestType: "json",
4812
4771
  body: _body,
4813
4772
  timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
@@ -5336,7 +5295,7 @@ var FoldersClient = class {
5336
5295
  this._options = normalizeClientOptionsWithAuth(options);
5337
5296
  }
5338
5297
  /**
5339
- * Returns a paginated list of your folders. Pass `parentFolderId` to list the direct children of a specific folder (tree navigation); omit it for a flat list across your account. You can also filter by owner using `userId`, `orgId`, or `clientId`. Results are returned as a `{data, nextCursor}` envelope — pass `nextCursor` as `startFrom` to fetch the next page. Requires the `folders:r` scope.
5298
+ * Returns a paginated list of your folders. Pass `parentFolderId` to list the direct children of a specific folder (tree navigation); omit it for a flat list across your account. You can also filter by owner using `userId` or `scope`. Results are returned as a `{data, nextCursor}` envelope — pass `nextCursor` as `startFrom` to fetch the next page. Requires the `folders:r` scope.
5340
5299
  *
5341
5300
  * @param {Vectros.ListFoldersRequest} request
5342
5301
  * @param {FoldersClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -5344,9 +5303,8 @@ var FoldersClient = class {
5344
5303
  * @example
5345
5304
  * await client.folders.listFolders({
5346
5305
  * parentFolderId: "f47ac10b-58cc-4372-a567-0e02b2c3d479",
5347
- * orgId: "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
5348
5306
  * userId: "550e8400-e29b-41d4-a716-446655440000",
5349
- * clientId: "f47ac10b-58cc-4372-a567-0e02b2c3d479",
5307
+ * scope: "group:eng-team",
5350
5308
  * startFrom: "fld_prev123"
5351
5309
  * })
5352
5310
  */
@@ -5354,12 +5312,11 @@ var FoldersClient = class {
5354
5312
  return HttpResponsePromise.fromPromise(this.__listFolders(request, requestOptions));
5355
5313
  }
5356
5314
  async __listFolders(request = {}, requestOptions) {
5357
- const { parentFolderId, orgId, userId, clientId, startFrom, limit } = request;
5315
+ const { parentFolderId, userId, scope, startFrom, limit } = request;
5358
5316
  const _queryParams = {
5359
5317
  parentFolderId,
5360
- orgId,
5361
5318
  userId,
5362
- clientId,
5319
+ scope,
5363
5320
  startFrom,
5364
5321
  limit
5365
5322
  };
@@ -5645,7 +5602,7 @@ var FoldersClient = class {
5645
5602
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "DELETE", "/v1/folders/{id}");
5646
5603
  }
5647
5604
  /**
5648
- * Partially updates a folder using an RFC 7386 JSON Merge Patch. The `name`, `description`, and ownership fields (`userId`, `orgId`, `clientId`) are applied when present and left unchanged when omitted; sending any of these as null is rejected, because clearing a field is not supported in this release (omit it instead). `slug` and `parentFolderId` are immutable — a folder cannot be re-slugged or moved via the API — and the request is rejected if either is present. Pass `expectedVersion` for optimistic concurrency (you get a 409 if the folder changed since you last read it). Requires the `folders:u` scope.
5605
+ * Partially updates a folder using an RFC 7386 JSON Merge Patch. The `name`, `description`, and ownership fields (`userId`, `scopes`) are applied when present and left unchanged when omitted; sending any of these as null is rejected, because clearing a field is not supported in this release (omit it instead). `slug` and `parentFolderId` are immutable — a folder cannot be re-slugged or moved via the API — and the request is rejected if either is present. Pass `expectedVersion` for optimistic concurrency (you get a 409 if the folder changed since you last read it). Requires the `folders:u` scope.
5649
5606
  *
5650
5607
  * @param {Vectros.PatchFolderRequest} request
5651
5608
  * @param {FoldersClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -5778,54 +5735,48 @@ var IdentityClient = class {
5778
5735
  this._options = normalizeClientOptionsWithAuth(options);
5779
5736
  }
5780
5737
  /**
5781
- * Returns a paginated list of clients in your account. Narrow the results with `orgId` or `userId`, or use `externalId` for an exact lookup by your own identifier. For schema-bound clients, you can also query by a schema-declared lookup field using `type`, `field`, and one lookup mode (`value` for equality, `from`/`to` for a range, or `prefix`). The response is a `{data, nextCursor}` envelope; pass `nextCursor` back as `startFrom` to fetch the next page. Requires the `clients:r` scope.
5738
+ * Returns a paginated list of entities in a namespace. Filter by `userId` (entities owned by a user), by `externalId` (exact lookup by your own identifier), or by `scope` (`scope=<namespace>:<value>` — entities that have that value as a parent, e.g. `scope=org:6ba7...`). Naming this namespace's own name in `scope` resolves the entity itself (`scope=team:6ba7...` on `/v1/entities/team` returns that team), since an entity is always in its own scope. `userId` and `scope` can be combined to narrow on both dimensions at once; `externalId` identifies a single entity and cannot be combined with either. Requires the `entities:r:<namespace>` scope.
5782
5739
  *
5783
- * @param {Vectros.ListClientsRequest} request
5740
+ * @param {Vectros.ListEntitiesRequest} request
5784
5741
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
5785
5742
  *
5786
5743
  * @example
5787
- * await client.identity.listClients({
5788
- * orgId: "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
5789
- * userId: "550e8400-e29b-41d4-a716-446655440000",
5790
- * externalId: "patient_789",
5791
- * startFrom: "f47ac10b-58cc-4372-a567-0e02b2c3d479",
5792
- * type: "client_v1",
5793
- * field: "industry",
5794
- * value: "healthcare",
5795
- * prefix: "health"
5744
+ * await client.identity.listEntities({
5745
+ * namespace: "team"
5796
5746
  * })
5797
5747
  */
5798
- listClients(request = {}, requestOptions) {
5799
- return HttpResponsePromise.fromPromise(this.__listClients(request, requestOptions));
5748
+ listEntities(request, requestOptions) {
5749
+ return HttpResponsePromise.fromPromise(this.__listEntities(request, requestOptions));
5800
5750
  }
5801
- async __listClients(request = {}, requestOptions) {
5751
+ async __listEntities(request, requestOptions) {
5802
5752
  const {
5803
- orgId,
5753
+ namespace,
5804
5754
  userId,
5805
5755
  externalId,
5806
- startFrom,
5807
- limit,
5756
+ scope,
5808
5757
  type: type_,
5809
5758
  field,
5810
5759
  value,
5811
5760
  from: from_,
5812
5761
  to,
5813
5762
  prefix,
5814
- order
5763
+ order,
5764
+ startFrom,
5765
+ limit
5815
5766
  } = request;
5816
5767
  const _queryParams = {
5817
- orgId,
5818
5768
  userId,
5819
5769
  externalId,
5820
- startFrom,
5821
- limit,
5770
+ scope,
5822
5771
  type: type_,
5823
5772
  field,
5824
5773
  value,
5825
5774
  from: from_,
5826
5775
  to,
5827
5776
  prefix,
5828
- order: order != null ? order : void 0
5777
+ order: order != null ? order : void 0,
5778
+ startFrom,
5779
+ limit
5829
5780
  };
5830
5781
  const _authRequest = await this._options.authProvider.getAuthRequest();
5831
5782
  const _headers = mergeHeaders(
@@ -5836,7 +5787,7 @@ var IdentityClient = class {
5836
5787
  const _response = await fetcher({
5837
5788
  url: url_exports.join(
5838
5789
  await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
5839
- "v1/clients"
5790
+ `v1/entities/${url_exports.encodePathParam(namespace)}`
5840
5791
  ),
5841
5792
  method: "GET",
5842
5793
  headers: _headers,
@@ -5857,12 +5808,12 @@ var IdentityClient = class {
5857
5808
  rawResponse: _response.rawResponse
5858
5809
  });
5859
5810
  }
5860
- return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/clients");
5811
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/entities/{namespace}");
5861
5812
  }
5862
5813
  /**
5863
- * Creates a new client identity in your account. This call is idempotent on `externalId`: if a client 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 client was returned) tells the two apart. To overwrite an existing client's content instead of returning it unchanged, set `?upsert=true` (this also requires the `clients:u` scope). Requires the `clients:c` scope.
5814
+ * 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.
5864
5815
  *
5865
- * @param {Vectros.CreateClientRequest} request
5816
+ * @param {Vectros.CreateEntityRequest} request
5866
5817
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
5867
5818
  *
5868
5819
  * @throws {@link Vectros.BadRequestError}
@@ -5870,17 +5821,18 @@ var IdentityClient = class {
5870
5821
  * @throws {@link Vectros.TooManyRequestsError}
5871
5822
  *
5872
5823
  * @example
5873
- * await client.identity.createClient({
5824
+ * await client.identity.createEntity({
5825
+ * namespace: "team",
5874
5826
  * body: {
5875
- * externalId: "patient_789"
5827
+ * externalId: "team_eng_platform"
5876
5828
  * }
5877
5829
  * })
5878
5830
  */
5879
- createClient(request, requestOptions) {
5880
- return HttpResponsePromise.fromPromise(this.__createClient(request, requestOptions));
5831
+ createEntity(request, requestOptions) {
5832
+ return HttpResponsePromise.fromPromise(this.__createEntity(request, requestOptions));
5881
5833
  }
5882
- async __createClient(request, requestOptions) {
5883
- const { upsert, body: _body } = request;
5834
+ async __createEntity(request, requestOptions) {
5835
+ const { namespace, upsert, body: _body } = request;
5884
5836
  const _queryParams = {
5885
5837
  upsert
5886
5838
  };
@@ -5893,7 +5845,7 @@ var IdentityClient = class {
5893
5845
  const _response = await fetcher({
5894
5846
  url: url_exports.join(
5895
5847
  await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
5896
- "v1/clients"
5848
+ `v1/entities/${url_exports.encodePathParam(namespace)}`
5897
5849
  ),
5898
5850
  method: "POST",
5899
5851
  headers: _headers,
@@ -5926,26 +5878,27 @@ var IdentityClient = class {
5926
5878
  });
5927
5879
  }
5928
5880
  }
5929
- return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/clients");
5881
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/entities/{namespace}");
5930
5882
  }
5931
5883
  /**
5932
- * Returns a single client by its Vectros-assigned UUID. Requires the `clients:r` scope.
5884
+ * Retrieves a single entity by its namespace and Vectros-assigned ID. Requires the `entities:r:<namespace>` scope.
5933
5885
  *
5934
- * @param {Vectros.GetClientRequest} request
5886
+ * @param {Vectros.GetEntityRequest} request
5935
5887
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
5936
5888
  *
5937
5889
  * @throws {@link Vectros.NotFoundError}
5938
5890
  *
5939
5891
  * @example
5940
- * await client.identity.getClient({
5941
- * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
5892
+ * await client.identity.getEntity({
5893
+ * namespace: "team",
5894
+ * id: "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
5942
5895
  * })
5943
5896
  */
5944
- getClient(request, requestOptions) {
5945
- return HttpResponsePromise.fromPromise(this.__getClient(request, requestOptions));
5897
+ getEntity(request, requestOptions) {
5898
+ return HttpResponsePromise.fromPromise(this.__getEntity(request, requestOptions));
5946
5899
  }
5947
- async __getClient(request, requestOptions) {
5948
- const { id } = request;
5900
+ async __getEntity(request, requestOptions) {
5901
+ const { namespace, id } = request;
5949
5902
  const _authRequest = await this._options.authProvider.getAuthRequest();
5950
5903
  const _headers = mergeHeaders(
5951
5904
  _authRequest.headers,
@@ -5955,7 +5908,7 @@ var IdentityClient = class {
5955
5908
  const _response = await fetcher({
5956
5909
  url: url_exports.join(
5957
5910
  await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
5958
- `v1/clients/${url_exports.encodePathParam(id)}`
5911
+ `v1/entities/${url_exports.encodePathParam(namespace)}/${url_exports.encodePathParam(id)}`
5959
5912
  ),
5960
5913
  method: "GET",
5961
5914
  headers: _headers,
@@ -5981,30 +5934,31 @@ var IdentityClient = class {
5981
5934
  });
5982
5935
  }
5983
5936
  }
5984
- return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/clients/{id}");
5937
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/entities/{namespace}/{id}");
5985
5938
  }
5986
5939
  /**
5987
- * Updates mutable fields on an existing client. Omitted fields are preserved (a null does not clear a field); when `payload` is supplied it replaces the stored payload in full rather than being deep-merged. Requires the `clients:u` scope.
5940
+ * Updates the mutable fields of an entity. Omitted fields are preserved (a null value does not clear a field), and the `payload` object is replaced in full when supplied. Providing `scopes` replaces the entity's parent edges. Requires the `entities:u:<namespace>` scope.
5988
5941
  *
5989
- * @param {Vectros.UpdateClientRequest} request
5942
+ * @param {Vectros.UpdateEntityRequest} request
5990
5943
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
5991
5944
  *
5992
5945
  * @throws {@link Vectros.NotFoundError}
5993
5946
  * @throws {@link Vectros.TooManyRequestsError}
5994
5947
  *
5995
5948
  * @example
5996
- * await client.identity.updateClient({
5949
+ * await client.identity.updateEntity({
5950
+ * namespace: "team",
5997
5951
  * id: "id",
5998
5952
  * body: {
5999
- * externalId: "patient_789"
5953
+ * externalId: "team_eng_platform"
6000
5954
  * }
6001
5955
  * })
6002
5956
  */
6003
- updateClient(request, requestOptions) {
6004
- return HttpResponsePromise.fromPromise(this.__updateClient(request, requestOptions));
5957
+ updateEntity(request, requestOptions) {
5958
+ return HttpResponsePromise.fromPromise(this.__updateEntity(request, requestOptions));
6005
5959
  }
6006
- async __updateClient(request, requestOptions) {
6007
- const { id, body: _body } = request;
5960
+ async __updateEntity(request, requestOptions) {
5961
+ const { namespace, id, body: _body } = request;
6008
5962
  const _authRequest = await this._options.authProvider.getAuthRequest();
6009
5963
  const _headers = mergeHeaders(
6010
5964
  _authRequest.headers,
@@ -6014,7 +5968,7 @@ var IdentityClient = class {
6014
5968
  const _response = await fetcher({
6015
5969
  url: url_exports.join(
6016
5970
  await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
6017
- `v1/clients/${url_exports.encodePathParam(id)}`
5971
+ `v1/entities/${url_exports.encodePathParam(namespace)}/${url_exports.encodePathParam(id)}`
6018
5972
  ),
6019
5973
  method: "PUT",
6020
5974
  headers: _headers,
@@ -6045,27 +5999,28 @@ var IdentityClient = class {
6045
5999
  });
6046
6000
  }
6047
6001
  }
6048
- return handleNonStatusCodeError(_response.error, _response.rawResponse, "PUT", "/v1/clients/{id}");
6002
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "PUT", "/v1/entities/{namespace}/{id}");
6049
6003
  }
6050
6004
  /**
6051
- * Permanently deletes the client. This action cannot be undone. Requires the `clients:d` scope.
6005
+ * Permanently deletes an entity. This action cannot be undone. Requires the `entities:d:<namespace>` scope.
6052
6006
  *
6053
- * @param {Vectros.DeleteClientRequest} request
6007
+ * @param {Vectros.DeleteEntityRequest} request
6054
6008
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
6055
6009
  *
6056
6010
  * @throws {@link Vectros.NotFoundError}
6057
6011
  * @throws {@link Vectros.TooManyRequestsError}
6058
6012
  *
6059
6013
  * @example
6060
- * await client.identity.deleteClient({
6014
+ * await client.identity.deleteEntity({
6015
+ * namespace: "team",
6061
6016
  * id: "id"
6062
6017
  * })
6063
6018
  */
6064
- deleteClient(request, requestOptions) {
6065
- return HttpResponsePromise.fromPromise(this.__deleteClient(request, requestOptions));
6019
+ deleteEntity(request, requestOptions) {
6020
+ return HttpResponsePromise.fromPromise(this.__deleteEntity(request, requestOptions));
6066
6021
  }
6067
- async __deleteClient(request, requestOptions) {
6068
- const { id } = request;
6022
+ async __deleteEntity(request, requestOptions) {
6023
+ const { namespace, id } = request;
6069
6024
  const _authRequest = await this._options.authProvider.getAuthRequest();
6070
6025
  const _headers = mergeHeaders(
6071
6026
  _authRequest.headers,
@@ -6075,7 +6030,7 @@ var IdentityClient = class {
6075
6030
  const _response = await fetcher({
6076
6031
  url: url_exports.join(
6077
6032
  await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
6078
- `v1/clients/${url_exports.encodePathParam(id)}`
6033
+ `v1/entities/${url_exports.encodePathParam(namespace)}/${url_exports.encodePathParam(id)}`
6079
6034
  ),
6080
6035
  method: "DELETE",
6081
6036
  headers: _headers,
@@ -6103,27 +6058,36 @@ var IdentityClient = class {
6103
6058
  });
6104
6059
  }
6105
6060
  }
6106
- return handleNonStatusCodeError(_response.error, _response.rawResponse, "DELETE", "/v1/clients/{id}");
6061
+ return handleNonStatusCodeError(
6062
+ _response.error,
6063
+ _response.rawResponse,
6064
+ "DELETE",
6065
+ "/v1/entities/{namespace}/{id}"
6066
+ );
6107
6067
  }
6108
6068
  /**
6109
- * Body-based equivalent of the `type`/`field`/`value` lookup on `GET /v1/clients`. Use this when looking up by a sensitive (blind-indexed) field: the value travels in the request body rather than the URL. The `GET` list rejects a sensitive field's value and directs you here. The response is a `{data, nextCursor}` envelope. Requires the `clients:r` scope.
6069
+ * Looks up entities in a namespace by a schema-declared field value, with the criteria in the request body instead of the URL. Use this for a sensitive field: the value travels in the body and never appears in the URL. Body equivalent of the `type`/`field`/`value` lookup on `GET /v1/entities/{namespace}`, which rejects sensitive-field values and directs you here. Requires the `entities:r:<namespace>` scope.
6110
6070
  *
6111
- * @param {Vectros.IdentityLookupRequest} request
6071
+ * @param {Vectros.LookupEntitiesRequest} request
6112
6072
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
6113
6073
  *
6114
6074
  * @throws {@link Vectros.BadRequestError}
6115
6075
  * @throws {@link Vectros.TooManyRequestsError}
6116
6076
  *
6117
6077
  * @example
6118
- * await client.identity.lookupClients({
6119
- * type: "person_v1",
6120
- * field: "ssn"
6078
+ * await client.identity.lookupEntities({
6079
+ * namespace: "team",
6080
+ * body: {
6081
+ * type: "person_v1",
6082
+ * field: "ssn"
6083
+ * }
6121
6084
  * })
6122
6085
  */
6123
- lookupClients(request, requestOptions) {
6124
- return HttpResponsePromise.fromPromise(this.__lookupClients(request, requestOptions));
6086
+ lookupEntities(request, requestOptions) {
6087
+ return HttpResponsePromise.fromPromise(this.__lookupEntities(request, requestOptions));
6125
6088
  }
6126
- async __lookupClients(request, requestOptions) {
6089
+ async __lookupEntities(request, requestOptions) {
6090
+ const { namespace, body: _body } = request;
6127
6091
  const _authRequest = await this._options.authProvider.getAuthRequest();
6128
6092
  const _headers = mergeHeaders(
6129
6093
  _authRequest.headers,
@@ -6133,14 +6097,14 @@ var IdentityClient = class {
6133
6097
  const _response = await fetcher({
6134
6098
  url: url_exports.join(
6135
6099
  await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
6136
- "v1/clients/lookup"
6100
+ `v1/entities/${url_exports.encodePathParam(namespace)}/lookup`
6137
6101
  ),
6138
6102
  method: "POST",
6139
6103
  headers: _headers,
6140
6104
  contentType: "application/json",
6141
6105
  queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
6142
6106
  requestType: "json",
6143
- body: request,
6107
+ body: _body,
6144
6108
  timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
6145
6109
  maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
6146
6110
  abortSignal: requestOptions?.abortSignal,
@@ -6164,26 +6128,32 @@ var IdentityClient = class {
6164
6128
  });
6165
6129
  }
6166
6130
  }
6167
- return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/clients/lookup");
6131
+ return handleNonStatusCodeError(
6132
+ _response.error,
6133
+ _response.rawResponse,
6134
+ "POST",
6135
+ "/v1/entities/{namespace}/lookup"
6136
+ );
6168
6137
  }
6169
6138
  /**
6170
- * Returns the audit trail of changes to a client, newest first. Identity auditing is always on, so this history is always available; sensitive field values are redacted in each version. The response is a `{data, nextCursor}` envelope. Requires the `clients:r` scope.
6139
+ * Returns the audit trail of changes made to an entity, newest first. Sensitive field values are redacted in the history. Requires the `entities:r:<namespace>` scope.
6171
6140
  *
6172
- * @param {Vectros.GetClientVersionsRequest} request
6141
+ * @param {Vectros.GetEntityVersionsRequest} request
6173
6142
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
6174
6143
  *
6175
6144
  * @throws {@link Vectros.NotFoundError}
6176
6145
  *
6177
6146
  * @example
6178
- * await client.identity.getClientVersions({
6147
+ * await client.identity.getEntityVersions({
6148
+ * namespace: "team",
6179
6149
  * id: "id"
6180
6150
  * })
6181
6151
  */
6182
- getClientVersions(request, requestOptions) {
6183
- return HttpResponsePromise.fromPromise(this.__getClientVersions(request, requestOptions));
6152
+ getEntityVersions(request, requestOptions) {
6153
+ return HttpResponsePromise.fromPromise(this.__getEntityVersions(request, requestOptions));
6184
6154
  }
6185
- async __getClientVersions(request, requestOptions) {
6186
- const { id, startFrom } = request;
6155
+ async __getEntityVersions(request, requestOptions) {
6156
+ const { namespace, id, startFrom } = request;
6187
6157
  const _queryParams = {
6188
6158
  startFrom
6189
6159
  };
@@ -6196,7 +6166,7 @@ var IdentityClient = class {
6196
6166
  const _response = await fetcher({
6197
6167
  url: url_exports.join(
6198
6168
  await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
6199
- `v1/clients/${url_exports.encodePathParam(id)}/versions`
6169
+ `v1/entities/${url_exports.encodePathParam(namespace)}/${url_exports.encodePathParam(id)}/versions`
6200
6170
  ),
6201
6171
  method: "GET",
6202
6172
  headers: _headers,
@@ -6222,174 +6192,31 @@ var IdentityClient = class {
6222
6192
  });
6223
6193
  }
6224
6194
  }
6225
- return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/clients/{id}/versions");
6226
- }
6227
- /**
6228
- * Returns a paginated list of organizations in your account. Filter by `userId` to return only the organizations owned by a specific user, or by `externalId` for an exact lookup using your own identifier. You can also query schema-declared lookup fields by supplying `type` and `field` together with one lookup mode (`value` for equality, `from`/`to` for a range, or `prefix`). Requires the `orgs:r` scope.
6229
- *
6230
- * @param {Vectros.ListOrgsRequest} request
6231
- * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
6232
- *
6233
- * @example
6234
- * await client.identity.listOrgs({
6235
- * userId: "550e8400-e29b-41d4-a716-446655440000",
6236
- * externalId: "clinic_001",
6237
- * startFrom: "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
6238
- * type: "org_v1",
6239
- * field: "region",
6240
- * value: "us-east",
6241
- * prefix: "us-"
6242
- * })
6243
- */
6244
- listOrgs(request = {}, requestOptions) {
6245
- return HttpResponsePromise.fromPromise(this.__listOrgs(request, requestOptions));
6246
- }
6247
- async __listOrgs(request = {}, requestOptions) {
6248
- const {
6249
- userId,
6250
- externalId,
6251
- startFrom,
6252
- limit,
6253
- type: type_,
6254
- field,
6255
- value,
6256
- from: from_,
6257
- to,
6258
- prefix,
6259
- order
6260
- } = request;
6261
- const _queryParams = {
6262
- userId,
6263
- externalId,
6264
- startFrom,
6265
- limit,
6266
- type: type_,
6267
- field,
6268
- value,
6269
- from: from_,
6270
- to,
6271
- prefix,
6272
- order: order != null ? order : void 0
6273
- };
6274
- const _authRequest = await this._options.authProvider.getAuthRequest();
6275
- const _headers = mergeHeaders(
6276
- _authRequest.headers,
6277
- this._options?.headers,
6278
- requestOptions?.headers
6195
+ return handleNonStatusCodeError(
6196
+ _response.error,
6197
+ _response.rawResponse,
6198
+ "GET",
6199
+ "/v1/entities/{namespace}/{id}/versions"
6279
6200
  );
6280
- const _response = await fetcher({
6281
- url: url_exports.join(
6282
- await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
6283
- "v1/orgs"
6284
- ),
6285
- method: "GET",
6286
- headers: _headers,
6287
- queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
6288
- timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
6289
- maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
6290
- abortSignal: requestOptions?.abortSignal,
6291
- fetchFn: this._options?.fetch,
6292
- logging: this._options.logging
6293
- });
6294
- if (_response.ok) {
6295
- return { data: _response.body, rawResponse: _response.rawResponse };
6296
- }
6297
- if (_response.error.reason === "status-code") {
6298
- throw new VectrosError({
6299
- statusCode: _response.error.statusCode,
6300
- body: _response.error.body,
6301
- rawResponse: _response.rawResponse
6302
- });
6303
- }
6304
- return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/orgs");
6305
6201
  }
6306
6202
  /**
6307
- * Creates a new organization in your account. This call is idempotent on `externalId`: if an organization 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 organization was returned) tells the two apart. To overwrite an existing organization's content instead of returning it unchanged, set `?upsert=true` (this also requires the `orgs:u` scope). Requires the `orgs:c` scope.
6203
+ * Retrieves a single scope-namespace registration by name. The reserved built-ins `org` and `client` are always resolvable.
6308
6204
  *
6309
- * @param {Vectros.CreateOrgRequest} request
6310
- * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
6311
- *
6312
- * @throws {@link Vectros.BadRequestError}
6313
- * @throws {@link Vectros.ForbiddenError}
6314
- * @throws {@link Vectros.TooManyRequestsError}
6315
- *
6316
- * @example
6317
- * await client.identity.createOrg({
6318
- * body: {
6319
- * externalId: "clinic_001"
6320
- * }
6321
- * })
6322
- */
6323
- createOrg(request, requestOptions) {
6324
- return HttpResponsePromise.fromPromise(this.__createOrg(request, requestOptions));
6325
- }
6326
- async __createOrg(request, requestOptions) {
6327
- const { upsert, body: _body } = request;
6328
- const _queryParams = {
6329
- upsert
6330
- };
6331
- const _authRequest = await this._options.authProvider.getAuthRequest();
6332
- const _headers = mergeHeaders(
6333
- _authRequest.headers,
6334
- this._options?.headers,
6335
- requestOptions?.headers
6336
- );
6337
- const _response = await fetcher({
6338
- url: url_exports.join(
6339
- await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
6340
- "v1/orgs"
6341
- ),
6342
- method: "POST",
6343
- headers: _headers,
6344
- contentType: "application/json",
6345
- queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
6346
- requestType: "json",
6347
- body: _body,
6348
- timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
6349
- maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
6350
- abortSignal: requestOptions?.abortSignal,
6351
- fetchFn: this._options?.fetch,
6352
- logging: this._options.logging
6353
- });
6354
- if (_response.ok) {
6355
- return { data: _response.body, rawResponse: _response.rawResponse };
6356
- }
6357
- if (_response.error.reason === "status-code") {
6358
- switch (_response.error.statusCode) {
6359
- case 400:
6360
- throw new BadRequestError(_response.error.body, _response.rawResponse);
6361
- case 403:
6362
- throw new ForbiddenError(_response.error.body, _response.rawResponse);
6363
- case 429:
6364
- throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
6365
- default:
6366
- throw new VectrosError({
6367
- statusCode: _response.error.statusCode,
6368
- body: _response.error.body,
6369
- rawResponse: _response.rawResponse
6370
- });
6371
- }
6372
- }
6373
- return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/orgs");
6374
- }
6375
- /**
6376
- * Retrieves a single organization by its Vectros-assigned ID, returning its current name, status, payload, and schema binding. Requires the `orgs:r` scope.
6377
- *
6378
- * @param {Vectros.GetOrgRequest} request
6205
+ * @param {Vectros.GetNamespaceRequest} request
6379
6206
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
6380
6207
  *
6381
6208
  * @throws {@link Vectros.NotFoundError}
6382
6209
  *
6383
6210
  * @example
6384
- * await client.identity.getOrg({
6385
- * id: "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
6211
+ * await client.identity.getNamespace({
6212
+ * namespace: "team"
6386
6213
  * })
6387
6214
  */
6388
- getOrg(request, requestOptions) {
6389
- return HttpResponsePromise.fromPromise(this.__getOrg(request, requestOptions));
6215
+ getNamespace(request, requestOptions) {
6216
+ return HttpResponsePromise.fromPromise(this.__getNamespace(request, requestOptions));
6390
6217
  }
6391
- async __getOrg(request, requestOptions) {
6392
- const { id } = request;
6218
+ async __getNamespace(request, requestOptions) {
6219
+ const { namespace } = request;
6393
6220
  const _authRequest = await this._options.authProvider.getAuthRequest();
6394
6221
  const _headers = mergeHeaders(
6395
6222
  _authRequest.headers,
@@ -6399,7 +6226,7 @@ var IdentityClient = class {
6399
6226
  const _response = await fetcher({
6400
6227
  url: url_exports.join(
6401
6228
  await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
6402
- `v1/orgs/${url_exports.encodePathParam(id)}`
6229
+ `v1/namespaces/${url_exports.encodePathParam(namespace)}`
6403
6230
  ),
6404
6231
  method: "GET",
6405
6232
  headers: _headers,
@@ -6425,30 +6252,31 @@ var IdentityClient = class {
6425
6252
  });
6426
6253
  }
6427
6254
  }
6428
- return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/orgs/{id}");
6255
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/namespaces/{namespace}");
6429
6256
  }
6430
6257
  /**
6431
- * Updates the mutable fields of an organization. Omitted fields are preserved (a null value does not clear a field), and the `payload` object is replaced in full when supplied rather than deep-merged. Requires the `orgs:u` scope.
6258
+ * 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.
6432
6259
  *
6433
- * @param {Vectros.UpdateOrgRequest} request
6260
+ * @param {Vectros.UpdateNamespaceRequest} request
6434
6261
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
6435
6262
  *
6263
+ * @throws {@link Vectros.ForbiddenError}
6436
6264
  * @throws {@link Vectros.NotFoundError}
6437
6265
  * @throws {@link Vectros.TooManyRequestsError}
6438
6266
  *
6439
6267
  * @example
6440
- * await client.identity.updateOrg({
6441
- * id: "id",
6268
+ * await client.identity.updateNamespace({
6269
+ * namespace: "team",
6442
6270
  * body: {
6443
- * externalId: "clinic_001"
6271
+ * namespace: "team"
6444
6272
  * }
6445
6273
  * })
6446
6274
  */
6447
- updateOrg(request, requestOptions) {
6448
- return HttpResponsePromise.fromPromise(this.__updateOrg(request, requestOptions));
6275
+ updateNamespace(request, requestOptions) {
6276
+ return HttpResponsePromise.fromPromise(this.__updateNamespace(request, requestOptions));
6449
6277
  }
6450
- async __updateOrg(request, requestOptions) {
6451
- const { id, body: _body } = request;
6278
+ async __updateNamespace(request, requestOptions) {
6279
+ const { namespace, body: _body } = request;
6452
6280
  const _authRequest = await this._options.authProvider.getAuthRequest();
6453
6281
  const _headers = mergeHeaders(
6454
6282
  _authRequest.headers,
@@ -6458,7 +6286,7 @@ var IdentityClient = class {
6458
6286
  const _response = await fetcher({
6459
6287
  url: url_exports.join(
6460
6288
  await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
6461
- `v1/orgs/${url_exports.encodePathParam(id)}`
6289
+ `v1/namespaces/${url_exports.encodePathParam(namespace)}`
6462
6290
  ),
6463
6291
  method: "PUT",
6464
6292
  headers: _headers,
@@ -6477,6 +6305,8 @@ var IdentityClient = class {
6477
6305
  }
6478
6306
  if (_response.error.reason === "status-code") {
6479
6307
  switch (_response.error.statusCode) {
6308
+ case 403:
6309
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
6480
6310
  case 404:
6481
6311
  throw new NotFoundError(_response.error.body, _response.rawResponse);
6482
6312
  case 429:
@@ -6489,27 +6319,28 @@ var IdentityClient = class {
6489
6319
  });
6490
6320
  }
6491
6321
  }
6492
- return handleNonStatusCodeError(_response.error, _response.rawResponse, "PUT", "/v1/orgs/{id}");
6322
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "PUT", "/v1/namespaces/{namespace}");
6493
6323
  }
6494
6324
  /**
6495
- * Permanently deletes an organization. This action cannot be undone. Requires the `orgs:d` scope.
6325
+ * Deletes a registered scope namespace. Requires a root API key. The reserved built-ins cannot be deleted. A namespace that still has entities cannot be deleted (409) — delete its entities first; this keeps them reachable by the account-teardown and erasure sweeps.
6496
6326
  *
6497
- * @param {Vectros.DeleteOrgRequest} request
6327
+ * @param {Vectros.DeleteNamespaceRequest} request
6498
6328
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
6499
6329
  *
6330
+ * @throws {@link Vectros.ForbiddenError}
6500
6331
  * @throws {@link Vectros.NotFoundError}
6501
6332
  * @throws {@link Vectros.TooManyRequestsError}
6502
6333
  *
6503
6334
  * @example
6504
- * await client.identity.deleteOrg({
6505
- * id: "id"
6335
+ * await client.identity.deleteNamespace({
6336
+ * namespace: "team"
6506
6337
  * })
6507
6338
  */
6508
- deleteOrg(request, requestOptions) {
6509
- return HttpResponsePromise.fromPromise(this.__deleteOrg(request, requestOptions));
6339
+ deleteNamespace(request, requestOptions) {
6340
+ return HttpResponsePromise.fromPromise(this.__deleteNamespace(request, requestOptions));
6510
6341
  }
6511
- async __deleteOrg(request, requestOptions) {
6512
- const { id } = request;
6342
+ async __deleteNamespace(request, requestOptions) {
6343
+ const { namespace } = request;
6513
6344
  const _authRequest = await this._options.authProvider.getAuthRequest();
6514
6345
  const _headers = mergeHeaders(
6515
6346
  _authRequest.headers,
@@ -6519,7 +6350,7 @@ var IdentityClient = class {
6519
6350
  const _response = await fetcher({
6520
6351
  url: url_exports.join(
6521
6352
  await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
6522
- `v1/orgs/${url_exports.encodePathParam(id)}`
6353
+ `v1/namespaces/${url_exports.encodePathParam(namespace)}`
6523
6354
  ),
6524
6355
  method: "DELETE",
6525
6356
  headers: _headers,
@@ -6535,6 +6366,8 @@ var IdentityClient = class {
6535
6366
  }
6536
6367
  if (_response.error.reason === "status-code") {
6537
6368
  switch (_response.error.statusCode) {
6369
+ case 403:
6370
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
6538
6371
  case 404:
6539
6372
  throw new NotFoundError(_response.error.body, _response.rawResponse);
6540
6373
  case 429:
@@ -6547,27 +6380,26 @@ var IdentityClient = class {
6547
6380
  });
6548
6381
  }
6549
6382
  }
6550
- return handleNonStatusCodeError(_response.error, _response.rawResponse, "DELETE", "/v1/orgs/{id}");
6383
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "DELETE", "/v1/namespaces/{namespace}");
6551
6384
  }
6552
6385
  /**
6553
- * Looks up organizations by a schema-declared field value, with the search criteria sent in the request body instead of the URL. Use this when looking up by a sensitive field: the value travels in the body and is never exposed in the URL. This is the body-based equivalent of the `type`/`field`/`value` lookup on `GET /v1/orgs`, which rejects sensitive-field values and directs you here. Returns a `{data, nextCursor}` envelope. Requires the `orgs:r` scope.
6386
+ * Returns the scope namespaces registered in your account, with the reserved built-ins `org` and `client` listed first. Returns a `{data, nextCursor}` envelope.
6554
6387
  *
6555
- * @param {Vectros.IdentityLookupRequest} request
6388
+ * @param {Vectros.ListNamespacesRequest} request
6556
6389
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
6557
6390
  *
6558
- * @throws {@link Vectros.BadRequestError}
6559
- * @throws {@link Vectros.TooManyRequestsError}
6560
- *
6561
6391
  * @example
6562
- * await client.identity.lookupOrgs({
6563
- * type: "person_v1",
6564
- * field: "ssn"
6565
- * })
6392
+ * await client.identity.listNamespaces()
6566
6393
  */
6567
- lookupOrgs(request, requestOptions) {
6568
- return HttpResponsePromise.fromPromise(this.__lookupOrgs(request, requestOptions));
6394
+ listNamespaces(request = {}, requestOptions) {
6395
+ return HttpResponsePromise.fromPromise(this.__listNamespaces(request, requestOptions));
6569
6396
  }
6570
- async __lookupOrgs(request, requestOptions) {
6397
+ async __listNamespaces(request = {}, requestOptions) {
6398
+ const { startFrom, limit } = request;
6399
+ const _queryParams = {
6400
+ startFrom,
6401
+ limit
6402
+ };
6571
6403
  const _authRequest = await this._options.authProvider.getAuthRequest();
6572
6404
  const _headers = mergeHeaders(
6573
6405
  _authRequest.headers,
@@ -6577,14 +6409,11 @@ var IdentityClient = class {
6577
6409
  const _response = await fetcher({
6578
6410
  url: url_exports.join(
6579
6411
  await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
6580
- "v1/orgs/lookup"
6412
+ "v1/namespaces"
6581
6413
  ),
6582
- method: "POST",
6414
+ method: "GET",
6583
6415
  headers: _headers,
6584
- contentType: "application/json",
6585
- queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
6586
- requestType: "json",
6587
- body: request,
6416
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
6588
6417
  timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
6589
6418
  maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
6590
6419
  abortSignal: requestOptions?.abortSignal,
@@ -6595,42 +6424,33 @@ var IdentityClient = class {
6595
6424
  return { data: _response.body, rawResponse: _response.rawResponse };
6596
6425
  }
6597
6426
  if (_response.error.reason === "status-code") {
6598
- switch (_response.error.statusCode) {
6599
- case 400:
6600
- throw new BadRequestError(_response.error.body, _response.rawResponse);
6601
- case 429:
6602
- throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
6603
- default:
6604
- throw new VectrosError({
6605
- statusCode: _response.error.statusCode,
6606
- body: _response.error.body,
6607
- rawResponse: _response.rawResponse
6608
- });
6609
- }
6427
+ throw new VectrosError({
6428
+ statusCode: _response.error.statusCode,
6429
+ body: _response.error.body,
6430
+ rawResponse: _response.rawResponse
6431
+ });
6610
6432
  }
6611
- return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/orgs/lookup");
6433
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/namespaces");
6612
6434
  }
6613
6435
  /**
6614
- * Returns the audit trail of changes made to an organization, newest first. Version history is always recorded for identity entities, and sensitive field values are redacted in the history. Requires the `orgs:r` scope.
6436
+ * 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.
6615
6437
  *
6616
- * @param {Vectros.GetOrgVersionsRequest} request
6438
+ * @param {Vectros.NamespaceRequest} request
6617
6439
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
6618
6440
  *
6619
- * @throws {@link Vectros.NotFoundError}
6441
+ * @throws {@link Vectros.BadRequestError}
6442
+ * @throws {@link Vectros.ForbiddenError}
6443
+ * @throws {@link Vectros.TooManyRequestsError}
6620
6444
  *
6621
6445
  * @example
6622
- * await client.identity.getOrgVersions({
6623
- * id: "id"
6446
+ * await client.identity.registerNamespace({
6447
+ * namespace: "team"
6624
6448
  * })
6625
6449
  */
6626
- getOrgVersions(request, requestOptions) {
6627
- return HttpResponsePromise.fromPromise(this.__getOrgVersions(request, requestOptions));
6450
+ registerNamespace(request, requestOptions) {
6451
+ return HttpResponsePromise.fromPromise(this.__registerNamespace(request, requestOptions));
6628
6452
  }
6629
- async __getOrgVersions(request, requestOptions) {
6630
- const { id, startFrom } = request;
6631
- const _queryParams = {
6632
- startFrom
6633
- };
6453
+ async __registerNamespace(request, requestOptions) {
6634
6454
  const _authRequest = await this._options.authProvider.getAuthRequest();
6635
6455
  const _headers = mergeHeaders(
6636
6456
  _authRequest.headers,
@@ -6640,11 +6460,14 @@ var IdentityClient = class {
6640
6460
  const _response = await fetcher({
6641
6461
  url: url_exports.join(
6642
6462
  await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
6643
- `v1/orgs/${url_exports.encodePathParam(id)}/versions`
6463
+ "v1/namespaces"
6644
6464
  ),
6645
- method: "GET",
6465
+ method: "POST",
6646
6466
  headers: _headers,
6647
- queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
6467
+ contentType: "application/json",
6468
+ queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
6469
+ requestType: "json",
6470
+ body: request,
6648
6471
  timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
6649
6472
  maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
6650
6473
  abortSignal: requestOptions?.abortSignal,
@@ -6656,8 +6479,12 @@ var IdentityClient = class {
6656
6479
  }
6657
6480
  if (_response.error.reason === "status-code") {
6658
6481
  switch (_response.error.statusCode) {
6659
- case 404:
6660
- throw new NotFoundError(_response.error.body, _response.rawResponse);
6482
+ case 400:
6483
+ throw new BadRequestError(_response.error.body, _response.rawResponse);
6484
+ case 403:
6485
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
6486
+ case 429:
6487
+ throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
6661
6488
  default:
6662
6489
  throw new VectrosError({
6663
6490
  statusCode: _response.error.statusCode,
@@ -6666,7 +6493,7 @@ var IdentityClient = class {
6666
6493
  });
6667
6494
  }
6668
6495
  }
6669
- return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/orgs/{id}/versions");
6496
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/namespaces");
6670
6497
  }
6671
6498
  /**
6672
6499
  * Returns a paginated list of the users in your account. Pass `externalId` to look up a single user by your own identifier. To filter on schema-declared lookup fields, supply `type` and `field` together with one lookup mode: `value` (exact match), `from`+`to` (range), or `prefix`. Requires the `users:r` scope.
@@ -7543,7 +7370,7 @@ var RecordsClient = class {
7543
7370
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/records/batch");
7544
7371
  }
7545
7372
  /**
7546
- * Returns a paginated list of records in your account as a `{data, nextCursor}` page. Supply exactly one of `type`, `folderId`, or `recent=true` to choose the mode: `type` lists all records of a single type; `folderId` lists all records in a folder (any type); and `recent=true` returns the account-wide recently-updated feed across all types, newest first. You may combine `type` with `folderId` to list a single type within a folder. The owner filters (`userId`, `orgId`, `clientId`) further narrow the type and folder modes; the `recent` feed is standalone and ignores all filters. Each token only sees the record types it is scoped to read. Requires the `records:r` scope. By default the response returns the indexed projection of each record; set `includePayload=true` to include full payloads.
7373
+ * Returns a paginated list of records in your account as a `{data, nextCursor}` page. Supply exactly one of `type`, `folderId`, or `recent=true` to choose the mode: `type` lists all records of a single type; `folderId` lists all records in a folder (any type); and `recent=true` returns the account-wide recently-updated feed across all types, newest first. You may combine `type` with `folderId` to list a single type within a folder. The owner filters (`userId`, `scope`) further narrow the type and folder modes; the `recent` feed is standalone and ignores all filters. Each token only sees the record types it is scoped to read. Requires the `records:r` scope. By default the response returns the indexed projection of each record; set `includePayload=true` to include full payloads.
7547
7374
  *
7548
7375
  * @param {Vectros.ListRecordsRequest} request
7549
7376
  * @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -7553,8 +7380,7 @@ var RecordsClient = class {
7553
7380
  * type: "intake_form",
7554
7381
  * folderId: "f47ac10b-58cc-4372-a567-0e02b2c3d479",
7555
7382
  * userId: "550e8400-e29b-41d4-a716-446655440000",
7556
- * orgId: "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
7557
- * clientId: "f47ac10b-58cc-4372-a567-0e02b2c3d479",
7383
+ * scope: "group:eng-team",
7558
7384
  * startFrom: "550e8400-e29b-41d4-a716-446655440000"
7559
7385
  * })
7560
7386
  */
@@ -7562,13 +7388,12 @@ var RecordsClient = class {
7562
7388
  return HttpResponsePromise.fromPromise(this.__listRecords(request, requestOptions));
7563
7389
  }
7564
7390
  async __listRecords(request = {}, requestOptions) {
7565
- const { type: type_, folderId, userId, orgId, clientId, startFrom, limit, includePayload, recent } = request;
7391
+ const { type: type_, folderId, userId, scope, startFrom, limit, includePayload, recent } = request;
7566
7392
  const _queryParams = {
7567
7393
  type: type_,
7568
7394
  folderId,
7569
7395
  userId,
7570
- orgId,
7571
- clientId,
7396
+ scope,
7572
7397
  startFrom,
7573
7398
  limit,
7574
7399
  includePayload,
@@ -7633,9 +7458,10 @@ var RecordsClient = class {
7633
7458
  return HttpResponsePromise.fromPromise(this.__createRecord(request, requestOptions));
7634
7459
  }
7635
7460
  async __createRecord(request, requestOptions) {
7636
- const { upsert, body: _body } = request;
7461
+ const { upsert, allowClear, body: _body } = request;
7637
7462
  const _queryParams = {
7638
- upsert
7463
+ upsert,
7464
+ allowClear
7639
7465
  };
7640
7466
  const _authRequest = await this._options.authProvider.getAuthRequest();
7641
7467
  const _headers = mergeHeaders(
@@ -7757,7 +7583,10 @@ var RecordsClient = class {
7757
7583
  return HttpResponsePromise.fromPromise(this.__updateRecord(request, requestOptions));
7758
7584
  }
7759
7585
  async __updateRecord(request, requestOptions) {
7760
- const { id, body: _body } = request;
7586
+ const { id, allowClear, body: _body } = request;
7587
+ const _queryParams = {
7588
+ allowClear
7589
+ };
7761
7590
  const _authRequest = await this._options.authProvider.getAuthRequest();
7762
7591
  const _headers = mergeHeaders(
7763
7592
  _authRequest.headers,
@@ -7772,7 +7601,7 @@ var RecordsClient = class {
7772
7601
  method: "PUT",
7773
7602
  headers: _headers,
7774
7603
  contentType: "application/json",
7775
- queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
7604
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
7776
7605
  requestType: "json",
7777
7606
  body: _body,
7778
7607
  timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
@@ -7863,7 +7692,7 @@ var RecordsClient = class {
7863
7692
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "DELETE", "/v1/records/{id}");
7864
7693
  }
7865
7694
  /**
7866
- * Partially updates a record using an RFC 7386 JSON Merge Patch. The `payload` object is deep-merged into the existing payload: keys you send overwrite (recursing into nested objects), a key set to null is deleted, and keys you omit are left unchanged — so you can change a single field without re-sending the rest (unlike the full-replacement PUT). Top-level fields (`status`, `folderId`, `userId`, `orgId`, `clientId`) are set when present and left unchanged when omitted; sending a top-level field as null is rejected (clearing a top-level field is not supported in this release — omit it instead). `typeName`, `schemaId`, `externalId`, and `indexMode` are immutable and rejected if present. The merged result is validated against the schema. Pass `expectedVersion` to make the patch conditional (optimistic concurrency, 409 on conflict). Requires the `records:u:<type>` scope.
7695
+ * Partially updates a record using an RFC 7386 JSON Merge Patch. The `payload` object is deep-merged into the existing payload: keys you send overwrite (recursing into nested objects), a key set to null is deleted, and keys you omit are left unchanged — so you can change a single field without re-sending the rest (unlike the full-replacement PUT). Top-level fields (`status`, `folderId`, `userId`, `scopes`) are set when present and left unchanged when omitted; sending a top-level field as null is rejected (clearing a top-level field is not supported in this release — omit it instead). `typeName`, `schemaId`, `externalId`, and `indexMode` are immutable and rejected if present. The merged result is validated against the schema. Pass `expectedVersion` to make the patch conditional (optimistic concurrency, 409 on conflict). Requires the `records:u:<type>` scope.
7867
7696
  *
7868
7697
  * @param {Vectros.PatchRecordRequest} request
7869
7698
  * @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -8189,7 +8018,7 @@ var SchemasClient = class {
8189
8018
  this._options = normalizeClientOptionsWithAuth(options);
8190
8019
  }
8191
8020
  /**
8192
- * Returns a paginated list of the record schemas defined in your account. Filter by `userId` or `orgId` to scope to an owner, by `surface` to list the types bindable to one surface, or by `recordType` to resolve the single schema for a type directly. Filtering by an identity surface (user, org, or client) lists your account-wide identity schemas regardless of the calling context; filtering by record or document lists within the calling context. Requires the `schemas:r` scope.
8021
+ * Returns a paginated list of the record schemas defined in your account. Filter by `userId` or `scope` to scope to an owner, by `surface` to list the types bindable to one surface, or by `recordType` to resolve the single schema for a type directly. Filtering by an identity surface (`user` or `entity`) lists your account-wide identity schemas regardless of the calling context; filtering by record or document lists within the calling context. Requires the `schemas:r` scope.
8193
8022
  *
8194
8023
  * @param {Vectros.ListSchemasRequest} request
8195
8024
  * @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -8197,7 +8026,7 @@ var SchemasClient = class {
8197
8026
  * @example
8198
8027
  * await client.schemas.listSchemas({
8199
8028
  * userId: "550e8400-e29b-41d4-a716-446655440000",
8200
- * orgId: "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
8029
+ * scope: "org:6ba7b810-9dad-11d1-80b4-00c04fd430c8",
8201
8030
  * surface: "document",
8202
8031
  * recordType: "intake_form",
8203
8032
  * startFrom: "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
@@ -8207,10 +8036,10 @@ var SchemasClient = class {
8207
8036
  return HttpResponsePromise.fromPromise(this.__listSchemas(request, requestOptions));
8208
8037
  }
8209
8038
  async __listSchemas(request = {}, requestOptions) {
8210
- const { userId, orgId, surface, recordType, startFrom, limit } = request;
8039
+ const { userId, scope, surface, recordType, startFrom, limit } = request;
8211
8040
  const _queryParams = {
8212
8041
  userId,
8213
- orgId,
8042
+ scope,
8214
8043
  surface,
8215
8044
  recordType,
8216
8045
  startFrom,
@@ -8656,12 +8485,12 @@ var VectrosClient = class {
8656
8485
  get auth() {
8657
8486
  return this._auth ?? (this._auth = new AuthClient(this._options));
8658
8487
  }
8659
- get identity() {
8660
- return this._identity ?? (this._identity = new IdentityClient(this._options));
8661
- }
8662
8488
  get documents() {
8663
8489
  return this._documents ?? (this._documents = new DocumentsClient(this._options));
8664
8490
  }
8491
+ get identity() {
8492
+ return this._identity ?? (this._identity = new IdentityClient(this._options));
8493
+ }
8665
8494
  get compliance() {
8666
8495
  return this._compliance ?? (this._compliance = new ComplianceClient(this._options));
8667
8496
  }
@@ -8764,8 +8593,8 @@ function warnOnSuboptimalKey(key, log) {
8764
8593
 
8765
8594
  // src/build-info.ts
8766
8595
  var BUILD_INFO = {
8767
- mcpServer: true ? "0.7.0" : "dev",
8768
- sdk: true ? "0.33.0" : "dev"
8596
+ mcpServer: true ? "0.10.0" : "dev",
8597
+ sdk: true ? "0.35.0" : "dev"
8769
8598
  };
8770
8599
 
8771
8600
  // src/log.ts
@@ -9001,7 +8830,7 @@ ${detail}${pointer}`
9001
8830
 
9002
8831
  // src/tools/hybrid_search.ts
9003
8832
  var MCP_DEFAULT_LIMIT = 3;
9004
- var MCP_MAX_LIMIT = 10;
8833
+ var MCP_MAX_LIMIT = 50;
9005
8834
  var MCP_RESPONSE_CHAR_BUDGET = 24e3;
9006
8835
  var SNIPPET_MAX_CHARS = 160;
9007
8836
  var INTERNAL_METADATA_KEYS = /* @__PURE__ */ new Set(["tenantId", "owner_id", "model_type", "rootFolderId", "folderId"]);
@@ -9035,9 +8864,9 @@ var inputSchema = {
9035
8864
  "Keyword-match precision for the BM25 leg (TEXT/HYBRID modes). OR = any term (broad recall), AND = all terms (higher precision), PHRASE = contiguous phrase. Default: PHRASE (slop 3) in HYBRID, OR in TEXT. (The advanced raw-query COMPLEX mode is intentionally not exposed here.)"
9036
8865
  ),
9037
8866
  limit: z.number().int().min(1).max(MCP_MAX_LIMIT).optional().describe(
9038
- `Max hits to return. MCP-specific cap of ${MCP_MAX_LIMIT} (vs API max of 50) to protect the agent context window. Default 3. Use offset for pagination.`
8867
+ `Max hits per page. Defaults to a low ${MCP_DEFAULT_LIMIT} to protect the agent context window; raise up to ${MCP_MAX_LIMIT} (the most a single search returns) in one call when you can accept the larger result, or page with \`offset\` instead.`
9039
8868
  ),
9040
- offset: z.number().int().min(0).optional().describe("Skip the first N hits \u2014 for pagination."),
8869
+ offset: z.number().int().min(0).max(200).optional().describe("Skip the first N hits \u2014 for pagination (0\u2013200)."),
9041
8870
  folderId: z.string().optional().describe("Scope to content in this EXACT folder (Vectros folder id)."),
9042
8871
  rootFolderId: z.string().optional().describe("Scope to content under this folder AND all its descendants (subtree-root folder id)."),
9043
8872
  // Content narrowing.
@@ -9050,8 +8879,9 @@ var inputSchema = {
9050
8879
  ),
9051
8880
  // Ownership.
9052
8881
  userId: z.string().optional().describe("Restrict to content owned by this user (Vectros UUID)."),
9053
- orgId: z.string().optional().describe("Restrict to content belonging to this org (Vectros UUID)."),
9054
- clientId: z.string().optional().describe("Restrict to content associated with this client (Vectros UUID)."),
8882
+ scope: z.string().optional().describe(
8883
+ 'Restrict to content carrying this scope value, in `namespace:value` form (e.g. "org:<uuid>", "client:<uuid>", "group:eng-team"). `org` and `client` are built-in namespaces; others are custom scopes you define.'
8884
+ ),
9055
8885
  // Date window.
9056
8886
  createdAfter: z.string().optional().describe("Restrict to content created at/after this ISO 8601 UTC timestamp."),
9057
8887
  createdBefore: z.string().optional().describe("Restrict to content created at/before this ISO 8601 UTC timestamp."),
@@ -9069,7 +8899,7 @@ var inputSchema = {
9069
8899
  var hybridSearch = ({ client, log }) => ({
9070
8900
  name: "hybrid_search",
9071
8901
  title: "Hybrid search",
9072
- description: `Search the partner tenant's indexed content (documents + structured records) using hybrid BM25 + dense ranking. Returns up to 10 results (default 3) with citations and surrounding context for grounding follow-up reasoning. Narrow with contentTypes/typeName/filters, ownership (userId/orgId/clientId), 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). textLegEmpty:true flags that the keyword leg matched nothing (all textScores 0) \u2014 usually a too-long PHRASE query; retry with textMode:"OR".`,
8902
+ 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 leg matched nothing (all textScores 0) \u2014 usually a too-long PHRASE query; retry with textMode:\"OR\".",
9073
8903
  inputSchema,
9074
8904
  handler: async (args) => {
9075
8905
  const limit = args.limit ?? MCP_DEFAULT_LIMIT;
@@ -9087,8 +8917,7 @@ var hybridSearch = ({ client, log }) => ({
9087
8917
  typeName: args.typeName,
9088
8918
  filters: args.filters,
9089
8919
  userId: args.userId,
9090
- orgId: args.orgId,
9091
- clientId: args.clientId,
8920
+ scope: args.scope,
9092
8921
  createdAfter: args.createdAfter,
9093
8922
  createdBefore: args.createdBefore,
9094
8923
  minSimilarity: args.minSimilarity,
@@ -9115,6 +8944,12 @@ var hybridSearch = ({ client, log }) => ({
9115
8944
  envelope.returnedResults = shaped.length;
9116
8945
  text = JSON.stringify(envelope, null, 2);
9117
8946
  }
8947
+ const offset = args.offset ?? 0;
8948
+ const totalResults = result.totalResults;
8949
+ if (typeof totalResults === "number" && offset + shaped.length < totalResults) {
8950
+ envelope.hasMore = true;
8951
+ text = JSON.stringify(envelope, null, 2);
8952
+ }
9118
8953
  log.debug(
9119
8954
  { tool: "hybrid_search", mode, limit, returned: shaped.length, textLegEmpty },
9120
8955
  "hybrid_search ok"
@@ -9150,7 +8985,7 @@ async function drainPages(fetchPage) {
9150
8985
 
9151
8986
  // src/tools/record_query.ts
9152
8987
  var MCP_DEFAULT_LIMIT2 = 3;
9153
- var MCP_MAX_LIMIT2 = 10;
8988
+ var MCP_MAX_LIMIT2 = 100;
9154
8989
  var inputSchema2 = {
9155
8990
  type: z2.string().min(1, "type (record type) is required").describe('Record type / schema name (e.g. "patient", "clinical_note").'),
9156
8991
  // Lookup-mode args — provide `field` plus EXACTLY ONE of: value | from+to | prefix.
@@ -9166,16 +9001,18 @@ var inputSchema2 = {
9166
9001
  ),
9167
9002
  // List-mode args:
9168
9003
  userId: z2.string().optional().describe("List mode: scope to records owned by this user."),
9169
- orgId: z2.string().optional().describe("List mode: scope to records owned by this org."),
9170
- clientId: z2.string().optional().describe("List mode: scope to records associated with this client."),
9004
+ scope: z2.string().optional().describe(
9005
+ 'List mode: filter to records carrying this scope value, in `namespace:value` form (e.g. "org:<uuid>", "client:<uuid>", "group:eng-team"). `org` and `client` are built-in namespaces; others are custom scopes you define.'
9006
+ ),
9007
+ startFrom: z2.string().optional().describe("Pagination cursor \u2014 pass the `nextCursor` from the previous page to fetch the next. Works in both list and lookup mode."),
9171
9008
  limit: z2.number().int().min(1).max(MCP_MAX_LIMIT2).optional().describe(
9172
- `Max records to return. MCP-specific cap of ${MCP_MAX_LIMIT2} (vs API max of 100) to protect the agent context window. Default 3.`
9009
+ `Max records per page. Defaults to a low ${MCP_DEFAULT_LIMIT2} to protect the agent context window; raise up to ${MCP_MAX_LIMIT2} (the records API max) in one call when you can accept the larger payload, or page with \`startFrom\` instead.`
9173
9010
  )
9174
9011
  };
9175
9012
  var recordQuery = ({ client, log }) => ({
9176
9013
  name: "record_query",
9177
9014
  title: "Record query (list or lookup)",
9178
- description: "Query structured records of a given type. Two modes:\n \u2022 Lookup on a lookup-indexed field: pass `field` plus exactly one of `value` (exact), `from`+`to` (range), or `prefix`. Works on sensitive fields too.\n \u2022 List by type: omit `field`; optionally filter by `userId`/`orgId`/`clientId`.\nReturns up to 10 records (default 3). Mode is auto-detected from the arguments present.",
9015
+ description: "Query structured records of a given type. Two modes:\n \u2022 Lookup on a lookup-indexed field: pass `field` plus exactly one of `value` (exact), `from`+`to` (range), or `prefix`. Works on sensitive fields too.\n \u2022 List by type: omit `field`; optionally filter by `userId` or `scope` (`namespace:value`).\nReturns a `{ data, nextCursor }` page: `data` holds up to `limit` records (default 3, max 100 \u2014 raise it in one call when you can accept the payload), and a non-null `nextCursor` means more remain \u2014 pass it back as `startFrom` to page. Mode is auto-detected from the arguments present.",
9179
9016
  inputSchema: inputSchema2,
9180
9017
  handler: async (args) => {
9181
9018
  const limit = args.limit ?? MCP_DEFAULT_LIMIT2;
@@ -9185,8 +9022,9 @@ var recordQuery = ({ client, log }) => ({
9185
9022
  const from = args.from;
9186
9023
  const to = args.to;
9187
9024
  const prefix = args.prefix;
9025
+ const startFrom = args.startFrom;
9188
9026
  try {
9189
- let records;
9027
+ let page;
9190
9028
  if (field) {
9191
9029
  const hasEquality = value !== void 0;
9192
9030
  const hasRange = from !== void 0 || to !== void 0;
@@ -9209,7 +9047,7 @@ var recordQuery = ({ client, log }) => ({
9209
9047
  if (hasRange && !(from !== void 0 && to !== void 0)) {
9210
9048
  return toolError("record_query", new Error("range lookup requires both 'from' and 'to'."));
9211
9049
  }
9212
- const page = await client.records.lookupRecordsByBody({
9050
+ page = await client.records.lookupRecordsByBody({
9213
9051
  type,
9214
9052
  field,
9215
9053
  value,
@@ -9217,29 +9055,30 @@ var recordQuery = ({ client, log }) => ({
9217
9055
  to,
9218
9056
  prefix,
9219
9057
  order: args.order,
9058
+ startFrom,
9220
9059
  limit
9221
9060
  });
9222
- records = pageItems(page);
9223
9061
  log.debug(
9224
- { tool: "record_query", mode: "lookup", type, field, returned: records.length },
9062
+ { tool: "record_query", mode: "lookup", type, field, returned: pageItems(page).length },
9225
9063
  "record_query lookup ok"
9226
9064
  );
9227
9065
  } else {
9228
- const page = await client.records.listRecords({
9066
+ page = await client.records.listRecords({
9229
9067
  type,
9230
9068
  userId: args.userId,
9231
- orgId: args.orgId,
9232
- clientId: args.clientId,
9069
+ scope: args.scope,
9070
+ startFrom,
9233
9071
  limit
9234
9072
  });
9235
- records = pageItems(page);
9236
9073
  log.debug(
9237
- { tool: "record_query", mode: "list", type, limit, returned: records.length },
9074
+ { tool: "record_query", mode: "list", type, limit, returned: pageItems(page).length },
9238
9075
  "record_query list ok"
9239
9076
  );
9240
9077
  }
9078
+ const records = pageItems(page);
9079
+ const nextCursor = page.nextCursor ?? null;
9241
9080
  return {
9242
- content: [{ type: "text", text: JSON.stringify(records, null, 2) }]
9081
+ content: [{ type: "text", text: JSON.stringify({ data: records, nextCursor }, null, 2) }]
9243
9082
  };
9244
9083
  } catch (err) {
9245
9084
  log.warn({ tool: "record_query", err: String(err) }, "record_query failed");
@@ -9361,8 +9200,9 @@ var inputSchema4 = {
9361
9200
  status: z4.string().optional().describe("Record lifecycle status. Defaults to ACTIVE server-side."),
9362
9201
  folderId: z4.string().optional().describe("Group this record into a folder."),
9363
9202
  userId: z4.string().optional().describe("Owning user id."),
9364
- orgId: z4.string().optional().describe("Owning organization id."),
9365
- clientId: z4.string().optional().describe("Associated client id.")
9203
+ scopes: z4.array(z4.string()).optional().describe(
9204
+ 'Scope ownership as `namespace:value` entries, at most 2 (e.g. ["org:<uuid>", "group:eng-team"]). `org` and `client` are built-in namespaces; others are custom scopes you define. This is the record\'s COMPLETE scope declaration and values must come from the credential\'s own identity. An empty array `[]` creates a PRIVATE record owned by the calling user alone. Omit to stamp the credential\'s full identity \u2014 the default.'
9205
+ )
9366
9206
  };
9367
9207
  var recordCreate = ({ client, log }) => ({
9368
9208
  name: "record_create",
@@ -9381,8 +9221,7 @@ var recordCreate = ({ client, log }) => ({
9381
9221
  status: args.status,
9382
9222
  folderId: args.folderId,
9383
9223
  userId: args.userId,
9384
- orgId: args.orgId,
9385
- clientId: args.clientId
9224
+ scopes: args.scopes
9386
9225
  }
9387
9226
  });
9388
9227
  log.debug({ tool: "record_create", type, id: created.id }, "record_create ok");
@@ -9467,24 +9306,27 @@ var record_delete_default = recordDelete;
9467
9306
  // src/tools/rag_ask.ts
9468
9307
  import { z as z7 } from "zod";
9469
9308
  var SEARCH_MCP_DEFAULT_LIMIT = 5;
9470
- var SEARCH_MCP_MAX_LIMIT = 10;
9309
+ var SEARCH_MCP_MAX_LIMIT = 50;
9471
9310
  var inputSchema7 = {
9472
9311
  query: z7.string().min(1, "query must be non-empty").describe("Question to ground against retrieved content."),
9473
9312
  instructions: z7.string().optional().describe(
9474
9313
  'System prompt that overrides the default for the generation step \u2014 e.g. "answer only from the provided context, cite sources, be concise". Default: a generic answer-from-context instruction.'
9475
9314
  ),
9476
9315
  model: z7.string().optional().describe(
9477
- "Inference model alias (e.g. claude-haiku-4-5, claude-sonnet-4-6, claude-opus-4-8). Default = tier-appropriate Haiku. See GET /v1/models for the catalog the calling key can reach."
9316
+ "Inference model alias (e.g. claude-haiku-4-5, claude-sonnet-5, claude-opus-4-8). Default = tier-appropriate Haiku. See GET /v1/models for the catalog the calling key can reach."
9478
9317
  ),
9479
9318
  search: z7.object({
9480
9319
  mode: z7.enum(["HYBRID", "TEXT", "SEMANTIC"]).optional().describe("Retrieval mode. Default HYBRID."),
9481
- limit: z7.number().int().min(1).max(SEARCH_MCP_MAX_LIMIT).optional().describe(`Passages to retrieve before generating. Default ${SEARCH_MCP_DEFAULT_LIMIT}, max ${SEARCH_MCP_MAX_LIMIT}.`),
9320
+ limit: z7.number().int().min(1).max(SEARCH_MCP_MAX_LIMIT).optional().describe(
9321
+ `Passages to retrieve before generating (the grounding-corpus size). Default ${SEARCH_MCP_DEFAULT_LIMIT}; raise up to ${SEARCH_MCP_MAX_LIMIT} (the RAG search API max) for a broader corpus when the extra grounding is worth the larger prompt.`
9322
+ ),
9482
9323
  // Retrieval scoping — parity with hybrid_search so an agent can ground the
9483
9324
  // answer on a specific owner / folder / type / metadata subset, not just the
9484
9325
  // whole-tenant corpus.
9485
9326
  userId: z7.string().optional().describe("Restrict retrieval to content owned by this user (Vectros UUID)."),
9486
- orgId: z7.string().optional().describe("Restrict retrieval to content owned by this org (Vectros UUID)."),
9487
- clientId: z7.string().optional().describe("Restrict retrieval to content tagged with this client (Vectros UUID)."),
9327
+ scope: z7.string().optional().describe(
9328
+ 'Restrict retrieval to content carrying this scope value, in `namespace:value` form (e.g. "org:<uuid>", "client:<uuid>", "group:eng-team"). `org` and `client` are built-in namespaces; others are custom scopes you define.'
9329
+ ),
9488
9330
  folderId: z7.string().optional().describe("Restrict retrieval to this exact folder."),
9489
9331
  rootFolderId: z7.string().optional().describe("Restrict retrieval to this folder and all its descendants."),
9490
9332
  typeName: z7.string().optional().describe("Restrict record retrieval to this schema type."),
@@ -9502,7 +9344,7 @@ var inputSchema7 = {
9502
9344
  var ragAsk = ({ client, log }) => ({
9503
9345
  name: "rag_ask",
9504
9346
  title: "RAG ask (corpus-wide)",
9505
- description: "Ask a question grounded against the partner tenant's indexed content. Vectros performs a hybrid search, injects the top-K passages into the prompt, and streams a model answer back. Scope retrieval with `search` (ownership, folder, type, metadata filters, date window) to ground on a subset \u2014 e.g. one patient or one folder \u2014 and steer generation with `instructions` / `temperature`. The full answer is returned as a single response; progress notifications keep the call alive during the 30-45s generation window. Inference runs in-perimeter against AWS Bedrock \u2014 PHI never leaves the BAA boundary.",
9347
+ description: "Ask a question grounded against your tenant's indexed content. Vectros performs a hybrid search, injects the top-K passages into the prompt, and streams a model answer back. Scope retrieval with `search` (ownership, folder, type, metadata filters, date window) to ground on a subset \u2014 e.g. one patient or one folder \u2014 and steer generation with `instructions` / `temperature`. The full answer is returned as a single response; progress notifications keep the call alive during the 30-45s generation window. Inference runs in-perimeter against AWS Bedrock \u2014 PHI never leaves the BAA boundary.",
9506
9348
  inputSchema: inputSchema7,
9507
9349
  handler: async (args, extra) => {
9508
9350
  try {
@@ -9511,8 +9353,7 @@ var ragAsk = ({ client, log }) => ({
9511
9353
  mode: searchArg.mode ?? "HYBRID",
9512
9354
  limit: searchArg.limit ?? SEARCH_MCP_DEFAULT_LIMIT,
9513
9355
  userId: searchArg.userId,
9514
- orgId: searchArg.orgId,
9515
- clientId: searchArg.clientId,
9356
+ scope: searchArg.scope,
9516
9357
  folderId: searchArg.folderId,
9517
9358
  rootFolderId: searchArg.rootFolderId,
9518
9359
  typeName: searchArg.typeName,
@@ -9657,32 +9498,32 @@ var inputSchema9 = {
9657
9498
  userId: z9.string().optional().describe(
9658
9499
  "Filter to schemas visible to a specific user. Optional; default returns all schemas the credential can see."
9659
9500
  ),
9660
- orgId: z9.string().optional().describe(
9661
- "Filter to schemas visible to a specific org. Optional; default returns all schemas the credential can see."
9501
+ scope: z9.string().optional().describe(
9502
+ 'Filter to schemas carrying this scope value, in `namespace:value` form (e.g. "org:<uuid>", "group:eng-team"). `org` and `client` are built-in namespaces. Optional; default returns all schemas the credential can see.'
9662
9503
  ),
9663
- surface: z9.enum(["record", "document", "user", "org", "client"]).optional().describe(
9664
- "Filter to schemas bindable to this surface \u2014 e.g. `document` to list only document types, or `record` for record types. The identity surfaces (user/org/client) are account-wide. Optional."
9504
+ surface: z9.enum(["record", "document", "user", "entity"]).optional().describe(
9505
+ "Filter to schemas bindable to this surface \u2014 e.g. `document` to list only document types, or `record` for record types. Identity entities in any namespace (org/client/one you registered) bind under the single `entity` surface; `user` and `entity` are account-wide. Optional."
9665
9506
  ),
9666
9507
  recordType: z9.string().optional().describe(
9667
- 'Resolve the single schema for this record type (its natural handle, e.g. "patient") instead of listing \u2014 returns a one-element result, or empty if none. Combine with `surface=user|org|client` for an identity schema. Takes precedence over userId/orgId. Optional.'
9508
+ 'Resolve the single schema for this record type (its natural handle, e.g. "patient") instead of listing \u2014 returns a one-element result, or empty if none. Combine with `surface=user|entity` for an identity schema. Takes precedence over userId. Optional.'
9668
9509
  )
9669
9510
  };
9670
9511
  var listSchemas = ({ client, log }) => ({
9671
9512
  name: "list_schemas",
9672
9513
  title: "List record schemas",
9673
- description: 'List the structured-record schema catalog for the partner tenant. Each schema describes a record type (e.g. "patient", "clinical_note") \u2014 its fields, lookup-indexed fields, and capabilities. Use this to discover what record types exist before calling `record_query`. Filter with `surface` (record/document/user/org/client \u2014 e.g. only document types), `recordType` (resolve one schema by its type name), or `userId`/`orgId`; default returns everything the credential can see.',
9514
+ description: 'List the structured-record schema catalog for your tenant. Each schema describes a record type (e.g. "patient", "clinical_note") \u2014 its fields, lookup-indexed fields, and capabilities. Use this to discover what record types exist before calling `record_query`. Filter with `surface` (record/document/user/entity \u2014 e.g. only document types), `recordType` (resolve one schema by its type name), or `userId`/`scope`; default returns everything the credential can see.',
9674
9515
  inputSchema: inputSchema9,
9675
9516
  handler: async (args) => {
9676
9517
  const userId = args.userId;
9677
- const orgId = args.orgId;
9518
+ const scope = args.scope;
9678
9519
  const surface = args.surface;
9679
9520
  const recordType = args.recordType;
9680
9521
  try {
9681
9522
  const schemas = await drainPages(
9682
- (startFrom) => client.schemas.listSchemas({ userId, orgId, surface, recordType, startFrom })
9523
+ (startFrom) => client.schemas.listSchemas({ userId, scope, surface, recordType, startFrom })
9683
9524
  );
9684
9525
  log.debug(
9685
- { tool: "list_schemas", userId, orgId, surface, recordType, returned: schemas.length },
9526
+ { tool: "list_schemas", userId, scope, surface, recordType, returned: schemas.length },
9686
9527
  "list_schemas ok"
9687
9528
  );
9688
9529
  return {
@@ -9792,7 +9633,7 @@ var document_get_default = documentGet;
9792
9633
  // src/tools/document_query.ts
9793
9634
  import { z as z11 } from "zod";
9794
9635
  var MCP_DEFAULT_LIMIT3 = 3;
9795
- var MCP_MAX_LIMIT3 = 10;
9636
+ var MCP_MAX_LIMIT3 = 100;
9796
9637
  var inputSchema11 = {
9797
9638
  // Lookup-mode args — provide `field` plus EXACTLY ONE of: value | from+to | prefix.
9798
9639
  field: z11.string().optional().describe("Lookup mode: name of the lookup-indexed field to query by."),
@@ -9807,16 +9648,18 @@ var inputSchema11 = {
9807
9648
  // List-mode args:
9808
9649
  folderId: z11.string().optional().describe("List mode: only documents in this folder (Vectros folder id)."),
9809
9650
  userId: z11.string().optional().describe("List mode: scope to documents owned by this user."),
9810
- orgId: z11.string().optional().describe("List mode: scope to documents belonging to this org."),
9811
- clientId: z11.string().optional().describe("List mode: scope to documents associated with this client."),
9651
+ scope: z11.string().optional().describe(
9652
+ 'List mode: filter to documents carrying this scope value, in `namespace:value` form (e.g. "org:<uuid>", "client:<uuid>", "group:eng-team"). `org` and `client` are built-in namespaces; others are custom scopes you define.'
9653
+ ),
9654
+ startFrom: z11.string().optional().describe("Pagination cursor \u2014 pass the `nextCursor` from the previous page to fetch the next. Works in both list and lookup mode."),
9812
9655
  limit: z11.number().int().min(1).max(MCP_MAX_LIMIT3).optional().describe(
9813
- `Max documents to return. MCP-specific cap of ${MCP_MAX_LIMIT3} (vs API max of 100) to protect the agent context window. Default 3.`
9656
+ `Max documents per page. Defaults to a low ${MCP_DEFAULT_LIMIT3} to protect the agent context window; raise up to ${MCP_MAX_LIMIT3} (the documents API max) in one call when you can accept the larger payload, or page with \`startFrom\` instead.`
9814
9657
  )
9815
9658
  };
9816
9659
  var documentQuery = ({ client, log }) => ({
9817
9660
  name: "document_query",
9818
9661
  title: "Document query (list or lookup)",
9819
- description: "Query document metadata. Two modes:\n \u2022 Lookup on a lookup-indexed field: pass `type` and `field` plus exactly one of `value` (exact), `from`+`to` (range), or `prefix`. Works on sensitive fields (equality only there); range/prefix need a range-enabled field.\n \u2022 List: omit `field`; optionally filter by `folderId`/`userId`/`orgId`/`clientId`.\nReturns up to 10 documents (default 3) as a bare array. Mode is auto-detected. Use document_get for the full text/download URL of one document.",
9662
+ description: "Query document metadata. Two modes:\n \u2022 Lookup on a lookup-indexed field: pass `type` and `field` plus exactly one of `value` (exact), `from`+`to` (range), or `prefix`. Works on sensitive fields (equality only there); range/prefix need a range-enabled field.\n \u2022 List: omit `field`; optionally filter by `folderId`/`userId`/`scope` (`namespace:value`).\nReturns a `{ data, nextCursor }` page: `data` holds up to `limit` documents (default 3, max 100 \u2014 raise it in one call when you can accept the payload), and a non-null `nextCursor` means more remain \u2014 pass it back as `startFrom` to page. Mode is auto-detected. Use document_get for the full text/download URL of one document.",
9820
9663
  inputSchema: inputSchema11,
9821
9664
  handler: async (args) => {
9822
9665
  const limit = args.limit ?? MCP_DEFAULT_LIMIT3;
@@ -9826,8 +9669,9 @@ var documentQuery = ({ client, log }) => ({
9826
9669
  const to = args.to;
9827
9670
  const prefix = args.prefix;
9828
9671
  const type = args.type;
9672
+ const startFrom = args.startFrom;
9829
9673
  try {
9830
- let documents;
9674
+ let page;
9831
9675
  if (field) {
9832
9676
  const hasEquality = value !== void 0;
9833
9677
  const hasRange = from !== void 0 || to !== void 0;
@@ -9856,7 +9700,7 @@ var documentQuery = ({ client, log }) => ({
9856
9700
  new Error("lookup requires 'type' (the document's bound schema type) alongside 'field'.")
9857
9701
  );
9858
9702
  }
9859
- const page = await client.documents.lookupDocumentsByBody({
9703
+ page = await client.documents.lookupDocumentsByBody({
9860
9704
  type,
9861
9705
  field,
9862
9706
  value,
@@ -9864,28 +9708,29 @@ var documentQuery = ({ client, log }) => ({
9864
9708
  to,
9865
9709
  prefix,
9866
9710
  order: args.order,
9711
+ startFrom,
9867
9712
  limit
9868
9713
  });
9869
- documents = pageItems(page);
9870
9714
  log.debug(
9871
- { tool: "document_query", mode: "lookup", type, field, returned: documents.length },
9715
+ { tool: "document_query", mode: "lookup", type, field, returned: pageItems(page).length },
9872
9716
  "document_query lookup ok"
9873
9717
  );
9874
9718
  } else {
9875
- const page = await client.documents.listDocuments({
9719
+ page = await client.documents.listDocuments({
9876
9720
  folderId: args.folderId,
9877
9721
  userId: args.userId,
9878
- orgId: args.orgId,
9879
- clientId: args.clientId,
9722
+ scope: args.scope,
9723
+ startFrom,
9880
9724
  limit
9881
9725
  });
9882
- documents = pageItems(page);
9883
9726
  log.debug(
9884
- { tool: "document_query", mode: "list", limit, returned: documents.length },
9727
+ { tool: "document_query", mode: "list", limit, returned: pageItems(page).length },
9885
9728
  "document_query list ok"
9886
9729
  );
9887
9730
  }
9888
- return { content: [{ type: "text", text: JSON.stringify(documents, null, 2) }] };
9731
+ const documents = pageItems(page);
9732
+ const nextCursor = page.nextCursor ?? null;
9733
+ return { content: [{ type: "text", text: JSON.stringify({ data: documents, nextCursor }, null, 2) }] };
9889
9734
  } catch (err) {
9890
9735
  log.warn({ tool: "document_query", err: String(err) }, "document_query failed");
9891
9736
  return toolError("document_query", err);
@@ -9914,8 +9759,9 @@ var inputSchema12 = {
9914
9759
  "Lifecycle status. `ARCHIVED` soft-retracts the document \u2014 it is pulled from search and recall but kept and recoverable; set it back to `ACTIVE` to re-index and restore it. The way to retire superseded content when the credential has no delete authority. Omit to leave unchanged."
9915
9760
  ),
9916
9761
  userId: z12.string().optional().describe("Reassign the owning user (Vectros UUID)."),
9917
- orgId: z12.string().optional().describe("Reassign the owning org (Vectros UUID)."),
9918
- clientId: z12.string().optional().describe("Reassign the associated client (Vectros UUID)."),
9762
+ scopes: z12.array(z12.string()).optional().describe(
9763
+ 'Reassign scope ownership as `namespace:value` entries, at most 2 (e.g. ["org:<uuid>", "group:eng-team"]) \u2014 the COMPLETE new parent set. `org`/`client` are built-in namespaces. Omit to leave ownership unchanged; `[]` clears it (private to the owning user).'
9764
+ ),
9919
9765
  expectedVersion: z12.number().int().optional().describe(
9920
9766
  "Optimistic concurrency: the version you last read. If the document changed since, the update is refused as a conflict (re-read and retry). Omit for last-write-wins."
9921
9767
  )
@@ -9935,8 +9781,7 @@ var documentUpdate = ({ client, log }) => ({
9935
9781
  const folderId = args.folderId;
9936
9782
  const status = args.status;
9937
9783
  const userId = args.userId;
9938
- const orgId = args.orgId;
9939
- const clientId = args.clientId;
9784
+ const scopes = args.scopes;
9940
9785
  const expectedVersion = args.expectedVersion;
9941
9786
  try {
9942
9787
  const resolved = await resolveDocumentIdByExternalId(client, { id: documentId, externalId, type });
@@ -9948,8 +9793,7 @@ var documentUpdate = ({ client, log }) => ({
9948
9793
  if (folderId !== void 0) body.folderId = folderId;
9949
9794
  if (status !== void 0) body.status = status;
9950
9795
  if (userId !== void 0) body.userId = userId;
9951
- if (orgId !== void 0) body.orgId = orgId;
9952
- if (clientId !== void 0) body.clientId = clientId;
9796
+ if (scopes !== void 0) body.scopes = scopes;
9953
9797
  if (expectedVersion !== void 0) body.expectedVersion = expectedVersion;
9954
9798
  const updated = await client.documents.patchDocument({
9955
9799
  id: resolved.id,
@@ -9994,20 +9838,23 @@ var document_delete_default = documentDelete;
9994
9838
  // src/tools/folder_query.ts
9995
9839
  import { z as z14 } from "zod";
9996
9840
  var MCP_DEFAULT_LIMIT4 = 10;
9997
- var MCP_MAX_LIMIT4 = 50;
9841
+ var MCP_MAX_LIMIT4 = 100;
9998
9842
  var inputSchema14 = {
9999
9843
  id: z14.string().optional().describe("Get mode: fetch this single folder by id."),
10000
9844
  parentId: z14.string().optional().describe("List mode: direct children of this folder (tree navigation). Omit for a flat tenant list."),
10001
9845
  userId: z14.string().optional().describe("List mode: scope to folders owned by this user."),
10002
- orgId: z14.string().optional().describe("List mode: scope to folders belonging to this org."),
10003
- clientId: z14.string().optional().describe("List mode: scope to folders associated with this client."),
9846
+ scope: z14.string().optional().describe(
9847
+ 'List mode: filter to folders carrying this scope value, in `namespace:value` form (e.g. "org:<uuid>", "client:<uuid>", "group:eng-team"). `org` and `client` are built-in namespaces; others are custom scopes you define.'
9848
+ ),
10004
9849
  startFrom: z14.string().optional().describe("List mode: pagination cursor \u2014 pass the `nextCursor` from the previous page to fetch the next."),
10005
- limit: z14.number().int().min(1).max(MCP_MAX_LIMIT4).optional().describe(`List mode: max folders to return. MCP cap of ${MCP_MAX_LIMIT4} (vs API 100). Default 10.`)
9850
+ limit: z14.number().int().min(1).max(MCP_MAX_LIMIT4).optional().describe(
9851
+ `List mode: max folders per page. Default 10; raise up to ${MCP_MAX_LIMIT4} (the folders API max) in one call when you can accept the larger page, or page with \`startFrom\`.`
9852
+ )
10006
9853
  };
10007
9854
  var folderQuery = ({ client, log }) => ({
10008
9855
  name: "folder_query",
10009
9856
  title: "Folder query (list or get)",
10010
- description: "Read folders. Two modes:\n \u2022 Get: pass `id` \u2192 returns the single folder.\n \u2022 List: omit `id`; pass `parentId` for a folder's direct children (tree navigation) or omit for a flat tenant list. Optionally filter by `userId`/`orgId`/`clientId`.\nList mode returns `{ data, nextCursor }` (default 10, max 50 per page); pass `nextCursor` back as `startFrom` to page through all folders. Get mode returns the single folder object.",
9857
+ description: "Read folders. Two modes:\n \u2022 Get: pass `id` \u2192 returns the single folder.\n \u2022 List: omit `id`; pass `parentId` for a folder's direct children (tree navigation) or omit for a flat tenant list. Optionally filter by `userId` or `scope` (`namespace:value`).\nList mode returns `{ data, nextCursor }` (default 10, max 100 per page \u2014 raise it in one call when you can accept the larger page); a non-null `nextCursor` means more remain \u2014 pass it back as `startFrom` to page through all folders. Get mode returns the single folder object.",
10011
9858
  inputSchema: inputSchema14,
10012
9859
  handler: async (args) => {
10013
9860
  const id = args.id;
@@ -10021,8 +9868,7 @@ var folderQuery = ({ client, log }) => ({
10021
9868
  const page = await client.folders.listFolders({
10022
9869
  parentFolderId: args.parentId,
10023
9870
  userId: args.userId,
10024
- orgId: args.orgId,
10025
- clientId: args.clientId,
9871
+ scope: args.scope,
10026
9872
  startFrom: args.startFrom,
10027
9873
  limit
10028
9874
  });
@@ -10046,8 +9892,9 @@ var inputSchema15 = {
10046
9892
  parentId: z15.string().optional().describe("Parent folder id \u2014 places the folder under this parent. Omit for the context default root. Create-only."),
10047
9893
  slug: z15.string().optional().describe("Optional stable slug (sibling-unique; idempotency key). Lowercase letters/digits/hyphens. Derived from name when omitted."),
10048
9894
  userId: z15.string().optional().describe("Owning user (Vectros UUID)."),
10049
- orgId: z15.string().optional().describe("Owning org (Vectros UUID)."),
10050
- clientId: z15.string().optional().describe("Associated client (Vectros UUID).")
9895
+ scopes: z15.array(z15.string()).optional().describe(
9896
+ 'Scope ownership as `namespace:value` entries, at most 2 (e.g. ["org:<uuid>", "group:eng-team"]). `org` and `client` are built-in namespaces; others are custom scopes you define. This is the folder\'s COMPLETE scope declaration and values must come from the credential\'s own identity. An empty array `[]` creates a PRIVATE folder owned by the calling user alone. Omit to stamp the credential\'s full identity \u2014 the default.'
9897
+ )
10051
9898
  };
10052
9899
  var folderCreate = ({ client, log }) => ({
10053
9900
  name: "folder_create",
@@ -10063,8 +9910,7 @@ var folderCreate = ({ client, log }) => ({
10063
9910
  parentFolderId: args.parentId,
10064
9911
  slug: args.slug,
10065
9912
  userId: args.userId,
10066
- orgId: args.orgId,
10067
- clientId: args.clientId
9913
+ scopes: args.scopes
10068
9914
  }
10069
9915
  });
10070
9916
  log.debug({ tool: "folder_create", id: folder.id, name: folder.name }, "folder_create ok");
@@ -10084,8 +9930,9 @@ var inputSchema16 = {
10084
9930
  name: z16.string().optional().describe("New folder name. Omit to keep the current name."),
10085
9931
  description: z16.string().optional().describe("New description. Omit to leave unchanged."),
10086
9932
  userId: z16.string().optional().describe("Reassign the owning user (Vectros UUID)."),
10087
- orgId: z16.string().optional().describe("Reassign the owning org (Vectros UUID)."),
10088
- clientId: z16.string().optional().describe("Reassign the associated client (Vectros UUID)."),
9933
+ scopes: z16.array(z16.string()).optional().describe(
9934
+ 'Reassign scope ownership as `namespace:value` entries, at most 2 (e.g. ["org:<uuid>", "group:eng-team"]) \u2014 the COMPLETE new parent set. `org`/`client` are built-in namespaces. Omit to leave ownership unchanged; `[]` clears it (private to the owning user).'
9935
+ ),
10089
9936
  expectedVersion: z16.number().int().optional().describe(
10090
9937
  "Optimistic concurrency: the version you last read. If the folder changed since, the update is refused as a conflict (re-read and retry). Omit for last-write-wins."
10091
9938
  )
@@ -10100,16 +9947,14 @@ var folderUpdate = ({ client, log }) => ({
10100
9947
  const name = args.name;
10101
9948
  const description = args.description;
10102
9949
  const userId = args.userId;
10103
- const orgId = args.orgId;
10104
- const clientId = args.clientId;
9950
+ const scopes = args.scopes;
10105
9951
  const expectedVersion = args.expectedVersion;
10106
9952
  try {
10107
9953
  const body = {};
10108
9954
  if (name !== void 0) body.name = name;
10109
9955
  if (description !== void 0) body.description = description;
10110
9956
  if (userId !== void 0) body.userId = userId;
10111
- if (orgId !== void 0) body.orgId = orgId;
10112
- if (clientId !== void 0) body.clientId = clientId;
9957
+ if (scopes !== void 0) body.scopes = scopes;
10113
9958
  if (expectedVersion !== void 0) body.expectedVersion = expectedVersion;
10114
9959
  const updated = await client.folders.patchFolder({ id, body });
10115
9960
  log.debug({ tool: "folder_update", id }, "folder_update ok");
@@ -10275,8 +10120,9 @@ var inputSchema19 = {
10275
10120
  // Common (both modes):
10276
10121
  folderId: z18.string().optional().describe("Optional folder to ingest into. Default: tenant root."),
10277
10122
  userId: z18.string().optional().describe("Owning user ID. Optional."),
10278
- orgId: z18.string().optional().describe("Owning org ID. Optional."),
10279
- clientId: z18.string().optional().describe("Owning client ID. Optional.")
10123
+ scopes: z18.array(z18.string()).optional().describe(
10124
+ "TEXT MODE ONLY. Scope ownership as `namespace:value` entries, at most 2 (e.g. [\"org:<uuid>\", \"group:eng-team\"]). `org` and `client` are built-in namespaces; others are custom scopes you define. This is the document's COMPLETE scope declaration and values must come from the credential's own identity. An empty array `[]` creates a PRIVATE document owned by the calling user alone. Omit to stamp the credential's full identity \u2014 the default. Rejected with `filePath` (file uploads do not accept a scope declaration): a file-uploaded document is stamped with the credential's full identity."
10125
+ )
10280
10126
  };
10281
10127
  var documentIngest = ({ client, log, transport, ingestRoot }) => ({
10282
10128
  name: "document_ingest",
@@ -10310,14 +10156,20 @@ var documentIngest = ({ client, log, transport, ingestRoot }) => ({
10310
10156
  )
10311
10157
  );
10312
10158
  }
10159
+ if (filePath && args.scopes !== void 0) {
10160
+ return toolError(
10161
+ "document_ingest",
10162
+ new Error(
10163
+ "`scopes` is not supported with `filePath` \u2014 file uploads do not accept a scope declaration, and silently ignoring it could make an intended-private document team-visible. Use `text` mode to declare scopes, or omit `scopes` (the upload is stamped with the credential's full identity)."
10164
+ )
10165
+ );
10166
+ }
10313
10167
  const common = {
10314
10168
  folderId: args.folderId,
10315
10169
  payload: args.payload,
10316
10170
  schemaId,
10317
10171
  externalId: args.externalId,
10318
- userId: args.userId,
10319
- orgId: args.orgId,
10320
- clientId: args.clientId
10172
+ userId: args.userId
10321
10173
  };
10322
10174
  try {
10323
10175
  if (text) {
@@ -10327,6 +10179,9 @@ var documentIngest = ({ client, log, transport, ingestRoot }) => ({
10327
10179
  title,
10328
10180
  text,
10329
10181
  indexMode,
10182
+ // Scope ownership is a TEXT-mode contract only (the upload-init
10183
+ // endpoint has no scopes field — see the gate above).
10184
+ scopes: args.scopes,
10330
10185
  ...common
10331
10186
  }
10332
10187
  });
@@ -10419,9 +10274,11 @@ var document_ingest_default = documentIngest;
10419
10274
  // src/tools/lookup_principal.ts
10420
10275
  import { z as z19 } from "zod";
10421
10276
  var MCP_DEFAULT_LIMIT5 = 10;
10422
- var MCP_MAX_LIMIT5 = 50;
10277
+ var MCP_MAX_LIMIT5 = 100;
10423
10278
  var inputSchema20 = {
10424
- kind: z19.enum(["user", "org", "client"]).describe("Which principal to look up: a user, an organization, or a client."),
10279
+ kind: z19.string().describe(
10280
+ 'Which principal to look up: "user" (the fixed principal surface), or an entity namespace \u2014 "org", "client" (built in), or a namespace you registered.'
10281
+ ),
10425
10282
  externalId: z19.string().optional().describe(
10426
10283
  "Resolve mode: your own stable identifier for the principal. Returns the single matching principal (with its Vectros UUID), or an empty array if none. The fastest path to the UUID the ownership filters need. Takes precedence if both this and a `field` lookup are supplied."
10427
10284
  ),
@@ -10433,15 +10290,19 @@ var inputSchema20 = {
10433
10290
  to: z19.string().optional().describe("Lookup mode (range): inclusive upper bound; requires `from`."),
10434
10291
  prefix: z19.string().optional().describe("Lookup mode (prefix): match values starting with this. Range-enabled string fields only."),
10435
10292
  order: z19.enum(["asc", "desc"]).optional().describe("Lookup mode: sort direction by the looked-up field. `asc` (default) or `desc`."),
10436
- limit: z19.number().int().min(1).max(MCP_MAX_LIMIT5).optional().describe(`Max principals to return. MCP cap of ${MCP_MAX_LIMIT5} (vs API 100). Default ${MCP_DEFAULT_LIMIT5}.`)
10293
+ startFrom: z19.string().optional().describe("Lookup mode: pagination cursor \u2014 pass the `nextCursor` from the previous page to fetch the next."),
10294
+ limit: z19.number().int().min(1).max(MCP_MAX_LIMIT5).optional().describe(
10295
+ `Max principals per page. Defaults to ${MCP_DEFAULT_LIMIT5}; raise up to ${MCP_MAX_LIMIT5} (the principals API max) in one call when you can accept the payload, or page with \`startFrom\`.`
10296
+ )
10437
10297
  };
10438
10298
  var lookupPrincipal = ({ client, log }) => ({
10439
10299
  name: "lookup_principal",
10440
- title: "Look up a user / org / client identity",
10441
- description: "Resolve a user, org, or client identity. Two modes:\n \u2022 Resolve by your own id: pass `externalId` \u2192 the matching principal incl. its Vectros UUID (the id the ownership filters on record_query / hybrid_search / rag_ask expect).\n \u2022 Lookup by a schema field: pass `type` and `field` plus exactly one of `value` (exact), `from`+`to` (range), or `prefix`. Sensitive-field-safe. (If both `externalId` and a `field` lookup are given, `externalId` wins.) Returns up to 50 principals (default 10) as a bare array. Read-only \u2014 does not create or modify identities.",
10300
+ title: "Look up a user identity or a namespaced identity entity",
10301
+ description: "Resolve a user, or an identity entity in a namespace (org/client/one you registered). Two modes:\n \u2022 Resolve by your own id: pass `externalId` \u2192 the matching principal incl. its Vectros UUID (the id the ownership filters on record_query / hybrid_search / rag_ask expect).\n \u2022 Lookup by a schema field: pass `type` and `field` plus exactly one of `value` (exact), `from`+`to` (range), or `prefix`. Sensitive-field-safe. (If both `externalId` and a `field` lookup are given, `externalId` wins.) Returns a `{ data, nextCursor }` page (default 10, max 100 \u2014 raise it in one call when you can accept the payload); a non-null `nextCursor` means more remain \u2014 pass it back as `startFrom`. Read-only \u2014 does not create or modify identities.",
10442
10302
  inputSchema: inputSchema20,
10443
10303
  handler: async (args) => {
10444
10304
  const kind = args.kind;
10305
+ const isUser = kind === "user";
10445
10306
  const limit = args.limit ?? MCP_DEFAULT_LIMIT5;
10446
10307
  const externalId = args.externalId;
10447
10308
  const type = args.type;
@@ -10451,16 +10312,11 @@ var lookupPrincipal = ({ client, log }) => ({
10451
10312
  const to = args.to;
10452
10313
  const prefix = args.prefix;
10453
10314
  const order = args.order;
10315
+ const startFrom = args.startFrom;
10454
10316
  try {
10455
10317
  let page;
10456
10318
  if (externalId !== void 0) {
10457
- if (kind === "user") {
10458
- page = await client.identity.listUsers({ externalId, limit });
10459
- } else if (kind === "org") {
10460
- page = await client.identity.listOrgs({ externalId, limit });
10461
- } else {
10462
- page = await client.identity.listClients({ externalId, limit });
10463
- }
10319
+ page = isUser ? await client.identity.listUsers({ externalId, limit }) : await client.identity.listEntities({ namespace: kind, externalId, limit });
10464
10320
  log.debug({ tool: "lookup_principal", mode: "resolve", kind }, "lookup_principal resolve ok");
10465
10321
  } else if (field !== void 0) {
10466
10322
  const hasEquality = value !== void 0;
@@ -10488,14 +10344,8 @@ var lookupPrincipal = ({ client, log }) => ({
10488
10344
  new Error("lookup requires 'type' (the identity schema's record type) alongside 'field'.")
10489
10345
  );
10490
10346
  }
10491
- const req = { type, field, value, from, to, prefix, order, limit };
10492
- if (kind === "user") {
10493
- page = await client.identity.lookupUsers(req);
10494
- } else if (kind === "org") {
10495
- page = await client.identity.lookupOrgs(req);
10496
- } else {
10497
- page = await client.identity.lookupClients(req);
10498
- }
10347
+ const req = { type, field, value, from, to, prefix, order, startFrom, limit };
10348
+ page = isUser ? await client.identity.lookupUsers(req) : await client.identity.lookupEntities({ namespace: kind, body: req });
10499
10349
  log.debug({ tool: "lookup_principal", mode: "lookup", kind, type, field }, "lookup_principal lookup ok");
10500
10350
  } else {
10501
10351
  return toolError(
@@ -10504,7 +10354,8 @@ var lookupPrincipal = ({ client, log }) => ({
10504
10354
  );
10505
10355
  }
10506
10356
  const principals = pageItems(page);
10507
- return { content: [{ type: "text", text: JSON.stringify(principals, null, 2) }] };
10357
+ const nextCursor = page.nextCursor ?? null;
10358
+ return { content: [{ type: "text", text: JSON.stringify({ data: principals, nextCursor }, null, 2) }] };
10508
10359
  } catch (err) {
10509
10360
  log.warn({ tool: "lookup_principal", kind, err: String(err) }, "lookup_principal failed");
10510
10361
  return toolError("lookup_principal", err);
@@ -11086,10 +10937,144 @@ function parseToolsEnv(value) {
11086
10937
  return requested;
11087
10938
  }
11088
10939
 
10940
+ // src/resolve-key.ts
10941
+ import { execFile } from "child_process";
10942
+ import { statSync } from "fs";
10943
+ import path from "path";
10944
+ var HELPER_COMMAND = "vectros";
10945
+ var HELPER_TIMEOUT_MS = 1e4;
10946
+ var HELPER_MAX_BUFFER = 64 * 1024;
10947
+ var ALIAS_RE = /^[A-Za-z0-9._-]+$/;
10948
+ var SECRET_RE = /(?:ssk|sk|st)_(?:live|test)_[A-Za-z0-9._-]+/gi;
10949
+ var DETAIL_MAX_CHARS = 200;
10950
+ async function resolveApiKey(deps = {}) {
10951
+ const env = deps.env ?? process.env;
10952
+ const envKey = env.VECTROS_API_KEY;
10953
+ if (envKey && envKey.trim().length > 0) {
10954
+ return { key: envKey.trim(), source: "env" };
10955
+ }
10956
+ const alias = env.VECTROS_KEYRING_ALIAS?.trim() || void 0;
10957
+ if (alias !== void 0 && !ALIAS_RE.test(alias)) {
10958
+ return {
10959
+ source: "none",
10960
+ reason: "bad-alias",
10961
+ detail: "VECTROS_KEYRING_ALIAS must be letters, digits, dot, dash, or underscore."
10962
+ };
10963
+ }
10964
+ const runHelper = deps.runHelper ?? defaultRunHelper;
10965
+ const outcome = await runHelper({ alias, env });
10966
+ switch (outcome.status) {
10967
+ case "ok":
10968
+ return { key: outcome.secret, source: "keyring", alias };
10969
+ case "cli-absent":
10970
+ return { source: "none", reason: "cli-absent", alias };
10971
+ // Redact HERE as well as in mapExecResult: `runHelper` is a public injectable
10972
+ // seam, so redacting only inside the default implementation would leave any
10973
+ // other implementation's text to reach the fatal log raw. Belongs at the sink.
10974
+ case "no-usable-key":
10975
+ return {
10976
+ source: "none",
10977
+ reason: "no-usable-key",
10978
+ alias,
10979
+ detail: outcome.detail ? redactDetail(outcome.detail) : void 0
10980
+ };
10981
+ case "error":
10982
+ return { source: "none", reason: "helper-failed", alias, detail: redactDetail(outcome.detail) };
10983
+ }
10984
+ }
10985
+ function noKeyMessage(resolved) {
10986
+ const setEnv = "set VECTROS_API_KEY to a Vectros key (recommended: ssk_live_\u2026)";
10987
+ switch (resolved.reason) {
10988
+ case "cli-absent":
10989
+ return `no API key: VECTROS_API_KEY is unset and the \`vectros\` CLI is not on PATH. Either ${setEnv}, or install @vectros-ai/cli and run \`vectros switch <alias>\`.`;
10990
+ case "no-usable-key":
10991
+ return `no API key: VECTROS_API_KEY is unset and \`vectros keyring show\` returned no key${resolved.detail ? ` \u2014 ${resolved.detail}` : ""}. Run \`vectros switch <alias>\` to pick an identity, \`vectros keyring doctor\` to inspect the keyring (CLI 0.10.0+), upgrade @vectros-ai/cli if it predates the keyring (0.9.0), or ${setEnv}.`;
10992
+ case "bad-alias":
10993
+ return `invalid VECTROS_KEYRING_ALIAS: ${resolved.detail ?? "not a valid keyring alias"} Run \`vectros keyring list\` to see the entry names, unset it to use the active identity, or ${setEnv}.`;
10994
+ case "helper-failed":
10995
+ return `no API key: VECTROS_API_KEY is unset and the \`vectros keyring show\` helper failed (${resolved.detail ?? "unknown error"}). Upgrade @vectros-ai/cli if it is an old build, or ${setEnv} to bypass the keyring.`;
10996
+ default:
10997
+ return `no API key: ${setEnv}.`;
10998
+ }
10999
+ }
11000
+ function keyringNotice(resolved) {
11001
+ if (resolved.source !== "keyring") return void 0;
11002
+ if (resolved.alias !== void 0) {
11003
+ return { level: "info", alias: resolved.alias, message: "resolved API key from the vectros CLI keyring" };
11004
+ }
11005
+ return {
11006
+ level: "warn",
11007
+ alias: "(active)",
11008
+ message: "resolved API key from the vectros CLI keyring: no entry was named, so this server is running as whatever identity `vectros switch` last made active. Set VECTROS_API_KEY, or VECTROS_KEYRING_ALIAS, to choose deliberately \u2014 `vectros keyring doctor` shows which entry is active and whether it holds a live key."
11009
+ };
11010
+ }
11011
+ function redactDetail(message) {
11012
+ const redacted = message.replace(/\s+/g, " ").trim().replace(SECRET_RE, "[redacted]");
11013
+ return redacted.length > DETAIL_MAX_CHARS ? `${redacted.slice(0, DETAIL_MAX_CHARS)}\u2026` : redacted;
11014
+ }
11015
+ function resolveCommandPath(command, env, platform = process.platform) {
11016
+ const pathVar = env.PATH ?? env.Path ?? env.path ?? "";
11017
+ if (!pathVar) return void 0;
11018
+ const exts = platform === "win32" ? (env.PATHEXT || ".COM;.EXE;.BAT;.CMD").split(";").map((e) => e.trim()).filter(Boolean) : [""];
11019
+ for (const rawDir of pathVar.split(path.delimiter)) {
11020
+ const dir = rawDir.trim().replace(/^"(.*)"$/, "$1");
11021
+ if (!dir || !path.isAbsolute(dir)) continue;
11022
+ for (const ext of exts) {
11023
+ const candidate = path.join(dir, command + ext);
11024
+ try {
11025
+ if (statSync(candidate).isFile()) return candidate;
11026
+ } catch {
11027
+ }
11028
+ }
11029
+ }
11030
+ return void 0;
11031
+ }
11032
+ function mapExecResult(err, stdout, stderr = "") {
11033
+ if (!err) {
11034
+ const secret = stdout.trim();
11035
+ return secret ? { status: "ok", secret } : { status: "no-usable-key" };
11036
+ }
11037
+ const code = err.code;
11038
+ if (code === "ENOENT") return { status: "cli-absent" };
11039
+ const detail = redactDetail(stderr.trim() || err.message);
11040
+ if (code === 1 || code === 2) return { status: "no-usable-key", detail: detail || void 0 };
11041
+ return { status: "error", detail };
11042
+ }
11043
+ function defaultRunHelper({ alias, env }, deps = {}) {
11044
+ const platform = deps.platform ?? process.platform;
11045
+ const exec = deps.execFileImpl ?? execFile;
11046
+ const resolved = resolveCommandPath(HELPER_COMMAND, env, platform);
11047
+ if (!resolved) return Promise.resolve({ status: "cli-absent" });
11048
+ const isWindows = platform === "win32";
11049
+ const args = ["keyring", "show", "--format", "raw", ...alias ? ["--alias", alias] : []];
11050
+ const file = isWindows ? `"${resolved}"` : resolved;
11051
+ return new Promise((resolve2) => {
11052
+ exec(
11053
+ file,
11054
+ args,
11055
+ {
11056
+ env,
11057
+ timeout: HELPER_TIMEOUT_MS,
11058
+ maxBuffer: HELPER_MAX_BUFFER,
11059
+ windowsHide: true,
11060
+ shell: isWindows
11061
+ },
11062
+ (err, stdout, stderr) => resolve2(mapExecResult(err, String(stdout ?? ""), String(stderr ?? "")))
11063
+ );
11064
+ });
11065
+ }
11066
+
11089
11067
  // src/cli-http.ts
11090
11068
  async function main() {
11091
11069
  const log = createLogger2();
11092
- const apiKey = process.env.VECTROS_API_KEY;
11070
+ const resolved = await resolveApiKey();
11071
+ const apiKey = resolved.key;
11072
+ const notice = keyringNotice(resolved);
11073
+ if (notice) log[notice.level]({ alias: notice.alias }, notice.message);
11074
+ if (!apiKey) {
11075
+ log.fatal({ reason: resolved.reason }, noKeyMessage(resolved));
11076
+ process.exit(1);
11077
+ }
11093
11078
  const apiBaseUrl = process.env.VECTROS_API_BASE_URL;
11094
11079
  if (apiBaseUrl !== void 0) {
11095
11080
  try {