@n24q02m/hull 0.4.0 → 0.5.0-beta.2

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 (169) hide show
  1. package/README.md +47 -16
  2. package/build/cli/build-cli.d.ts +5 -6
  3. package/build/cli/build-cli.d.ts.map +1 -1
  4. package/build/cli/build-cli.js +4 -61
  5. package/build/cli/build-cli.js.map +1 -1
  6. package/build/crypto/index.d.ts +1 -1
  7. package/build/crypto/index.d.ts.map +1 -1
  8. package/build/crypto/index.js +1 -1
  9. package/build/crypto/index.js.map +1 -1
  10. package/build/crypto/kdf.d.ts +0 -13
  11. package/build/crypto/kdf.d.ts.map +1 -1
  12. package/build/crypto/kdf.js +3 -18
  13. package/build/crypto/kdf.js.map +1 -1
  14. package/build/index.d.ts +1 -11
  15. package/build/index.d.ts.map +1 -1
  16. package/build/index.js +4 -16
  17. package/build/index.js.map +1 -1
  18. package/build/storage/account-registry.d.ts +53 -0
  19. package/build/storage/account-registry.d.ts.map +1 -0
  20. package/build/storage/account-registry.js +148 -0
  21. package/build/storage/account-registry.js.map +1 -0
  22. package/build/storage/backends.d.ts +0 -26
  23. package/build/storage/backends.d.ts.map +1 -1
  24. package/build/storage/backends.js +0 -65
  25. package/build/storage/backends.js.map +1 -1
  26. package/build/storage/config-file.d.ts +2 -19
  27. package/build/storage/config-file.d.ts.map +1 -1
  28. package/build/storage/config-file.js +2 -23
  29. package/build/storage/config-file.js.map +1 -1
  30. package/build/storage/credential-store.d.ts +1 -9
  31. package/build/storage/credential-store.d.ts.map +1 -1
  32. package/build/storage/credential-store.js +4 -16
  33. package/build/storage/credential-store.js.map +1 -1
  34. package/build/storage/data-dir.d.ts +2 -2
  35. package/build/storage/data-dir.js +2 -2
  36. package/build/storage/encryption.d.ts.map +1 -1
  37. package/build/storage/encryption.js +4 -0
  38. package/build/storage/encryption.js.map +1 -1
  39. package/build/storage/index.d.ts +5 -3
  40. package/build/storage/index.d.ts.map +1 -1
  41. package/build/storage/index.js +5 -3
  42. package/build/storage/index.js.map +1 -1
  43. package/build/storage/key-pool-crypto.d.ts +44 -0
  44. package/build/storage/key-pool-crypto.d.ts.map +1 -0
  45. package/build/storage/key-pool-crypto.js +132 -0
  46. package/build/storage/key-pool-crypto.js.map +1 -0
  47. package/build/storage/key-pool-store.d.ts +134 -0
  48. package/build/storage/key-pool-store.d.ts.map +1 -0
  49. package/build/storage/key-pool-store.js +470 -0
  50. package/build/storage/key-pool-store.js.map +1 -0
  51. package/build/storage/key-pool.d.ts +172 -0
  52. package/build/storage/key-pool.d.ts.map +1 -0
  53. package/build/storage/key-pool.js +374 -0
  54. package/build/storage/key-pool.js.map +1 -0
  55. package/build/storage/resolver.js +1 -1
  56. package/build/storage/resolver.js.map +1 -1
  57. package/build/token-auth/index.d.ts +1 -1
  58. package/build/token-auth/index.js +1 -1
  59. package/build/transport/index.d.ts +1 -2
  60. package/build/transport/index.d.ts.map +1 -1
  61. package/build/transport/index.js +1 -2
  62. package/build/transport/index.js.map +1 -1
  63. package/build/transport/local-server.d.ts +12 -128
  64. package/build/transport/local-server.d.ts.map +1 -1
  65. package/build/transport/local-server.js +20 -262
  66. package/build/transport/local-server.js.map +1 -1
  67. package/build/transport/streamable-http.d.ts +6 -7
  68. package/build/transport/streamable-http.d.ts.map +1 -1
  69. package/build/transport/streamable-http.js +6 -6
  70. package/build/transport/streamable-http.js.map +1 -1
  71. package/build/util/browser.d.ts.map +1 -0
  72. package/build/{relay → util}/browser.js +2 -2
  73. package/build/util/browser.js.map +1 -0
  74. package/package.json +4 -21
  75. package/build/auth/credential-form.d.ts +0 -163
  76. package/build/auth/credential-form.d.ts.map +0 -1
  77. package/build/auth/credential-form.js +0 -1869
  78. package/build/auth/credential-form.js.map +0 -1
  79. package/build/auth/delegated-oauth-app.d.ts +0 -90
  80. package/build/auth/delegated-oauth-app.d.ts.map +0 -1
  81. package/build/auth/delegated-oauth-app.js +0 -881
  82. package/build/auth/delegated-oauth-app.js.map +0 -1
  83. package/build/auth/index.d.ts +0 -12
  84. package/build/auth/index.d.ts.map +0 -1
  85. package/build/auth/index.js +0 -12
  86. package/build/auth/index.js.map +0 -1
  87. package/build/auth/local-oauth-app.d.ts +0 -152
  88. package/build/auth/local-oauth-app.d.ts.map +0 -1
  89. package/build/auth/local-oauth-app.js +0 -975
  90. package/build/auth/local-oauth-app.js.map +0 -1
  91. package/build/auth/relay-login.d.ts +0 -46
  92. package/build/auth/relay-login.d.ts.map +0 -1
  93. package/build/auth/relay-login.js +0 -197
  94. package/build/auth/relay-login.js.map +0 -1
  95. package/build/auth/router.d.ts +0 -18
  96. package/build/auth/router.d.ts.map +0 -1
  97. package/build/auth/router.js +0 -62
  98. package/build/auth/router.js.map +0 -1
  99. package/build/auth/session-store.d.ts +0 -49
  100. package/build/auth/session-store.d.ts.map +0 -1
  101. package/build/auth/session-store.js +0 -94
  102. package/build/auth/session-store.js.map +0 -1
  103. package/build/auth/stable-sub.d.ts +0 -27
  104. package/build/auth/stable-sub.d.ts.map +0 -1
  105. package/build/auth/stable-sub.js +0 -38
  106. package/build/auth/stable-sub.js.map +0 -1
  107. package/build/auth/well-known.d.ts +0 -4
  108. package/build/auth/well-known.d.ts.map +0 -1
  109. package/build/auth/well-known.js +0 -26
  110. package/build/auth/well-known.js.map +0 -1
  111. package/build/oauth/cache.d.ts +0 -22
  112. package/build/oauth/cache.d.ts.map +0 -1
  113. package/build/oauth/cache.js +0 -24
  114. package/build/oauth/cache.js.map +0 -1
  115. package/build/oauth/index.d.ts +0 -6
  116. package/build/oauth/index.d.ts.map +0 -1
  117. package/build/oauth/index.js +0 -6
  118. package/build/oauth/index.js.map +0 -1
  119. package/build/oauth/jwt-issuer.d.ts +0 -87
  120. package/build/oauth/jwt-issuer.d.ts.map +0 -1
  121. package/build/oauth/jwt-issuer.js +0 -205
  122. package/build/oauth/jwt-issuer.js.map +0 -1
  123. package/build/oauth/pkce.d.ts +0 -10
  124. package/build/oauth/pkce.d.ts.map +0 -1
  125. package/build/oauth/pkce.js +0 -34
  126. package/build/oauth/pkce.js.map +0 -1
  127. package/build/oauth/provider.d.ts +0 -52
  128. package/build/oauth/provider.d.ts.map +0 -1
  129. package/build/oauth/provider.js +0 -98
  130. package/build/oauth/provider.js.map +0 -1
  131. package/build/oauth/user-store.d.ts +0 -25
  132. package/build/oauth/user-store.d.ts.map +0 -1
  133. package/build/oauth/user-store.js +0 -85
  134. package/build/oauth/user-store.js.map +0 -1
  135. package/build/relay/browser.d.ts.map +0 -1
  136. package/build/relay/browser.js.map +0 -1
  137. package/build/relay/client.d.ts +0 -36
  138. package/build/relay/client.d.ts.map +0 -1
  139. package/build/relay/client.js +0 -135
  140. package/build/relay/client.js.map +0 -1
  141. package/build/relay/session.d.ts +0 -12
  142. package/build/relay/session.d.ts.map +0 -1
  143. package/build/relay/session.js +0 -55
  144. package/build/relay/session.js.map +0 -1
  145. package/build/relay/tool-helpers.d.ts +0 -85
  146. package/build/relay/tool-helpers.d.ts.map +0 -1
  147. package/build/relay/tool-helpers.js +0 -103
  148. package/build/relay/tool-helpers.js.map +0 -1
  149. package/build/relay/wordlist.d.ts +0 -2
  150. package/build/relay/wordlist.d.ts.map +0 -1
  151. package/build/relay/wordlist.js +0 -7782
  152. package/build/relay/wordlist.js.map +0 -1
  153. package/build/schema/types.d.ts +0 -67
  154. package/build/schema/types.d.ts.map +0 -1
  155. package/build/schema/types.js +0 -2
  156. package/build/schema/types.js.map +0 -1
  157. package/build/storage/mode.d.ts +0 -23
  158. package/build/storage/mode.d.ts.map +0 -1
  159. package/build/storage/mode.js +0 -46
  160. package/build/storage/mode.js.map +0 -1
  161. package/build/storage/session-lock.d.ts +0 -19
  162. package/build/storage/session-lock.d.ts.map +0 -1
  163. package/build/storage/session-lock.js +0 -105
  164. package/build/storage/session-lock.js.map +0 -1
  165. package/build/transport/oauth-middleware.d.ts +0 -45
  166. package/build/transport/oauth-middleware.d.ts.map +0 -1
  167. package/build/transport/oauth-middleware.js +0 -86
  168. package/build/transport/oauth-middleware.js.map +0 -1
  169. /package/build/{relay → util}/browser.d.ts +0 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @n24q02m/hull
