@softure-ai/mcp-access 0.2.9 → 0.3.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.
Files changed (125) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/README.md +231 -11
  3. package/dist/cli/run.d.ts +1 -1
  4. package/dist/cli/run.d.ts.map +1 -1
  5. package/dist/cli/run.js +2 -2
  6. package/dist/cli/run.js.map +1 -1
  7. package/dist/contract.d.ts +48 -2
  8. package/dist/contract.d.ts.map +1 -1
  9. package/dist/index.d.ts +88 -2
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +19 -4
  12. package/dist/index.js.map +1 -1
  13. package/dist/jobs/index.d.ts +2 -0
  14. package/dist/jobs/index.d.ts.map +1 -1
  15. package/dist/jobs/index.js +5 -2
  16. package/dist/jobs/index.js.map +1 -1
  17. package/dist/jobs/operation-state.d.ts +58 -0
  18. package/dist/jobs/operation-state.d.ts.map +1 -0
  19. package/dist/jobs/operation-state.js +68 -0
  20. package/dist/jobs/operation-state.js.map +1 -0
  21. package/dist/jobs/operation-tasks.d.ts +61 -0
  22. package/dist/jobs/operation-tasks.d.ts.map +1 -0
  23. package/dist/jobs/operation-tasks.js +161 -0
  24. package/dist/jobs/operation-tasks.js.map +1 -0
  25. package/dist/jobs/operations.d.ts +68 -0
  26. package/dist/jobs/operations.d.ts.map +1 -0
  27. package/dist/jobs/operations.js +110 -0
  28. package/dist/jobs/operations.js.map +1 -0
  29. package/dist/messages/en.d.ts +55 -0
  30. package/dist/messages/en.d.ts.map +1 -1
  31. package/dist/messages/en.js +55 -0
  32. package/dist/messages/en.js.map +1 -1
  33. package/dist/messages/index.d.ts +54 -0
  34. package/dist/messages/index.d.ts.map +1 -1
  35. package/dist/next/issue-token.d.ts +11 -2
  36. package/dist/next/issue-token.d.ts.map +1 -1
  37. package/dist/next/issue-token.js +56 -7
  38. package/dist/next/issue-token.js.map +1 -1
  39. package/dist/next/token-manager-props.d.ts +3 -2
  40. package/dist/next/token-manager-props.d.ts.map +1 -1
  41. package/dist/next/token-manager-props.js +12 -2
  42. package/dist/next/token-manager-props.js.map +1 -1
  43. package/dist/options.d.ts +47 -0
  44. package/dist/options.d.ts.map +1 -1
  45. package/dist/options.js +53 -0
  46. package/dist/options.js.map +1 -1
  47. package/dist/schema.d.ts +214 -0
  48. package/dist/schema.d.ts.map +1 -1
  49. package/dist/schema.js +21 -3
  50. package/dist/schema.js.map +1 -1
  51. package/dist/server/api-tokens.d.ts +64 -0
  52. package/dist/server/api-tokens.d.ts.map +1 -0
  53. package/dist/server/api-tokens.js +176 -0
  54. package/dist/server/api-tokens.js.map +1 -0
  55. package/dist/server/confirmation.d.ts +69 -0
  56. package/dist/server/confirmation.d.ts.map +1 -0
  57. package/dist/server/confirmation.js +220 -0
  58. package/dist/server/confirmation.js.map +1 -0
  59. package/dist/server/health.d.ts.map +1 -1
  60. package/dist/server/health.js +3 -1
  61. package/dist/server/health.js.map +1 -1
  62. package/dist/server/index.d.ts +4 -2
  63. package/dist/server/index.d.ts.map +1 -1
  64. package/dist/server/index.js +3 -1
  65. package/dist/server/index.js.map +1 -1
  66. package/dist/server/privacy.d.ts +4 -0
  67. package/dist/server/privacy.d.ts.map +1 -1
  68. package/dist/server/privacy.js +5 -1
  69. package/dist/server/privacy.js.map +1 -1
  70. package/dist/server/prune.d.ts +5 -1
  71. package/dist/server/prune.d.ts.map +1 -1
  72. package/dist/server/prune.js +14 -4
  73. package/dist/server/prune.js.map +1 -1
  74. package/dist/server/strict-input.d.ts +3 -1
  75. package/dist/server/strict-input.d.ts.map +1 -1
  76. package/dist/server/strict-input.js +54 -8
  77. package/dist/server/strict-input.js.map +1 -1
  78. package/dist/server/tokens.d.ts +46 -11
  79. package/dist/server/tokens.d.ts.map +1 -1
  80. package/dist/server/tokens.js +46 -24
  81. package/dist/server/tokens.js.map +1 -1
  82. package/dist/server/tools.d.ts +8 -0
  83. package/dist/server/tools.d.ts.map +1 -1
  84. package/dist/server/tools.js +1 -0
  85. package/dist/server/tools.js.map +1 -1
  86. package/dist/tokens/index.d.ts +6 -0
  87. package/dist/tokens/index.d.ts.map +1 -0
  88. package/dist/tokens/index.js +8 -0
  89. package/dist/tokens/index.js.map +1 -0
  90. package/dist/ui/index.d.ts +1 -1
  91. package/dist/ui/index.d.ts.map +1 -1
  92. package/dist/ui/index.js.map +1 -1
  93. package/dist/ui/token-manager.d.ts +18 -2
  94. package/dist/ui/token-manager.d.ts.map +1 -1
  95. package/dist/ui/token-manager.js +28 -3
  96. package/dist/ui/token-manager.js.map +1 -1
  97. package/migrations/0004_create_used_confirmations.sql +13 -0
  98. package/migrations/0005_add_api_tokens.sql +15 -0
  99. package/migrations/0006_create_operation_tasks.sql +18 -0
  100. package/module.json +9 -3
  101. package/package.json +7 -2
  102. package/src/cli/run.ts +2 -2
  103. package/src/contract.ts +60 -2
  104. package/src/index.ts +31 -3
  105. package/src/jobs/index.ts +41 -2
  106. package/src/jobs/operation-state.ts +119 -0
  107. package/src/jobs/operation-tasks.ts +229 -0
  108. package/src/jobs/operations.ts +213 -0
  109. package/src/messages/en.ts +56 -0
  110. package/src/next/issue-token.ts +64 -9
  111. package/src/next/token-manager-props.ts +15 -4
  112. package/src/options.ts +62 -0
  113. package/src/schema.ts +23 -3
  114. package/src/server/api-tokens.ts +224 -0
  115. package/src/server/confirmation.ts +316 -0
  116. package/src/server/health.ts +3 -1
  117. package/src/server/index.ts +32 -2
  118. package/src/server/privacy.ts +9 -1
  119. package/src/server/prune.ts +17 -4
  120. package/src/server/strict-input.ts +62 -13
  121. package/src/server/tokens.ts +73 -27
  122. package/src/server/tools.ts +9 -0
  123. package/src/tokens/index.ts +22 -0
  124. package/src/ui/index.ts +1 -0
  125. package/src/ui/token-manager.tsx +140 -3
