@iwas/mcp 1.0.0 → 1.0.1
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 +141 -100
- package/dist/auth/index.js +25 -2451
- package/dist/bin.js +133 -1801
- package/dist/catalog/index.js +1 -1118
- package/dist/client/index.js +1 -18
- package/dist/index.d.ts +5 -10
- package/dist/index.js +25 -3458
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,110 +1,148 @@
|
|
|
1
1
|
# @iwas/mcp
|
|
2
2
|
|
|
3
|
-
Intelligent WiFi Access & Presence Service (IWAS) Model Context Protocol (MCP)
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
- **Account:** Profile key in canonical format `<origin>::<clientId>` (e.g. `https://getiwas.com::iwas-cli`).
|
|
26
|
-
- macOS: Uses `/usr/bin/security` (`add-generic-password -U`, `find-generic-password -w`, `delete-generic-password`).
|
|
27
|
-
- Linux: Uses `secret-tool` (`store`, `lookup`, `clear`) with secrets passed strictly via `stdin` (never exposed in `argv` or `ps`).
|
|
28
|
-
- **Manual Verification on macOS:**
|
|
29
|
-
```bash
|
|
30
|
-
# Check stored secret in macOS Keychain:
|
|
31
|
-
security find-generic-password -s iwas-cli -a "https://getiwas.com::iwas-cli" -w
|
|
32
|
-
```
|
|
33
|
-
- **File Fallback (`~/.config/iwas/credentials.json`):**
|
|
34
|
-
- Active in headless CI, Docker containers, and on Windows (`%USERPROFILE%\.config\iwas\credentials.json`).
|
|
35
|
-
- Respects `$XDG_CONFIG_HOME/iwas/credentials.json`.
|
|
36
|
-
- Enforces strict POSIX permissions: directory `0700` (`rwx------`), file `0600` (`rw-------`).
|
|
37
|
-
- Atomic write strategy: writes to temporary file, syncs to disk (`fsync`), and renames atomically.
|
|
38
|
-
- Protects corrupt files: if the JSON is malformed or missing fields, the vault fails closed and refuses to overwrite.
|
|
39
|
-
- **Security Considerations & Trade-offs:**
|
|
40
|
-
> [!WARNING]
|
|
41
|
-
> The file fallback stores serialized credentials in plaintext JSON protected only by OS file permissions (`0600`). On systems where native OS keychain utilities are available, the keychain backend is strongly preferred.
|
|
42
|
-
> On macOS workstations, `/usr/bin/security` accepts `-w <secret>` via arguments which is transiently visible in the process table `ps` to local processes running under the same user UID.
|
|
43
|
-
- **Conflict Resolution & Precedence:**
|
|
44
|
-
- Credentials include an internal `updatedAt` timestamp (`Date.now()`). When operating in `auto` mode with both keychain and file present, the vault compares timestamps (`updatedAt ?? expiresAt`) and automatically migrates newer file credentials into the keychain while purging stale copies (resolving split-backend desync).
|
|
45
|
-
- **Environment Override:**
|
|
46
|
-
- Set `IWAS_MCP_VAULT=auto` (default: keychain if available, fallback to file).
|
|
47
|
-
- Set `IWAS_MCP_VAULT=keychain` (strict keychain; throws if unavailable or locked).
|
|
48
|
-
- Set `IWAS_MCP_VAULT=file` (forces file storage; useful for headless CI).
|
|
49
|
-
- Set `IWAS_MCP_REAL_KEYCHAIN=1` (opt-in to execute real host macOS Keychain tests).
|
|
50
|
-
|
|
51
|
-
## Local CLI
|
|
52
|
-
|
|
53
|
-
Executable binary is `iwas` (with `iwas-mcp` provided as a backward-compatible alias):
|
|
3
|
+
> **Intelligent WiFi Access & Presence Service (IWAS) Model Context Protocol (MCP) CLI & SDK**
|
|
4
|
+
|
|
5
|
+
Official command-line tool and developer SDK for connecting AI coding assistants (Claude Desktop, Cursor, Antigravity, Cline) and enterprise applications to the **IWAS** WiFi billing, captive portal, and network presence infrastructure.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@iwas/mcp)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Highlights
|
|
13
|
+
|
|
14
|
+
- 🚀 **Zero Setup**: Run instantly via `npx @iwas/mcp` without cloning or pre-installing dependencies.
|
|
15
|
+
- 🔐 **RFC 8628 Device Authorization**: Secure, headless browser-based login with standard OAuth 2.0 device flow.
|
|
16
|
+
- 🛡️ **Enterprise Credential Security**: Integrates with native OS Keychains (macOS Keychain, Linux Secret Service) with atomic, permissions-hardened file fallbacks.
|
|
17
|
+
- 🤖 **Native AI Assistant Support**: Plug-and-play Model Context Protocol (MCP) server for Claude, Cursor, and custom agentic frameworks.
|
|
18
|
+
- 📦 **Standalone Zero-Dependency Binary**: Self-contained runtime bundle engineered for maximum reliability.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Quickstart
|
|
23
|
+
|
|
24
|
+
### Run with `npx` (No installation needed)
|
|
54
25
|
|
|
55
26
|
```bash
|
|
56
|
-
#
|
|
57
|
-
iwas --
|
|
27
|
+
# Log in via interactive browser
|
|
28
|
+
npx @iwas/mcp login --browser
|
|
29
|
+
|
|
30
|
+
# Check session & authentication status
|
|
31
|
+
npx @iwas/mcp status
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Install Globally
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install -g @iwas/mcp
|
|
38
|
+
|
|
39
|
+
# Verify installation
|
|
58
40
|
iwas --version
|
|
41
|
+
iwas --help
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
*(Note: `iwas-mcp` is also provided as a backward-compatible command alias).*
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Integrating with AI Assistants
|
|
49
|
+
|
|
50
|
+
You can wire IWAS tools directly into your favorite AI environments via standard MCP configuration:
|
|
51
|
+
|
|
52
|
+
### Claude Desktop (`claude_desktop_config.json`)
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"mcpServers": {
|
|
57
|
+
"iwas": {
|
|
58
|
+
"command": "npx",
|
|
59
|
+
"args": ["-y", "@iwas/mcp"]
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Cursor / Cline / Antigravity
|
|
66
|
+
|
|
67
|
+
Configure an MCP server with command `npx` and arguments `["-y", "@iwas/mcp"]`. The CLI will automatically use your stored credentials from `iwas login`.
|
|
59
68
|
|
|
60
|
-
|
|
61
|
-
iwas login
|
|
62
|
-
iwas login --server https://getiwas.com --no-browser
|
|
63
|
-
iwas login --scopes "analytics:read session:read offline_access" --json
|
|
69
|
+
---
|
|
64
70
|
|
|
65
|
-
|
|
71
|
+
## CLI Commands
|
|
72
|
+
|
|
73
|
+
### 1. `iwas login`
|
|
74
|
+
Authenticate your workstation or development environment using OAuth 2.0 Device Flow:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Interactive login with automatic browser opening
|
|
78
|
+
iwas login --browser
|
|
79
|
+
|
|
80
|
+
# Connect to a custom or self-hosted IWAS gateway
|
|
81
|
+
iwas login --server https://getiwas.com --browser
|
|
82
|
+
|
|
83
|
+
# Headless / remote server login (shows verification URL & code)
|
|
84
|
+
iwas login --no-browser
|
|
85
|
+
|
|
86
|
+
# Request custom scopes
|
|
87
|
+
iwas login --scopes "analytics:read session:read offline_access"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 2. `iwas status`
|
|
91
|
+
Inspect the active authenticated profile, expiration status, and authorized scopes:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
66
94
|
iwas status
|
|
67
|
-
iwas status --server https://getiwas.com --json
|
|
68
95
|
|
|
69
|
-
#
|
|
96
|
+
# JSON output for automated scripting & CI/CD
|
|
97
|
+
iwas status --json
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 3. `iwas logout`
|
|
101
|
+
Revoke active session grants on the server and remove stored credentials from the local vault:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
70
104
|
iwas logout
|
|
71
|
-
|
|
105
|
+
|
|
106
|
+
# Force local cleanup even if the authentication server is unreachable
|
|
107
|
+
iwas logout --force
|
|
72
108
|
```
|
|
73
109
|
|
|
74
|
-
|
|
110
|
+
---
|
|
75
111
|
|
|
76
|
-
|
|
112
|
+
## Machine-Readable JSON Mode (`--json`)
|
|
77
113
|
|
|
78
|
-
|
|
114
|
+
When passed the `--json` flag, all commands output structured, newline-delimited JSON events to `stdout`, while human-readable prompts and notices are redirected to `stderr`.
|
|
79
115
|
|
|
80
|
-
|
|
81
|
-
|
|
116
|
+
**Example: Initiating device login**
|
|
117
|
+
```json
|
|
118
|
+
{"event":"device_authorization","user_code":"WDJB-MJHT","verification_uri":"https://getiwas.com/device","verification_uri_complete":"https://getiwas.com/device?user_code=WDJB-MJHT","expires_in":600,"interval":5}
|
|
119
|
+
```
|
|
82
120
|
|
|
83
|
-
|
|
121
|
+
**Example: Successful login**
|
|
122
|
+
```json
|
|
123
|
+
{"event":"login_success","success":true,"profileKey":"https://getiwas.com::iwas-cli","serverUrl":"https://getiwas.com","clientId":"iwas-cli","organizationId":"org_123","scope":"...","expiresAt":1792376265000}
|
|
124
|
+
```
|
|
84
125
|
|
|
85
|
-
|
|
126
|
+
---
|
|
86
127
|
|
|
87
|
-
|
|
88
|
-
```json
|
|
89
|
-
{"event":"device_authorization","user_code":"WDJB-MJHT","verification_uri":"https://getiwas.com/device","verification_uri_complete":"https://getiwas.com/device?user_code=WDJB-MJHT","expires_in":600,"interval":5}
|
|
90
|
-
```
|
|
91
|
-
*Security:* per RFC 8628 §3.2, `device_code` is strictly kept internal to the CLI and never included in this payload.
|
|
128
|
+
## TypeScript SDK & Programmatic Usage
|
|
92
129
|
|
|
93
|
-
|
|
94
|
-
```json
|
|
95
|
-
{"event":"login_success","success":true,"profileKey":"https://getiwas.com::iwas-cli","serverUrl":"https://getiwas.com","clientId":"iwas-cli","organizationId":"org_123","scope":"...","resource":"...","expiresAt":1792376265000}
|
|
96
|
-
```
|
|
130
|
+
`@iwas/mcp` provides first-class TypeScript library exports for building custom agents and administrative tools:
|
|
97
131
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
132
|
+
```bash
|
|
133
|
+
pnpm add @iwas/mcp
|
|
134
|
+
# or
|
|
135
|
+
npm install @iwas/mcp
|
|
136
|
+
```
|
|
102
137
|
|
|
103
|
-
|
|
138
|
+
### Subpath Exports
|
|
104
139
|
|
|
105
|
-
|
|
140
|
+
* `@iwas/mcp` — Core entrypoint and package metadata.
|
|
141
|
+
* `@iwas/mcp/client` — Programmatic MCP client transport and client interfaces.
|
|
142
|
+
* `@iwas/mcp/auth` — Credential vault (`CredentialVault`), Token refresh manager (`TokenRefreshManager`), and OS Keychain utilities.
|
|
143
|
+
* `@iwas/mcp/catalog` — Typed permission vocabulary and tool definition catalog.
|
|
106
144
|
|
|
107
|
-
|
|
145
|
+
### Example: Automated Token Refresh in Node.js
|
|
108
146
|
|
|
109
147
|
```typescript
|
|
110
148
|
import { CredentialVault, TokenRefreshManager } from '@iwas/mcp/auth';
|
|
@@ -112,24 +150,27 @@ import { CredentialVault, TokenRefreshManager } from '@iwas/mcp/auth';
|
|
|
112
150
|
const vault = new CredentialVault();
|
|
113
151
|
const refreshManager = new TokenRefreshManager({ vault });
|
|
114
152
|
|
|
115
|
-
// Automatically
|
|
153
|
+
// Automatically retrieves a valid token, refreshing via OAuth family rotation if near expiration
|
|
116
154
|
const accessToken = await refreshManager.getValidAccessToken('https://getiwas.com::iwas-cli');
|
|
117
155
|
```
|
|
118
156
|
|
|
119
|
-
|
|
120
|
-
- **In-process Single-flight:** Multiple concurrent asynchronous calls (both automatic and explicit force `refresh()`) for the same profile collapse to exactly one HTTP refresh request.
|
|
121
|
-
- **Cross-process Mutual Exclusion (`VaultLock`):** Protects `<config-dir>/iwas/credentials.lock` via atomic `wx` creation (mode `0600`), dedicated app directory `0700` verification, and default 60s bounded timeout.
|
|
122
|
-
- **Double-Checked Locking:** After acquiring the cross-process lock, the vault is re-read. If another concurrent process has already rotated the token family, the refreshed token is used immediately without issuing a redundant request.
|
|
123
|
-
- **Active Process Immunity & Dead PID Reclaim (M1):** On the same host, a lock owned by a running process (`process.kill(pid, 0)`) is **never** reclaimed or stolen regardless of age, preventing token family destruction during slow network operations. Stale lock recovery occurs only when the holding PID is confirmed dead. *Cross-host/network FS tradeoff:* Across different machines or on shared network mounts (e.g. NFS/SMB), remote PIDs cannot be probed, so locks older than `staleTimeoutMs = 60s` are reclaimed based on lease age; configure a higher `staleTimeoutMs` for multi-host setups with operations exceeding 60s.
|
|
124
|
-
- **TOCTOU-Safe Reclamation & Inode Verification:** Stale locks are verified via hardlink (`linkSync`) + `nlink` checks and inode matching before unlinking, ensuring racing processes acquiring new locks are never unlinked or overwritten. If the filesystem does not support hardlinks, reclamation fails closed (the caller times out) rather than risk deleting a live lock; remove the stale lock manually in that environment.
|
|
125
|
-
- **Strictly Scoped Terminal Errors (M2):** ONLY `invalid_grant` (revoked/expired refresh token) and `invalid_client` purge local vault credentials and raise `ReauthenticationRequiredError`. Non-terminal 4xx errors (e.g. `invalid_request`, `invalid_scope`) throw sanitized errors while safely preserving credentials in the vault.
|
|
126
|
-
- **Transient Retries & 30s Reuse Grace Window:** Network errors and 5xx server errors retry with bounded exponential backoff and never wipe stored credentials. Single retry on POST is protected by Better Auth's 30s refresh token reuse grace window (`MCP-OAUTH-04`).
|
|
127
|
-
- **Atomic Persistence Failure Handling:** If saving rotated credentials to the vault fails, the profile is purged and raises `ReauthenticationRequiredError` ('persistence_failure') to avoid repeated replay of stale refresh tokens. Secret tokens are strictly redacted from diagnostic logs and error messages.
|
|
157
|
+
---
|
|
128
158
|
|
|
129
|
-
##
|
|
159
|
+
## Credential Storage & Security
|
|
130
160
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
161
|
+
Credentials are protected using defense-in-depth:
|
|
162
|
+
|
|
163
|
+
* **macOS**: Stored securely in the **macOS Keychain Services** under service `iwas-cli`.
|
|
164
|
+
* **Linux**: Stored via standard **Secret Service API / libsecret**.
|
|
165
|
+
* **Headless / Windows / Container Fallback**: Stored in `~/.config/iwas/credentials.json` with strict POSIX `0600` permissions and atomic write guarantees.
|
|
166
|
+
|
|
167
|
+
You can explicitly enforce storage mode via the `IWAS_MCP_VAULT` environment variable:
|
|
168
|
+
- `IWAS_MCP_VAULT=auto` (default: Keychain if available, fallback to file)
|
|
169
|
+
- `IWAS_MCP_VAULT=keychain` (strict Keychain only)
|
|
170
|
+
- `IWAS_MCP_VAULT=file` (strict file storage only)
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## License
|
|
175
|
+
|
|
176
|
+
MIT © [9xlayer](https://getiwas.com)
|