2
2
 
3
- **TypeScript core of hull: MCP Streamable HTTP transport, OAuth 2.1 authorization server, credential storage and relay client for self-hosted MCP servers.**
3
+ **TypeScript core of hull: MCP Streamable HTTP transport, token-table HTTP auth, encrypted credential storage and a CLI builder for self-hosted MCP servers.**
4
4
 
5
5
  This package is the TypeScript side of the hull monorepo. It is released in
6
6
  lockstep with the Python dist `n24q02m-hull`: one hull release tag publishes
@@ -25,13 +25,9 @@ subpath:
25
25
  | Import path | Provides |
26
26
  |---|---|
27
27
  | `@n24q02m/hull` | Everything below, plus `buildCli` (console-script subcommand dispatch around a server entry point) and `tryOpenBrowser` |
28
- | `@n24q02m/hull/transport` | `runHttpServer` (local HTTP server with routes), `StreamableHTTPServer` (MCP Streamable HTTP transport), `OAuthMiddleware` (bearer JWT verification) |
29
- | `@n24q02m/hull/oauth` | `OAuthProvider` (OAuth 2.1 authorization server), `JWTIssuer`, `verifyPKCE`, `InMemoryAuthCache`, `SqliteUserStore` |
30
- | `@n24q02m/hull/auth` | `createLocalOAuthApp` and `createDelegatedOAuthApp` (credential-form and upstream-OAuth flows), `renderCredentialForm`, `createSessionStore`, `deriveStableSub`, `authorizationServerMetadata` / `protectedResourceMetadata` (well-known documents) |
31
- | `@n24q02m/hull/crypto` | AES `encrypt` / `decrypt`, ECDH `generateKeyPair` / `deriveSharedSecret` / `exportPublicKey` / `importPublicKey`, key derivation `deriveAesKey` / `deriveJwtSigningSeed` |
32
- | `@n24q02m/hull/storage` | `atomicWriteFile`, credential backends (`LocalFsBackend`, `InMemoryBackend`, `CfKvBackend`, `backendFromEnv`), encrypted credential read/write/delete and config import/export, `PerPluginStore`, data dir helpers (`dataDir`, `dataDirCandidates`, `legacyDataDirs`), `resolveConfig` (environment variables, then stored config, then defaults), server mode state, session lock, machine identity helpers |
33
- | `@n24q02m/hull/relay` | Relay client: `createSession`, `generatePassphrase`, `pollForResult`, `sendMessage`, `pollForResponses`, `notifyComplete` |
34
- | `@n24q02m/hull/schema` | Type-only config schema: `ConfigField`, `ConfigMode`, `RelayConfigSchema` and related form layout types |
28
+ | `@n24q02m/hull/transport` | `runHttpServer` (local HTTP server with routes), `StreamableHTTPServer` (MCP Streamable HTTP transport), `jsonResponse` |
29
+ | `@n24q02m/hull/crypto` | AES `encrypt` / `decrypt`, ECDH `generateKeyPair` / `deriveSharedSecret` / `exportPublicKey` / `importPublicKey`, key derivation `deriveAesKey` |
30
+ | `@n24q02m/hull/storage` | `atomicWriteFile`, credential backends (`LocalFsBackend`, `InMemoryBackend`, `backendFromEnv`), encrypted credential read/write/delete and config import/export, `PerPluginStore`, data dir helpers (`dataDir`, `dataDirCandidates`, `legacyDataDirs`), `resolveConfig` (environment variables, then stored config, then defaults), machine identity helpers, and the provider key pool (`CredentialStore`, `KeyPool`, `AccountRegistry`, `SecretCipher`) |
35
31
  | `@n24q02m/hull/token-auth` | Token-table HTTP auth: `Authenticator`, `hashToken` / `verifyToken`, `loadUsers`, `currentUser`, `ensurePathAllowed`, `guardRequest`, `SlidingWindowLimiter`, `tokenCliHandler` |