@@ -1,5 +1,6 @@
1
1
  export { createMcpEndpoint, MAX_MCP_REQUEST_BYTES, MCP_RATE_LIMIT_BUCKET, MCP_READ_SCOPE, MCP_WRITE_SCOPE, type McpEndpoint, type McpEndpointOptions, type McpServerFactory, } from "./endpoint.js";
2
2
  export { actionTool, toFormData, type ActionToolOptions, type FormActionHandler } from "./action-tool.js";
3
+ export { CONFIRMATION_FIELD, CONFIRMATION_SECRET_ENV, confirmationInput, DEFAULT_CONFIRMATION_TTL_SECONDS, MIN_CONFIRMATION_SECRET_LENGTH, pruneUsedConfirmations, toCanonicalJson, withConfirmation, type ConfirmationErrorCode, type ConfirmationEstimate, type ConfirmationRequest, type ConfirmedToolArgs, type WithConfirmationOptions, } from "./confirmation.js";
3
4
  export { createMcpAccessContext } from "./context.js";
4
5
  export { isWritingEnabled } from "./writes-switch.js";
5
6
  export { checkAccessTokensTable } from "./health.js";
@@ -12,12 +13,13 @@ export type { OAuthClientRow, OAuthTokenEndpointAuthMethod } from "../schema.js"
12
13
  export { describeRedirectUri, isAllowedRedirectUri, MAX_CLIENT_NAME_LENGTH, parseClientRegistration, type ClientRegistrationResult, type RegistrationError } from "./oauth-validation.js";
13
14
  export { getCodeChallenge, isPkceVerifierValid, isValidCodeChallenge, PKCE_METHOD } from "./pkce.js";
14
15
  export { getMcpAccessMessages, getMcpAccessOptions, getMcpAccessRoutes, getMcpEndpointUrl, type McpAccessRoutes } from "./options.js";
15
- export { pruneMcpAccess, type PrunedMcpAccessRecords } from "./prune.js";
16
+ export { pruneMcpAccess, pruneOperationTasks, type PrunedMcpAccessRecords } from "./prune.js";
16
17
  export { deleteMcpAccessUserData, exportMcpAccessUserData, mcpAccessPrivacyContributor, type McpAccessUserData, } from "./privacy.js";
17
18
  export { ACCESS_TOKEN_PREFIX, hashAccessToken, isAccessTokenShape, issueAccessToken, listAccessTokens, pruneAccessTokens, findTokenClientName, revokeAccessToken, verifyAccessToken, type IssueAccessTokenInput, type IssueAccessTokenResult, type IssuedAccessToken, type McpAccessContext, type RevokeAccessTokenInput, type VerifiedAccessToken, } from "./tokens.js";
19
+ export { API_RATE_LIMIT_BUCKET, API_TOKEN_RATE_LIMIT_BUCKET, apiTokenErrorResponse, getApiTokenOptions, isApiTokenShape, issueApiToken, requireApiToken, verifyApiToken, type IssueApiTokenInput, type IssueApiTokenResult, type IssuedApiToken, type RequireApiTokenOptions, type VerifiedApiToken, } from "./api-tokens.js";
18
20
  export { createMcpServerFactory, type McpServerFactoryOptions } from "./server-factory.js";
19
21
  export { registerServerInfoTool, SERVER_INFO_TOOL_NAME, type McpBuildInfo, type RegisterServerInfoToolOptions, type ServedServerInfo, type ServerInfoAnswer, type ServerInfoToolOptions, } from "./server-info.js";
20
- export { toStrictToolInput, withStrictToolInput, type StrictToolInputMessages, type StrictToolInputOptions } from "./strict-input.js";
22
+ export { toStrictToolInput, withStrictToolInput, type RenamedFields, type StrictToolInputMessages, type StrictToolInputOptions } from "./strict-input.js";
21
23
  export { DEFAULT_TOOL_LIST_RELEASE, describeToolList, fingerprintToolList, listServedTools, measureToolList, type MeasureToolListOptions, type RegisterTools, type ServedTool, type ToolListMeasurement, } from "./tool-list.js";
22
24
  export { toolError, toolResult, withToolErrors, type ToolCaller, type ToolCallHook, type ToolCallOutcome, type ToolCallRecord, type ToolErrorHints, type ToolErrorOptions, } from "./tools.js";
23
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@
2
2
  // (`{ db, clock, config }`) and never reads request scope; the endpoint takes a Web `Request`.
3
3
  export { createMcpEndpoint, MAX_MCP_REQUEST_BYTES, MCP_RATE_LIMIT_BUCKET, MCP_READ_SCOPE, MCP_WRITE_SCOPE, } from "./endpoint.js";
4
4
  export { actionTool, toFormData } from "./action-tool.js";
5
+ export { CONFIRMATION_FIELD, CONFIRMATION_SECRET_ENV, confirmationInput, DEFAULT_CONFIRMATION_TTL_SECONDS, MIN_CONFIRMATION_SECRET_LENGTH, pruneUsedConfirmations, toCanonicalJson, withConfirmation, } from "./confirmation.js";
5
6
  export { createMcpAccessContext } from "./context.js";
6
7
  export { isWritingEnabled } from "./writes-switch.js";
7
8
  export { checkAccessTokensTable } from "./health.js";
@@ -13,9 +14,10 @@ export { resolveMcpOrigins } from "./origins.js";
13
14
  export { describeRedirectUri, isAllowedRedirectUri, MAX_CLIENT_NAME_LENGTH, parseClientRegistration } from "./oauth-validation.js";
14
15
  export { getCodeChallenge, isPkceVerifierValid, isValidCodeChallenge, PKCE_METHOD } from "./pkce.js";
15
16
  export { getMcpAccessMessages, getMcpAccessOptions, getMcpAccessRoutes, getMcpEndpointUrl } from "./options.js";
16
- export { pruneMcpAccess } from "./prune.js";
17
+ export { pruneMcpAccess, pruneOperationTasks } from "./prune.js";
17
18
  export { deleteMcpAccessUserData, exportMcpAccessUserData, mcpAccessPrivacyContributor, } from "./privacy.js";
18
19
  export { ACCESS_TOKEN_PREFIX, hashAccessToken, isAccessTokenShape, issueAccessToken, listAccessTokens, pruneAccessTokens, findTokenClientName, revokeAccessToken, verifyAccessToken, } from "./tokens.js";
20
+ export { API_RATE_LIMIT_BUCKET, API_TOKEN_RATE_LIMIT_BUCKET, apiTokenErrorResponse, getApiTokenOptions, isApiTokenShape, issueApiToken, requireApiToken, verifyApiToken, } from "./api-tokens.js";
19
21
  export { createMcpServerFactory } from "./server-factory.js";
20
22
  export { registerServerInfoTool, SERVER_INFO_TOOL_NAME, } from "./server-info.js";
