@aerostack/openclaw-bridge 0.1.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 ADDED
@@ -0,0 +1,146 @@
1
+ # @aerostack/openclaw-bridge
2
+
3
+ Connect [OpenClaw](https://openclaw.ai) to any [Aerostack Workspace](https://aerostack.dev) — one URL, all your MCP tools, with built-in security.
4
+
5
+ [![License: MIT](https://img.shields.io/badge/LICENSE_//_MIT-3b5bdb?style=for-the-badge&labelColor=eff6ff)](https://opensource.org/licenses/MIT)
6
+ [![npm](https://img.shields.io/npm/v/@aerostack/openclaw-bridge?style=for-the-badge&color=3b5bdb&labelColor=eff6ff)](https://www.npmjs.com/package/@aerostack/openclaw-bridge)
7
+
8
+ ## Why?
9
+
10
+ OpenClaw only supports **stdio** MCP servers. Aerostack Workspaces use **HTTP**. This bridge connects them — no code required.
11
+
12
+ Instead of configuring 50 separate MCP servers in OpenClaw, point at one Aerostack Workspace and get:
13
+
14
+ - **All tools in one place** — composed from multiple MCP servers
15
+ - **Centralized OAuth** — 27+ providers managed by Aerostack, not your agent
16
+ - **Human approval gates** — sensitive tools require workspace owner approval before executing
17
+ - **Per-tool permissions** — workspace tokens scope exactly which tools are accessible
18
+ - **Usage tracking & audit** — every tool call logged and metered
19
+ - **Rate limiting** — per-token, plan-tiered
20
+
21
+ ## Quick Start
22
+
23
+ ### 1. Get a workspace token
24
+
25
+ In your [Aerostack Admin Dashboard](https://app.aerostack.dev), go to your workspace settings and generate a token (`mwt_...`).
26
+
27
+ ### 2. Configure OpenClaw
28
+
29
+ Add to your OpenClaw config (`openclaw.json` or via `openclaw mcp set`):
30
+
31
+ ```json
32
+ {
33
+ "mcp": {
34
+ "servers": {
35
+ "my-workspace": {
36
+ "command": "npx",
37
+ "args": ["-y", "@aerostack/openclaw-bridge"],
38
+ "env": {
39
+ "AEROSTACK_WORKSPACE_URL": "https://api.aerostack.dev/api/gateway/ws/my-workspace",
40
+ "AEROSTACK_TOKEN": "mwt_your_token_here"
41
+ }
42
+ }
43
+ }
44
+ }
45
+ }
46
+ ```
47
+
48
+ Or via CLI:
49
+
50
+ ```bash
51
+ openclaw mcp set my-workspace '{
52
+ "command": "npx",
53
+ "args": ["-y", "@aerostack/openclaw-bridge"],
54
+ "env": {
55
+ "AEROSTACK_WORKSPACE_URL": "https://api.aerostack.dev/api/gateway/ws/my-workspace",
56
+ "AEROSTACK_TOKEN": "mwt_your_token_here"
57
+ }
58
+ }'
59
+ ```
60
+
61
+ ### 3. Use it
62
+
63
+ ```
64
+ You: Search GitHub for open issues in my repo
65
+ OpenClaw: [calls github__search_issues via Aerostack workspace]
66
+ ```
67
+
68
+ Tools are namespaced as `{server}__{tool}` (e.g., `github__create_issue`, `slack__send_message`).
69
+
70
+ ## How It Works
71
+
72
+ ```
73
+ OpenClaw (stdio) → Bridge (this package) → HTTPS → Aerostack Workspace Gateway
74
+
75
+ ┌─────────────────────────┐
76
+ │ Fan-out to MCP servers │
77
+ │ GitHub, Slack, Gmail, │
78
+ │ custom Workers, etc. │
79
+ └─────────────────────────┘
80
+ ```
81
+
82
+ The bridge:
83
+
84
+ 1. Starts as a stdio MCP server (what OpenClaw expects)
85
+ 2. Forwards all JSON-RPC requests to your workspace over HTTPS
86
+ 3. Handles SSE streaming responses transparently
87
+ 4. Manages the approval gate flow automatically
88
+
89
+ ## Approval Gates
90
+
91
+ When a workspace owner configures approval requirements on sensitive tools, the bridge handles it transparently:
92
+
93
+ ```
94
+ OpenClaw calls dangerous_tool
95
+ → Bridge forwards to workspace
96
+ → Workspace returns "needs approval" (-32050)
97
+ → Bridge polls for approval status (logs to stderr)
98
+ → Workspace owner approves/rejects in admin dashboard
99
+ → Bridge retries on approval, returns error on rejection
100
+ ```
101
+
102
+ Your OpenClaw agent sees either a successful result or a clear error — no special handling needed.
103
+
104
+ ## Configuration
105
+
106
+ All configuration is via environment variables:
107
+
108
+ | Variable | Required | Default | Description |
109
+ |----------|----------|---------|-------------|
110
+ | `AEROSTACK_WORKSPACE_URL` | Yes | — | Full workspace endpoint URL |
111
+ | `AEROSTACK_TOKEN` | Yes | — | Workspace token (`mwt_...`) |
112
+ | `AEROSTACK_APPROVAL_POLL_MS` | No | `3000` | Approval polling interval (ms) |
113
+ | `AEROSTACK_APPROVAL_TIMEOUT_MS` | No | `300000` | Max approval wait time (5 min) |
114
+ | `AEROSTACK_REQUEST_TIMEOUT_MS` | No | `30000` | HTTP request timeout (30s) |
115
+
116
+ ## Supported MCP Methods
117
+
118
+ | Method | Description |
119
+ |--------|-------------|
120
+ | `tools/list` | List all tools from all workspace servers |
121
+ | `tools/call` | Call a namespaced tool (with approval handling) |
122
+ | `resources/list` | List resources from all workspace servers |
123
+ | `resources/read` | Read a specific resource |
124
+ | `prompts/list` | List prompts from all workspace servers |
125
+ | `prompts/get` | Get a prompt with arguments |
126
+
127
+ ## Works With Any stdio MCP Client
128
+
129
+ While built for OpenClaw, this bridge works with **any MCP client that supports stdio transport** — Claude Desktop, Cursor, Windsurf, or custom integrations.
130
+
131
+ ## Requirements
132
+
133
+ - Node.js 18+
134
+ - An Aerostack account with a configured workspace
135
+ - A workspace token with appropriate tool permissions
136
+
137
+ ## Links
138
+
139
+ - [Aerostack Docs](https://docs.aerostack.dev)
140
+ - [Aerostack Admin](https://app.aerostack.dev)
141
+ - [OpenClaw](https://openclaw.ai)
142
+ - [MCP Specification](https://modelcontextprotocol.io)
143
+
144
+ ## License
145
+
146
+ MIT
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @aerostack/openclaw-bridge
4
+ *
5
+ * stdio-to-HTTP bridge connecting OpenClaw (and any stdio MCP client)
6
+ * to an Aerostack Workspace via Streamable HTTP transport.
7
+ *
8
+ * OpenClaw config:
9
+ * {
10
+ * "mcp": {
11
+ * "servers": {
12
+ * "my-workspace": {
13
+ * "command": "npx",
14
+ * "args": ["-y", "@aerostack/openclaw-bridge"],
15
+ * "env": {
16
+ * "AEROSTACK_WORKSPACE_URL": "https://api.aerostack.dev/api/gateway/ws/my-workspace",
17
+ * "AEROSTACK_TOKEN": "mwt_..."
18
+ * }
19
+ * }
20
+ * }
21
+ * }
22
+ * }
23
+ */
24
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,265 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @aerostack/openclaw-bridge
4
+ *
5
+ * stdio-to-HTTP bridge connecting OpenClaw (and any stdio MCP client)
6
+ * to an Aerostack Workspace via Streamable HTTP transport.
7
+ *
8
+ * OpenClaw config:
9
+ * {
10
+ * "mcp": {
11
+ * "servers": {
12
+ * "my-workspace": {
13
+ * "command": "npx",
14
+ * "args": ["-y", "@aerostack/openclaw-bridge"],
15
+ * "env": {
16
+ * "AEROSTACK_WORKSPACE_URL": "https://api.aerostack.dev/api/gateway/ws/my-workspace",
17
+ * "AEROSTACK_TOKEN": "mwt_..."
18
+ * }
19
+ * }
20
+ * }
21
+ * }
22
+ * }
23
+ */
24
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
25
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
26
+ import { ListToolsRequestSchema, CallToolRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
27
+ // ── Config ─────────────────────────────────────────────────────────
28
+ const WORKSPACE_URL = process.env.AEROSTACK_WORKSPACE_URL;
29
+ const TOKEN = process.env.AEROSTACK_TOKEN;
30
+ const APPROVAL_POLL_INTERVAL_MS = parseInt(process.env.AEROSTACK_APPROVAL_POLL_MS ?? '3000', 10);
31
+ const APPROVAL_TIMEOUT_MS = parseInt(process.env.AEROSTACK_APPROVAL_TIMEOUT_MS ?? '300000', 10); // 5 min
32
+ const REQUEST_TIMEOUT_MS = parseInt(process.env.AEROSTACK_REQUEST_TIMEOUT_MS ?? '30000', 10);
33
+ if (!WORKSPACE_URL) {
34
+ process.stderr.write('ERROR: AEROSTACK_WORKSPACE_URL is required\n');
35
+ process.exit(1);
36
+ }
37
+ if (!TOKEN) {
38
+ process.stderr.write('ERROR: AEROSTACK_TOKEN is required\n');
39
+ process.exit(1);
40
+ }
41
+ // Strip trailing slash
42
+ const baseUrl = WORKSPACE_URL.replace(/\/+$/, '');
43
+ async function rpcCall(method, params) {
44
+ const body = {
45
+ jsonrpc: '2.0',
46
+ id: Date.now(),
47
+ method,
48
+ params: params ?? {},
49
+ };
50
+ const controller = new AbortController();
51
+ const timer = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
52
+ try {
53
+ const res = await fetch(baseUrl, {
54
+ method: 'POST',
55
+ headers: {
56
+ 'Content-Type': 'application/json',
57
+ 'Authorization': `Bearer ${TOKEN}`,
58
+ 'User-Agent': 'aerostack-openclaw-bridge/0.1.0',
59
+ 'X-Agent-Id': 'openclaw',
60
+ },
61
+ body: JSON.stringify(body),
62
+ signal: controller.signal,
63
+ });
64
+ clearTimeout(timer);
65
+ const contentType = res.headers.get('content-type') ?? '';
66
+ // Handle SSE streaming — collect all data events and return the last JSON-RPC response
67
+ if (contentType.includes('text/event-stream')) {
68
+ const text = await res.text();
69
+ return parseSSEResponse(text, body.id);
70
+ }
71
+ const json = await res.json();
72
+ return json;
73
+ }
74
+ catch (err) {
75
+ clearTimeout(timer);
76
+ const message = err instanceof Error ? err.message : 'Unknown error';
77
+ if (err instanceof Error && err.name === 'AbortError') {
78
+ return { jsonrpc: '2.0', id: body.id, error: { code: -32603, message: 'Request timed out' } };
79
+ }
80
+ return { jsonrpc: '2.0', id: body.id, error: { code: -32603, message: `HTTP error: ${message}` } };
81
+ }
82
+ }
83
+ function parseSSEResponse(text, requestId) {
84
+ const lines = text.split('\n');
85
+ let lastData = null;
86
+ for (const line of lines) {
87
+ if (line.startsWith('data: ')) {
88
+ try {
89
+ lastData = JSON.parse(line.slice(6));
90
+ }
91
+ catch {
92
+ // skip malformed lines
93
+ }
94
+ }
95
+ }
96
+ return lastData ?? { jsonrpc: '2.0', id: requestId, error: { code: -32603, message: 'Empty SSE response' } };
97
+ }
98
+ async function pollApproval(approvalId) {
99
+ const pollUrl = `${baseUrl}/approval-status/${approvalId}`;
100
+ const deadline = Date.now() + APPROVAL_TIMEOUT_MS;
101
+ process.stderr.write(`[aerostack-bridge] Tool requires approval (${approvalId}). Waiting...\n`);
102
+ while (Date.now() < deadline) {
103
+ await sleep(APPROVAL_POLL_INTERVAL_MS);
104
+ try {
105
+ const res = await fetch(pollUrl, {
106
+ headers: { 'User-Agent': 'aerostack-openclaw-bridge/0.1.0' },
107
+ });
108
+ if (!res.ok)
109
+ continue;
110
+ const status = await res.json();
111
+ if (status.status === 'executed') {
112
+ process.stderr.write(`[aerostack-bridge] Approved and executed.\n`);
113
+ return status;
114
+ }
115
+ if (status.status === 'approved') {
116
+ process.stderr.write(`[aerostack-bridge] Approved. Retrying tool call...\n`);
117
+ return status;
118
+ }
119
+ if (status.status === 'rejected') {
120
+ process.stderr.write(`[aerostack-bridge] Rejected: ${status.reviewer_note ?? 'no reason given'}\n`);
121
+ return status;
122
+ }
123
+ if (status.status === 'expired') {
124
+ process.stderr.write(`[aerostack-bridge] Approval expired.\n`);
125
+ return status;
126
+ }
127
+ // still pending — keep polling
128
+ }
129
+ catch {
130
+ // network error — keep trying
131
+ }
132
+ }
133
+ return { id: approvalId, status: 'expired', tool_name: '' };
134
+ }
135
+ function sleep(ms) {
136
+ return new Promise(resolve => setTimeout(resolve, ms));
137
+ }
138
+ // ── Handle tools/call with approval retry ──────────────────────────
139
+ async function callToolWithApproval(name, args) {
140
+ const response = await rpcCall('tools/call', { name, arguments: args });
141
+ // Check for approval-required error (-32050)
142
+ if (response.error?.code === -32050) {
143
+ const data = response.error.data;
144
+ const approvalId = data?.approval_id;
145
+ if (!approvalId) {
146
+ return { jsonrpc: '2.0', id: response.id, error: { code: -32603, message: 'Approval required but no approval_id returned' } };
147
+ }
148
+ const status = await pollApproval(approvalId);
149
+ if (status.status === 'rejected') {
150
+ return {
151
+ jsonrpc: '2.0',
152
+ id: response.id,
153
+ error: { code: -32603, message: `Tool call rejected: ${status.reviewer_note ?? 'no reason given'}` },
154
+ };
155
+ }
156
+ if (status.status === 'expired') {
157
+ return {
158
+ jsonrpc: '2.0',
159
+ id: response.id,
160
+ error: { code: -32603, message: 'Approval request expired' },
161
+ };
162
+ }
163
+ // Approved — retry the tool call (gateway will find the cached approval)
164
+ return rpcCall('tools/call', { name, arguments: args });
165
+ }
166
+ return response;
167
+ }
168
+ // ── MCP Server (stdio) ────────────────────────────────────────────
169
+ let cachedServerInfo = null;
170
+ async function ensureInitialized() {
171
+ if (cachedServerInfo)
172
+ return;
173
+ const res = await rpcCall('initialize', {
174
+ protocolVersion: '2024-11-05',
175
+ capabilities: {},
176
+ clientInfo: { name: 'aerostack-openclaw-bridge', version: '0.1.0' },
177
+ });
178
+ if (res.result) {
179
+ const r = res.result;
180
+ cachedServerInfo = {
181
+ protocolVersion: r.protocolVersion ?? '2024-11-05',
182
+ instructions: r.instructions,
183
+ };
184
+ }
185
+ }
186
+ const server = new Server({ name: 'aerostack-openclaw-bridge', version: '0.1.0' }, { capabilities: { tools: {}, resources: {}, prompts: {} } });
187
+ // ── tools/list ─────────────────────────────────────────────────────
188
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
189
+ await ensureInitialized();
190
+ const res = await rpcCall('tools/list');
191
+ if (res.error) {
192
+ throw new Error(res.error.message);
193
+ }
194
+ const result = res.result;
195
+ return { tools: result.tools ?? [] };
196
+ });
197
+ // ── tools/call ─────────────────────────────────────────────────────
198
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
199
+ await ensureInitialized();
200
+ const { name, arguments: args } = request.params;
201
+ const res = await callToolWithApproval(name, (args ?? {}));
202
+ if (res.error) {
203
+ return {
204
+ content: [{ type: 'text', text: `Error: ${res.error.message}` }],
205
+ isError: true,
206
+ };
207
+ }
208
+ const result = res.result;
209
+ return { content: result.content ?? [{ type: 'text', text: JSON.stringify(res.result) }] };
210
+ });
211
+ // ── resources/list ─────────────────────────────────────────────────
212
+ server.setRequestHandler(ListResourcesRequestSchema, async () => {
213
+ await ensureInitialized();
214
+ const res = await rpcCall('resources/list');
215
+ if (res.error) {
216
+ throw new Error(res.error.message);
217
+ }
218
+ const result = res.result;
219
+ return { resources: result.resources ?? [] };
220
+ });
221
+ // ── resources/read ─────────────────────────────────────────────────
222
+ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
223
+ await ensureInitialized();
224
+ const res = await rpcCall('resources/read', { uri: request.params.uri });
225
+ if (res.error) {
226
+ throw new Error(res.error.message);
227
+ }
228
+ const result = res.result;
229
+ return { contents: result.contents ?? [] };
230
+ });
231
+ // ── prompts/list ───────────────────────────────────────────────────
232
+ server.setRequestHandler(ListPromptsRequestSchema, async () => {
233
+ await ensureInitialized();
234
+ const res = await rpcCall('prompts/list');
235
+ if (res.error) {
236
+ throw new Error(res.error.message);
237
+ }
238
+ const result = res.result;
239
+ return { prompts: result.prompts ?? [] };
240
+ });
241
+ // ── prompts/get ────────────────────────────────────────────────────
242
+ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
243
+ await ensureInitialized();
244
+ const res = await rpcCall('prompts/get', {
245
+ name: request.params.name,
246
+ arguments: request.params.arguments,
247
+ });
248
+ if (res.error) {
249
+ throw new Error(res.error.message);
250
+ }
251
+ const result = res.result;
252
+ return { messages: result.messages ?? [] };
253
+ });
254
+ // ── Start ──────────────────────────────────────────────────────────
255
+ async function main() {
256
+ process.stderr.write(`[aerostack-bridge] Connecting to ${baseUrl}\n`);
257
+ const transport = new StdioServerTransport();
258
+ await server.connect(transport);
259
+ process.stderr.write(`[aerostack-bridge] Ready. Workspace: ${baseUrl}\n`);
260
+ }
261
+ main().catch((err) => {
262
+ process.stderr.write(`[aerostack-bridge] Fatal: ${err}\n`);
263
+ process.exit(1);
264
+ });
265
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@aerostack/openclaw-bridge",
3
+ "version": "0.1.0",
4
+ "description": "stdio-to-HTTP bridge connecting OpenClaw to Aerostack Workspaces via MCP",
5
+ "author": "Aerostack",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "main": "dist/index.js",
9
+ "types": "dist/index.d.ts",
10
+ "bin": {
11
+ "aerostack-openclaw-bridge": "dist/index.js"
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "scripts": {
17
+ "build": "tsc",
18
+ "prepublishOnly": "npm run build"
19
+ },
20
+ "dependencies": {
21
+ "@modelcontextprotocol/sdk": "^1.25.3"
22
+ },
23
+ "devDependencies": {
24
+ "typescript": "~5.8.3",
25
+ "@types/node": "^22.0.0"
26
+ },
27
+ "engines": {
28
+ "node": ">=18"
29
+ },
30
+ "keywords": [
31
+ "aerostack",
32
+ "openclaw",
33
+ "mcp",
34
+ "model-context-protocol",
35
+ "bridge",
36
+ "stdio"
37
+ ]
38
+ }