36
32
 
37
33
  ## Credential storage layout
@@ -64,9 +60,48 @@ dirs are only read, never written. The next `save()` writes to `~/.<plugin>/`,
64
60
  and from then on the new copy takes precedence. `clear()` removes the blob
65
61
  from every location. A corrupt blob is reported as corrupt; the store does
66
62
  not fall back to an older copy behind it. Injected backends (`InMemoryBackend`,
67
- `CfKvBackend`, a `LocalFsBackend` with a custom `baseDir`) are used as the
63
+ a `LocalFsBackend` with a custom `baseDir`) are used as the
68
64
  only source.
69
65
 
66
+ ## Provider key pools (`~/.hull/hull.db`)
67
+
68
+ `@n24q02m/hull/storage` mirrors the Python key pool: ordered credentials per
69
+ provider (optionally scoped to a named account), encrypted at rest and rotated
70
+ on failure. This is separate from `PerPluginStore` above — the pool lives in the
71
+ shared hull database, not in `~/.<plugin>/`.
72
+
73
+ ```ts
74
+ import { CredentialStore } from '@n24q02m/hull/storage'
75
+
76
+ const store = new CredentialStore() // ~/.hull/hull.db + ~/.hull/.credential-key
77
+ store.migrateModelCells(settings.models) // idempotent seed from existing cells
78
+
79
+ const work = store.accounts().add({ provider: 'openrouter', name: 'Work', email: 'ops@example.com' })
80
+ store.addCredential({
81
+ provider: 'openrouter',
82
+ apiKey: process.env.OPENROUTER_KEY ?? '',
83
+ baseUrl: 'https://openrouter.ai/api/v1',
84
+ accountId: work.accountId // "openrouter:work"
85
+ })
86
+
87
+ const pool = store.poolForCell(settings.models.embed)
88
+ const result = await pool.runAsync((credential) => callProvider(credential))
89
+ ```
90
+
91
+ | Upstream | Rotation behaviour |
92
+ |---|---|
93
+ | `401` / `403` | disable that credential, take the next |
94
+ | `429` | cooldown `Retry-After` / `rate_limit_reset` (1 s…1 h, default 60 s), take the next |
95
+ | `5xx` | retry the same credential once (`max5xxRetries`), then rotate |
96
+ | anything else | re-throw unchanged; pool state untouched |
97
+ | empty / all blocked | `PoolExhaustedError` with counts and a redacted last error |
98
+
99
+ Acquired credentials are leased (default 60 s), so concurrent tasks never
100
+ receive the same key. `store.health(provider)` is the read-only view; keys and
101
+ their values never appear in health, `toString`, `toJSON`, or error text — only
102
+ a 4-character hint. Tables (`provider_accounts`, `provider_credentials`) are
103
+ created additively with `CREATE TABLE IF NOT EXISTS` in the existing database.
104
+
70
105
  ## CLI built-ins
71
106
 
72
107
  `buildCli(serverName, { serve, extra, version, pluginName })` routes a leading
@@ -79,21 +114,17 @@ positional argument to a subcommand. Bare or flag-prefixed argv (for example
79
114
  | `logout [--yes]` | Same as `config delete`: removes the stored credential from the current and every legacy dir. Without `--yes` it prompts on a TTY; non-interactive use without `--yes` exits 1. |
80
115
  | `config status` / `config delete [--yes]` | The long forms of the two commands above. |
81
116
  | `doctor` | Runtime, backend, store dir and config checks. Warns `only legacy store dir found` when credentials still sit in a legacy dir. |
82
- | `relay status` / `relay open` / `relay reset` | Relay session state. |
83
117
  | `token hash` | Mint a token-table hash (see below). |
84
118
 
85
119
  `auth` is not a built-in. Signing in depends on the server (OAuth device code,
86
- bot token, API key, relay form), so each server provides its own `auth`
120
+ bot token, API key), so each server provides its own `auth`
87
121
  handler through `extra`. Entries in `extra` also override a built-in of the
88
122
  same name.
89
123
 
90
124
  ## Token-table HTTP auth
91
125
 
92
126
  `runHttpServer` accepts an `auth` option with the three modes of core-py
