@pilot-status/mcp-server 0.1.0 → 0.1.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.
Files changed (2) hide show
  1. package/README.md +34 -81
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -2,24 +2,22 @@
2
2
 
3
3
  A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that
4
4
  exposes the **Pilot Status public `/v1` API** as MCP tools, so any MCP-capable
5
- client (Claude Desktop, Cursor, custom agents, …) can send WhatsApp messages,
6
- manage numbers/templates, read conversations, and more — using a Pilot Status
7
- API key.
5
+ client (Claude Desktop, Cursor, the claude.ai connector, custom agents, …) can
6
+ send WhatsApp messages, manage numbers/templates, read conversations, and more —
7
+ using a Pilot Status API key.
8
8
 
9
9
  It speaks two transports:
10
10
 
11
11
  - **stdio** — for local clients that spawn the server as a child process. The
12
12
  API key is read once from `PILOT_STATUS_API_KEY`.
13
- - **streamable HTTP** — deployable; clients connect over HTTP and authenticate
14
- either with an `x-api-key` header **or** with an OAuth 2.1 bearer token (for
15
- the [claude.ai custom connector](#remote-oauth--claudeai-connector)). Runs
16
- stateless (a fresh MCP session per request), so it scales horizontally behind
17
- a load balancer.
13
+ - **streamable HTTP** — clients connect over HTTP and authenticate either with an
14
+ `x-api-key` header **or** with an OAuth 2.1 bearer token (for the
15
+ [claude.ai custom connector](#remote-oauth--claudeai-connector)).
18
16
 
19
17
  ## Install
20
18
 
21
19
  ```bash
22
- # Run straight from npm (no clone/build):
20
+ # Run straight from npm (no install needed):
23
21
  npx @pilot-status/mcp-server stdio # stdio transport (default)
24
22
  npx @pilot-status/mcp-server http # streamable HTTP transport
25
23
 
@@ -42,8 +40,8 @@ There are two ways to authenticate against the public `/v1` API:
42
40
  1. **API key** (`x-api-key`) — a `ps_*` key, used by stdio and by HTTP clients
43
41
  that send the header themselves.
44
42
  2. **OAuth 2.1 bearer token** — used by the claude.ai custom connector
45
- (HTTP transport). The token is forwarded verbatim to `/v1`; this server does
46
- not verify it. See [Remote (OAuth)](#remote-oauth--claudeai-connector).
43
+ (HTTP transport). claude.ai handles the login, so no API key is shared with
44
+ the client. See [Remote (OAuth)](#remote-oauth--claudeai-connector).
47
45
 
48
46
  Scope matters (same rules as the REST API):
49
47
 
@@ -55,9 +53,9 @@ Scope matters (same rules as the REST API):
55
53
  surfaced as a tool error.)
56
54
 
57
55
  Under an OAuth/tenant token there is no number scope, so number-scoped tools
58
- accept an optional `whatsappNumberId` argument. It is sent as the
59
- `x-whatsapp-number-id` header so the backend can resolve the target number; it
60
- is ignored when the API key is already scoped to a single number.
56
+ accept an optional `whatsappNumberId` argument so the backend can resolve the
57
+ target number. It is ignored when the API key is already scoped to a single
58
+ number.
61
59
 
62
60
  Token-based pairing/connect routes (interactive browser flows) are intentionally
63
61
  **not** exposed as tools.
@@ -103,39 +101,24 @@ See [`.env.example`](./.env.example). Key variables:
103
101
  | `PILOT_STATUS_API_URL` | `https://pilotstatuss.com` | Public API base URL (no trailing slash). |
104
102
  | `PILOT_STATUS_API_KEY` | — | `ps_*` key. Required for stdio; optional fallback for HTTP. |
105
103
  | `PILOT_STATUS_API_KEY_ID` | — | Optional `x-api-key-id` companion. |
106
- | `MCP_RESOURCE_URL` | `https://mcp.pilotstatuss.com` | Public URL of THIS server (OAuth `resource`). |
104
+ | `MCP_RESOURCE_URL` | `https://mcp.pilotstatuss.com` | Public URL of this server (OAuth `resource`). |
107
105
  | `PILOT_STATUS_AUTH_SERVER_URL` | `https://pilotstatuss.com` | OAuth authorization server (the backend). |
108
106
  | `MCP_TRANSPORT` | `stdio` | `stdio` or `http`. |
109
107
  | `PORT` | `8787` | HTTP transport port. |
110
108
  | `HOST` | `0.0.0.0` | HTTP transport bind host. |
111
109
 
112
- ## Running
110
+ ## HTTP endpoint
113
111
 
114
- ```bash
115
- npm install # from the repo root (workspaces)
116
- npm --workspace @pilot-status/mcp-server run build
117
-
118
- # stdio (default)
119
- PILOT_STATUS_API_KEY=ps_xxx node apps/mcp-server/dist/index.js
120
-
121
- # streamable HTTP
122
- MCP_TRANSPORT=http PORT=8787 node apps/mcp-server/dist/index.js
123
- # or: node apps/mcp-server/dist/index.js http
124
- ```
125
-
126
- Dev mode (no build): `npm --workspace @pilot-status/mcp-server run dev`.
127
-
128
- ### HTTP endpoint
112
+ When running the HTTP transport, the server exposes:
129
113
 
130
114
  - `POST /mcp` — JSON-RPC over Streamable HTTP. Authenticate with `x-api-key:
131
115
  ps_xxx` **or** `Authorization: Bearer <oauth-token>`. With no credentials it
132
116
  replies `401` + `WWW-Authenticate`, which starts the OAuth flow.
133
117
  - `GET /.well-known/oauth-protected-resource` — OAuth 2.1 protected-resource
134
118
  metadata (RFC 9728); points discovery at the authorization server.
135
- - `GET /health` — liveness probe.
136
119
 
137
120
  ```bash
138
- curl -s http://localhost:8787/mcp \
121
+ curl -s https://mcp.pilotstatuss.com/mcp \
139
122
  -H "content-type: application/json" \
140
123
  -H "accept: application/json, text/event-stream" \
141
124
  -H "x-api-key: ps_xxx" \
@@ -146,8 +129,8 @@ curl -s http://localhost:8787/mcp \
146
129
 
147
130
  ### Claude Desktop / Cursor (stdio)
148
131
 
149
- Use the published binary via `npx` (recommended) — add to the client's MCP
150
- config (e.g. `claude_desktop_config.json`):
132
+ Use the published binary via `npx` — add to the client's MCP config (e.g.
133
+ `claude_desktop_config.json`):
151
134
 
152
135
  ```json
153
136
  {
@@ -164,12 +147,9 @@ config (e.g. `claude_desktop_config.json`):
164
147
  }
165
148
  ```
166
149
 
167
- Or point `command`/`args` at a local build
168
- (`node /absolute/path/to/apps/mcp-server/dist/index.js`).
169
-
170
150
  ### Remote / HTTP clients (API key)
171
151
 
172
- Point the client at the deployed URL and supply the API key as a header:
152
+ Point the client at the hosted URL and supply the API key as a header:
173
153
 
174
154
  ```json
175
155
  {
@@ -185,46 +165,19 @@ Point the client at the deployed URL and supply the API key as a header:
185
165
 
186
166
  ### Remote (OAuth) — claude.ai connector
187
167
 
188
- For the [claude.ai](https://claude.ai) **Custom Connector**, deploy this server
189
- (HTTP transport) at a public HTTPS URL and let claude.ai run the OAuth login —
190
- no API key is shared with the client.
191
-
192
- 1. Deploy with `MCP_TRANSPORT=http` and set:
193
- - `MCP_RESOURCE_URL` — the public URL of this server, e.g.
194
- `https://mcp.pilotstatuss.com`.
195
- - `PILOT_STATUS_AUTH_SERVER_URL` — the Pilot Status backend, e.g.
196
- `https://pilotstatuss.com` (the default).
197
- - Leave `PILOT_STATUS_API_KEY` **unset** so unauthenticated requests return a
198
- `401` challenge (otherwise the env key would short-circuit OAuth).
199
- 2. In claude.ai → **Settings → Connectors → Add custom connector**, set the URL
200
- to `https://mcp.pilotstatuss.com/mcp`.
201
- 3. claude.ai fetches `GET /.well-known/oauth-protected-resource`, discovers the
202
- authorization server (`PILOT_STATUS_AUTH_SERVER_URL`), and runs the OAuth
203
- 2.1 login (Pilot Status SSO). The resulting access token is sent on every
204
- `POST /mcp` as `Authorization: Bearer <token>`.
205
-
206
- This server is a **dumb forwarder**: it does not verify the token. It forwards
207
- the bearer token to the public `/v1` API, which validates it. If `/v1` rejects
208
- the token (`401`), the response is relayed as `401` + `WWW-Authenticate` so the
209
- client re-authenticates. The authorization server itself (`/api/oauth/*` and
210
- `/.well-known/oauth-authorization-server`) lives in the Pilot Status backend.
211
-
212
- ## Deployment
213
-
214
- `MCP_TRANSPORT=http` behind HTTPS at `MCP_RESOURCE_URL`. A container image +
215
- generator entry + Traefik host (`mcp.pilotstatuss.com`) and the backend
216
- authorization-server endpoints are tracked as follow-up tasks. The server is
217
- stateless, so it can run with multiple replicas behind the load balancer.
218
-
219
- ## Tests
168
+ For the [claude.ai](https://claude.ai) **Custom Connector**, point claude.ai at
169
+ the hosted HTTPS URL and let it run the OAuth login — no API key is shared with
170
+ the client.
220
171
 
221
- ```bash
222
- npm --workspace @pilot-status/mcp-server test
223
- ```
224
-
225
- Covers the API client (header injection, bearer/OAuth mode, the
226
- `x-whatsapp-number-id` selector, query building, HTTP error mapping), the HTTP
227
- transport (protected-resource metadata, the unauthenticated `401` +
228
- `WWW-Authenticate` challenge, CORS) and tool registration (every public endpoint
229
- registered, argument dispatch, number-selector threading, error wrapping).
230
- `fetch` is mocked for the unit tests — no external network access required.
172
+ 1. In claude.ai → **Settings → Connectors → Add custom connector**, set the URL
173
+ to `https://mcp.pilotstatuss.com/mcp`.
174
+ 2. claude.ai fetches `GET /.well-known/oauth-protected-resource`, discovers the
175
+ authorization server, and runs the OAuth 2.1 login (Pilot Status SSO). The
176
+ resulting access token is sent on every `POST /mcp` as
177
+ `Authorization: Bearer <token>`.
178
+
179
+ If you run your own instance, serve the HTTP transport at a public HTTPS URL and
180
+ set `MCP_RESOURCE_URL` to that URL and `PILOT_STATUS_AUTH_SERVER_URL` to the
181
+ Pilot Status backend (`https://pilotstatuss.com`). Leave `PILOT_STATUS_API_KEY`
182
+ unset so unauthenticated requests return the `401` challenge that starts the
183
+ OAuth flow.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pilot-status/mcp-server",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "description": "Model Context Protocol (MCP) server exposing the Pilot Status public /v1 API as tools. Supports stdio and streamable HTTP transports (with OAuth 2.1 for the claude.ai custom connector).",
6
6
  "license": "MIT",