21
23
  export { toStrictToolInput, withStrictToolInput } from "./strict-input.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,+FAA+F;AAC/F,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,EACd,eAAe,GAIhB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAkD,MAAM,kBAAkB,CAAC;AAC1G,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EACL,uBAAuB,EACvB,4BAA4B,EAC5B,wBAAwB,EACxB,+BAA+B,EAC/B,sBAAsB,GAGvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,EACvB,yBAAyB,EACzB,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,GASjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,kCAAkC,EAClC,mBAAmB,EACnB,8BAA8B,EAC9B,cAAc,EACd,cAAc,EACd,4BAA4B,EAC5B,+BAA+B,EAC/B,gCAAgC,EAChC,2BAA2B,EAC3B,wBAAwB,EACxB,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,qBAAqB,EACrB,2BAA2B,EAC3B,YAAY,EACZ,gCAAgC,EAChC,uBAAuB,EACvB,sBAAsB,EACtB,4BAA4B,GAK7B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,wBAAwB,EAAE,eAAe,EAAE,iBAAiB,EAA0C,MAAM,eAAe,CAAC;AACrI,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,uBAAuB,EAAyD,MAAM,uBAAuB,CAAC;AAC1L,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACrG,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,iBAAiB,EAAwB,MAAM,cAAc,CAAC;AACtI,OAAO,EAAE,cAAc,EAA+B,MAAM,YAAY,CAAC;AACzE,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,2BAA2B,GAE5B,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,GAOlB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,sBAAsB,EAAgC,MAAM,qBAAqB,CAAC;AAC3F,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GAMtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAA6D,MAAM,mBAAmB,CAAC;AACtI,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,eAAe,GAKhB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,SAAS,EACT,UAAU,EACV,cAAc,GAOf,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,10 @@ import { type ModuleContext, type Ok, type PrivacyContributor } from "@softure-a