93
- `[server] auth`. It replaces the OAuth/relay stack for that server: `auth` is
94
- mutually exclusive with `relaySchema`, `delegatedOAuth`, `jwtIssuer`,
95
- `authDisabled` and `authScope`, and needs neither a relay nor an OAuth
96
- issuer.
127
+ `[server] auth`; when omitted the server runs in `no-auth` mode (loopback only).
97
128
 
98
129
  | Mode | Config | Behaviour |
99
130
  |---|---|---|
@@ -150,7 +181,7 @@ printf '%s' "$TOKEN" | my-mcp token hash
150
181
  ```ts
151
182
  import { runHttpServer } from '@n24q02m/hull/transport'
152
183
  import { encrypt, decrypt } from '@n24q02m/hull/crypto'
153
- import type { RelayConfigSchema } from '@n24q02m/hull/schema'
184
+ import { buildCli, tryOpenBrowser } from '@n24q02m/hull'
154
185
  ```
155
186
 
156
187
  ## Development
@@ -14,13 +14,13 @@
14
14
  * those would hang in stdio mode instead of printing the requested output.
15
15
  *
16
16
  * A leading *positional* argv[0] is treated as a subcommand name -- either one
17
- * of the reserved built-ins (`config`/`doctor`/`logout`/`relay`/`status`/`token`)
17
+ * of the reserved built-ins (`config`/`doctor`/`logout`/`status`/`token`)
18
18
  * or a server-specific one supplied via `extra` -- and is routed to its handler
19
19
  * instead of `serve`. `status` and `logout` are top-level aliases of
20
20
  * `config status` and `config delete` (same output and exit codes).
21
21
  *
22
22
  * `auth` is deliberately NOT a built-in: signing in is domain-specific (OAuth
23
- * device code, bot token, API key paste, relay form, ...), so each server that
23
+ * device code, bot token, API key paste, ...), so each server that
24
24
  * needs it supplies its own `auth` handler via `extra`.
25
25
  * STDOUT is the MCP protocol channel in stdio mode, so only this subcommand
26
26
  * path prints to stdout; the `serve` path never touches stdout here.
