@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.
- package/README.md +47 -16
- package/build/cli/build-cli.d.ts +5 -6
- package/build/cli/build-cli.d.ts.map +1 -1
- package/build/cli/build-cli.js +4 -61
- package/build/cli/build-cli.js.map +1 -1
- package/build/crypto/index.d.ts +1 -1
- package/build/crypto/index.d.ts.map +1 -1
- package/build/crypto/index.js +1 -1
- package/build/crypto/index.js.map +1 -1
- package/build/crypto/kdf.d.ts +0 -13
- package/build/crypto/kdf.d.ts.map +1 -1
- package/build/crypto/kdf.js +3 -18
- package/build/crypto/kdf.js.map +1 -1
- package/build/index.d.ts +1 -11
- package/build/index.d.ts.map +1 -1
- package/build/index.js +4 -16
- package/build/index.js.map +1 -1
- package/build/storage/account-registry.d.ts +53 -0
- package/build/storage/account-registry.d.ts.map +1 -0
- package/build/storage/account-registry.js +148 -0
- package/build/storage/account-registry.js.map +1 -0
- package/build/storage/backends.d.ts +0 -26
- package/build/storage/backends.d.ts.map +1 -1
- package/build/storage/backends.js +0 -65
- package/build/storage/backends.js.map +1 -1
- package/build/storage/config-file.d.ts +2 -19
- package/build/storage/config-file.d.ts.map +1 -1
- package/build/storage/config-file.js +2 -23
- package/build/storage/config-file.js.map +1 -1
- package/build/storage/credential-store.d.ts +1 -9
- package/build/storage/credential-store.d.ts.map +1 -1
- package/build/storage/credential-store.js +4 -16
- package/build/storage/credential-store.js.map +1 -1
- package/build/storage/data-dir.d.ts +2 -2
- package/build/storage/data-dir.js +2 -2
- package/build/storage/encryption.d.ts.map +1 -1
- package/build/storage/encryption.js +4 -0
- package/build/storage/encryption.js.map +1 -1
- package/build/storage/index.d.ts +5 -3
- package/build/storage/index.d.ts.map +1 -1
- package/build/storage/index.js +5 -3
- package/build/storage/index.js.map +1 -1
- package/build/storage/key-pool-crypto.d.ts +44 -0
- package/build/storage/key-pool-crypto.d.ts.map +1 -0
- package/build/storage/key-pool-crypto.js +132 -0
- package/build/storage/key-pool-crypto.js.map +1 -0
- package/build/storage/key-pool-store.d.ts +134 -0
- package/build/storage/key-pool-store.d.ts.map +1 -0
- package/build/storage/key-pool-store.js +470 -0
- package/build/storage/key-pool-store.js.map +1 -0
- package/build/storage/key-pool.d.ts +172 -0
- package/build/storage/key-pool.d.ts.map +1 -0
- package/build/storage/key-pool.js +374 -0
- package/build/storage/key-pool.js.map +1 -0
- package/build/storage/resolver.js +1 -1
- package/build/storage/resolver.js.map +1 -1
- package/build/token-auth/index.d.ts +1 -1
- package/build/token-auth/index.js +1 -1
- package/build/transport/index.d.ts +1 -2
- package/build/transport/index.d.ts.map +1 -1
- package/build/transport/index.js +1 -2
- package/build/transport/index.js.map +1 -1
- package/build/transport/local-server.d.ts +12 -128
- package/build/transport/local-server.d.ts.map +1 -1
- package/build/transport/local-server.js +20 -262
- package/build/transport/local-server.js.map +1 -1
- package/build/transport/streamable-http.d.ts +6 -7
- package/build/transport/streamable-http.d.ts.map +1 -1
- package/build/transport/streamable-http.js +6 -6
- package/build/transport/streamable-http.js.map +1 -1
- package/build/util/browser.d.ts.map +1 -0
- package/build/{relay → util}/browser.js +2 -2
- package/build/util/browser.js.map +1 -0
- package/package.json +4 -21
- package/build/auth/credential-form.d.ts +0 -163
- package/build/auth/credential-form.d.ts.map +0 -1
- package/build/auth/credential-form.js +0 -1869
- package/build/auth/credential-form.js.map +0 -1
- package/build/auth/delegated-oauth-app.d.ts +0 -90
- package/build/auth/delegated-oauth-app.d.ts.map +0 -1
- package/build/auth/delegated-oauth-app.js +0 -881
- package/build/auth/delegated-oauth-app.js.map +0 -1
- package/build/auth/index.d.ts +0 -12
- package/build/auth/index.d.ts.map +0 -1
- package/build/auth/index.js +0 -12
- package/build/auth/index.js.map +0 -1
- package/build/auth/local-oauth-app.d.ts +0 -152
- package/build/auth/local-oauth-app.d.ts.map +0 -1
- package/build/auth/local-oauth-app.js +0 -975
- package/build/auth/local-oauth-app.js.map +0 -1
- package/build/auth/relay-login.d.ts +0 -46
- package/build/auth/relay-login.d.ts.map +0 -1
- package/build/auth/relay-login.js +0 -197
- package/build/auth/relay-login.js.map +0 -1
- package/build/auth/router.d.ts +0 -18
- package/build/auth/router.d.ts.map +0 -1
- package/build/auth/router.js +0 -62
- package/build/auth/router.js.map +0 -1
- package/build/auth/session-store.d.ts +0 -49
- package/build/auth/session-store.d.ts.map +0 -1
- package/build/auth/session-store.js +0 -94
- package/build/auth/session-store.js.map +0 -1
- package/build/auth/stable-sub.d.ts +0 -27
- package/build/auth/stable-sub.d.ts.map +0 -1
- package/build/auth/stable-sub.js +0 -38
- package/build/auth/stable-sub.js.map +0 -1
- package/build/auth/well-known.d.ts +0 -4
- package/build/auth/well-known.d.ts.map +0 -1
- package/build/auth/well-known.js +0 -26
- package/build/auth/well-known.js.map +0 -1
- package/build/oauth/cache.d.ts +0 -22
- package/build/oauth/cache.d.ts.map +0 -1
- package/build/oauth/cache.js +0 -24
- package/build/oauth/cache.js.map +0 -1
- package/build/oauth/index.d.ts +0 -6
- package/build/oauth/index.d.ts.map +0 -1
- package/build/oauth/index.js +0 -6
- package/build/oauth/index.js.map +0 -1
- package/build/oauth/jwt-issuer.d.ts +0 -87
- package/build/oauth/jwt-issuer.d.ts.map +0 -1
- package/build/oauth/jwt-issuer.js +0 -205
- package/build/oauth/jwt-issuer.js.map +0 -1
- package/build/oauth/pkce.d.ts +0 -10
- package/build/oauth/pkce.d.ts.map +0 -1
- package/build/oauth/pkce.js +0 -34
- package/build/oauth/pkce.js.map +0 -1
- package/build/oauth/provider.d.ts +0 -52
- package/build/oauth/provider.d.ts.map +0 -1
- package/build/oauth/provider.js +0 -98
- package/build/oauth/provider.js.map +0 -1
- package/build/oauth/user-store.d.ts +0 -25
- package/build/oauth/user-store.d.ts.map +0 -1
- package/build/oauth/user-store.js +0 -85
- package/build/oauth/user-store.js.map +0 -1
- package/build/relay/browser.d.ts.map +0 -1
- package/build/relay/browser.js.map +0 -1
- package/build/relay/client.d.ts +0 -36
- package/build/relay/client.d.ts.map +0 -1
- package/build/relay/client.js +0 -135
- package/build/relay/client.js.map +0 -1
- package/build/relay/session.d.ts +0 -12
- package/build/relay/session.d.ts.map +0 -1
- package/build/relay/session.js +0 -55
- package/build/relay/session.js.map +0 -1
- package/build/relay/tool-helpers.d.ts +0 -85
- package/build/relay/tool-helpers.d.ts.map +0 -1
- package/build/relay/tool-helpers.js +0 -103
- package/build/relay/tool-helpers.js.map +0 -1
- package/build/relay/wordlist.d.ts +0 -2
- package/build/relay/wordlist.d.ts.map +0 -1
- package/build/relay/wordlist.js +0 -7782
- package/build/relay/wordlist.js.map +0 -1
- package/build/schema/types.d.ts +0 -67
- package/build/schema/types.d.ts.map +0 -1
- package/build/schema/types.js +0 -2
- package/build/schema/types.js.map +0 -1
- package/build/storage/mode.d.ts +0 -23
- package/build/storage/mode.d.ts.map +0 -1
- package/build/storage/mode.js +0 -46
- package/build/storage/mode.js.map +0 -1
- package/build/storage/session-lock.d.ts +0 -19
- package/build/storage/session-lock.d.ts.map +0 -1
- package/build/storage/session-lock.js +0 -105
- package/build/storage/session-lock.js.map +0 -1
- package/build/transport/oauth-middleware.d.ts +0 -45
- package/build/transport/oauth-middleware.d.ts.map +0 -1
- package/build/transport/oauth-middleware.js +0 -86
- package/build/transport/oauth-middleware.js.map +0 -1
- /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,
|
|
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), `
|
|
29
|
-
| `@n24q02m/hull/
|
|
30
|
-
| `@n24q02m/hull/
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
184
|
+
import { buildCli, tryOpenBrowser } from '@n24q02m/hull'
|
|
154
185
|
```
|
|
155
186
|
|
|
156
187
|
## Development
|
package/build/cli/build-cli.d.ts
CHANGED
|
@@ -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`/`
|
|
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,
|
|
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`/`
|
|
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
|
|
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), `
|
|
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;
|
|
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"}
|
package/build/cli/build-cli.js
CHANGED
|
@@ -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`/`
|
|
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,
|
|
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
|
|
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), `
|
|
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":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"build-cli.js","sourceRoot":"","sources":["../../src/cli/build-cli.ts"],"names":[],"mappings":"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"}
|
package/build/crypto/index.d.ts
CHANGED
|
@@ -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
|
|
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,
|
|
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"}
|
package/build/crypto/index.js
CHANGED
|
@@ -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
|
|
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,
|
|
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"}
|
package/build/crypto/kdf.d.ts
CHANGED
|
@@ -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
|
|
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"}
|
package/build/crypto/kdf.js
CHANGED
|
@@ -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
|
package/build/crypto/kdf.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kdf.js","sourceRoot":"","sources":["../../src/crypto/kdf.ts"],"names":[],"mappings":"AAAA,
|
|
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
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
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
|
-
//
|
|
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 (
|
|
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
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
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"}
|