3
3
  export interface McpAccessUserData {
4
4
  readonly accessTokens: readonly {
5
5
  readonly name: string;
6
+ /** `mcp` for an assistant, `api` for the app's HTTP routes. */
7
+ readonly kind: "mcp" | "api";
8
+ /** The app scopes of an API token; empty for an MCP token. */
9
+ readonly scopes: readonly string[];
6
10
  readonly canWrite: boolean;
7
11
  readonly createdAt: Date;
8
12
  readonly expiresAt: Date;
@@ -1 +1 @@
1
- {"version":3,"file":"privacy.d.ts","sourceRoot":"","sources":["../../src/server/privacy.ts"],"names":[],"mappings":"AAGA,OAAO,EAAM,KAAK,aAAa,EAAE,KAAK,EAAE,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAK5F,2EAA2E;AAC3E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,YAAY,EAAE,SAAS;QAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;QACzB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;QACzB,QAAQ,CAAC,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;KAClC,EAAE,CAAC;IACJ,+FAA+F;IAC/F,QAAQ,CAAC,aAAa,EAAE,SAAS;QAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;QACzB,QAAQ,CAAC,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;KAClC,EAAE,CAAC;CACL;AAID,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAsBpH;AAED,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAQ5G;AAED,eAAO,MAAM,2BAA2B,EAAE,kBAGzC,CAAC"}
1
+ {"version":3,"file":"privacy.d.ts","sourceRoot":"","sources":["../../src/server/privacy.ts"],"names":[],"mappings":"AAGA,OAAO,EAAM,KAAK,aAAa,EAAE,KAAK,EAAE,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAK5F,2EAA2E;AAC3E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,YAAY,EAAE,SAAS;QAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,+DAA+D;QAC/D,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,KAAK,CAAC;QAC7B,8DAA8D;QAC9D,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;QACnC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;QACzB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;QACzB,QAAQ,CAAC,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;KAClC,EAAE,CAAC;IACJ,+FAA+F;IAC/F,QAAQ,CAAC,aAAa,EAAE,SAAS;QAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;QACzB,QAAQ,CAAC,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;KAClC,EAAE,CAAC;CACL;AAID,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAwBpH;AAED,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAU5G;AAED,eAAO,MAAM,2BAA2B,EAAE,kBAGzC,CAAC"}
@@ -3,7 +3,7 @@
3
3
  // by name before auth deletes the account, so it does not rest on the foreign keys' cascade alone.
4
4
  import { ok } from "@softure-ai/core";
5
5
  import { and, asc, eq, isNull } from "drizzle-orm";
6
- import { accessTokens, oauthAuthorizationCodes, oauthClients, oauthGrants } from "../schema.js";
6
+ import { accessTokens, oauthAuthorizationCodes, oauthClients, oauthGrants, operationTasks } from "../schema.js";
7
7
  const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
8
8
  export async function exportMcpAccessUserData(context, userId) {
9
9
  if (!UUID.test(userId))
@@ -13,6 +13,8 @@ export async function exportMcpAccessUserData(context, userId) {
13
13
  const tokens = await db
14
14
  .select({
15
15
  name: accessTokens.name,
16
+ kind: accessTokens.kind,
17
+ scopes: accessTokens.scopes,
16
18
  canWrite: accessTokens.canWrite,
17
19
  createdAt: accessTokens.createdAt,
18
20
  expiresAt: accessTokens.expiresAt,
@@ -37,6 +39,8 @@ export async function deleteMcpAccessUserData(context, userId) {
37
39
  // A grant's access tokens go with it by cascade; the next line takes the hand-issued ones.
38
40
  await db.delete(oauthGrants).where(eq(oauthGrants.userId, userId));
39
41
  await db.delete(accessTokens).where(eq(accessTokens.userId, userId));
42
+ // MCP tasks hold a job id and dates only, so the export leaves them out; they go with the account.
43
+ await db.delete(operationTasks).where(eq(operationTasks.userId, userId));
40
44
  return ok();
41
45
  }
42
46
  export const mcpAccessPrivacyContributor = {
@@ -1 +1 @@
1
- {"version":3,"file":"privacy.js","sourceRoot":"","sources":["../../src/server/privacy.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,mGAAmG;AACnG,mGAAmG;AACnG,OAAO,EAAE,EAAE,EAAwD,MAAM,kBAAkB,CAAC;AAE5F,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,uBAAuB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAoBhG,MAAM,IAAI,GAAG,iEAAiE,CAAC;AAE/E,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,OAAsB,EAAE,MAAc;IAClF,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC,CAAC;IAC3E,2FAA2F;IAC3F,MAAM,EAAE,GAAG,OAAO,CAAC,EAAe,CAAC;IACnC,MAAM,MAAM,GAAG,MAAM,EAAE;SACpB,MAAM,CAAC;QACN,IAAI,EAAE,YAAY,CAAC,IAAI;QACvB,QAAQ,EAAE,YAAY,CAAC,QAAQ;QAC/B,SAAS,EAAE,YAAY,CAAC,SAAS;QACjC,SAAS,EAAE,YAAY,CAAC,SAAS;QACjC,UAAU,EAAE,YAAY,CAAC,UAAU;KACpC,CAAC;SACD,IAAI,CAAC,YAAY,CAAC;SAClB,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;SACzE,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC;IACxC,MAAM,aAAa,GAAG,MAAM,EAAE;SAC3B,MAAM,CAAC,EAAE,UAAU,EAAE,YAAY,CAAC,UAAU,EAAE,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAAE,SAAS,EAAE,WAAW,CAAC,SAAS,EAAE,UAAU,EAAE,WAAW,CAAC,UAAU,EAAE,CAAC;SACrJ,IAAI,CAAC,WAAW,CAAC;SACjB,SAAS,CAAC,YAAY,EAAE,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC;SAClE,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;SACrC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC;IACvC,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,OAAsB,EAAE,MAAc;IAClF,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,EAAE,CAAC;IACpC,MAAM,EAAE,GAAG,OAAO,CAAC,EAAe,CAAC;IACnC,MAAM,EAAE,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3F,2FAA2F;IAC3F,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnE,MAAM,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACrE,OAAO,EAAE,EAAE,CAAC;AACd,CAAC;AAED,MAAM,CAAC,MAAM,2BAA2B,GAAuB;IAC7D,cAAc,EAAE,uBAAuB;IACvC,cAAc,EAAE,uBAAuB;CACxC,CAAC"}
1
+ {"version":3,"file":"privacy.js","sourceRoot":"","sources":["../../src/server/privacy.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,11 @@ import { type PrunedOAuthRecords } from "./oauth.js";
2
2
  import { type McpAccessContext } from "./tokens.js";
3
3
  export interface PrunedMcpAccessRecords extends PrunedOAuthRecords {
4
4
  readonly accessTokens: number;
5
+ readonly usedConfirmations: number;
6
+ readonly operationTasks: number;
5
7
  }
6
- /** Runs `pruneAccessTokens`, then `pruneOAuthRecords`, and counts what each removed. */
8
+ /** Runs `pruneAccessTokens`, `pruneOAuthRecords`, `pruneUsedConfirmations`, then `pruneOperationTasks`, and counts what each removed. */
7
9
  export declare function pruneMcpAccess(ctx: McpAccessContext): Promise<PrunedMcpAccessRecords>;
10
+ /** Deletes the MCP tasks past their expiry (#977); the operations' jobs stay with `@softure-ai/jobs`. */
11
+ export declare function pruneOperationTasks(ctx: McpAccessContext): Promise<number>;
8
12
  //# sourceMappingURL=prune.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prune.d.ts","sourceRoot":"","sources":["../../src/server/prune.ts"],"names":[],"mappings":"AAEA,OAAO,EAAqB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEvE,MAAM,WAAW,sBAAuB,SAAQ,kBAAkB;IAChE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,wFAAwF;AACxF,wBAAsB,cAAc,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAG3F"}
1
+ {"version":3,"file":"prune.d.ts","sourceRoot":"","sources":["../../src/server/prune.ts"],"names":[],"mappings":"AAKA,OAAO,EAAqB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEvE,MAAM,WAAW,sBAAuB,SAAQ,kBAAkB;IAChE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,yIAAyI;AACzI,wBAAsB,cAAc,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAK3F;AAED,yGAAyG;AACzG,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAGhF"}
@@ -1,10 +1,20 @@
1
- // The module's scheduled cleanup: expired access tokens and dead OAuth records of every account, in
2
- // one call for a daily job (`softure-mcp prune`, a deploy `maintain` hook) instead of inline on requests.
1
+ // The module's scheduled cleanup: expired access tokens, dead OAuth records of every account, used
2
+ // confirmation tokens and MCP tasks past their expiry, in one call for a daily job (`softure-mcp prune`, a deploy `maintain` hook) instead of inline on requests.
3
+ import { lte } from "drizzle-orm";
4
+ import { operationTasks } from "../schema.js";
5
+ import { pruneUsedConfirmations } from "./confirmation.js";
3
6
  import { pruneOAuthRecords } from "./oauth.js";
4
7
  import { pruneAccessTokens } from "./tokens.js";
5
- /** Runs `pruneAccessTokens`, then `pruneOAuthRecords`, and counts what each removed. */
8
+ /** Runs `pruneAccessTokens`, `pruneOAuthRecords`, `pruneUsedConfirmations`, then `pruneOperationTasks`, and counts what each removed. */
6
9
  export async function pruneMcpAccess(ctx) {
7
10
  const accessTokens = await pruneAccessTokens(ctx);
8
- return { accessTokens, ...(await pruneOAuthRecords(ctx)) };
11
+ const oauth = await pruneOAuthRecords(ctx);
12
+ const usedConfirmations = await pruneUsedConfirmations(ctx);
13
+ return { accessTokens, ...oauth, usedConfirmations, operationTasks: await pruneOperationTasks(ctx) };
14
+ }
15
+ /** Deletes the MCP tasks past their expiry (#977); the operations' jobs stay with `@softure-ai/jobs`. */
16
+ export async function pruneOperationTasks(ctx) {
17
+ const removed = await ctx.db.delete(operationTasks).where(lte(operationTasks.expiresAt, ctx.clock.now())).returning({ taskId: operationTasks.taskId });
18
+ return removed.length;
9
19
  }
10
20
  //# sourceMappingURL=prune.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prune.js","sourceRoot":"","sources":["../../src/server/prune.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,0GAA0G;AAC1G,OAAO,EAAE,iBAAiB,EAA2B,MAAM,YAAY,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAyB,MAAM,aAAa,CAAC;AAMvE,wFAAwF;AACxF,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAqB;IACxD,MAAM,YAAY,GAAG,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAClD,OAAO,EAAE,YAAY,EAAE,GAAG,CAAC,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;AAC7D,CAAC"}
1
+ {"version":3,"file":"prune.js","sourceRoot":"","sources":["../../src/server/prune.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,kKAAkK;AAClK,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAA2B,MAAM,YAAY,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAyB,MAAM,aAAa,CAAC;AAQvE,yIAAyI;AACzI,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAqB;IACxD,MAAM,YAAY,GAAG,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAC3C,MAAM,iBAAiB,GAAG,MAAM,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAC5D,OAAO,EAAE,YAAY,EAAE,GAAG,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC,GAAG,CAAC,EAAE,CAAC;AACvG,CAAC;AAED,yGAAyG;AACzG,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,GAAqB;IAC7D,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC;IACvJ,OAAO,OAAO,CAAC,MAAM,CAAC;AACxB,CAAC"}
@@ -2,9 +2,11 @@ import type { McpServer } from "@modelcontextprotocol/server";
2
2
  import { en } from "../messages/en.js";
3
3
  /** The texts of a refused field: `toolInput` of the module dictionary (`getMcpAccessMessages(config).toolInput`). */
4
4
  export type StrictToolInputMessages = typeof en.toolInput;
5
+ /** Old field name → new field name, as a map or a rule (`undefined`: not renamed). */
6
+ export type RenamedFields = Readonly<Record<string, string>> | ((field: string) => string | undefined);
5
7
  export interface StrictToolInputOptions {
6
8
  /** Old field name → new field name, refused as `input.field_renamed` wherever an object accepts the new name. */
7
- readonly renamedFields?: Readonly<Record<string, string>>;
9
+ readonly renamedFields?: RenamedFields;
8
10
  /** Boolean fields also take `"true"`/`"false"` and number fields a number written as text. Default: `true`. */
9
11
  readonly coerceTextScalars?: boolean;
10
12
  /** Default: the module's English dictionary. */
@@ -1 +1 @@
1
- {"version":3,"file":"strict-input.d.ts","sourceRoot":"","sources":["../../src/server/strict-input.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAI9D,OAAO,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AAEvC,qHAAqH;AACrH,MAAM,MAAM,uBAAuB,GAAG,OAAO,EAAE,CAAC,SAAS,CAAC;AAE1D,MAAM,WAAW,sBAAsB;IACrC,iHAAiH;IACjH,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1D,+GAA+G;IAC/G,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IACrC,gDAAgD;IAChD,QAAQ,CAAC,QAAQ,CAAC,EAAE,uBAAuB,CAAC;CAC7C;AAUD,6GAA6G;AAC7G,wBAAgB,mBAAmB,CAAC,MAAM,SAAS,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B,GAAG,MAAM,CAS1H;AAED,0HAA0H;AAC1H,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAShG"}
1
+ {"version":3,"file":"strict-input.d.ts","sourceRoot":"","sources":["../../src/server/strict-input.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAI9D,OAAO,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AAEvC,qHAAqH;AACrH,MAAM,MAAM,uBAAuB,GAAG,OAAO,EAAE,CAAC,SAAS,CAAC;AAE1D,sFAAsF;AACtF,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC;AAEvG,MAAM,WAAW,sBAAsB;IACrC,iHAAiH;IACjH,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;IACvC,+GAA+G;IAC/G,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IACrC,gDAAgD;IAChD,QAAQ,CAAC,QAAQ,CAAC,EAAE,uBAAuB,CAAC;CAC7C;AAWD,6GAA6G;AAC7G,wBAAgB,mBAAmB,CAAC,MAAM,SAAS,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B,GAAG,MAAM,CAc1H;AAED,0HAA0H;AAC1H,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAShG"}
@@ -10,7 +10,14 @@ export function withStrictToolInput(server, options = {}) {
10
10
  return server;
11
11
  // The SDK's overloads only differ in how the schema is typed; at runtime it is one method.
12
12
  const register = server.registerTool.bind(server);
13
- const registerStrict = (name, config, callback) => register(name, config.inputSchema === undefined ? config : { ...config, inputSchema: toStrictToolInput(config.inputSchema, options) }, callback);
13
+ const registerStrict = (name, config, callback) => {
14
+ if (config.inputSchema !== undefined)
15
+ return register(name, { ...config, inputSchema: toStrictToolInput(config.inputSchema, options) }, callback);
16
+ // Without a schema the SDK skips validation and calls `callback(ctx)`; with the strict empty object it calls
17
+ // `callback(args, ctx)`, so the callback keeps receiving the context only.
18
+ const contextCallback = callback;
19
+ return register(name, { ...config, inputSchema: toStrictToolInput(z.object({}), options) }, (_args, ctx) => contextCallback(ctx));
20
+ };
14
21
  Object.defineProperty(server, "registerTool", { value: registerStrict, configurable: true, writable: true });
15
22
  strictServers.add(server);
16
23
  return server;
@@ -21,7 +28,7 @@ export function toStrictToolInput(schema, options = {}) {
21
28
  if (zodSchema === null)
22
29
  return schema;
23
30
  const rewriter = new StrictRewriter({
24
- renamedFields: options.renamedFields ?? {},
31
+ renameField: toRenameRule(options.renamedFields ?? {}),
25
32
  coerceTextScalars: options.coerceTextScalars ?? true,
26
33
  messages: options.messages ?? en.toolInput,
27
34
  });
@@ -35,6 +42,13 @@ function isRawShape(value) {
35
42
  return false;
36
43
  return Object.values(value).every(isZodSchema);
37
44
  }
45
+ function toRenameRule(renamedFields) {
46
+ if (typeof renamedFields === "function")
47
+ return renamedFields;
48
+ return (field) => (Object.hasOwn(renamedFields, field) ? renamedFields[field] : undefined);
49
+ }
50
+ /** Wrappers that keep the value's kind: a chain of them around a scalar takes the text step around the whole chain. */
51
+ const WRAPPER_TYPES = new Set(["optional", "nullable", "default", "prefault", "nonoptional", "readonly", "catch"]);
38
52
  class StrictRewriter {
39
53
  settings;
40
54
  // The same node (a shared field, a recursive `z.lazy`) is rewritten once.
@@ -63,8 +77,14 @@ class StrictRewriter {
63
77
  case "prefault":
64
78
  case "nonoptional":
65
79
  case "readonly":
66
- case "catch":
80
+ case "catch": {
81
+ // Outside the chain, zod still lists its `default` (it drops one on a transforming node) and the field's
82
+ // optionality is the chain's own; the step passes `undefined` and `null` through to it.
83
+ const reader = this.findTextReader(schema);
84
+ if (reader !== undefined)
85
+ return withTextStep(reader, schema);
67
86
  return this.cloneWith(schema, { innerType: this.rewrite(def.innerType) });
87
+ }
68
88
  case "union":
69
89
  return this.cloneWith(schema, { options: def.options.map((option) => this.rewrite(option)) });
70
90
  case "intersection":
@@ -83,13 +103,29 @@ class StrictRewriter {
83
103
  return this.cloneWith(schema, { getter: () => this.rewrite(getter()) });
84
104
  }
85
105
  case "boolean":
86
- return this.settings.coerceTextScalars && def.coerce !== true ? z.preprocess(readBooleanText, schema) : schema;
87
- case "number":
88
- return this.settings.coerceTextScalars && def.coerce !== true ? z.preprocess(readNumberText, schema) : schema;
106
+ case "number": {
107
+ const reader = this.findTextReader(schema);
108
+ return reader === undefined ? schema : withTextStep(reader, schema);
109
+ }
89
110
  default:
90
111
  return schema;
91
112
  }
92
113
  }
114
+ /** The text reader for a boolean or number, seen through its wrapper chain; none when text is not taken. */
115
+ findTextReader(schema) {
116
+ if (!this.settings.coerceTextScalars)
117
+ return undefined;
118
+ let def = schema._zod.def;
119
+ while (WRAPPER_TYPES.has(def.type))
120
+ def = def.innerType._zod.def;
121
+ if (def.coerce === true)
122
+ return undefined;
123
+ if (def.type === "boolean")
124
+ return readBooleanText;
125
+ if (def.type === "number")
126
+ return readNumberText;
127
+ return undefined;
128
+ }
93
129
  /** Only the input side: `in`, or `out` after a preprocess (whose `in` is the transform). */
94
130
  rewritePipe(schema, def) {
95
131
  const input = def.in;
@@ -126,11 +162,11 @@ class StrictRewriter {
126
162
  function describeUnknownFields(issue, accepted, settings) {
127
163
  if (issue.code !== "unrecognized_keys")
128
164
  return undefined;
129
- const { messages, renamedFields } = settings;
165
+ const { messages, renameField } = settings;
130
166
  const renamed = [];
131
167
  const unknown = [];
132
168
  for (const field of issue.keys) {
133
- const newName = Object.hasOwn(renamedFields, field) ? renamedFields[field] : undefined;
169
+ const newName = renameField(field);
134
170
  if (newName !== undefined && accepted.includes(newName))
135
171
  renamed.push(formatMessage(messages.fieldRenamed, { field, renamed: newName }));
136
172
  else
@@ -144,6 +180,16 @@ function describeUnknownFields(issue, accepted, settings) {
144
180
  function quoteAll(names) {
145
181
  return names.map((name) => JSON.stringify(name)).join(", ");
146
182
  }
183
+ /**
184
+ * `schema` behind a text step. zod gives every transform an optional input, so a step would make a required field
185
+ * look optional in the listed JSON Schema inside `nullable` or a union; it takes the optionality of the schema it
186
+ * wraps instead. That changes no parse: the step passes `undefined` on, and the schema refuses it as before.
187
+ */
188
+ function withTextStep(reader, schema) {
189
+ const step = z.preprocess(reader, schema);
190
+ Object.defineProperty(step._zod, "optin", { value: schema._zod.optin, configurable: true, writable: true });
191
+ return step;
192
+ }
147
193
  function readBooleanText(value) {
148
194
  if (value === "true")
149
195
  return true;
@@ -1 +1 @@
1
- {"version":3,"file":"strict-input.js","sourceRoot":"","sources":["../../src/server/strict-input.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AAcvC,+DAA+D;AAC/D,MAAM,WAAW,GAAG,+CAA+C,CAAC;AAEpE,MAAM,aAAa,GAAG,IAAI,OAAO,EAAa,CAAC;AAK/C,6GAA6G;AAC7G,MAAM,UAAU,mBAAmB,CAA2B,MAAc,EAAE,UAAkC,EAAE;IAChH,IAAI,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAC7C,2FAA2F;IAC3F,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAA4B,CAAC;IAC7E,MAAM,cAAc,GAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,CAC9D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,iBAAiB,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;IACnJ,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7G,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,0HAA0H;AAC1H,MAAM,UAAU,iBAAiB,CAAC,MAAe,EAAE,UAAkC,EAAE;IACrF,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9F,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IACtC,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC;QAClC,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,EAAE;QAC1C,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,IAAI,IAAI;QACpD,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,SAAS;KAC3C,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK,CAAC;AACxE,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IACnH,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AACjD,CAAC;AAOD,MAAM,cAAc;IAIW;IAH7B,0EAA0E;IACzD,SAAS,GAAG,IAAI,GAAG,EAAgC,CAAC;IAErE,YAA6B,QAAyB;QAAzB,aAAQ,GAAR,QAAQ,CAAiB;IAAG,CAAC;IAE1D,OAAO,CAAC,MAAqB;QAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QACtC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,WAAW,CAAC,MAAqB;QACvC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAa,CAAC;QACtC,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;YACjB,KAAK,QAAQ;gBACX,OAAO,IAAI,CAAC,aAAa,CAAC,MAAyB,CAAC,CAAC;YACvD,KAAK,OAAO;gBACV,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAwB,CAAC,EAAE,CAAC,CAAC;YACzF,KAAK,UAAU,CAAC;YAChB,KAAK,UAAU,CAAC;YAChB,KAAK,SAAS,CAAC;YACf,KAAK,UAAU,CAAC;YAChB,KAAK,aAAa,CAAC;YACnB,KAAK,UAAU,CAAC;YAChB,KAAK,OAAO;gBACV,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAA0B,CAAC,EAAE,CAAC,CAAC;YAC7F,KAAK,OAAO;gBACV,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,OAAO,EAAG,GAAG,CAAC,OAA2B,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;YACrH,KAAK,cAAc;gBACjB,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAqB,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAsB,CAAC,EAAE,CAAC,CAAC;YACpI,KAAK,QAAQ;gBACX,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAA0B,CAAC,EAAE,CAAC,CAAC;YAC7F,KAAK,OAAO;gBACV,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE;oBAC5B,KAAK,EAAG,GAAG,CAAC,KAAyB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;oBACvE,IAAI,EAAE,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAqB,CAAC;iBACzE,CAAC,CAAC;YACL,KAAK,MAAM;gBACT,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YACvC,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,MAAM,MAAM,GAAG,GAAG,CAAC,MAA6B,CAAC;gBACjD,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;YAC1E,CAAC;YACD,KAAK,SAAS;gBACZ,OAAO,IAAI,CAAC,QAAQ,CAAC,iBAAiB,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACjH,KAAK,QAAQ;gBACX,OAAO,IAAI,CAAC,QAAQ,CAAC,iBAAiB,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAChH;gBACE,OAAO,MAAM,CAAC;QAClB,CAAC;IACH,CAAC;IAED,4FAA4F;IACpF,WAAW,CAAC,MAAqB,EAAE,GAAW;QACpD,MAAM,KAAK,GAAG,GAAG,CAAC,EAAmB,CAAC;QACtC,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC;YAAE,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAoB,CAAC,EAAE,CAAC,CAAC;QAC3H,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC7D,CAAC;IAEO,aAAa,CAAC,MAAuB;QAC3C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QAC5B,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAChH,mGAAmG;QACnG,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,OAAO;YAAE,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACnH,2GAA2G;QAC3G,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAsC,CAAC;QAC5D,MAAM,QAAQ,GAAG,CAAC,KAAwB,EAAsB,EAAE,CAAC,qBAAqB,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnI,MAAM,KAAK,GAAsB,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC;QACjF,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,oGAAoG;IAC5F,SAAS,CAAC,MAAqB,EAAE,KAA8B;QACrE,MAAM,IAAI,GAAI,MAA+B,CAAC,KAAK,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;QACtF,MAAM,IAAI,GAAG,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,kHAAkH;YAClH,MAAM,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC,EAAE,CAAC;YACf,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,6GAA6G;AAC7G,SAAS,qBAAqB,CAAC,KAAwB,EAAE,QAA2B,EAAE,QAAyB;IAC7G,IAAI,KAAK,CAAC,IAAI,KAAK,mBAAmB;QAAE,OAAO,SAAS,CAAC;IACzD,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,GAAG,QAAQ,CAAC;IAC7C,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACvF,IAAI,OAAO,KAAK,SAAS,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;;YACpI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAC7J,CAAC;IACD,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3B,CAAC;AAED,SAAS,QAAQ,CAAC,KAAwB;IACxC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAClC,IAAI,KAAK,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IACpC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACpC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AACtF,CAAC"}
1
+ {"version":3,"file":"strict-input.js","sourceRoot":"","sources":["../../src/server/strict-input.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { type Err, type ModuleContext, type Ok } from "@softure-ai/core";
2
2
  import type { Queryable } from "@softure-ai/db";
3
- import type { AccessTokenView } from "../contract.js";
3
+ import type { AccessTokenKind, AccessTokenView } from "../contract.js";
4
4
  export type McpAccessContext = ModuleContext<Queryable>;
5
5
  /** Marks a token as this module's, for people and for secret scanners. */
6
6
  export declare const ACCESS_TOKEN_PREFIX = "sftmcp_";
@@ -29,15 +29,36 @@ export interface IssuedAccessToken {
29
29
  }
30
30
  export type IssueAccessTokenResult = Ok<IssuedAccessToken> | Err<"mcp-access.name_required" | "mcp-access.name_too_long" | "mcp-access.token_limit_reached">;
31
31
  /**
32
- * Issues a token for its owner. The per-account limit counts unexpired tokens, in one transaction
33
- * that holds a per-user advisory lock, so two parallel requests cannot both take the last place.
34
- * The owner's expired tokens are deleted first: they would otherwise count against the limit.
32
+ * Issues an MCP token for its owner. The per-account limit counts unexpired tokens of both kinds, in one
33
+ * transaction that holds a per-user advisory lock, so two parallel requests cannot both take the last
34
+ * place. The owner's expired tokens are deleted first: they would otherwise count against the limit.
35
35
  * Database failures propagate.
36
36
  */
37
37
  export declare function issueAccessToken(ctx: McpAccessContext, input: IssueAccessTokenInput): Promise<IssueAccessTokenResult>;
38
+ /** What `insertToken` stores: the new secret with its hash, write access and scopes are already decided. */
39
+ export interface TokenInsert {
40
+ readonly userId: string;
41
+ readonly name: string;
42
+ readonly kind: AccessTokenKind;
43
+ readonly canWrite: boolean;
44
+ readonly scopes: readonly string[];
45
+ /** The plaintext and the hash the lookup will find it by (`createSecret`, or the API token's own). */
46
+ readonly secret: {
47
+ readonly secret: string;
48
+ readonly secretHash: string;
49
+ };
50
+ }
51
+ export type InsertTokenResult = Ok<{
52
+ readonly id: string;
53
+ readonly token: string;
54
+ readonly name: string;
55
+ readonly expiresAt: Date;
56
+ }> | Err<"mcp-access.name_required" | "mcp-access.name_too_long" | "mcp-access.token_limit_reached">;
57
+ /** Stores a new token of either kind under the owner's lock and limit; the plaintext is returned once. */
58
+ export declare function insertToken(ctx: McpAccessContext, input: TokenInsert): Promise<InsertTokenResult>;
38
59
  /**
39
- * The owner's hand-issued tokens, newest first, expired ones included (the list marks them).
40
- * OAuth access tokens are left out: the page shows their grants instead.
60
+ * The owner's hand-issued tokens of both kinds, newest first, expired ones included (the list marks
61
+ * them). OAuth access tokens are left out: the page shows their grants instead.
41
62
  */
42
63
  export declare function listAccessTokens(ctx: McpAccessContext, userId: string): Promise<AccessTokenView[]>;
43
64
  export interface RevokeAccessTokenInput {
@@ -68,14 +89,28 @@ export interface VerifiedAccessToken {
68
89
  */
69
90
  export declare function findTokenClientName(ctx: McpAccessContext, tokenId: string): Promise<string | null>;
70
91
  /**
71
- * The identity behind a token, or null for anything unknown, revoked or expired: the caller cannot
72
- * tell which, so a guess learns nothing. The expiry sits in the query, so no code path can forget
73
- * it. Records the use (at most once a minute per token); a failed record is logged and does not
74
- * fail the request. Database failures of the lookup propagate.
92
+ * The identity behind an MCP token, or null for anything unknown, revoked or expired, and for an API
93
+ * token: the caller cannot tell which, so a guess learns nothing. The expiry sits in the query, so no
94
+ * code path can forget it. Records the use (at most once a minute per token); a failed record is
95
+ * logged and does not fail the request. Database failures of the lookup propagate.
75
96
  */
76
97
  export declare function verifyAccessToken(ctx: McpAccessContext, token: string): Promise<VerifiedAccessToken | null>;
98
+ /** A stored, unexpired token of one kind, found by the hash of its plaintext. */
99
+ export interface ValidTokenRow {
100
+ readonly id: string;
101
+ readonly userId: string;
102
+ readonly canWrite: boolean;
103
+ readonly expiresAt: Date;
104
+ readonly grantId: string | null;
105
+ readonly scopes: readonly string[];
106
+ }
107
+ /**
108
+ * The unexpired token of `kind` stored under this hash, or null, after recording its use. The caller
109
+ * checks the shape first, so no lookup runs for a value that cannot be a token.
110
+ */
111
+ export declare function findValidToken(ctx: McpAccessContext, tokenHash: string, kind: AccessTokenKind): Promise<ValidTokenRow | null>;
77
112
  /**
78
- * Deletes every expired token, of every account, hand-issued and OAuth alike. Issuing already
113
+ * Deletes every expired token, of every account and kind, hand-issued and OAuth alike. Issuing already
79
114
  * removes the issuer's own; an app may call this from a scheduled job so abandoned accounts do not
80
115
  * keep dead rows (with `pruneOAuthRecords` for codes, grants and clients).
81
116
  */
@@ -1 +1 @@
1
- {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/server/tokens.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/server/tokens.ts"],"names":[],"mappings":"AAIA,OAAO,EAA0B,KAAK,GAAG,EAAE,KAAK,aAAa,EAAE,KAAK,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACjG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAKvE,MAAM,MAAM,gBAAgB,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;AAExD,0EAA0E;AAC1E,eAAO,MAAM,mBAAmB,YAAY,CAAC;AAU7C,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,8DAA8D;AAC9D,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEzD;AAYD,qGAAqG;AACrG,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAGrG;AAED,MAAM,WAAW,qBAAqB;IACpC,uDAAuD;IACvD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;CAC1B;AAED,MAAM,MAAM,sBAAsB,GAC9B,EAAE,CAAC,iBAAiB,CAAC,GACrB,GAAG,CAAC,0BAA0B,GAAG,0BAA0B,GAAG,gCAAgC,CAAC,CAAC;AAEpG;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,EAAE,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAO3H;AAED,4GAA4G;AAC5G,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,sGAAsG;IACtG,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3E;AAED,MAAM,MAAM,iBAAiB,GACzB,EAAE,CAAC;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAA;CAAE,CAAC,GACpG,GAAG,CAAC,0BAA0B,GAAG,0BAA0B,GAAG,gCAAgC,CAAC,CAAC;AAEpG,0GAA0G;AAC1G,wBAAsB,WAAW,CAAC,GAAG,EAAE,gBAAgB,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA2BvG;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAexG;AAED,MAAM,WAAW,sBAAsB;IACrC,mCAAmC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,sEAAsE;IACtE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,gBAAgB,EACrB,KAAK,EAAE,sBAAsB,GAC5B,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC,4BAA4B,CAAC,CAAC,CAO5D;AAED,yCAAyC;AACzC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,2FAA2F;IAC3F,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAIxG;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAYjH;AAED,iFAAiF;AACjF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAgBnI;AAsBD;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAM9E"}
@@ -1,5 +1,5 @@
1
- // Access tokens (an adopting app's token code, generalised). A token is `sftmcp_` and 32 random
2
- // bytes; the database holds only its sha256, so a leaked row cannot be replayed. The plaintext
1
+ // Access tokens (an adopting app's token code, generalised). An MCP token is `sftmcp_` and 32 random
2
+ // bytes, an API token (`api-tokens.ts`) the app's prefix and 32 random bytes; the database holds only its sha256, so a leaked row cannot be replayed. The plaintext
3
3
  // leaves this file once, in the result of `issueAccessToken` (or of an OAuth exchange, `oauth.ts`).
4
4
  import { createHash, randomBytes } from "node:crypto";
5
5
  import { err, errorLogLabel, ok } from "@softure-ai/core";
@@ -39,19 +39,28 @@ export function createSecret(prefix) {
39
39
  return { secret, secretHash: hashAccessToken(secret) };
40
40
  }
41
41
  /**
42
- * Issues a token for its owner. The per-account limit counts unexpired tokens, in one transaction
43
- * that holds a per-user advisory lock, so two parallel requests cannot both take the last place.
44
- * The owner's expired tokens are deleted first: they would otherwise count against the limit.
42
+ * Issues an MCP token for its owner. The per-account limit counts unexpired tokens of both kinds, in one
43
+ * transaction that holds a per-user advisory lock, so two parallel requests cannot both take the last
44
+ * place. The owner's expired tokens are deleted first: they would otherwise count against the limit.
45
45
  * Database failures propagate.
46
46
  */
47
47
  export async function issueAccessToken(ctx, input) {
48
+ const options = getMcpAccessOptions(ctx.config);
49
+ const canWrite = input.canWrite && options.allowWrites;
50
+ const result = await insertToken(ctx, { userId: input.userId, name: input.name, kind: "mcp", canWrite, scopes: [], secret: createSecret(ACCESS_TOKEN_PREFIX) });
51
+ if (!result.ok)
52
+ return result;
53
+ const { id, token, name, expiresAt } = result.value;
54
+ return ok({ id, token, name, canWrite, expiresAt });
55
+ }
56
+ /** Stores a new token of either kind under the owner's lock and limit; the plaintext is returned once. */
57
+ export async function insertToken(ctx, input) {
48
58
  const name = input.name.trim();
49
59
  if (name === "")
50
60
  return err("mcp-access.name_required");
51
61
  if (name.length > MAX_TOKEN_NAME_LENGTH)
52
62
  return err("mcp-access.name_too_long");
53
63
  const options = getMcpAccessOptions(ctx.config);
54
- const canWrite = input.canWrite && options.allowWrites;
55
64
  const now = ctx.clock.now();
56
65
  const expiresAt = new Date(now.getTime() + options.tokenLifetimeDays * DAY_MS);
57
66
  return ctx.db.transaction(async (tx) => {
@@ -64,25 +73,27 @@ export async function issueAccessToken(ctx, input) {
64
73
  .where(and(eq(accessTokens.userId, input.userId), isNull(accessTokens.grantId)));
65
74
  if ((held?.total ?? 0) >= options.maxTokensPerUser)
66
75
  return err("mcp-access.token_limit_reached");
67
- const { secret: token, secretHash: tokenHash } = createSecret(ACCESS_TOKEN_PREFIX);
76
+ const { secret: token, secretHash: tokenHash } = input.secret;
68
77
  const [row] = await tx
69
78
  .insert(accessTokens)
70
- .values({ userId: input.userId, name, tokenHash, canWrite, createdAt: now, expiresAt })
79
+ .values({ userId: input.userId, name, tokenHash, canWrite: input.canWrite, createdAt: now, expiresAt, kind: input.kind, scopes: [...input.scopes] })
71
80
  .returning();
72
81
  if (row === undefined)
73
82
  throw new Error("@softure-ai/mcp-access: inserting a token returned no row");
74
- return ok({ id: row.id, token, name, canWrite, expiresAt });
83
+ return ok({ id: row.id, token, name, expiresAt });
75
84
  });
76
85
  }
77
86
  /**
78
- * The owner's hand-issued tokens, newest first, expired ones included (the list marks them).
79
- * OAuth access tokens are left out: the page shows their grants instead.
87
+ * The owner's hand-issued tokens of both kinds, newest first, expired ones included (the list marks
88
+ * them). OAuth access tokens are left out: the page shows their grants instead.
80
89
  */
81
90
  export async function listAccessTokens(ctx, userId) {
82
91
  return ctx.db
83
92
  .select({
84
93
  id: accessTokens.id,
85
94
  name: accessTokens.name,
95
+ kind: accessTokens.kind,
96
+ scopes: accessTokens.scopes,
86
97
  canWrite: accessTokens.canWrite,
87
98
  createdAt: accessTokens.createdAt,
88
99
  expiresAt: accessTokens.expiresAt,
@@ -117,15 +128,31 @@ export async function findTokenClientName(ctx, tokenId) {
117
128
  return row?.name ?? null;
118
129
  }
119
130
  /**
120
- * The identity behind a token, or null for anything unknown, revoked or expired: the caller cannot
121
- * tell which, so a guess learns nothing. The expiry sits in the query, so no code path can forget
122
- * it. Records the use (at most once a minute per token); a failed record is logged and does not
123
- * fail the request. Database failures of the lookup propagate.
131
+ * The identity behind an MCP token, or null for anything unknown, revoked or expired, and for an API
132
+ * token: the caller cannot tell which, so a guess learns nothing. The expiry sits in the query, so no
133
+ * code path can forget it. Records the use (at most once a minute per token); a failed record is
134
+ * logged and does not fail the request. Database failures of the lookup propagate.
124
135
  */
125
136
  export async function verifyAccessToken(ctx, token) {
126
137
  const options = getMcpAccessOptions(ctx.config);
127
138
  if (!isAcceptedTokenShape(options, token))
128
139
  return null;
140
+ const row = await findValidToken(ctx, hashAccessToken(token), "mcp");
141
+ if (row === null)
142
+ return null;
143
+ return {
144
+ tokenId: row.id,
145
+ userId: row.userId,
146
+ canWrite: row.canWrite && options.allowWrites,
147
+ expiresAt: row.expiresAt,
148
+ grantId: row.grantId,
149
+ };
150
+ }
151
+ /**
152
+ * The unexpired token of `kind` stored under this hash, or null, after recording its use. The caller
153
+ * checks the shape first, so no lookup runs for a value that cannot be a token.
154
+ */
155
+ export async function findValidToken(ctx, tokenHash, kind) {
129
156
  const now = ctx.clock.now();
130
157
  const [row] = await ctx.db
131
158
  .select({
@@ -134,19 +161,14 @@ export async function verifyAccessToken(ctx, token) {
134
161
  canWrite: accessTokens.canWrite,
135
162
  expiresAt: accessTokens.expiresAt,
136
163
  grantId: accessTokens.grantId,
164
+ scopes: accessTokens.scopes,
137
165
  })
138
166
  .from(accessTokens)
139
- .where(and(eq(accessTokens.tokenHash, hashAccessToken(token)), gt(accessTokens.expiresAt, now)));
167
+ .where(and(eq(accessTokens.tokenHash, tokenHash), eq(accessTokens.kind, kind), gt(accessTokens.expiresAt, now)));
140
168
  if (row === undefined)
141
169
  return null;
142
170
  await recordUse(ctx, row, now);
143
- return {
144
- tokenId: row.id,
145
- userId: row.userId,
146
- canWrite: row.canWrite && options.allowWrites,
147
- expiresAt: row.expiresAt,
148
- grantId: row.grantId,
149
- };
171
+ return row;
150
172
  }
151
173
  /** Records the use on the token and, for an OAuth token, on its grant (the connected apps list). */
152
174
  async function recordUse(ctx, token, now) {
@@ -169,7 +191,7 @@ async function recordUse(ctx, token, now) {
169
191
  }
170
192
  }
171
193
  /**
172
- * Deletes every expired token, of every account, hand-issued and OAuth alike. Issuing already
194
+ * Deletes every expired token, of every account and kind, hand-issued and OAuth alike. Issuing already
173
195
  * removes the issuer's own; an app may call this from a scheduled job so abandoned accounts do not
174
196
  * keep dead rows (with `pruneOAuthRecords` for codes, grants and clients).
175
197
  */