@carrierllc/mcp 0.13.28 → 0.13.30
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 +137 -1
- package/dist/{chunk-RF3NNGZX.js → chunk-ZJY7H2QW.js} +12 -3
- package/dist/chunk-ZJY7H2QW.js.map +1 -0
- package/dist/cli.js +966 -343
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/native/claude-keychain.js +57 -0
- package/package.json +10 -2
- package/plugin/.claude-plugin/marketplace.json +2 -2
- package/plugin/carrier/.claude-plugin/plugin.json +1 -1
- package/shell/carrier.bash +56 -0
- package/shell/carrier.zsh +35 -0
- package/templates/storefront/open-next.config.ts +8 -1
- package/templates/storefront/wrangler.jsonc +1 -1
- package/dist/chunk-RF3NNGZX.js.map +0 -1
package/README.md
CHANGED
|
@@ -21,12 +21,148 @@ carrier status # plugin + MCP + next steps
|
|
|
21
21
|
carrier plugin install # zero-cred MCP URL; OAuth on first use in Claude
|
|
22
22
|
carrier open signup # create account
|
|
23
23
|
carrier examples # paste-ready “talk to fleet” prompts
|
|
24
|
-
carrier
|
|
24
|
+
carrier login # browser once; native OAuth refreshes silently
|
|
25
|
+
carrier ask "fleet health" # uses CLI OAuth / compatible Claude Code OAuth / explicit key
|
|
26
|
+
carrier exec -- bash # real child terminal with CARRIER_API_KEY in its environment
|
|
25
27
|
```
|
|
26
28
|
|
|
27
29
|
**Entry A:** register `https://mcp.carrier.llc/mcp` with no token. The first tool
|
|
28
30
|
call in Claude/Cursor opens Clerk OAuth (Google / GitHub / email).
|
|
29
31
|
|
|
32
|
+
### OAuth and terminal handoff
|
|
33
|
+
|
|
34
|
+
Carrier commands, status and Ask the Fleet share credential resolution. Explicit
|
|
35
|
+
`CARRIER_API_KEY` / `CARRIER_ORG_API_KEY` always win. Native `carrier login` stores
|
|
36
|
+
a private refreshable session with one cross-process owner lock and atomic writes.
|
|
37
|
+
Login, refresh and logout serialize; a completed logout cannot be resurrected by
|
|
38
|
+
an earlier refresh. A crashed CLI owner leaves a fail-closed `credentials.lock`
|
|
39
|
+
directory: verify that no CLI login/refresh is running before manually removing
|
|
40
|
+
that directory. Changing the callback port triggers fresh client registration.
|
|
41
|
+
Native login and refresh request the exact production MCP resource. A present
|
|
42
|
+
wrong/malformed token-response resource is rejected before credential storage;
|
|
43
|
+
legacy absence is distinct and refresh retains a previously known binding.
|
|
44
|
+
|
|
45
|
+
### Existing bash/zsh terminal (explicit setup)
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
source "$(carrier shell-path bash)" # use zsh instead of bash in zsh
|
|
49
|
+
carrier_auth_export
|
|
50
|
+
# CARRIER_API_KEY is now exported in THIS shell and its subsequent children.
|
|
51
|
+
# Before an arbitrary headless job, refresh this snapshot again:
|
|
52
|
+
carrier_auth_export && your-headless-job
|
|
53
|
+
carrier logout
|
|
54
|
+
carrier_auth_clear # erase this shell's snapshot too
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Only a shipped static file is sourced. No secret is printed, evaluated as code,
|
|
58
|
+
put in command arguments/history, or written to a startup file. The function
|
|
59
|
+
reads an anonymous private pipe via an inherited descriptor. It refuses shell
|
|
60
|
+
traps and turns off xtrace/verbose **without restoring them**, because the next
|
|
61
|
+
caller command could expand the newly exported environment. Bash opt-in loading
|
|
62
|
+
enables errtrace so caller ERR traps are visible for refusal. Trusted commands,
|
|
63
|
+
same-UID process environment readers and crash dumps can still expose a bearer;
|
|
64
|
+
this is not protection from a compromised shell/OS. Do not re-enable tracing
|
|
65
|
+
around credentials.
|
|
66
|
+
|
|
67
|
+
Shell acceptance requires **both bash and zsh**: `pnpm test:oauth-shell`.
|
|
68
|
+
`CARRIER_TEST_ZSH` may point to an isolated zsh binary and
|
|
69
|
+
`CARRIER_TEST_ZSH_MODULE_PATH` to its matching modules. The general repair suite
|
|
70
|
+
reports a missing zsh interpreter as an explicit SKIP, never a zsh pass; the
|
|
71
|
+
acceptance command fails when either interpreter is unavailable.
|
|
72
|
+
|
|
73
|
+
OAuth exports carry `CARRIER_OAUTH_ORIGIN`, `CARRIER_OAUTH_EXPIRES_AT` (epoch ms)
|
|
74
|
+
and a `CARRIER_OAUTH_HANDOFF` fingerprint plus non-secret `CARRIER_OAUTH_BINDING`.
|
|
75
|
+
Carrier invocations reread only the selected owner, source directory/file, server,
|
|
76
|
+
registration and opaque subject/grant. Same-owner token rotation is allowed;
|
|
77
|
+
expiry, logout, owner/config/account/org changes fail closed, never switch to
|
|
78
|
+
another valid client session. Old exports without binding must be exported again.
|
|
79
|
+
These metadata equality checks are not cryptographic account/org proof.
|
|
80
|
+
Arbitrary programs retain it until expiry: re-run `carrier_auth_export` before
|
|
81
|
+
consumption. Replacing `CARRIER_API_KEY` intentionally overrides the fingerprint
|
|
82
|
+
and remains authoritative. `carrier_auth_clear` removes this shell's exported
|
|
83
|
+
key and metadata, not the other client's login.
|
|
84
|
+
|
|
85
|
+
`carrier exec -- <command> [args...]` remains available for a trusted child only;
|
|
86
|
+
no setup required, no parent-shell mutation, and child exit/signal is preserved.
|
|
87
|
+
OAuth is a short-lived bearer, **not** an `ak_` key.
|
|
88
|
+
|
|
89
|
+
### Supported read-only MCP owners
|
|
90
|
+
|
|
91
|
+
Without a native session, a current compatible MCP access token may be reused;
|
|
92
|
+
no refresh grant is copied, rotated or written by Carrier. If the owner expires,
|
|
93
|
+
refresh it in that client or use native `carrier login`. No owner reauth command
|
|
94
|
+
is invoked. Multiple current owners require `CARRIER_MCP_OAUTH_OWNER=hermes` or
|
|
95
|
+
`claude`; the CLI never guesses which account to use.
|
|
96
|
+
|
|
97
|
+
- **Claude Code 2.1.277 and 2.1.296:** exact inspected config and storage adapters.
|
|
98
|
+
The owner's `.claude.json` lives under `CLAUDE_CONFIG_DIR || ~`; an existing
|
|
99
|
+
legacy `.config.json` takes precedence. For the consuming CLI's cwd, local
|
|
100
|
+
`projects[real git root || real cwd].mcpServers` wins over approved ancestor
|
|
101
|
+
`.mcp.json` project config, which wins over user config. Other projects are not
|
|
102
|
+
candidates. Project import supports explicit trusted user settings approval
|
|
103
|
+
only; pending/rejected or ambiguous policy/settings fail closed.
|
|
104
|
+
Hashes the actual `{type,url,headers:headers||{}}` in original insertion order:
|
|
105
|
+
HTTP, SSE and absent `type` remain distinct. No hardcoded empty-header hash.
|
|
106
|
+
Managed selection remains unsupported and fails closed; no inferred
|
|
107
|
+
plugin/proxy/CLI override resolution. Authorization/API-key/cookie headers and
|
|
108
|
+
unresolved environment substitutions are not imported as OAuth.
|
|
109
|
+
`CLAUDE_SECURESTORAGE_CONFIG_DIR` takes precedence by presence for credential
|
|
110
|
+
storage; present-empty selects `~/.claude`, while nonempty and `CLAUDE_CONFIG_DIR`
|
|
111
|
+
retain the exact NFC strings (no trim or resolve before the Keychain hash).
|
|
112
|
+
`USER || os.userInfo().username` selects the exact account, with Claude's
|
|
113
|
+
invalid-account fallback. An approved custom OAuth environment selects only
|
|
114
|
+
its own suffix; unrelated suffixes/accounts are never enumerated.
|
|
115
|
+
Linux reads the private `.credentials.json`. `CARRIER_MCP_OAUTH_FILE` explicitly
|
|
116
|
+
selects that file backend on either platform, without consulting Keychain.
|
|
117
|
+
CamelCase expiry is epoch milliseconds.
|
|
118
|
+
- **Hermes:** selected `HERMES_HOME` (default `~/.hermes`), exact configured
|
|
119
|
+
`mcp_servers.carrier.url`, with private `mcp-tokens/carrier.json`,
|
|
120
|
+
`.client.json` and `.meta.json`. Real snake_case access-token fields,
|
|
121
|
+
`hermes_issuer`, Bearer type and absolute `expires_at` in seconds are required.
|
|
122
|
+
Issuer/discovery endpoints, client registration and resource configuration are
|
|
123
|
+
checked. Legacy relative-only expiry is refused. Config JSON and simple scalar
|
|
124
|
+
block YAML are supported; nested/alias/flow constructs fail closed.
|
|
125
|
+
|
|
126
|
+
`CARRIER_MCP_OAUTH_SERVER` selects an alternative explicit name. Private mode
|
|
127
|
+
and current-user file ownership, exact issuer/resource, `read` scope and finite
|
|
128
|
+
future expiry are required. `CARRIER_OAUTH_ACCOUNT` optionally selects the
|
|
129
|
+
Carrier opaque token's user prefix; it is **not** cryptographic account/org
|
|
130
|
+
proof. Only the server validates actual token audience, organization and grant
|
|
131
|
+
permissions. Invalid native state never falls through to another owner.
|
|
132
|
+
|
|
133
|
+
On macOS the packaged `native/claude-keychain.js` uses the built-in JXA
|
|
134
|
+
Objective-C bridge and Apple Security Framework: one generic-password query,
|
|
135
|
+
exact service and account, `kSecMatchLimitOne`, `kSecReturnData`,
|
|
136
|
+
`kSecUseAuthenticationUIFail`, plus process-local legacy UI inhibition.
|
|
137
|
+
There is no compiler/download/install-at-login dependency, no `security -w`,
|
|
138
|
+
no broad dump, and no owner lock/refresh/login. Only non-secret selectors reach
|
|
139
|
+
stdin. Only the selected access-token fields reach an inherited private FD;
|
|
140
|
+
stdout/stderr are discarded. Owner refresh grants, client secrets and unrelated
|
|
141
|
+
credentials never leave the helper. Apple may report an ACL prompt requirement
|
|
142
|
+
or locked store identically (`errSecInteractionNotAllowed`): `locked` denotes
|
|
143
|
+
that noninteractive refusal, not a diagnosis of the physical Keychain state.
|
|
144
|
+
`errSecAuthFailed`/user-cancel are `denied`, parse errors are `malformed`, and
|
|
145
|
+
other failures are `unavailable`. None falls back to plaintext or Hermes.
|
|
146
|
+
Only `errSecItemNotFound` for the exact item permits Claude's documented private
|
|
147
|
+
file fallback. An existing item without the exact MCP entry does not fall back.
|
|
148
|
+
Keychain reuse requires `claude --version` to be exactly 2.1.277 or 2.1.296;
|
|
149
|
+
other versions fail closed. Compatibility is an explicit inspected allowlist,
|
|
150
|
+
not a version range. The source contracts are tested on Linux; a real Darwin
|
|
151
|
+
absent-item probe also executes the packaged helper byte-for-byte without
|
|
152
|
+
stdout/stderr. Successful existing-item access and installed end-to-end Mac
|
|
153
|
+
OAuth remain unproved. The inspected Mac 2.1.296 query returned `denied`
|
|
154
|
+
(OSStatus -25293), not absence; this adapter never broadens Keychain access or
|
|
155
|
+
falls back after that refusal.
|
|
156
|
+
Claude Desktop, Cursor, Windsurf and mcp-remote remain unsupported owners.
|
|
157
|
+
Issuer-less entries are intentionally rejected. `carrier logout` disables MCP
|
|
158
|
+
reuse until a successful native login and never edits the owner's store or
|
|
159
|
+
another shell's explicit keys.
|
|
160
|
+
|
|
161
|
+
Native API references: [Apple SecItemCopyMatching](https://developer.apple.com/documentation/security/secitemcopymatching(_:_:)),
|
|
162
|
+
[Apple SecItem.h](https://github.com/apple-oss-distributions/Security/blob/main/keychain/headers/SecItem.h),
|
|
163
|
+
[Apple JXA release notes](https://developer.apple.com/library/archive/releasenotes/InterapplicationCommunication/RN-JavaScriptForAutomation/),
|
|
164
|
+
[Claude authentication storage](https://code.claude.com/docs/en/authentication).
|
|
165
|
+
|
|
30
166
|
### Domain commands
|
|
31
167
|
|
|
32
168
|
With a headless key in the environment, each capability has its own command,
|
|
@@ -1855,16 +1855,22 @@ function storefrontScreen(input) {
|
|
|
1855
1855
|
// package.json
|
|
1856
1856
|
var package_default = {
|
|
1857
1857
|
name: "@carrierllc/mcp",
|
|
1858
|
-
version: "0.13.
|
|
1858
|
+
version: "0.13.30",
|
|
1859
1859
|
description: "Carrier MCP \u2014 natural-language control of MVNO/eSIM fleets via eSIMVault OCS. Stdio mode for direct integration with Claude Desktop, Cursor, Windsurf, and MCP-compatible clients. Ships the `carrier` CLI (plugin install + white-label eSIM storefront scaffold).",
|
|
1860
1860
|
license: "MIT",
|
|
1861
1861
|
author: "Carrier (Lifecycle Innovations Limited)",
|
|
1862
1862
|
homepage: "https://mcp.carrier.llc",
|
|
1863
1863
|
type: "module",
|
|
1864
|
+
carrierCompatibility: {
|
|
1865
|
+
claudeOAuthOwnerVersion: "2.1.277",
|
|
1866
|
+
claudeOAuthOwnerVersions: ["2.1.277", "2.1.296"]
|
|
1867
|
+
},
|
|
1864
1868
|
main: "./dist/index.js",
|
|
1865
1869
|
files: [
|
|
1866
1870
|
"dist",
|
|
1867
1871
|
"plugin",
|
|
1872
|
+
"shell",
|
|
1873
|
+
"native",
|
|
1868
1874
|
"README.md",
|
|
1869
1875
|
"templates",
|
|
1870
1876
|
"!templates/**/node_modules",
|
|
@@ -1882,7 +1888,9 @@ var package_default = {
|
|
|
1882
1888
|
lint: "eslint src",
|
|
1883
1889
|
prepublishOnly: "pnpm run build",
|
|
1884
1890
|
"build:test": "tsup --config tsup.test.config.ts",
|
|
1885
|
-
test: "pnpm run build && pnpm run build:test && node --test test/*.test.js",
|
|
1891
|
+
test: "pnpm run build && pnpm run build:test && node --test-concurrency=1 --test test/*.test.js && pnpm run test:oauth-repair",
|
|
1892
|
+
"test:oauth-repair": "node --experimental-transform-types --test-concurrency=1 --test test/oauth-repair.test.mjs test/claude-owner.test.mjs test/current-owner.test.mjs",
|
|
1893
|
+
"test:oauth-shell": "node scripts/check-oauth-shell.mjs",
|
|
1886
1894
|
"check:pack": "node scripts/check-pack-size.mjs",
|
|
1887
1895
|
"generate:domains": "node scripts/generate-domains.mjs"
|
|
1888
1896
|
},
|
|
@@ -5480,6 +5488,7 @@ export {
|
|
|
5480
5488
|
walletScreen,
|
|
5481
5489
|
greenzoneScreen,
|
|
5482
5490
|
storefrontScreen,
|
|
5491
|
+
package_default,
|
|
5483
5492
|
CARRIER_VERSION
|
|
5484
5493
|
};
|
|
5485
|
-
//# sourceMappingURL=chunk-
|
|
5494
|
+
//# sourceMappingURL=chunk-ZJY7H2QW.js.map
|