openclaw-mcp 1.5.0 → 1.6.0
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 +3 -0
- package/dist/index.js +9 -7
- package/docs/configuration.md +12 -0
- package/docs/deployment.md +20 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -54,6 +54,7 @@ services:
|
|
|
54
54
|
- MCP_CLIENT_ID=openclaw
|
|
55
55
|
- MCP_CLIENT_SECRET=${MCP_CLIENT_SECRET}
|
|
56
56
|
- MCP_ISSUER_URL=${MCP_ISSUER_URL:-}
|
|
57
|
+
- MCP_REDIRECT_URIS=https://claude.ai/api/mcp/auth_callback,https://claude.com/api/mcp/auth_callback
|
|
57
58
|
- TRUST_PROXY=1
|
|
58
59
|
- CORS_ORIGINS=https://claude.ai
|
|
59
60
|
extra_hosts:
|
|
@@ -115,6 +116,8 @@ AUTH_ENABLED=true MCP_CLIENT_ID=openclaw MCP_CLIENT_SECRET=your-secret \
|
|
|
115
116
|
> - `MCP_ISSUER_URL` (or `--issuer-url`) to your public HTTPS URL — otherwise OAuth metadata advertises `http://localhost:3000` and clients fail to authenticate.
|
|
116
117
|
> - `TRUST_PROXY=1` (or `--trust-proxy 1`) — otherwise `express-rate-limit` rejects the proxy's `X-Forwarded-For` header and `/token` crashes with `ERR_ERL_UNEXPECTED_X_FORWARDED_FOR`.
|
|
117
118
|
|
|
119
|
+
> **Recommended:** Set `MCP_REDIRECT_URIS=https://claude.ai/api/mcp/auth_callback,https://claude.com/api/mcp/auth_callback` so authorization codes can only be delivered to Claude's callbacks. Note the exact `/api/mcp/auth_callback` path — matching is exact, and getting it wrong fails OAuth with `Unregistered redirect_uri` (see [Troubleshooting](docs/deployment.md#invalid_request--unregistered-redirect_uri-on-authorize)).
|
|
120
|
+
|
|
118
121
|
See [Installation Guide](docs/installation.md) for details.
|
|
119
122
|
|
|
120
123
|
## Architecture
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
5
5
|
|
|
6
6
|
// src/config/constants.ts
|
|
7
7
|
var SERVER_NAME = "openclaw-mcp";
|
|
8
|
-
var SERVER_VERSION = "1.
|
|
8
|
+
var SERVER_VERSION = "1.6.0";
|
|
9
9
|
var DEFAULT_OPENCLAW_URL = "http://127.0.0.1:18789";
|
|
10
10
|
var DEFAULT_MODEL = "openclaw";
|
|
11
11
|
var SERVER_ICON_SVG_BASE64 = "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjgiIGhlaWdodD0iMTI4IiB2aWV3Qm94PSIwIDAgMTI4IDEyOCIgZmlsbD0ibm9uZSI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJiZyIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzFhMWEyZSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzE2MjEzZSIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJjbGF3IiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIxMDAlIj48c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjZmYzMzMzIi8+PHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjY2MwMDAwIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3Qgd2lkdGg9IjEyOCIgaGVpZ2h0PSIxMjgiIHJ4PSIyNCIgZmlsbD0idXJsKCNiZykiLz48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSg2NCA2NCkiIHN0cm9rZT0idXJsKCNjbGF3KSIgc3Ryb2tlLXdpZHRoPSI3IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGZpbGw9Im5vbmUiPjxwYXRoIGQ9Ik0tMjggLTM4YzAgMCAtMTAgMjAgMCAzMiIvPjxwYXRoIGQ9Ik0tMTIgLTQwYzAgMCAtNiAyMiA0IDM0Ii8+PHBhdGggZD0iTTI4IC0zOGMwIDAgMTAgMjAgMCAzMiIvPjxwYXRoIGQ9Ik0xMiAtNDBjMCAwIDYgMjIgLTQgMzQiLz48Y2lyY2xlIGN4PSIwIiBjeT0iMTAiIHI9IjIwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNLTEwIDR2LTQiIHN0cm9rZS13aWR0aD0iNCIvPjxwYXRoIGQ9Ik0xMCA0di00IiBzdHJva2Utd2lkdGg9IjQiLz48cGF0aCBkPSJNLTggMjBjNCA2IDEyIDYgMTYgMCIgc3Ryb2tlLXdpZHRoPSIzIi8+PC9nPjwvc3ZnPg==";
|
|
@@ -1175,13 +1175,15 @@ var TOKEN_TTL_MS = 60 * 60 * 1e3;
|
|
|
1175
1175
|
var AUTH_CODE_TTL_MS = 10 * 60 * 1e3;
|
|
1176
1176
|
var REFRESH_TOKEN_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
1177
1177
|
var REAPER_INTERVAL_MS = 5 * 60 * 1e3;
|
|
1178
|
-
var
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
if (prop === "length") return 1;
|
|
1182
|
-
return Reflect.get(target, prop);
|
|
1178
|
+
var AllowAnyRedirectUris = class extends Array {
|
|
1179
|
+
includes(_searchElement, _fromIndex) {
|
|
1180
|
+
return true;
|
|
1183
1181
|
}
|
|
1184
|
-
|
|
1182
|
+
some(_predicate, _thisArg) {
|
|
1183
|
+
return true;
|
|
1184
|
+
}
|
|
1185
|
+
};
|
|
1186
|
+
var ALLOW_ANY_REDIRECT = new AllowAnyRedirectUris();
|
|
1185
1187
|
var MAX_DYNAMIC_CLIENTS = 100;
|
|
1186
1188
|
var OpenClawClientsStore = class {
|
|
1187
1189
|
client;
|
package/docs/configuration.md
CHANGED
|
@@ -170,6 +170,18 @@ When auth is enabled, the server exposes these OAuth 2.1 endpoints:
|
|
|
170
170
|
|
|
171
171
|
Dynamic client registration is **disabled by default** — only the pre-configured client (from `MCP_CLIENT_ID` + `MCP_CLIENT_SECRET`) can authenticate. This prevents anyone who knows the server URL from self-registering and bypassing auth.
|
|
172
172
|
|
|
173
|
+
#### Redirect URI allow-list
|
|
174
|
+
|
|
175
|
+
`MCP_REDIRECT_URIS` restricts which `redirect_uri` values the `/authorize` endpoint accepts for the pre-configured client. When unset, any redirect URI is accepted (the client secret verified during token exchange remains the actual auth gate) — set it in production so authorization codes can only be delivered to callbacks you trust.
|
|
176
|
+
|
|
177
|
+
Claude.ai uses exactly this callback (note the `/api/mcp/auth_callback` path):
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
MCP_REDIRECT_URIS=https://claude.ai/api/mcp/auth_callback,https://claude.com/api/mcp/auth_callback
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Matching is exact (scheme, host, path). A common mistake is registering `https://claude.ai/oauth/callback`, which does **not** match and makes Claude.ai fail with `Unregistered redirect_uri`. If you also connect other clients (e.g. MCP Inspector), append their callbacks to the comma-separated list — loopback callbacks (`http://localhost/...`, `http://127.0.0.1/...`) match on any port per RFC 8252.
|
|
184
|
+
|
|
173
185
|
#### Cursor / Windsurf compatibility (dev only)
|
|
174
186
|
|
|
175
187
|
Cursor and Windsurf only support MCP servers that expose OAuth 2.0 Dynamic Client Registration (RFC 7591). To let them connect, set `MCP_DANGEROUSLY_ALLOW_DCR=true`. The server will then advertise a `/register` endpoint and accept ad-hoc client registrations (kept in an in-memory FIFO store, capped at 100 entries).
|
package/docs/deployment.md
CHANGED
|
@@ -24,6 +24,7 @@ services:
|
|
|
24
24
|
- MCP_CLIENT_SECRET=${MCP_CLIENT_SECRET:-}
|
|
25
25
|
- MCP_ISSUER_URL=${MCP_ISSUER_URL:-}
|
|
26
26
|
- MCP_REDIRECT_URIS=${MCP_REDIRECT_URIS:-}
|
|
27
|
+
- TRUST_PROXY=${TRUST_PROXY:-}
|
|
27
28
|
- CORS_ORIGINS=${CORS_ORIGINS:-https://claude.ai}
|
|
28
29
|
- NODE_ENV=production
|
|
29
30
|
extra_hosts:
|
|
@@ -56,6 +57,12 @@ AUTH_ENABLED=true
|
|
|
56
57
|
# Public URL (required when behind a reverse proxy)
|
|
57
58
|
MCP_ISSUER_URL=https://mcp.your-domain.com
|
|
58
59
|
|
|
60
|
+
# Trust the reverse proxy's X-Forwarded-For (required behind a reverse proxy)
|
|
61
|
+
TRUST_PROXY=1
|
|
62
|
+
|
|
63
|
+
# Allowed OAuth redirect URIs — Claude.ai callbacks (recommended for production)
|
|
64
|
+
MCP_REDIRECT_URIS=https://claude.ai/api/mcp/auth_callback,https://claude.com/api/mcp/auth_callback
|
|
65
|
+
|
|
59
66
|
# Allowed CORS origins
|
|
60
67
|
CORS_ORIGINS=https://claude.ai
|
|
61
68
|
```
|
|
@@ -79,7 +86,7 @@ docker compose up -d
|
|
|
79
86
|
- [ ] `MCP_CLIENT_SECRET` generated securely (`openssl rand -hex 32`, min 32 chars)
|
|
80
87
|
- [ ] `MCP_ISSUER_URL` set to public HTTPS URL (when behind reverse proxy)
|
|
81
88
|
- [ ] `TRUST_PROXY` set to the right hop count / CIDR (when behind reverse proxy)
|
|
82
|
-
- [ ] `MCP_REDIRECT_URIS` restricted to known callback URLs
|
|
89
|
+
- [ ] `MCP_REDIRECT_URIS` restricted to known callback URLs (for Claude.ai: `https://claude.ai/api/mcp/auth_callback,https://claude.com/api/mcp/auth_callback`)
|
|
83
90
|
- [ ] CORS restricted to known origins (`CORS_ORIGINS=https://claude.ai`)
|
|
84
91
|
- [ ] `OPENCLAW_GATEWAY_TOKEN` set for gateway authentication
|
|
85
92
|
- [ ] Dynamic client registration is disabled (default — no `/register` endpoint)
|
|
@@ -205,6 +212,18 @@ You're running behind a reverse proxy but haven't set `MCP_ISSUER_URL`. The OAut
|
|
|
205
212
|
|
|
206
213
|
Your Claude.ai connector URL is missing the `/mcp` path. The MCP Streamable HTTP transport is mounted at `/mcp`, not at the server root (which is intentional — root is reserved for `/health`, `/.well-known/*`, OAuth endpoints, and legacy SSE endpoints). Update the connector URL in Claude.ai to end with `/mcp`, e.g. `https://mcp.your-domain.com/mcp`.
|
|
207
214
|
|
|
215
|
+
### `invalid_request` / `Unregistered redirect_uri` on `/authorize`
|
|
216
|
+
|
|
217
|
+
The `redirect_uri` the client sent is not on the server's allow-list. Two common causes:
|
|
218
|
+
|
|
219
|
+
1. **`MCP_REDIRECT_URIS` is set but doesn't contain the client's exact callback.** Claude.ai uses `https://claude.ai/api/mcp/auth_callback` (and `https://claude.com/api/mcp/auth_callback`) — a similar-looking entry like `https://claude.ai/oauth/callback` does **not** match. Matching is exact on scheme, host, and path; only loopback callbacks (`localhost`, `127.0.0.1`, `[::1]`) get port relaxation per RFC 8252.
|
|
220
|
+
|
|
221
|
+
2. **You're on bridge ≤ 1.5.0 with `MCP_REDIRECT_URIS` unset.** The allow-any fallback in those versions was silently broken by a change in MCP SDK 1.29 (the SDK switched its membership check from `.includes()` to `.some()`), so *every* redirect_uri was rejected — fresh `npx openclaw-mcp@latest` installs picked the new SDK up automatically. Upgrade to bridge ≥ 1.6.0, or set `MCP_REDIRECT_URIS` explicitly (recommended for production anyway):
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
MCP_REDIRECT_URIS=https://claude.ai/api/mcp/auth_callback,https://claude.com/api/mcp/auth_callback
|
|
225
|
+
```
|
|
226
|
+
|
|
208
227
|
### `ValidationError: ERR_ERL_UNEXPECTED_X_FORWARDED_FOR` on `/token`
|
|
209
228
|
|
|
210
229
|
The server is behind a reverse proxy that sets `X-Forwarded-For`, but Express's `trust proxy` is left at its default (`false`). The MCP SDK's OAuth handlers use `express-rate-limit`, which refuses to read the forwarded header in that configuration and crashes the request. Set `TRUST_PROXY=1` (single proxy in front) or `--trust-proxy 1`. Use a higher hop count, a CIDR/IP, or a keyword (`loopback`, `linklocal`, `uniquelocal`) for more complex topologies — see [Server Settings](configuration.md#server-settings-http-transport).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openclaw-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"mcpName": "io.github.freema/openclaw-mcp",
|
|
5
5
|
"description": "Model Context Protocol (MCP) server for OpenClaw AI assistant integration",
|
|
6
6
|
"author": "Tomáš Grasl <https://www.tomasgrasl.cz/>",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"node": ">=20.0.0"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
43
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
44
44
|
"yargs": "^17.7.2"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|