@@ -45,7 +45,7 @@ export interface BuildCliOptions {
45
45
  serve: ServeFn;
46
46
  /**
47
47
  * Server-specific subcommands. A name here overrides the reserved built-in
48
- * of the same name (`config`/`doctor`/`logout`/`relay`/`status`/`token`), so a
48
+ * of the same name (`config`/`doctor`/`logout`/`status`/`token`), so a
49
49
  * server can supply its own handler. This is also where a server provides
50
50
  * `auth`, which is not a built-in because sign-in is domain-specific.
51
51
  */
@@ -67,8 +67,7 @@ export interface BuildCliOptions {
67
67
  * Build the console-script entry point for one MCP server.
68
68
  *
69
69
  * `serverName` is the console/display name (e.g. `"wet-mcp"`): it names the
70
- * program in help/usage and status lines, and keys relay session state and
71
- * run mode (which servers store under their `SERVER_NAME`).
70
+ * program in help/usage and status lines.
72
71
  *
73
72
  * `options.pluginName` is the credential storage slug that `PerPluginStore`
74
73
  * keys on (e.g. `"wet"`): it decides where `config` and `doctor` read/write
@@ -80,7 +79,7 @@ export interface BuildCliOptions {
80
79
  *
81
80
  * Reserved built-ins: `config` (`status`/`delete`), `status` (= `config
82
81
  * status`), `logout` (= `config delete`; non-interactive use needs `--yes`,
83
- * otherwise exit 1), `relay`, `doctor` and `token`. `auth` is not a built-in:
82
+ * otherwise exit 1), `doctor` and `token`. `auth` is not a built-in:
84
83
  * sign-in is domain-specific, so a server that needs it passes an `auth`
85
84
  * handler in `extra`.
86
85
  *
@@ -1 +1 @@
1
- {"version":3,"file":"build-cli.d.ts","sourceRoot":"","sources":["../../src/cli/build-cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAmBH,4EAA4E;AAC5E,MAAM,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;AAEhF;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AAErE,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,KAAK,EAAE,OAAO,CAAA;IACd;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAClC,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AA6LD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAiDlH"}
1
+ {"version":3,"file":"build-cli.d.ts","sourceRoot":"","sources":["../../src/cli/build-cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAgBH,4EAA4E;AAC5E,MAAM,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;AAEhF;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AAErE,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,KAAK,EAAE,OAAO,CAAA;IACd;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAClC,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAwID;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAgDlH"}
@@ -14,13 +14,13 @@
14
14
  * those would hang in stdio mode instead of printing the requested output.
15
15
  *
16
16
  * A leading *positional* argv[0] is treated as a subcommand name -- either one
17
- * of the reserved built-ins (`config`/`doctor`/`logout`/`relay`/`status`/`token`)
17
+ * of the reserved built-ins (`config`/`doctor`/`logout`/`status`/`token`)
18
18
  * or a server-specific one supplied via `extra` -- and is routed to its handler
19
19
  * instead of `serve`. `status` and `logout` are top-level aliases of
20
20
  * `config status` and `config delete` (same output and exit codes).
21
21
  *
22
22
  * `auth` is deliberately NOT a built-in: signing in is domain-specific (OAuth
23
- * device code, bot token, API key paste, relay form, ...), so each server that
23
+ * device code, bot token, API key paste, ...), so each server that
24
24
  * needs it supplies its own `auth` handler via `extra`.
25
25
  * STDOUT is the MCP protocol channel in stdio mode, so only this subcommand
26
26
  * path prints to stdout; the `serve` path never touches stdout here.
@@ -34,13 +34,10 @@
34
34
  */
35
35
  import { accessSync, constants, existsSync } from 'node:fs';
36
36
  import { createInterface } from 'node:readline';
37
- import { tryOpenBrowser } from '../relay/browser.js';
38
37
  import { backendFromEnv } from '../storage/backends.js';
39
38
  import { pluginNameForServer } from '../storage/credential-store.js';
40
39
  import { dataDir, legacyDataDirs } from '../storage/data-dir.js';
41
- import { clearMode, getMode } from '../storage/mode.js';
42
40
  import { PerPluginStore } from '../storage/per-plugin-store.js';
43
- import { acquireSessionLock, releaseSessionLock } from '../storage/session-lock.js';
44
41
  import { tokenCliHandler } from '../token-auth/cli.js';
45
42
  // Minimum Node major the stack supports (mcp-core package.json `engines`
46
43
  // pins `>=24.18.0`). Doctor's runtime check is the TS analogue of core-py's
@@ -111,50 +108,6 @@ function configHandler(serverName, pluginName) {
111
108
  return 2;
112
109
  };
113
110
  }
114
- function relayStatus(serverName, info) {
115
- if (info === null) {
116
- console.error(`${serverName}: no active relay session`);
117
- return 1;
118
- }
119
- const ageS = (Date.now() - info.createdAt) / 1000;
120
- console.log(`${serverName}: session ${info.sessionId.slice(0, 8)} relay_url=${info.relayUrl} age=${ageS.toFixed(0)}s`);
121
- return 0;
122
- }
123
- function relayHandler(serverName) {
124
- return async (argv) => {
125
- const action = argv[0];
126
- if (action === 'reset') {
127
- await releaseSessionLock(serverName);
128
- await clearMode(serverName);
129
- console.log(`${serverName}: relay state cleared`);
130
- return 0;
131
- }
132
- if (action !== 'status' && action !== 'open') {
133
- console.error(`${serverName}: relay expects 'status', 'open', or 'reset'`);
134
- return 2;
135
- }
136
- const info = await acquireSessionLock(serverName);
137
- if (action === 'status')
138
- return relayStatus(serverName, info);
139
- // "open"
140
- if (info === null) {
141
- console.error(`${serverName}: no active relay session`);
142
- return 1;
143
- }
144
- // Branch on the return value: `tryOpenBrowser` declines under headless / CI
145
- // / the env-guard, and printing "opened" there is untrue in the very first
146
- // line the user reads -- they wait for a tab that never appears. Failing to
147
- // open is not a failure of the command (the URL is still correct and still
148
- // usable), so the exit code stays 0.
149
- if (await tryOpenBrowser(info.relayUrl)) {
150
- console.log(`${serverName}: opened ${info.relayUrl}`);
151
- }
152
- else {
153
- console.log(`${serverName}: could not launch a browser here; visit ${info.relayUrl}`);
154
- }
155
- return 0;
156
- };
157
- }
158
111
  async function runDoctor(serverName, pluginName) {
159
112
  let ok = true;
160
113
  const nodeVersion = process.versions.node;
@@ -219,14 +172,6 @@ async function runDoctor(serverName, pluginName) {
219
172
  console.log('[warn] config: not configured');
220
173
  }
221
174
  }
222
- const info = await acquireSessionLock(serverName);
223
- if (info !== null) {
224
- console.log(`[ok] relay session active (${info.sessionId.slice(0, 8)})`);
225
- }
226
- else {
227
- console.log('[warn] no active relay session');
228
- }
229
- console.log(`[ok] mode: ${(await getMode(serverName)) ?? 'unset'}`);
230
175
  return ok ? 0 : 1;
231
176
  }
232
177
  function doctorHandler(serverName, pluginName) {
@@ -236,8 +181,7 @@ function doctorHandler(serverName, pluginName) {
236
181
  * Build the console-script entry point for one MCP server.
237
182
  *
238
183
  * `serverName` is the console/display name (e.g. `"wet-mcp"`): it names the
239
- * program in help/usage and status lines, and keys relay session state and
240
- * run mode (which servers store under their `SERVER_NAME`).
184
+ * program in help/usage and status lines.
241
185
  *
242
186
  * `options.pluginName` is the credential storage slug that `PerPluginStore`
243
187
  * keys on (e.g. `"wet"`): it decides where `config` and `doctor` read/write
@@ -249,7 +193,7 @@ function doctorHandler(serverName, pluginName) {
249
193
  *
250
194
  * Reserved built-ins: `config` (`status`/`delete`), `status` (= `config
251
195
  * status`), `logout` (= `config delete`; non-interactive use needs `--yes`,
252
- * otherwise exit 1), `relay`, `doctor` and `token`. `auth` is not a built-in:
196
+ * otherwise exit 1), `doctor` and `token`. `auth` is not a built-in:
253
197
  * sign-in is domain-specific, so a server that needs it passes an `auth`
254
198
  * handler in `extra`.
255
199
  *
@@ -268,7 +212,6 @@ export function buildCli(serverName, options) {
268
212
  config: configHandler(serverName, pluginName),
269
213
  status: () => configStatus(serverName, pluginName),
270
214
  logout: (argv) => configDelete(serverName, pluginName, argv.includes('--yes')),
271
- relay: relayHandler(serverName),
272
215
  doctor: doctorHandler(serverName, pluginName),
273
216
  token: tokenCliHandler(),
274
217
  ...extra
@@ -1 +1 @@
1
- {"version":3,"file":"build-cli.js","sourceRoot":"","sources":["../../src/cli/build-cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"build-cli.js","sourceRoot":"","sources":["../../src/cli/build-cli.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  export { decrypt, type EncryptResult, encrypt } from './aes.js';
2
2
  export { deriveSharedSecret, exportPublicKey, generateKeyPair, importPublicKey } from './ecdh.js';
3
- export { deriveAesKey, deriveJwtSigningSeed } from './kdf.js';
3
+ export { deriveAesKey } from './kdf.js';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/crypto/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,aAAa,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAC/D,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AACjG,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/crypto/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,aAAa,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAC/D,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AACjG,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA"}
@@ -1,4 +1,4 @@
1
1
  export { decrypt, encrypt } from './aes.js';
2
2
  export { deriveSharedSecret, exportPublicKey, generateKeyPair, importPublicKey } from './ecdh.js';
3
- export { deriveAesKey, deriveJwtSigningSeed } from './kdf.js';
3
+ export { deriveAesKey } from './kdf.js';
4
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/crypto/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAsB,OAAO,EAAE,MAAM,UAAU,CAAA;AAC/D,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AACjG,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/crypto/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAsB,OAAO,EAAE,MAAM,UAAU,CAAA;AAC/D,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AACjG,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA"}
@@ -1,15 +1,2 @@
1
1
  export declare function deriveAesKey(sharedSecret: ArrayBuffer, passphrase: string): Promise<CryptoKey>;
2
- /**
3
- * Derive a deterministic 32-byte Ed25519 seed for OAuth JWT signing.
4
- *
5
- * Used in HTTP multi-user mode (CREDENTIAL_SECRET set) so every container
6
- * replica converges on the SAME signing key without a shared volume or
7
- * external secret store. Domain-separated per server via the HKDF info label.
8
- *
9
- * HKDF-SHA256 with IKM = secret, empty salt, info =
10
- * `mcp-jwt-signing-key-v1:<serverName>`. Byte-identical to core-py's
11
- * `derive_jwt_signing_seed` for the same inputs (enforced by the shared
12
- * crypto-vectors fixture).
13
- */
14
- export declare function deriveJwtSigningSeed(secret: string, serverName: string): Buffer;
15
2
  //# sourceMappingURL=kdf.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"kdf.d.ts","sourceRoot":"","sources":["../../src/crypto/kdf.ts"],"names":[],"mappings":"AAOA,wBAAsB,YAAY,CAAC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAWpG;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAG/E"}
1
+ {"version":3,"file":"kdf.d.ts","sourceRoot":"","sources":["../../src/crypto/kdf.ts"],"names":[],"mappings":"AAOA,wBAAsB,YAAY,CAAC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAWpG"}
@@ -1,26 +1,11 @@
1
- import { hkdfSync } from 'node:crypto';
2
1
  const encoder = new TextEncoder();
2
+ // HKDF info label inherited from the former relay handshake. It is an input to
3
+ // the derived key, so changing it changes every key (see the cross-language
4
+ // vectors in tests/fixtures/crypto-vectors.json); the value must stay.
3
5
  const INFO = encoder.encode('mcp-relay');
4
- const JWT_SIGNING_INFO_PREFIX = 'mcp-jwt-signing-key-v1:';
5
6
  export async function deriveAesKey(sharedSecret, passphrase) {
6
7
  const salt = encoder.encode(passphrase);
7
8
  const keyMaterial = await crypto.subtle.importKey('raw', sharedSecret, 'HKDF', false, ['deriveKey']);
8
9
  return crypto.subtle.deriveKey({ name: 'HKDF', hash: 'SHA-256', salt, info: INFO }, keyMaterial, { name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt']);
9
10
  }
10
- /**
11
- * Derive a deterministic 32-byte Ed25519 seed for OAuth JWT signing.
12
- *
13
- * Used in HTTP multi-user mode (CREDENTIAL_SECRET set) so every container
14
- * replica converges on the SAME signing key without a shared volume or
15
- * external secret store. Domain-separated per server via the HKDF info label.
16
- *
17
- * HKDF-SHA256 with IKM = secret, empty salt, info =
18
- * `mcp-jwt-signing-key-v1:<serverName>`. Byte-identical to core-py's
19
- * `derive_jwt_signing_seed` for the same inputs (enforced by the shared
20
- * crypto-vectors fixture).
21
- */
22
- export function deriveJwtSigningSeed(secret, serverName) {
23
- const info = encoder.encode(`${JWT_SIGNING_INFO_PREFIX}${serverName}`);
24
- return Buffer.from(hkdfSync('sha256', Buffer.from(secret, 'utf-8'), Buffer.alloc(0), info, 32));
25
- }
26
11
  //# sourceMappingURL=kdf.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"kdf.js","sourceRoot":"","sources":["../../src/crypto/kdf.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEtC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAA;AAEjC,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;AACxC,MAAM,uBAAuB,GAAG,yBAAyB,CAAA;AAEzD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,YAAyB,EAAE,UAAkB;IAC9E,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IACvC,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;IAEpG,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAC5B,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EACnD,WAAW,EACX,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,EAChC,IAAI,EACJ,CAAC,SAAS,EAAE,SAAS,CAAC,CACvB,CAAA;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,UAAkB;IACrE,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,uBAAuB,GAAG,UAAU,EAAE,CAAC,CAAA;IACtE,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAA;AACjG,CAAC"}
1
+ {"version":3,"file":"kdf.js","sourceRoot":"","sources":["../../src/crypto/kdf.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAA;AAEjC,+EAA+E;AAC/E,4EAA4E;AAC5E,uEAAuE;AACvE,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;AAExC,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,YAAyB,EAAE,UAAkB;IAC9E,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IACvC,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;IAEpG,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAC5B,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EACnD,WAAW,EACX,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,EAChC,IAAI,EACJ,CAAC,SAAS,EAAE,SAAS,CAAC,CACvB,CAAA;AACH,CAAC"}
package/build/index.d.ts CHANGED
@@ -1,19 +1,9 @@
1
- export { authorizationServerMetadata, type CapabilityInfo, type ConfigField, type CredentialsCallback, createDelegatedOAuthApp, createLocalOAuthApp, type DelegatedOAuthAppOptions, type DelegatedOAuthAppResult, type FlowType, type LocalOAuthAppOptions, type LocalOAuthAppResult, type NextStep, type OAuthTokens, protectedResourceMetadata, type RelayConfigSchema, type RenderOptions, renderCredentialForm, type StepCallback, type SubjectContext, type TokenCallback, type UpstreamOAuthConfig } from './auth/index.js';
2
1
  export { type BuildCliOptions, buildCli, type CliHandler, type ServeFn } from './cli/build-cli.js';
3
2
  export * from './crypto/index.js';
4
- export { JWTIssuer } from './oauth/jwt-issuer.js';
5
- export { verifyPKCE } from './oauth/pkce.js';
6
- export { InMemoryAuthCache, type IOAuthSessionCache, OAuthProvider, type OAuthProviderOptions, type PreAuthSession } from './oauth/provider.js';
7
- export { type IUserCredentialStore, SqliteUserStore } from './oauth/user-store.js';
8
- export { tryOpenBrowser } from './relay/browser.js';
9
- export { createSession, generatePassphrase, notifyComplete, pollForResponses, pollForResult, type RelaySession, sendMessage } from './relay/client.js';
10
- export { buildOpenRelayHandler, type ElicitationServer, type OpenRelayHandlerOptions, type OpenRelayResult, registerOpenRelayTool, type ToolRegistrar } from './relay/tool-helpers.js';
11
- export type * from './schema/types.js';
12
3
  export { exportConfig, importConfig, listConfigs, scheduleReloadExit } from './storage/config-file.js';
13
4
  export { deleteStoredConfig as deleteConfig, readStoredConfig as readConfig, writeStoredConfig as writeConfig } from './storage/credential-store.js';
14
- export { clearMode, getMode, type ServerMode, setLocalMode } from './storage/mode.js';
15
5
  export * from './storage/resolver.js';
16
- export { acquireSessionLock, releaseSessionLock, type SessionInfo, writeSessionLock } from './storage/session-lock.js';
17
6
  export * from './token-auth/index.js';
18
7
  export { type HttpRoute, type HttpServerHandle, type RunHttpServerOptions, runHttpServer } from './transport/local-server.js';
8
+ export { tryOpenBrowser } from './util/browser.js';
19
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,2BAA2B,EAC3B,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,uBAAuB,EACvB,mBAAmB,EACnB,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,QAAQ,EACb,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,yBAAyB,EACzB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,oBAAoB,EACpB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACzB,MAAM,iBAAiB,CAAA;AAGxB,OAAO,EAAE,KAAK,eAAe,EAAE,QAAQ,EAAE,KAAK,UAAU,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAClG,cAAc,mBAAmB,CAAA;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EACL,iBAAiB,EACjB,KAAK,kBAAkB,EACvB,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACpB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,KAAK,oBAAoB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,KAAK,YAAY,EACjB,WAAW,EACZ,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,qBAAqB,EACrB,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACpB,qBAAqB,EACrB,KAAK,aAAa,EACnB,MAAM,yBAAyB,CAAA;AAChC,mBAAmB,mBAAmB,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAGtG,OAAO,EACL,kBAAkB,IAAI,YAAY,EAClC,gBAAgB,IAAI,UAAU,EAC9B,iBAAiB,IAAI,WAAW,EACjC,MAAM,+BAA+B,CAAA;AACtC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrF,cAAc,uBAAuB,CAAA;AACrC,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,KAAK,WAAW,EAChB,gBAAgB,EACjB,MAAM,2BAA2B,CAAA;AAGlC,cAAc,uBAAuB,CAAA;AAErC,OAAO,EACL,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,aAAa,EACd,MAAM,6BAA6B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,eAAe,EAAE,QAAQ,EAAE,KAAK,UAAU,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAClG,cAAc,mBAAmB,CAAA;AACjC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAGtG,OAAO,EACL,kBAAkB,IAAI,YAAY,EAClC,gBAAgB,IAAI,UAAU,EAC9B,iBAAiB,IAAI,WAAW,EACjC,MAAM,+BAA+B,CAAA;AACtC,cAAc,uBAAuB,CAAA;AAGrC,cAAc,uBAAuB,CAAA;AAErC,OAAO,EACL,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,aAAa,EACd,MAAM,6BAA6B,CAAA;AAEpC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA"}
package/build/index.js CHANGED
@@ -1,28 +1,16 @@
1
- // Local OAuth 2.1 Authorization Server (single-user, 127.0.0.1) +
2
- // Delegated OAuth (upstream redirect / device code) for remote multi-user.
3
- export { authorizationServerMetadata, createDelegatedOAuthApp, createLocalOAuthApp, protectedResourceMetadata, renderCredentialForm } from './auth/index.js';
4
- // Console-script CLI builder shared by every TS MCP server (config/relay/doctor
5
- // built-ins + version + help; parity with core-py's build_cli).
1
+ // Console-script CLI builder shared by every TS MCP server (config/doctor/logout/status/token built-ins).
6
2
  export { buildCli } from './cli/build-cli.js';
7
3
  export * from './crypto/index.js';
8
- // OAuth 2.1 multi-user infrastructure (HTTP mode)
9
- export { JWTIssuer } from './oauth/jwt-issuer.js';
10
- export { verifyPKCE } from './oauth/pkce.js';
11
- export { InMemoryAuthCache, OAuthProvider } from './oauth/provider.js';
12
- export { SqliteUserStore } from './oauth/user-store.js';
13
- export { tryOpenBrowser } from './relay/browser.js';
14
- export { createSession, generatePassphrase, notifyComplete, pollForResponses, pollForResult, sendMessage } from './relay/client.js';
15
- export { buildOpenRelayHandler, registerOpenRelayTool } from './relay/tool-helpers.js';
16
4
  export { exportConfig, importConfig, listConfigs, scheduleReloadExit } from './storage/config-file.js';
17
5
  // Single-user credential read/write/delete route through the unified
18
6
  // per-plugin store (with legacy config.enc read fallback).
19
7
  export { deleteStoredConfig as deleteConfig, readStoredConfig as readConfig, writeStoredConfig as writeConfig } from './storage/credential-store.js';
20
- export { clearMode, getMode, setLocalMode } from './storage/mode.js';
21
8
  export * from './storage/resolver.js';
22
- export { acquireSessionLock, releaseSessionLock, writeSessionLock } from './storage/session-lock.js';
23
9
  // HTTP token-table auth (no-auth / token / multi users.toml), the TS port of
24
10
  // core-py hull_core.auth; wired into runHttpServer via its `auth` option.
25
11
  export * from './token-auth/index.js';
26
- // HTTP MCP server entry point (OAuth AS + /mcp transport on 127.0.0.1)
12
+ // HTTP MCP server entry point (Streamable HTTP transport on host:port)
27
13
  export { runHttpServer } from './transport/local-server.js';
14
+ // Cross-platform best-effort browser opener (WSL-aware, headless/CI-guarded).
15
+ export { tryOpenBrowser } from './util/browser.js';
28
16
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,2EAA2E;AAC3E,OAAO,EACL,2BAA2B,EAI3B,uBAAuB,EACvB,mBAAmB,EAQnB,yBAAyB,EAGzB,oBAAoB,EAKrB,MAAM,iBAAiB,CAAA;AACxB,gFAAgF;AAChF,gEAAgE;AAChE,OAAO,EAAwB,QAAQ,EAAiC,MAAM,oBAAoB,CAAA;AAClG,cAAc,mBAAmB,CAAA;AACjC,kDAAkD;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EACL,iBAAiB,EAEjB,aAAa,EAGd,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAA6B,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAChB,aAAa,EAEb,WAAW,EACZ,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,qBAAqB,EAIrB,qBAAqB,EAEtB,MAAM,yBAAyB,CAAA;AAEhC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AACtG,qEAAqE;AACrE,2DAA2D;AAC3D,OAAO,EACL,kBAAkB,IAAI,YAAY,EAClC,gBAAgB,IAAI,UAAU,EAC9B,iBAAiB,IAAI,WAAW,EACjC,MAAM,+BAA+B,CAAA;AACtC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAmB,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrF,cAAc,uBAAuB,CAAA;AACrC,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAElB,gBAAgB,EACjB,MAAM,2BAA2B,CAAA;AAClC,6EAA6E;AAC7E,0EAA0E;AAC1E,cAAc,uBAAuB,CAAA;AACrC,uEAAuE;AACvE,OAAO,EAIL,aAAa,EACd,MAAM,6BAA6B,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0GAA0G;AAC1G,OAAO,EAAwB,QAAQ,EAAiC,MAAM,oBAAoB,CAAA;AAClG,cAAc,mBAAmB,CAAA;AACjC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AACtG,qEAAqE;AACrE,2DAA2D;AAC3D,OAAO,EACL,kBAAkB,IAAI,YAAY,EAClC,gBAAgB,IAAI,UAAU,EAC9B,iBAAiB,IAAI,WAAW,EACjC,MAAM,+BAA+B,CAAA;AACtC,cAAc,uBAAuB,CAAA;AACrC,6EAA6E;AAC7E,0EAA0E;AAC1E,cAAc,uBAAuB,CAAA;AACrC,uEAAuE;AACvE,OAAO,EAIL,aAAa,EACd,MAAM,6BAA6B,CAAA;AACpC,8EAA8E;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Named provider accounts for multi-account pools (TypeScript mirror of
3
+ * `hull_core/credentials/registry.py`).
4
+ *
5
+ * A provider such as OpenRouter can be used through several identities (one
6
+ * per email, workspace or billing owner). Each account owns its own credential
7
+ * pool: rotation never hops between accounts, so a 429 on one account's key
8
+ * cannot silently spend another account's quota.
9
+ *
10
+ * `accountId` is the stable identifier config points at; `name` is the human
11
+ * label and is unique per provider. Credentials can only be attached to an
12
+ * existing account whose provider matches.
13
+ */
14
+ import { type Account, type CredentialHealth, type KeyPool, type KeyPoolOptions } from './key-pool.js';
15
+ import type { CredentialStore } from './key-pool-store.js';
16
+ /** CRUD over `provider_accounts` plus per-account pool resolution. */
17
+ export declare class AccountRegistry {
18
+ readonly store: CredentialStore;
19
+ constructor(store: CredentialStore);
20
+ /** Register one named account; the default id is `<provider>:<name slug>`. */
21
+ add(input: {
22
+ provider: string;
23
+ name: string;
24
+ accountId?: string | null;
25
+ email?: string | null;
26
+ workspace?: string | null;
27
+ labels?: Record<string, unknown> | null;
28
+ }): Account;
29
+ /** Resolve an account id first, then a unique name; `null` when absent. */
30
+ maybeGet(ref: string): Account | null;
31
+ get(ref: string): Account;
32
+ listAccounts(provider?: string): Account[];
33
+ /**
34
+ * Partially update metadata; omitted fields keep their value. `labels: null`
35
+ * clears the labels, `email: null`/`workspace: null` clear those fields. The
36
+ * provider and account id are immutable.
37
+ */
38
+ update(ref: string, patch?: {
39
+ name?: string;
40
+ email?: string | null;
41
+ workspace?: string | null;
42
+ labels?: Record<string, unknown> | null;
43
+ }): Account;
44
+ /** Delete an account; credentials block the delete unless dropped explicitly. */
45
+ remove(ref: string, options?: {
46
+ dropCredentials?: boolean;
47
+ }): void;
48
+ /** Masked pool state for one account (safe to log). */
49
+ credentials(ref: string): CredentialHealth[];
50
+ /** The KeyPool scoped to one account (provider + account id). */
51
+ pool(ref: string, options?: KeyPoolOptions): KeyPool;
52
+ }
53
+ //# sourceMappingURL=account-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-registry.d.ts","sourceRoot":"","sources":["../../src/storage/account-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,KAAK,OAAO,EAAgB,KAAK,gBAAgB,EAAE,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAA;AACpH,OAAO,KAAK,EAAc,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAqDtE,sEAAsE;AACtE,qBAAa,eAAe;IAC1B,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAA;IAE/B,YAAY,KAAK,EAAE,eAAe,EAEjC;IAED,8EAA8E;IAC9E,GAAG,CAAC,KAAK,EAAE;QACT,QAAQ,EAAE,MAAM,CAAA;QAChB,IAAI,EAAE,MAAM,CAAA;QACZ,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACzB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACrB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACzB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;KACxC,GAAG,OAAO,CAcV;IAED,2EAA2E;IAC3E,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAapC;IAED,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAIxB;IAED,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,EAAE,CAGzC;IAED;;;;OAIG;IACH,MAAM,CACJ,GAAG,EAAE,MAAM,EACX,KAAK,GAAE;QACL,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACrB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACzB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;KACnC,GACL,OAAO,CAaT;IAED,iFAAiF;IACjF,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,IAAI,CAGrE;IAED,uDAAuD;IACvD,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAG3C;IAED,iEAAiE;IACjE,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAGvD;CACF"}