@iwas/mcp 1.0.0 → 1.0.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 +372 -101
- package/dist/auth/index.d.ts +5 -1
- 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 +6 -11
- package/dist/index.js +25 -3458
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,135 +1,406 @@
|
|
|
1
1
|
# @iwas/mcp
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- **
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
+
# IWAS MCP server
|
|
4
|
+
|
|
5
|
+
[`@iwas/mcp`](https://www.npmjs.com/package/@iwas/mcp) is the official MCP server for [IWAS](https://getiwas.com) — the enterprise WiFi billing, captive portal, FreeRADIUS control, and network presence intelligence platform.
|
|
6
|
+
|
|
7
|
+
It operates over **stdio** as a secure bridge: it signs in via OAuth 2.0 Device Authorization (RFC 8628), persists credentials to native OS Keychains, transparently rotates expired tokens behind a cross-process lock (`VaultLock`), and proxies MCP tool calls to the IWAS API with authorized Bearer tokens.
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/@iwas/mcp)
|
|
10
|
+
[](https://opensource.org/licenses/MIT)
|
|
11
|
+
[](https://nodejs.org)
|
|
12
|
+
|
|
13
|
+
> 💡 **Dual-Transport Architecture:** Every IWAS API deployment also exposes a native Streamable HTTP MCP endpoint at `/mcp` (e.g. `https://getiwas.com/mcp` or `http://localhost:3001/mcp`) supporting RFC 9728 Protected Resource Metadata and RFC 9449 DPoP proofs. If your client supports direct Streamable HTTP (such as cloud agents or webhooks), you can connect directly. For desktop AI IDEs that communicate over stdio, use this `@iwas/mcp` bridge.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Highlights
|
|
18
|
+
|
|
19
|
+
- 🚀 **Zero Setup**: Run instantly via `npx -y @iwas/mcp` without cloning the repository or pre-installing dependencies.
|
|
20
|
+
- 🔐 **RFC 8628 Device Authorization**: Browser-based interactive login supporting Passkeys (Touch ID/Face ID), Google OAuth, and 2FA.
|
|
21
|
+
- 🛡️ **Native OS Keychain Security**: Stores tokens directly in **Apple Keychain Services** (macOS) and **Secret Service** (Linux), with atomic POSIX `0600` file fallback.
|
|
22
|
+
- 🔄 **Silent Token Rotation**: Seamless background refresh before expiration (`TokenRefreshManager`) and automatic recovery on HTTP 401.
|
|
23
|
+
- 🔒 **Concurrency-Safe (`VaultLock`)**: Cross-process file locking ensures multiple IDE windows or concurrent subagents never corrupt token families.
|
|
24
|
+
- 🤖 **Plug-and-Play AI Assistant Support**: Instant integration for Claude Desktop, Cursor, Antigravity IDE, Windsurf, and VS Code (Cline / Roo Code).
|
|
25
|
+
- 📦 **Dual Executable**: Provides both `iwas` and backward-compatible `iwas-mcp` CLI commands.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Prerequisites
|
|
30
|
+
|
|
31
|
+
- **Node.js 18+** (Node.js 20+ recommended)
|
|
32
|
+
- An accessible IWAS API instance (defaults to production `https://getiwas.com`, or local development `http://localhost:3001`).
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Quickstart
|
|
37
|
+
|
|
38
|
+
### 1. Authenticate Workstation
|
|
39
|
+
|
|
40
|
+
Run the login command once to authenticate your machine via OAuth 2.0 Device Flow:
|
|
54
41
|
|
|
55
42
|
```bash
|
|
56
|
-
#
|
|
57
|
-
iwas
|
|
58
|
-
|
|
43
|
+
# Interactive login (automatically opens browser)
|
|
44
|
+
npx -y @iwas/mcp login
|
|
45
|
+
|
|
46
|
+
# Connect to a self-hosted or local development instance
|
|
47
|
+
npx -y @iwas/mcp login --server http://localhost:3001
|
|
48
|
+
|
|
49
|
+
# Headless / remote server login (prints verification URL & user code)
|
|
50
|
+
npx -y @iwas/mcp login --no-browser
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 2. Verify Session Status
|
|
54
|
+
|
|
55
|
+
Inspect your active profile and token remaining duration:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Check default production profile (https://getiwas.com)
|
|
59
|
+
npx -y @iwas/mcp status
|
|
60
|
+
|
|
61
|
+
# Check a specific server or local development instance
|
|
62
|
+
npx -y @iwas/mcp status --server http://localhost:3001
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
_Example Output:_
|
|
66
|
+
|
|
67
|
+
```text
|
|
68
|
+
============================================================
|
|
69
|
+
IWAS MCP Auth Status
|
|
70
|
+
============================================================
|
|
71
|
+
|
|
72
|
+
- Profile: https://getiwas.com::iwas-cli
|
|
73
|
+
- Server: https://getiwas.com
|
|
74
|
+
- Client ID: iwas-cli
|
|
75
|
+
- Status: 🟢 Active
|
|
76
|
+
- Organization: org_123 (or platform scope)
|
|
77
|
+
- Resource: https://getiwas.com/mcp
|
|
78
|
+
- Expires: 2026-10-19T10:43:18.314Z (48m 51s remaining)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Integrating with AI Assistants
|
|
84
|
+
|
|
85
|
+
Wire IWAS tools into your AI coding assistant using standard MCP configuration.
|
|
86
|
+
|
|
87
|
+
> ⚠️ **Important:** Ensure you have completed `npx -y @iwas/mcp login` once before launching your MCP client.
|
|
88
|
+
|
|
89
|
+
### Claude Desktop (`claude_desktop_config.json`)
|
|
90
|
+
|
|
91
|
+
On macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
92
|
+
On Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"mcpServers": {
|
|
97
|
+
"iwas": {
|
|
98
|
+
"command": "npx",
|
|
99
|
+
"args": ["-y", "@iwas/mcp", "mcp"],
|
|
100
|
+
"env": {
|
|
101
|
+
"IWAS_SERVER_URL": "https://getiwas.com"
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Cursor (`.cursor/mcp.json` or Global Features > MCP)
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"mcpServers": {
|
|
113
|
+
"iwas": {
|
|
114
|
+
"command": "npx",
|
|
115
|
+
"args": ["-y", "@iwas/mcp", "mcp"],
|
|
116
|
+
"env": {
|
|
117
|
+
"IWAS_SERVER_URL": "https://getiwas.com"
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Antigravity IDE (`mcp_config.json`)
|
|
125
|
+
|
|
126
|
+
In `~/.gemini/config/mcp_config.json` or `.agents/mcp_config.json`:
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"mcpServers": {
|
|
131
|
+
"iwas": {
|
|
132
|
+
"command": "npx",
|
|
133
|
+
"args": ["-y", "@iwas/mcp", "mcp"],
|
|
134
|
+
"env": {
|
|
135
|
+
"IWAS_SERVER_URL": "https://getiwas.com"
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### VS Code (Cline / Roo Code)
|
|
143
|
+
|
|
144
|
+
In Cline MCP settings (`cline_mcp_settings.json`):
|
|
145
|
+
|
|
146
|
+
```json
|
|
147
|
+
{
|
|
148
|
+
"mcpServers": {
|
|
149
|
+
"iwas": {
|
|
150
|
+
"command": "npx",
|
|
151
|
+
"args": ["-y", "@iwas/mcp", "mcp"],
|
|
152
|
+
"env": {
|
|
153
|
+
"IWAS_SERVER_URL": "https://getiwas.com"
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
> 💡 **Local Development:** When pairing against a local NestJS backend, set `"IWAS_SERVER_URL": "http://localhost:3001"`.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Environment Variables
|
|
165
|
+
|
|
166
|
+
| Variable | Default | Description |
|
|
167
|
+
| :---------------- | :-------------------- | :------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
168
|
+
| `IWAS_SERVER_URL` | `https://getiwas.com` | Base origin of the IWAS API & Auth server (e.g. `http://localhost:3001` for local dev). |
|
|
169
|
+
| `IWAS_MCP_VAULT` | `auto` | Credential storage mode: `auto` (OS Keychain with file fallback), `keychain` (strict OS Keychain only), or `file` (strict POSIX file only). |
|
|
170
|
+
| `XDG_CONFIG_HOME` | `~/.config` | Custom base directory for credentials file fallback (`$XDG_CONFIG_HOME/iwas/credentials.json`). |
|
|
171
|
+
|
|
172
|
+
_Note: Custom OAuth Client IDs and Resource endpoints can be configured via `--client-id <id>` and `--resource <url>` CLI options._
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## CLI Reference
|
|
177
|
+
|
|
178
|
+
The package provides two identical executable binaries: `iwas` and `iwas-mcp`.
|
|
179
|
+
|
|
180
|
+
```text
|
|
181
|
+
USAGE:
|
|
182
|
+
iwas <command> [options]
|
|
183
|
+
iwas-mcp <command> [options]
|
|
184
|
+
|
|
185
|
+
COMMANDS:
|
|
186
|
+
login Authenticate using OAuth 2.0 Device Authorization Grant (RFC 8628)
|
|
187
|
+
status Display current authentication status for a server profile
|
|
188
|
+
logout Remove stored credentials for a server profile
|
|
189
|
+
mcp Run a stdio MCP bridge using the stored device-flow credentials
|
|
190
|
+
help Display help information
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### `iwas login`
|
|
59
194
|
|
|
60
|
-
|
|
195
|
+
Initiate an OAuth 2.0 Device Authorization Grant flow:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
# Standard browser login
|
|
61
199
|
iwas login
|
|
62
|
-
iwas login --server https://getiwas.com --no-browser
|
|
63
|
-
iwas login --scopes "analytics:read session:read offline_access" --json
|
|
64
200
|
|
|
65
|
-
#
|
|
201
|
+
# Specify target server
|
|
202
|
+
iwas login --server http://localhost:3001
|
|
203
|
+
|
|
204
|
+
# Headless / remote SSH session (no browser)
|
|
205
|
+
iwas login --no-browser
|
|
206
|
+
|
|
207
|
+
# Custom least-privilege OAuth scopes
|
|
208
|
+
iwas login --scopes "analytics:read session:read offline_access"
|
|
209
|
+
|
|
210
|
+
# Machine-readable JSON output for automated scripting
|
|
211
|
+
iwas login --json
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### `iwas status`
|
|
215
|
+
|
|
216
|
+
Display authentication status, active profile, and human-readable expiration countdown:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
# Check default profile
|
|
66
220
|
iwas status
|
|
67
|
-
iwas status --server https://getiwas.com --json
|
|
68
221
|
|
|
69
|
-
#
|
|
222
|
+
# Check status for a specific server instance
|
|
223
|
+
iwas status --server http://localhost:3001
|
|
224
|
+
|
|
225
|
+
# Machine-readable JSON output
|
|
226
|
+
iwas status --json
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### `iwas logout`
|
|
230
|
+
|
|
231
|
+
Revoke active session grants on the server (RFC 7009) and purge stored credentials from the local vault:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
# Logout from default server
|
|
70
235
|
iwas logout
|
|
71
|
-
|
|
236
|
+
|
|
237
|
+
# Logout from a specific server instance
|
|
238
|
+
iwas logout --server http://localhost:3001
|
|
239
|
+
|
|
240
|
+
# Force local cleanup even if the authentication server is unreachable
|
|
241
|
+
iwas logout --force
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### `iwas mcp`
|
|
245
|
+
|
|
246
|
+
Launch the stdio-to-HTTP MCP bridge used by AI coding assistants. Reads tokens automatically from native OS Keychain and routes JSON-RPC frames:
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
iwas mcp
|
|
250
|
+
iwas mcp --server http://localhost:3001
|
|
72
251
|
```
|
|
73
252
|
|
|
74
|
-
|
|
253
|
+
_Note: The `mcp` command strictly reserves stdout for JSON-RPC frames; passing `--json` will error._
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## 🛠️ Complete MCP Capabilities Catalog (26 Tools + 2 Prompts)
|
|
258
|
+
|
|
259
|
+
### 1. Analytics & Revenue Intelligence
|
|
75
260
|
|
|
76
|
-
|
|
261
|
+
| Tool | Description |
|
|
262
|
+
| :--- | :--- |
|
|
263
|
+
| `get_dashboard_stats` | Real-time network telemetry, active WiFi guests, revenue today, and router connectivity. Aligned with `/api/admin/stats`. |
|
|
264
|
+
| `get_revenue_breakdown` | Granular revenue breakdown by time period, package tier, venue, and payment provider. Aligned with `/api/admin/revenue`. |
|
|
265
|
+
| `list_packages` | Paginated listing of hotspot billing packages, duration, bandwidth limits, and pricing. |
|
|
266
|
+
| `get_package` | Retrieve full configuration and tax category for a specific package ID. |
|
|
77
267
|
|
|
78
|
-
|
|
268
|
+
### 2. Sessions & FreeRADIUS Accounting
|
|
79
269
|
|
|
80
|
-
|
|
81
|
-
|
|
270
|
+
| Tool | Description |
|
|
271
|
+
| :--- | :--- |
|
|
272
|
+
| `list_active_sessions` | Inspect currently connected captive portal and hotspot guest sessions. |
|
|
273
|
+
| `list_today_sessions` | Query all guest sessions recorded for the current day with `revenueToday` summary. |
|
|
274
|
+
| `get_session_accounting` | Granular byte count, duration, and FreeRADIUS RFC 2866 accounting usage per session ID. |
|
|
82
275
|
|
|
83
|
-
###
|
|
276
|
+
### 3. Business Insights & Optimization
|
|
84
277
|
|
|
85
|
-
|
|
278
|
+
| Tool | Description |
|
|
279
|
+
| :--- | :--- |
|
|
280
|
+
| `summarize_package_performance` | Statistical duration, ARPU, and conversion metrics across billing plans (default 7-day lookback). |
|
|
281
|
+
| `suggest_promo_windows` | AI-driven revenue timing analysis to identify optimal discount and marketing windows. |
|
|
86
282
|
|
|
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.
|
|
283
|
+
### 4. Diagnostics & Network Observability
|
|
92
284
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
285
|
+
| Tool | Description |
|
|
286
|
+
| :--- | :--- |
|
|
287
|
+
| `read_service_health` | Real-time liveness, readiness, and database connectivity checks. Valid authentication required. |
|
|
288
|
+
| `get_mcp_span` | Retrieve end-to-end execution span telemetry for an MCP request by `requestId` or numeric ID. |
|
|
289
|
+
| `get_error_by_request_id` _(Platform Staff)_ | Deep diagnostic trace and error detail for a specific failed `requestId`. |
|
|
290
|
+
| `list_error_events` _(Platform Staff)_ | Fetch recent unhandled exceptions, paths, and sanitized stack traces. |
|
|
291
|
+
| `list_flow_events` _(Platform Staff)_ | Interactive multi-stage journey lifecycle traces (OAuth, login, checkout). |
|
|
292
|
+
| `list_issues` _(Platform Staff)_ | Recurring incident clusters, severity badges, and automated triage statuses. |
|
|
293
|
+
| `update_issue_status` _(Platform Staff)_ | Update diagnostic issue triage state (`open`, `investigating`, `resolved`, `ignored`). |
|
|
294
|
+
| `list_audit_logs` | Query tamper-evident administrative action history. |
|
|
295
|
+
| `query_system_logs` _(Platform Staff)_ | Execute structured queries against system JSONL infrastructure logs. |
|
|
97
296
|
|
|
98
|
-
|
|
99
|
-
```json
|
|
100
|
-
{"event":"error","error":"Invalid OAuth client: client not found"}
|
|
101
|
-
```
|
|
297
|
+
### 5. Captive Portal Content & Announcements
|
|
102
298
|
|
|
103
|
-
|
|
299
|
+
| Tool | Description |
|
|
300
|
+
| :--- | :--- |
|
|
301
|
+
| `blog_list_posts` | List captive portal venue announcements, promotions, and articles with filters. |
|
|
302
|
+
| `blog_get_post` | Retrieve full content and metadata of a specific portal post by ID or slug. |
|
|
303
|
+
| `blog_create_post` | Author a new captive portal announcement with Markdown, SEO tags, and translation pairing. |
|
|
304
|
+
| `blog_update_post` | Update title, content, published status, or cover image. |
|
|
305
|
+
| `blog_delete_post` | Soft-delete an obsolete portal announcement. |
|
|
306
|
+
| `blog_import_media` | Download an external image from a public URL and store it in IWAS media CDN storage. |
|
|
307
|
+
| `blog_request_upload_url` | Request a presigned URL for direct client-side media uploads. |
|
|
308
|
+
| `blog_upload_media_base64` | Direct Base64 media asset upload (max 10MB decoded) for portal banners. |
|
|
104
309
|
|
|
105
|
-
|
|
310
|
+
### 6. MCP Prompts (Pre-Configured Workflows)
|
|
106
311
|
|
|
107
|
-
|
|
312
|
+
| Prompt | Description | Parameters |
|
|
313
|
+
| :--- | :--- | :--- |
|
|
314
|
+
| `morning_revenue_digest` | Multi-step workflow to analyze 24-hour financial metrics, peak hours, and underperforming billing packages. | `lookbackDays` (1..30, optional) |
|
|
315
|
+
| `investigate_api_failure` | Diagnostic workflow to trace an error by `requestId`, inspect span telemetry, and correlate recurring issues. | `requestId` (string, optional) |
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## Security & Credential Storage
|
|
320
|
+
|
|
321
|
+
`@iwas/mcp` applies defense-in-depth principles to protect developer credentials:
|
|
322
|
+
|
|
323
|
+
1. **Native OS Keychains**:
|
|
324
|
+
- **macOS**: Stored securely in **Apple Keychain Services** under service name `iwas-cli` with account key `<serverUrl>::<clientId>`.
|
|
325
|
+
- **Linux**: Stored via standard **Secret Service API / libsecret**.
|
|
326
|
+
2. **Hardened File Fallback**:
|
|
327
|
+
- On headless environments, Docker containers, or Windows, credentials fall back to `~/.config/iwas/credentials.json` with strict POSIX `0700` directory and `0600` file permissions.
|
|
328
|
+
3. **Cross-Process Concurrency (`VaultLock`)**:
|
|
329
|
+
- Acquires an atomic file lock (`~/.config/iwas/credentials.lock`) during token refresh. Prevents race conditions and token family invalidation when multiple IDE windows or subagents make concurrent requests.
|
|
330
|
+
4. **Zero Token Leakage**:
|
|
331
|
+
- Tokens and secrets are automatically redacted from stdout, stderr, logs, and error traces.
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## Troubleshooting
|
|
336
|
+
|
|
337
|
+
### 1. `No IWAS credentials for profile "..."`
|
|
338
|
+
|
|
339
|
+
- **Cause:** The machine has not been authenticated yet.
|
|
340
|
+
- **Solution:** Run `npx -y @iwas/mcp login` (or `npx -y @iwas/mcp login --server http://localhost:3001` for local development).
|
|
341
|
+
|
|
342
|
+
### 2. `fetch failed: connection closed` or `ECONNREFUSED`
|
|
343
|
+
|
|
344
|
+
- **Cause:** The IWAS backend server specified by `IWAS_SERVER_URL` is offline or unreachable.
|
|
345
|
+
- **Solution:** Verify the API server is running (e.g. `pnpm dev:api` on `http://localhost:3001`) or check internet connectivity to `https://getiwas.com`.
|
|
346
|
+
|
|
347
|
+
### 3. macOS Keychain Permission Prompt
|
|
348
|
+
|
|
349
|
+
- **Cause:** macOS prompts once when a new Node.js binary accesses Keychain Services items created under `iwas-cli`.
|
|
350
|
+
- **Solution:** Click **"Always Allow"** in the macOS dialog. Alternatively, set `IWAS_MCP_VAULT=file` in your environment to use file-based storage.
|
|
351
|
+
|
|
352
|
+
### 4. `The mcp command reserves stdout for MCP frames; --json is not supported`
|
|
353
|
+
|
|
354
|
+
- **Cause:** Passing `--json` to `iwas mcp`.
|
|
355
|
+
- **Solution:** The MCP stdio protocol requires raw JSON-RPC on stdout. Do not pass `--json` to the `mcp` command.
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## Programmatic TypeScript SDK Usage
|
|
360
|
+
|
|
361
|
+
`@iwas/mcp` exports programmatic primitives for custom agent developers:
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
pnpm add @iwas/mcp
|
|
365
|
+
```
|
|
108
366
|
|
|
109
367
|
```typescript
|
|
110
|
-
import { CredentialVault, TokenRefreshManager } from '@iwas/mcp/auth'
|
|
368
|
+
import { CredentialVault, TokenRefreshManager } from '@iwas/mcp/auth'
|
|
111
369
|
|
|
112
|
-
const vault = new CredentialVault()
|
|
113
|
-
const refreshManager = new TokenRefreshManager({ vault })
|
|
370
|
+
const vault = new CredentialVault()
|
|
371
|
+
const refreshManager = new TokenRefreshManager({ vault })
|
|
114
372
|
|
|
115
|
-
// Automatically
|
|
116
|
-
const
|
|
373
|
+
// Automatically retrieves a valid token, refreshing via OAuth family rotation if near expiration:
|
|
374
|
+
const credentials = await refreshManager.getValidCredentials('https://getiwas.com::iwas-cli')
|
|
375
|
+
console.log('Access token:', credentials.accessToken)
|
|
117
376
|
```
|
|
118
377
|
|
|
119
|
-
###
|
|
120
|
-
|
|
121
|
-
-
|
|
122
|
-
-
|
|
123
|
-
-
|
|
124
|
-
-
|
|
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.
|
|
378
|
+
### Subpath Exports:
|
|
379
|
+
|
|
380
|
+
- `@iwas/mcp` — Core entrypoint and metadata.
|
|
381
|
+
- `@iwas/mcp/auth` — `CredentialVault`, `TokenRefreshManager`, `VaultLock`, and Device Flow utilities.
|
|
382
|
+
- `@iwas/mcp/catalog` — Typed permission vocabulary, tool schemas, and prompt definitions.
|
|
383
|
+
- `@iwas/mcp/client` — MCP client transport and Streamable HTTP utilities.
|
|
128
384
|
|
|
129
|
-
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## Develop from Source
|
|
388
|
+
|
|
389
|
+
From the monorepo root:
|
|
130
390
|
|
|
131
391
|
```bash
|
|
132
|
-
|
|
133
|
-
pnpm --filter @iwas/mcp
|
|
392
|
+
# Build the package
|
|
393
|
+
pnpm --filter @iwas/mcp build
|
|
394
|
+
|
|
395
|
+
# Run unit and integration tests (126 tests)
|
|
396
|
+
pnpm --filter @iwas/mcp test
|
|
397
|
+
|
|
398
|
+
# Run type check
|
|
134
399
|
pnpm --filter @iwas/mcp exec tsc --noEmit
|
|
135
400
|
```
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## License
|
|
405
|
+
|
|
406
|
+
MIT © [9xlayer](https://getiwas.com)
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -395,6 +395,10 @@ declare function pollDeviceToken(serverUrl: string, params: {
|
|
|
395
395
|
* Orchestrates the full login flow, saves credentials in vault, and formats output.
|
|
396
396
|
*/
|
|
397
397
|
declare function executeLogin(options?: DeviceLoginOptions): Promise<DeviceLoginResult>;
|
|
398
|
+
/**
|
|
399
|
+
* Formats a duration in seconds into human-readable units (e.g. "1d 2h 30m 15s", "52m 1s", or "45s").
|
|
400
|
+
*/
|
|
401
|
+
declare function formatRemainingDuration(totalSeconds: number): string;
|
|
398
402
|
/**
|
|
399
403
|
* Checks and outputs stored authentication status for the given profile.
|
|
400
404
|
*/
|
|
@@ -627,5 +631,5 @@ declare class TokenRefreshManager {
|
|
|
627
631
|
private performTokenExchange;
|
|
628
632
|
}
|
|
629
633
|
|
|
630
|
-
export { CredentialVault, DEFAULT_CLI_CLIENT_ID, DEFAULT_KEYCHAIN_SERVICE, DEFAULT_READ_ONLY_SCOPES, DEFAULT_SCOPES, DEFAULT_SERVER_URL, DEVICE_CODE_GRANT_TYPE, DefaultKeychainRunner, HttpError, KeychainService, ReauthenticationRequiredError, TokenRefreshManager, VaultLock, VaultLockError, VaultLockTimeoutError, decodeJwtPayload, defaultIsProcessAlive, executeLogin, executeLogout, executeStatus, isCredentialExpired, isLocalhost, isValidStoredCredentials, normalizeProfileKey, openBrowser, pollDeviceToken, redactCredentials, requestDeviceCode, resolveAuthServerUrl, resolveMcpResourceUrl, sanitizeSecretString, sendRequest, validateScopes, withVaultLock };
|
|
634
|
+
export { CredentialVault, DEFAULT_CLI_CLIENT_ID, DEFAULT_KEYCHAIN_SERVICE, DEFAULT_READ_ONLY_SCOPES, DEFAULT_SCOPES, DEFAULT_SERVER_URL, DEVICE_CODE_GRANT_TYPE, DefaultKeychainRunner, HttpError, KeychainService, ReauthenticationRequiredError, TokenRefreshManager, VaultLock, VaultLockError, VaultLockTimeoutError, decodeJwtPayload, defaultIsProcessAlive, executeLogin, executeLogout, executeStatus, formatRemainingDuration, isCredentialExpired, isLocalhost, isValidStoredCredentials, normalizeProfileKey, openBrowser, pollDeviceToken, redactCredentials, requestDeviceCode, resolveAuthServerUrl, resolveMcpResourceUrl, sanitizeSecretString, sendRequest, validateScopes, withVaultLock };
|
|
631
635
|
export type { CredentialVaultOptions, DeviceAuthorizationResponse, DeviceLoginOptions, DeviceLoginResult, HttpResponse, KeychainCommandRunner, KeychainOptions, KeychainRunResult, LogoutOptions, LogoutResult, McpCredentials, OAuthTokenErrorResponse, OAuthTokenSuccessResponse, RequestOptions, SpawnFunction, StoredMcpCredentials, TokenRefreshManagerOptions, VaultBackendType, VaultLockData, VaultLockOptions };
|