@mcp-b/webmcp-local-relay 2.2.0 → 2.3.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 +47 -28
- package/dist/browser/embed.js +1 -1
- package/dist/browser/widget.html +1 -1
- package/dist/browser/widget.js +1 -1
- package/dist/{cli.js → cli.mjs} +11 -2
- package/dist/cli.mjs.map +1 -0
- package/dist/{index.d.ts → index.d.mts} +45 -3
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +3 -0
- package/dist/{mcpRelayServer-rbay_DSr.js → mcpRelayServer-BL8kNwIK.mjs} +221 -109
- package/dist/mcpRelayServer-BL8kNwIK.mjs.map +1 -0
- package/package.json +34 -34
- package/skills/webmcp-local-relay/SKILL.md +2 -2
- package/dist/cli.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -3
- package/dist/mcpRelayServer-rbay_DSr.js.map +0 -1
- /package/dist/{cli.d.ts → cli.d.mts} +0 -0
package/README.md
CHANGED
|
@@ -84,6 +84,16 @@ Custom relay port:
|
|
|
84
84
|
></script>
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
+
Increase the per-request timeout (default `60000` ms) for tools that chain
|
|
88
|
+
several slow API calls and might exceed one minute:
|
|
89
|
+
|
|
90
|
+
```html
|
|
91
|
+
<script
|
|
92
|
+
src="https://cdn.jsdelivr.net/npm/@mcp-b/webmcp-local-relay@latest/dist/browser/embed.js"
|
|
93
|
+
data-request-timeout="120000"
|
|
94
|
+
></script>
|
|
95
|
+
```
|
|
96
|
+
|
|
87
97
|
Tool registration references:
|
|
88
98
|
|
|
89
99
|
- [`@mcp-b/global` quick start and `registerTool`](../global/README.md)
|
|
@@ -109,12 +119,12 @@ npx @mcp-b/webmcp-local-relay
|
|
|
109
119
|
|
|
110
120
|
The relay exposes four static management tools that are always available:
|
|
111
121
|
|
|
112
|
-
| Tool
|
|
113
|
-
|
|
114
|
-
| `webmcp_list_sources` | Lists connected browser tabs with metadata (tab ID, origin, URL, title, icon, tool count)
|
|
115
|
-
| `webmcp_list_tools`
|
|
116
|
-
| `webmcp_call_tool`
|
|
117
|
-
| `webmcp_open_page`
|
|
122
|
+
| Tool | Description |
|
|
123
|
+
| --------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
124
|
+
| `webmcp_list_sources` | Lists connected browser tabs with metadata (tab ID, origin, URL, title, icon, tool count) |
|
|
125
|
+
| `webmcp_list_tools` | Lists all relayed tools with source info |
|
|
126
|
+
| `webmcp_call_tool` | Invokes a relayed tool by name with JSON arguments — useful for clients that don't support dynamic tool registration |
|
|
127
|
+
| `webmcp_open_page` | Opens a URL in the user's default browser, or refreshes a connected source page by matching origin |
|
|
118
128
|
|
|
119
129
|
**Dynamic tools** are registered directly on the MCP server using the original tool name, sanitized to `[a-zA-Z0-9_]`. When tools from different tabs share a name, a short tab-ID suffix is appended for disambiguation:
|
|
120
130
|
|
|
@@ -153,6 +163,7 @@ npx @mcp-b/webmcp-local-relay --widget-origin https://myapp.com
|
|
|
153
163
|
- The default `allowedOrigins` is `*`, which permits any browser page to connect and register tools. This is convenient for development but means any website open in your browser can expose tools to the relay.
|
|
154
164
|
- `--widget-origin` validates the **host page origin** reported in the browser `hello` message. This is the origin of the page that loaded `embed.js` (e.g., `https://myapp.com`), regardless of whether the widget iframe is served from CDN or self-hosted.
|
|
155
165
|
- **Recommended:** Use `--widget-origin` to restrict which websites can register tools:
|
|
166
|
+
|
|
156
167
|
```bash
|
|
157
168
|
# Only allow tools from myapp.com
|
|
158
169
|
webmcp-local-relay --widget-origin https://myapp.com
|
|
@@ -160,6 +171,7 @@ npx @mcp-b/webmcp-local-relay --widget-origin https://myapp.com
|
|
|
160
171
|
# Allow multiple origins
|
|
161
172
|
webmcp-local-relay --widget-origin https://app1.com,https://app2.com
|
|
162
173
|
```
|
|
174
|
+
|
|
163
175
|
- Only the host page origin is checked — any local process can connect regardless of origin restrictions.
|
|
164
176
|
|
|
165
177
|
### Architecture
|
|
@@ -227,12 +239,13 @@ For Chromium/Chrome Canary native preview testing:
|
|
|
227
239
|
|
|
228
240
|
### Troubleshooting
|
|
229
241
|
|
|
230
|
-
| Problem
|
|
231
|
-
|
|
232
|
-
| `No sources connected`
|
|
233
|
-
| `No tools listed`
|
|
234
|
-
| `Tool not found`
|
|
235
|
-
| Connection blocked
|
|
242
|
+
| Problem | Fix |
|
|
243
|
+
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
244
|
+
| `No sources connected` | Ensure the page loaded `embed.js` and the relay process is running |
|
|
245
|
+
| `No tools listed` | Ensure tools are registered on the page's WebMCP runtime. If tools register after load, confirm your runtime emits tool-change notifications (`toolschanged` or `registerToolsChangedCallback`) |
|
|
246
|
+
| `Tool not found` | Tab reloaded or disconnected — call `webmcp_list_tools` again to refresh |
|
|
247
|
+
| Connection blocked | Verify `--widget-origin` matches your host page's origin (e.g., `https://myapp.com`), and relay port matches `data-relay-port` |
|
|
248
|
+
| `Host response timeout:` | The host page took longer than the per-request timeout (default 60s) to respond. Increase via `data-request-timeout="<ms>"` on the embed script tag |
|
|
236
249
|
|
|
237
250
|
---
|
|
238
251
|
|
|
@@ -242,18 +255,24 @@ For Chromium/Chrome Canary native preview testing:
|
|
|
242
255
|
|
|
243
256
|
```text
|
|
244
257
|
src/
|
|
245
|
-
├── cli.ts
|
|
246
|
-
├── cli-utils.ts
|
|
247
|
-
├── mcpRelayServer.ts
|
|
248
|
-
├── bridgeServer.ts
|
|
249
|
-
├── registry.ts
|
|
250
|
-
├── naming.ts
|
|
251
|
-
├── schemas.ts
|
|
252
|
-
├── browser/embed.
|
|
253
|
-
├── browser/widget.
|
|
254
|
-
|
|
258
|
+
├── cli.ts CLI entry point
|
|
259
|
+
├── cli-utils.ts CLI argument parsing
|
|
260
|
+
├── mcpRelayServer.ts MCP server (stdio + dynamic tool sync)
|
|
261
|
+
├── bridgeServer.ts WebSocket relay server
|
|
262
|
+
├── registry.ts Multi-source aggregation and deduplication
|
|
263
|
+
├── naming.ts Tool name sanitization and namespacing
|
|
264
|
+
├── schemas.ts Browser <-> relay protocol schemas
|
|
265
|
+
├── browser/embed.ts Script-tag loader for website owners
|
|
266
|
+
├── browser/widget.ts Widget IIFE entry point (calls startWidgetRuntime)
|
|
267
|
+
├── browser/widgetRuntime.ts Hidden iframe bridge runtime
|
|
268
|
+
├── browser/shared.ts Shared browser-side utilities
|
|
269
|
+
└── index.ts Public API exports
|
|
255
270
|
```
|
|
256
271
|
|
|
272
|
+
`dist/browser/widget.html` is generated at build time by
|
|
273
|
+
`scripts/build-widget-html.js`, which wraps the bundled `widget.js` (compiled
|
|
274
|
+
from `widget.ts` + `widgetRuntime.ts`) into a minimal HTML shell.
|
|
275
|
+
|
|
257
276
|
### Build and Test
|
|
258
277
|
|
|
259
278
|
From repository root:
|
|
@@ -275,13 +294,13 @@ Produces `webmcp-local-relay-<version>.mcpb` for distribution via Claude Desktop
|
|
|
275
294
|
|
|
276
295
|
### Plugin and Skill Files
|
|
277
296
|
|
|
278
|
-
| File
|
|
279
|
-
|
|
280
|
-
| `.claude-plugin/plugin.json`
|
|
281
|
-
| `.claude-plugin/marketplace.json`
|
|
282
|
-
| `.mcp.json`
|
|
297
|
+
| File | Purpose |
|
|
298
|
+
| ------------------------------------ | ------------------------------- |
|
|
299
|
+
| `.claude-plugin/plugin.json` | Claude Code plugin definition |
|
|
300
|
+
| `.claude-plugin/marketplace.json` | Plugin marketplace metadata |
|
|
301
|
+
| `.mcp.json` | MCP server configuration |
|
|
283
302
|
| `skills/webmcp-local-relay/SKILL.md` | Claude Code skill documentation |
|
|
284
|
-
| `manifest.json`
|
|
303
|
+
| `manifest.json` | MCPB bundle manifest |
|
|
285
304
|
|
|
286
305
|
### References
|
|
287
306
|
|
package/dist/browser/embed.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(){function e(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}let t=`[data-webmcp-relay]`,n=`__webmcp_relay_tab_id`,r=null,i;function a(){return document.currentScript instanceof HTMLScriptElement?document.currentScript:null}let o=a(),s=o?o.hasAttribute(`data-debug`):!1;function c(...e){s&&console.warn(`[webmcp-relay-embed]`,...e)}function l(){return typeof crypto<`u`&&typeof crypto.randomUUID==`function`?crypto.randomUUID():`${String(Date.now())}_${String(Math.random()).slice(2,10)}`}function u(){try{let e=sessionStorage.getItem(n);if(e)return e}catch(e){c(`sessionStorage read failed, tab ID will not persist:`,e)}let e=l();try{sessionStorage.setItem(n,e)}catch(e){c(`sessionStorage write failed:`,e)}return e}function d(e){if(e?.src)try{return new URL(`widget.html`,e.src).href}catch(e){c(`Failed to resolve widget URL from script src, falling back to CDN:`,e)}else c(`Script element has no src attribute, falling back to CDN widget URL.`);return`https://cdn.jsdelivr.net/npm/@mcp-b/webmcp-local-relay/dist/browser/widget.html`}function f(e){let t=d(e),n=e?.getAttribute(`data-relay-id`)||void 0,r=e?.getAttribute(`data-relay-workspace`)||void 0;return{autoConnect:e?.getAttribute(`data-auto-connect`)!==`false`,relayHost:e?.getAttribute(`data-relay-host`)||`127.0.0.1`,relayPort:e?.getAttribute(`data-relay-port`)||`9333`,...n?{relayId:n}:{},...r?{relayWorkspace:r}:{},tabId:u(),widgetUrl:t,widgetOrigin:new URL(t).origin}}function p(t){if(typeof t!=`string`||t.length===0)return{type:`object`,properties:{}};try{let n=JSON.parse(t);return e(n)?n:{type:`object`,properties:{}}}catch(e){return c(`Tool inputSchema is not valid JSON:`,typeof t==`string`?t.slice(0,200):t,e),{type:`object`,properties:{}}}}function m(t){return e(t)?t:(t!=null&&c(`Tool invocation args must be an object, got`,typeof t),{})}function h(e){return{name:e.name,description:e.description,inputSchema:e.inputSchema}}function g(e){return{name:e.name,description:e.description,inputSchema:p(e.inputSchema)}}function _(){let e=navigator.modelContext;if(e&&typeof e.listTools==`function`&&typeof e.callTool==`function`)return e}function v(){let t=_();if(t)return{listTools(){return t.listTools().map(h)},invoke(e,n){return t.callTool({name:e,arguments:n})}};let n=navigator.modelContextTesting;return n&&typeof n.listTools==`function`&&typeof n.executeTool==`function`?{listTools(){return n.listTools().map(g)},async invoke(t,r){let i=await n.executeTool(t,JSON.stringify(r));if(i===null)return{isError:!0,content:[{type:`text`,text:`Tool execution interrupted by navigation`}]};let a;try{a=JSON.parse(i)}catch{throw Error(`Testing tool returned invalid JSON: ${String(i).slice(0,200)}`)}if(!e(a))throw Error(`Testing tool response was not an object`);return a}}:(c(`No WebMCP runtime found (navigator.modelContext or navigator.modelContextTesting).`),null)}let y=!1;function b(){y||!r||(y=!0,setTimeout(()=>{if(y=!1,!r)return;let e=v();(e?Promise.resolve(e.listTools()):Promise.resolve([])).then(e=>{r&&r.postMessage({type:`webmcp.tools.changed`,tools:Array.isArray(e)?e:[]},i.widgetOrigin)}).catch(e=>{c(`Failed to push tool changes:`,e)})},0))}function x(){let e=_();if(e)try{return e.addEventListener(`
|
|
1
|
+
(function(){function e(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}let t=`[data-webmcp-relay]`,n=`__webmcp_relay_tab_id`,r=null,i;function a(){return document.currentScript instanceof HTMLScriptElement?document.currentScript:null}let o=a(),s=o?o.hasAttribute(`data-debug`):!1;function c(...e){s&&console.warn(`[webmcp-relay-embed]`,...e)}function l(){return typeof crypto<`u`&&typeof crypto.randomUUID==`function`?crypto.randomUUID():`${String(Date.now())}_${String(Math.random()).slice(2,10)}`}function u(){try{let e=sessionStorage.getItem(n);if(e)return e}catch(e){c(`sessionStorage read failed, tab ID will not persist:`,e)}let e=l();try{sessionStorage.setItem(n,e)}catch(e){c(`sessionStorage write failed:`,e)}return e}function d(e){if(e?.src)try{return new URL(`widget.html`,e.src).href}catch(e){c(`Failed to resolve widget URL from script src, falling back to CDN:`,e)}else c(`Script element has no src attribute, falling back to CDN widget URL.`);return`https://cdn.jsdelivr.net/npm/@mcp-b/webmcp-local-relay/dist/browser/widget.html`}function f(e){let t=d(e),n=e?.getAttribute(`data-relay-id`)||void 0,r=e?.getAttribute(`data-relay-workspace`)||void 0,i=e?.getAttribute(`data-request-timeout`)||void 0;return{autoConnect:e?.getAttribute(`data-auto-connect`)!==`false`,relayHost:e?.getAttribute(`data-relay-host`)||`127.0.0.1`,relayPort:e?.getAttribute(`data-relay-port`)||`9333`,...n?{relayId:n}:{},...r?{relayWorkspace:r}:{},...i?{requestTimeout:i}:{},tabId:u(),widgetUrl:t,widgetOrigin:new URL(t).origin}}function p(t){if(typeof t!=`string`||t.length===0)return{type:`object`,properties:{}};try{let n=JSON.parse(t);return e(n)?n:{type:`object`,properties:{}}}catch(e){return c(`Tool inputSchema is not valid JSON:`,typeof t==`string`?t.slice(0,200):t,e),{type:`object`,properties:{}}}}function m(t){return e(t)?t:(t!=null&&c(`Tool invocation args must be an object, got`,typeof t),{})}function h(e){return{name:e.name,description:e.description,inputSchema:e.inputSchema}}function g(e){return{name:e.name,description:e.description,inputSchema:p(e.inputSchema)}}function _(){let e=navigator.modelContext;if(e&&typeof e.listTools==`function`&&typeof e.callTool==`function`)return e}function v(){let t=_();if(t)return{listTools(){return t.listTools().map(h)},invoke(e,n){return t.callTool({name:e,arguments:n})}};let n=navigator.modelContextTesting;return n&&typeof n.listTools==`function`&&typeof n.executeTool==`function`?{listTools(){return n.listTools().map(g)},async invoke(t,r){let i=await n.executeTool(t,JSON.stringify(r));if(i===null)return{isError:!0,content:[{type:`text`,text:`Tool execution interrupted by navigation`}]};let a;try{a=JSON.parse(i)}catch{throw Error(`Testing tool returned invalid JSON: ${String(i).slice(0,200)}`)}if(!e(a))throw Error(`Testing tool response was not an object`);return a}}:(c(`No WebMCP runtime found (navigator.modelContext or navigator.modelContextTesting).`),null)}let y=!1;function b(){y||!r||(y=!0,setTimeout(()=>{if(y=!1,!r)return;let e=v();(e?Promise.resolve(e.listTools()):Promise.resolve([])).then(e=>{r&&r.postMessage({type:`webmcp.tools.changed`,tools:Array.isArray(e)?e:[]},i.widgetOrigin)}).catch(e=>{c(`Failed to push tool changes:`,e)})},0))}function x(){let e=_();if(e)try{return e.addEventListener(`toolchange`,b),!0}catch(e){c(`addEventListener threw:`,e)}let t=navigator.modelContextTesting;if(t&&typeof t.registerToolsChangedCallback==`function`)try{return t.registerToolsChangedCallback(b),!0}catch(e){c(`Failed to subscribe via registerToolsChangedCallback:`,e)}return!1}function S(){if(x())return;let e=0,t=100,n=()=>{setTimeout(()=>{if(e++,!x()){if(e>=40){c(`Could not subscribe to tool changes after 40 retries. Dynamic tool updates will not be relayed.`);return}t=Math.min(Math.round(t*1.5),1e3),n()}},t)};n()}function C(e,t,n){!e||typeof e!=`object`||!(`postMessage`in e)||e.postMessage(n,t)}function w(t){return!e(t)||typeof t.requestId!=`string`||typeof t.type!=`string`?null:{requestId:t.requestId,type:t.type,toolName:t.toolName,args:t.args}}function T(e,t){let n=v();(n?Promise.resolve(n.listTools()):Promise.resolve([])).then(n=>{C(t.source,t.origin,{type:`webmcp.tools.list.response`,requestId:e.requestId,tools:Array.isArray(n)?n:[]})}).catch(n=>{c(`Failed to list tools:`,n),C(t.source,t.origin,{type:`webmcp.tools.list.response`,requestId:e.requestId,tools:[],error:`Failed to list tools: ${n instanceof Error?n.message:String(n)}`})})}let E=!1;function D(t,n){if(E)return;let r=_();if(!r||typeof r.elicitInput!=`function`){c(`Elicitation bridge not installed: elicitInput not available on modelContext`);return}r.elicitInput=(r,i)=>{let a=k();return new Promise(i=>{let o=()=>{window.removeEventListener(`message`,l),clearTimeout(s)},s=setTimeout(()=>{o(),c(`Elicitation request timed out after 60s`),i({action:`decline`,content:null})},6e4),l=t=>{if(t.origin!==n)return;let r=t.data;!e(r)||r.type!==`webmcp.elicitation.response`||r.callId!==a||(o(),i(e(r.result)?r.result:{action:`decline`,content:null}))};window.addEventListener(`message`,l),t.postMessage({type:`webmcp.elicitation.request`,callId:a,params:r},n)})},E=!0,c(`Elicitation bridge installed`)}let O=0;function k(){return O+=1,`elicit_${String(Date.now())}_${String(O)}`}function A(t,n){let r=v();if(!r){C(n.source,n.origin,{type:`webmcp.tools.invoke.error`,requestId:t.requestId,error:`No WebMCP runtime found on this page`});return}n.source&&D(n.source,n.origin),Promise.resolve(r.invoke(String(t.toolName??``),m(t.args))).then(r=>{C(n.source,n.origin,{type:`webmcp.tools.invoke.response`,requestId:t.requestId,result:e(r)?r:{}})}).catch(e=>{C(n.source,n.origin,{type:`webmcp.tools.invoke.error`,requestId:t.requestId,error:String(e instanceof Error?e.message:e)})})}async function j(e){if(document.querySelector(t))return;let n=new URLSearchParams;n.set(`tabId`,e.tabId),n.set(`hostOrigin`,window.location.origin);let a=new URL(window.location.href);a.search=``,a.hash=``,n.set(`hostUrl`,a.href),n.set(`hostTitle`,document.title||``),n.set(`relayHost`,e.relayHost),n.set(`relayPort`,e.relayPort),n.set(`autoConnect`,e.autoConnect?`true`:`false`),e.relayId&&n.set(`relayId`,e.relayId),e.relayWorkspace&&n.set(`relayWorkspace`,e.relayWorkspace),e.requestTimeout&&n.set(`requestTimeout`,e.requestTimeout);let o=null;try{let t=await fetch(e.widgetUrl);if(!t.ok)console.warn(`[webmcp-relay-embed] Widget HTML fetch returned ${String(t.status)}; falling back to direct iframe src.`);else if(t.ok){let e=await t.text(),r=`<script>window.__WEBMCP_RELAY_CONFIG=${JSON.stringify(Object.fromEntries(n))};<\/script>`,a=new Blob([e.replace(`</head>`,`${r}</head>`)],{type:`text/html`});o=URL.createObjectURL(a),i.widgetOrigin=window.location.origin}}catch(e){c(`Failed to fetch widget HTML for blob URL:`,e)}let s=document.createElement(`iframe`);s.src=o??`${e.widgetUrl}?${n.toString()}`,s.style.display=`none`,s.setAttribute(`aria-hidden`,`true`),s.setAttribute(`data-webmcp-relay`,`1`),s.setAttribute(`allow`,`loopback-network; local-network; local-network-access`),document.body.appendChild(s),r=s.contentWindow,s.addEventListener(`load`,()=>{r=s.contentWindow,o&&URL.revokeObjectURL(o)}),s.addEventListener(`error`,()=>{console.error(`[webmcp-relay-embed] Failed to load relay widget iframe from:`,s.src,`-- WebMCP tools will NOT be relayed. Check network connectivity and widget URL.`),o&&URL.revokeObjectURL(o)})}if(!document.querySelector(t)){try{i=f(o)}catch(e){throw console.error(`[webmcp-relay-embed] Failed to initialize relay configuration:`,e),e}window.addEventListener(`message`,t=>{if(t.origin!==i.widgetOrigin||!r||t.source!==r)return;let n=t.data;if(e(n)&&n.type===`webmcp.reload`){window.location.reload();return}let a=w(t.data);if(a){if(a.type===`webmcp.tools.list.request`){T(a,t);return}a.type===`webmcp.tools.invoke.request`&&A(a,t)}});let t=()=>{j(i).catch(e=>{console.error(`[webmcp-relay-embed] Failed to inject relay widget:`,e)})};document.body?t():document.addEventListener(`DOMContentLoaded`,t,{once:!0}),S()}})();
|
package/dist/browser/widget.html
CHANGED
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
<title>WebMCP Relay Widget</title>
|
|
6
6
|
</head>
|
|
7
7
|
<body>
|
|
8
|
-
<script>(function(){let e=new Set([`127.0.0.1`,`localhost`,`::1`,`[::1]`]);function t(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function n(t){return e.has(t)}function r(){return typeof crypto<`u`&&typeof crypto.randomUUID==`function`?crypto.randomUUID():`${String(Date.now())}_${String(Math.random()).slice(2,10)}`}function i(e){return String(e).replace(/[\r\n]/g,``)}function a(e,t){try{e.readyState===WebSocket.OPEN&&e.send(t)}catch(e){console.warn(`[webmcp-relay] Failed to send message:`,e)}}function o(e){return`__webmcp_relay_endpoint:${[e.hostOrigin,e.relayId??``,e.workspace??``].map(e=>encodeURIComponent(e)).join(`:`)}`}let s=3e3;function c(e=window.location.search){let t=new URLSearchParams(e),i=t.get(`hostOrigin`);if(!
|
|
8
|
+
<script>(function(){let e=new Set([`127.0.0.1`,`localhost`,`::1`,`[::1]`]);function t(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function n(t){return e.has(t)}function r(){return typeof crypto<`u`&&typeof crypto.randomUUID==`function`?crypto.randomUUID():`${String(Date.now())}_${String(Math.random()).slice(2,10)}`}function i(e){return String(e).replace(/[\r\n]/g,``)}function a(e,t){try{e.readyState===WebSocket.OPEN&&e.send(t)}catch(e){console.warn(`[webmcp-relay] Failed to send message:`,e)}}function o(e){return`__webmcp_relay_endpoint:${[e.hostOrigin,e.relayId??``,e.workspace??``].map(e=>encodeURIComponent(e)).join(`:`)}`}let s=3e3;function c(e=window.location.search){let t=new URLSearchParams(e),i=globalThis.__WEBMCP_RELAY_CONFIG;function a(e){return t.get(e)??i?.[e]??null}let o=a(`hostOrigin`);if(!o)return null;let s=a(`hostUrl`)||o,c=a(`hostTitle`)||``,l=a(`tabId`)||r(),u=a(`relayHost`)||`127.0.0.1`,d=a(`relayPort`),f=d&&d.length>0?Number.parseInt(d,10):9333,p=a(`autoConnect`)!==`false`,m=a(`relayId`)||void 0,h=a(`relayWorkspace`)||void 0,g=a(`requestTimeout`),_=g&&g.length>0?Number.parseInt(g,10):6e4;return n(u)?!Number.isInteger(f)||f<1||f>65535?(console.error(`[webmcp-relay-widget] relayPort must be an integer between 1 and 65535, got:`,d),null):!Number.isInteger(_)||_<1?(console.error(`[webmcp-relay-widget] requestTimeout must be a positive integer (ms), got:`,g),null):{autoConnect:p,hostOrigin:o,hostTitle:c,hostUrl:s,relayHostHint:u,relayPortHint:f,...m?{relayId:m}:{},...h?{relayWorkspace:h}:{},requestTimeoutMs:_,tabId:l}:(console.error(`[webmcp-relay-widget] relayHost must be a loopback address, got:`,u),null)}function l(e){return!t(e)||typeof e.requestId!=`string`||typeof e.type!=`string`?null:{requestId:e.requestId,type:e.type,tools:e.tools,result:e.result,error:e.error}}function u(){let e=c();if(!e){console.warn(`[webmcp-relay-widget] Missing required hostOrigin parameter. Widget will not start.`);return}b(e)}function d(e){return!t(e)||e.type!==`server-hello`||e.service!==`webmcp-local-relay`||e.version!==1||typeof e.host!=`string`||typeof e.instanceId!=`string`||typeof e.port!=`number`?null:{type:`server-hello`,service:`webmcp-local-relay`,version:1,host:e.host,instanceId:e.instanceId,port:e.port,...typeof e.label==`string`?{label:e.label}:{},...typeof e.relayId==`string`?{relayId:e.relayId}:{},...typeof e.workspace==`string`?{workspace:e.workspace}:{}}}function f(e){return!t(e)||e.type!==`hello/accepted`?null:{type:`hello/accepted`}}function p(e){return!t(e)||e.type!==`hello/rejected`||typeof e.message!=`string`||typeof e.reason!=`string`?null:{type:`hello/rejected`,message:e.message,reason:e.reason}}function m(e){return o({hostOrigin:e.hostOrigin,...e.relayId?{relayId:e.relayId}:{},...e.relayWorkspace?{workspace:e.relayWorkspace}:{}})}function h(e){if(typeof sessionStorage>`u`)return null;try{let t=sessionStorage.getItem(m(e));if(!t)return null;let n=JSON.parse(t);return typeof n.host!=`string`||n.host.length===0||typeof n.port!=`number`||!Number.isInteger(n.port)||n.port<1||n.port>65535?null:{host:n.host,port:n.port}}catch{return null}}function g(e,t){if(!(typeof sessionStorage>`u`))try{sessionStorage.setItem(m(e),JSON.stringify({host:t.host,port:t.port}))}catch{}}function _(e){if(!(typeof sessionStorage>`u`))try{sessionStorage.removeItem(m(e))}catch{}}function v(e){let t=h(e),n=new Set,r=[],i=(e,t)=>{if(!Number.isInteger(t)||t<1||t>65535)return;let i=`${e}:${String(t)}`;n.has(i)||(n.add(i),r.push({host:e,port:t}))};e.relayPortHint!==void 0&&i(e.relayHostHint,e.relayPortHint),t&&i(t.host,t.port);for(let e of[`127.0.0.1`,`[::1]`])for(let t=9333;t<=9348;t+=1)i(e,t);return r}async function y(e){let t=`ws://${e.host}:${String(e.port)}`;return new Promise(n=>{let r=!1,i=new WebSocket(t,[`webmcp-discovery.v1`,`webmcp.v1`]),a=e=>{if(!r){if(r=!0,clearTimeout(l),i.removeEventListener(`close`,s),i.removeEventListener(`error`,o),i.removeEventListener(`message`,c),e===null)try{i.close()}catch{}n(e)}},o=()=>{a(null)},s=()=>{a(null)},c=t=>{let n;try{n=JSON.parse(String(t.data))}catch{return}let r=d(n);r&&a({endpoint:{hello:r,host:e.host,port:e.port},socket:i})},l=setTimeout(()=>{a(null)},1200);i.addEventListener(`close`,s,{once:!0}),i.addEventListener(`error`,o,{once:!0}),i.addEventListener(`message`,c)})}function b(e){let n=new Map,o=null,c=null,u=0,m=!1,h=null,b=500,x=null,S=`idle`,C=e=>{for(let[t,r]of n)clearTimeout(r.timeoutId),n.delete(t),r.reject(Error(e))},w=e=>{S=e};function T(t,i){let a=r();return new Promise((r,o)=>{let s=setTimeout(()=>{n.delete(a),o(Error(`Host response timeout: ${t}`))},e.requestTimeoutMs);n.set(a,{resolve:r,reject:o,timeoutId:s,responseType:`${t}.response`,errorType:`${t}.error`}),window.parent.postMessage({type:`${t}.request`,requestId:a,...i},e.hostOrigin)})}let E=(n,r)=>{let s=[],l=()=>{h&&(clearTimeout(h),h=null)},v=()=>{a(n,JSON.stringify({type:`tools/list`,tools:s}))};x&&(clearTimeout(x),x=null),o=r,c=n,b=500,m=!1,w(`connected`),n.addEventListener(`message`,s=>{let c;try{c=JSON.parse(String(s.data))}catch(e){console.warn(`[webmcp-relay-widget] Failed to parse relay message:`,e);return}let u=d(c);if(u){o={hello:u,host:r.host,port:r.port};return}if(f(c)){l(),m=!0,g(e,r),v();return}let h=p(c);if(h){l(),m=!1,_(e),window.parent.postMessage({type:`webmcp.relay.rejected`,host:r.host,port:r.port,message:h.message,reason:h.reason},e.hostOrigin),console.error(`[webmcp-relay-widget] Relay rejected browser hello:`,h.reason,h.message);try{n.close(1008,h.message)}catch{}return}if(!t(c)||typeof c.type!=`string`){console.debug(`[webmcp-relay-widget] Ignoring non-object or untyped relay message`);return}if(c.type===`ping`){a(n,JSON.stringify({type:`pong`}));return}if(c.type===`reload`){window.parent.postMessage({type:`webmcp.reload`},e.hostOrigin);return}if(c.type===`elicitation-response`){window.parent.postMessage({type:`webmcp.elicitation.response`,callId:c.callId,result:t(c.result)?c.result:{action:`decline`,content:null}},e.hostOrigin);return}if(c.type!==`invoke`){console.debug(`[webmcp-relay-widget] Ignoring unrecognized message type:`,i(c.type));return}T(`webmcp.tools.invoke`,{toolName:c.toolName,args:t(c.args)?c.args:{}}).then(e=>{a(n,JSON.stringify({type:`result`,callId:c.callId,result:e.result}))}).catch(e=>{a(n,JSON.stringify({type:`result`,callId:c.callId,result:{isError:!0,content:[{type:`text`,text:String(e instanceof Error?e.message:e)}]}}))})}),n.addEventListener(`close`,()=>{if(c===n){if(m=!1,c=null,l(),C(`WebSocket connection lost`),u+=1,u>=5){u=0,A();return}k()}},{once:!0}),n.addEventListener(`error`,e=>{console.warn(`[webmcp-relay-widget] WebSocket error:`,e);try{n.close()}catch(e){console.warn(`[webmcp-relay-widget] Error closing socket after error:`,e)}}),T(`webmcp.tools.list`,{}).then(t=>{s=Array.isArray(t.tools)?t.tools:[],a(n,JSON.stringify({type:`hello`,tabId:e.tabId,origin:e.hostOrigin,title:e.hostTitle||document.referrer||`Unknown page`,url:e.hostUrl})),h=setTimeout(()=>{h=null,!(c!==n||n.readyState!==WebSocket.OPEN||m)&&(m=!0,g(e,r),v())},250)}).catch(e=>{console.warn(`[webmcp-relay-widget] Hello handshake failed:`,e);try{n.close()}catch{}})},D=async t=>{let n=await y({host:t.host,port:t.port});if(!n)return!1;let r=n.endpoint;return e.relayId&&r.hello.relayId!==e.relayId||e.relayWorkspace&&r.hello.workspace!==e.relayWorkspace?(n.socket.close(),!1):(E(n.socket,r),!0)},O=async()=>{w(`discovering`);for(let t of v(e))if(await D(t))return u=0,!0;return!1},k=()=>{if(!o||x)return;w(`retry-same-endpoint`);let e={host:o.host,port:o.port},t=Math.min(s,Math.round(b*(.85+Math.random()*.3)));b=Math.min(Math.round(b*1.5),s),x=setTimeout(()=>{x=null,D(e).then(e=>{if(e){u=0;return}if(u>=5){u=0,A();return}k()})},t)},A=()=>{if(x)return;w(`rediscover`);let e=Math.min(s,Math.round(b*(.85+Math.random()*.3)));b=Math.min(Math.round(b*1.5),s),x=setTimeout(()=>{x=null,O().then(e=>{e||A()})},e)};window.addEventListener(`message`,r=>{if(r.origin!==e.hostOrigin)return;let i=r.data;if(t(i)&&i.type===`webmcp.tools.changed`){c&&m&&a(c,JSON.stringify({type:`tools/changed`,tools:Array.isArray(i.tools)?i.tools:[]}));return}if(t(i)&&i.type===`webmcp.connect`){!c&&S!==`discovering`&&O();return}if(t(i)&&i.type===`webmcp.elicitation.request`){c&&c.readyState===WebSocket.OPEN&&a(c,JSON.stringify({type:`elicitation-request`,callId:i.callId,params:t(i.params)?i.params:{}}));return}let o=l(i);if(!o)return;let s=n.get(o.requestId);if(s){if(o.type===s.responseType){clearTimeout(s.timeoutId),n.delete(o.requestId),s.resolve(o);return}o.type===s.errorType&&(clearTimeout(s.timeoutId),n.delete(o.requestId),s.reject(Error(String(o.error||`Unknown host error`))))}}),e.autoConnect?O().then(e=>{e||A()}):w(`idle`)}u()})();</script>
|
|
9
9
|
</body>
|
|
10
10
|
</html>
|
package/dist/browser/widget.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(){let e=new Set([`127.0.0.1`,`localhost`,`::1`,`[::1]`]);function t(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function n(t){return e.has(t)}function r(){return typeof crypto<`u`&&typeof crypto.randomUUID==`function`?crypto.randomUUID():`${String(Date.now())}_${String(Math.random()).slice(2,10)}`}function i(e){return String(e).replace(/[\r\n]/g,``)}function a(e,t){try{e.readyState===WebSocket.OPEN&&e.send(t)}catch(e){console.warn(`[webmcp-relay] Failed to send message:`,e)}}function o(e){return`__webmcp_relay_endpoint:${[e.hostOrigin,e.relayId??``,e.workspace??``].map(e=>encodeURIComponent(e)).join(`:`)}`}let s=3e3;function c(e=window.location.search){let t=new URLSearchParams(e),i=t.get(`hostOrigin`);if(!
|
|
1
|
+
(function(){let e=new Set([`127.0.0.1`,`localhost`,`::1`,`[::1]`]);function t(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function n(t){return e.has(t)}function r(){return typeof crypto<`u`&&typeof crypto.randomUUID==`function`?crypto.randomUUID():`${String(Date.now())}_${String(Math.random()).slice(2,10)}`}function i(e){return String(e).replace(/[\r\n]/g,``)}function a(e,t){try{e.readyState===WebSocket.OPEN&&e.send(t)}catch(e){console.warn(`[webmcp-relay] Failed to send message:`,e)}}function o(e){return`__webmcp_relay_endpoint:${[e.hostOrigin,e.relayId??``,e.workspace??``].map(e=>encodeURIComponent(e)).join(`:`)}`}let s=3e3;function c(e=window.location.search){let t=new URLSearchParams(e),i=globalThis.__WEBMCP_RELAY_CONFIG;function a(e){return t.get(e)??i?.[e]??null}let o=a(`hostOrigin`);if(!o)return null;let s=a(`hostUrl`)||o,c=a(`hostTitle`)||``,l=a(`tabId`)||r(),u=a(`relayHost`)||`127.0.0.1`,d=a(`relayPort`),f=d&&d.length>0?Number.parseInt(d,10):9333,p=a(`autoConnect`)!==`false`,m=a(`relayId`)||void 0,h=a(`relayWorkspace`)||void 0,g=a(`requestTimeout`),_=g&&g.length>0?Number.parseInt(g,10):6e4;return n(u)?!Number.isInteger(f)||f<1||f>65535?(console.error(`[webmcp-relay-widget] relayPort must be an integer between 1 and 65535, got:`,d),null):!Number.isInteger(_)||_<1?(console.error(`[webmcp-relay-widget] requestTimeout must be a positive integer (ms), got:`,g),null):{autoConnect:p,hostOrigin:o,hostTitle:c,hostUrl:s,relayHostHint:u,relayPortHint:f,...m?{relayId:m}:{},...h?{relayWorkspace:h}:{},requestTimeoutMs:_,tabId:l}:(console.error(`[webmcp-relay-widget] relayHost must be a loopback address, got:`,u),null)}function l(e){return!t(e)||typeof e.requestId!=`string`||typeof e.type!=`string`?null:{requestId:e.requestId,type:e.type,tools:e.tools,result:e.result,error:e.error}}function u(){let e=c();if(!e){console.warn(`[webmcp-relay-widget] Missing required hostOrigin parameter. Widget will not start.`);return}b(e)}function d(e){return!t(e)||e.type!==`server-hello`||e.service!==`webmcp-local-relay`||e.version!==1||typeof e.host!=`string`||typeof e.instanceId!=`string`||typeof e.port!=`number`?null:{type:`server-hello`,service:`webmcp-local-relay`,version:1,host:e.host,instanceId:e.instanceId,port:e.port,...typeof e.label==`string`?{label:e.label}:{},...typeof e.relayId==`string`?{relayId:e.relayId}:{},...typeof e.workspace==`string`?{workspace:e.workspace}:{}}}function f(e){return!t(e)||e.type!==`hello/accepted`?null:{type:`hello/accepted`}}function p(e){return!t(e)||e.type!==`hello/rejected`||typeof e.message!=`string`||typeof e.reason!=`string`?null:{type:`hello/rejected`,message:e.message,reason:e.reason}}function m(e){return o({hostOrigin:e.hostOrigin,...e.relayId?{relayId:e.relayId}:{},...e.relayWorkspace?{workspace:e.relayWorkspace}:{}})}function h(e){if(typeof sessionStorage>`u`)return null;try{let t=sessionStorage.getItem(m(e));if(!t)return null;let n=JSON.parse(t);return typeof n.host!=`string`||n.host.length===0||typeof n.port!=`number`||!Number.isInteger(n.port)||n.port<1||n.port>65535?null:{host:n.host,port:n.port}}catch{return null}}function g(e,t){if(!(typeof sessionStorage>`u`))try{sessionStorage.setItem(m(e),JSON.stringify({host:t.host,port:t.port}))}catch{}}function _(e){if(!(typeof sessionStorage>`u`))try{sessionStorage.removeItem(m(e))}catch{}}function v(e){let t=h(e),n=new Set,r=[],i=(e,t)=>{if(!Number.isInteger(t)||t<1||t>65535)return;let i=`${e}:${String(t)}`;n.has(i)||(n.add(i),r.push({host:e,port:t}))};e.relayPortHint!==void 0&&i(e.relayHostHint,e.relayPortHint),t&&i(t.host,t.port);for(let e of[`127.0.0.1`,`[::1]`])for(let t=9333;t<=9348;t+=1)i(e,t);return r}async function y(e){let t=`ws://${e.host}:${String(e.port)}`;return new Promise(n=>{let r=!1,i=new WebSocket(t,[`webmcp-discovery.v1`,`webmcp.v1`]),a=e=>{if(!r){if(r=!0,clearTimeout(l),i.removeEventListener(`close`,s),i.removeEventListener(`error`,o),i.removeEventListener(`message`,c),e===null)try{i.close()}catch{}n(e)}},o=()=>{a(null)},s=()=>{a(null)},c=t=>{let n;try{n=JSON.parse(String(t.data))}catch{return}let r=d(n);r&&a({endpoint:{hello:r,host:e.host,port:e.port},socket:i})},l=setTimeout(()=>{a(null)},1200);i.addEventListener(`close`,s,{once:!0}),i.addEventListener(`error`,o,{once:!0}),i.addEventListener(`message`,c)})}function b(e){let n=new Map,o=null,c=null,u=0,m=!1,h=null,b=500,x=null,S=`idle`,C=e=>{for(let[t,r]of n)clearTimeout(r.timeoutId),n.delete(t),r.reject(Error(e))},w=e=>{S=e};function T(t,i){let a=r();return new Promise((r,o)=>{let s=setTimeout(()=>{n.delete(a),o(Error(`Host response timeout: ${t}`))},e.requestTimeoutMs);n.set(a,{resolve:r,reject:o,timeoutId:s,responseType:`${t}.response`,errorType:`${t}.error`}),window.parent.postMessage({type:`${t}.request`,requestId:a,...i},e.hostOrigin)})}let E=(n,r)=>{let s=[],l=()=>{h&&(clearTimeout(h),h=null)},v=()=>{a(n,JSON.stringify({type:`tools/list`,tools:s}))};x&&(clearTimeout(x),x=null),o=r,c=n,b=500,m=!1,w(`connected`),n.addEventListener(`message`,s=>{let c;try{c=JSON.parse(String(s.data))}catch(e){console.warn(`[webmcp-relay-widget] Failed to parse relay message:`,e);return}let u=d(c);if(u){o={hello:u,host:r.host,port:r.port};return}if(f(c)){l(),m=!0,g(e,r),v();return}let h=p(c);if(h){l(),m=!1,_(e),window.parent.postMessage({type:`webmcp.relay.rejected`,host:r.host,port:r.port,message:h.message,reason:h.reason},e.hostOrigin),console.error(`[webmcp-relay-widget] Relay rejected browser hello:`,h.reason,h.message);try{n.close(1008,h.message)}catch{}return}if(!t(c)||typeof c.type!=`string`){console.debug(`[webmcp-relay-widget] Ignoring non-object or untyped relay message`);return}if(c.type===`ping`){a(n,JSON.stringify({type:`pong`}));return}if(c.type===`reload`){window.parent.postMessage({type:`webmcp.reload`},e.hostOrigin);return}if(c.type===`elicitation-response`){window.parent.postMessage({type:`webmcp.elicitation.response`,callId:c.callId,result:t(c.result)?c.result:{action:`decline`,content:null}},e.hostOrigin);return}if(c.type!==`invoke`){console.debug(`[webmcp-relay-widget] Ignoring unrecognized message type:`,i(c.type));return}T(`webmcp.tools.invoke`,{toolName:c.toolName,args:t(c.args)?c.args:{}}).then(e=>{a(n,JSON.stringify({type:`result`,callId:c.callId,result:e.result}))}).catch(e=>{a(n,JSON.stringify({type:`result`,callId:c.callId,result:{isError:!0,content:[{type:`text`,text:String(e instanceof Error?e.message:e)}]}}))})}),n.addEventListener(`close`,()=>{if(c===n){if(m=!1,c=null,l(),C(`WebSocket connection lost`),u+=1,u>=5){u=0,A();return}k()}},{once:!0}),n.addEventListener(`error`,e=>{console.warn(`[webmcp-relay-widget] WebSocket error:`,e);try{n.close()}catch(e){console.warn(`[webmcp-relay-widget] Error closing socket after error:`,e)}}),T(`webmcp.tools.list`,{}).then(t=>{s=Array.isArray(t.tools)?t.tools:[],a(n,JSON.stringify({type:`hello`,tabId:e.tabId,origin:e.hostOrigin,title:e.hostTitle||document.referrer||`Unknown page`,url:e.hostUrl})),h=setTimeout(()=>{h=null,!(c!==n||n.readyState!==WebSocket.OPEN||m)&&(m=!0,g(e,r),v())},250)}).catch(e=>{console.warn(`[webmcp-relay-widget] Hello handshake failed:`,e);try{n.close()}catch{}})},D=async t=>{let n=await y({host:t.host,port:t.port});if(!n)return!1;let r=n.endpoint;return e.relayId&&r.hello.relayId!==e.relayId||e.relayWorkspace&&r.hello.workspace!==e.relayWorkspace?(n.socket.close(),!1):(E(n.socket,r),!0)},O=async()=>{w(`discovering`);for(let t of v(e))if(await D(t))return u=0,!0;return!1},k=()=>{if(!o||x)return;w(`retry-same-endpoint`);let e={host:o.host,port:o.port},t=Math.min(s,Math.round(b*(.85+Math.random()*.3)));b=Math.min(Math.round(b*1.5),s),x=setTimeout(()=>{x=null,D(e).then(e=>{if(e){u=0;return}if(u>=5){u=0,A();return}k()})},t)},A=()=>{if(x)return;w(`rediscover`);let e=Math.min(s,Math.round(b*(.85+Math.random()*.3)));b=Math.min(Math.round(b*1.5),s),x=setTimeout(()=>{x=null,O().then(e=>{e||A()})},e)};window.addEventListener(`message`,r=>{if(r.origin!==e.hostOrigin)return;let i=r.data;if(t(i)&&i.type===`webmcp.tools.changed`){c&&m&&a(c,JSON.stringify({type:`tools/changed`,tools:Array.isArray(i.tools)?i.tools:[]}));return}if(t(i)&&i.type===`webmcp.connect`){!c&&S!==`discovering`&&O();return}if(t(i)&&i.type===`webmcp.elicitation.request`){c&&c.readyState===WebSocket.OPEN&&a(c,JSON.stringify({type:`elicitation-request`,callId:i.callId,params:t(i.params)?i.params:{}}));return}let o=l(i);if(!o)return;let s=n.get(o.requestId);if(s){if(o.type===s.responseType){clearTimeout(s.timeoutId),n.delete(o.requestId),s.resolve(o);return}o.type===s.errorType&&(clearTimeout(s.timeoutId),n.delete(o.requestId),s.reject(Error(String(o.error||`Unknown host error`))))}}),e.autoConnect?O().then(e=>{e||A()}):w(`idle`)}u()})();
|
package/dist/{cli.js → cli.mjs}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { n as parseCliOptions, t as LocalRelayMcpServer } from "./mcpRelayServer-BL8kNwIK.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/cli.ts
|
|
5
5
|
let options;
|
|
@@ -52,6 +52,15 @@ const shutdown = async (signal) => {
|
|
|
52
52
|
process.exit(0);
|
|
53
53
|
};
|
|
54
54
|
let shuttingDown = false;
|
|
55
|
+
process.on("uncaughtException", (err) => {
|
|
56
|
+
process.stderr.write(`[webmcp-local-relay] error: uncaught exception: ${err.stack ?? err.message}\n`);
|
|
57
|
+
shutdown("uncaughtException");
|
|
58
|
+
});
|
|
59
|
+
process.on("unhandledRejection", (reason) => {
|
|
60
|
+
const message = reason instanceof Error ? reason.stack ?? reason.message : String(reason);
|
|
61
|
+
process.stderr.write(`[webmcp-local-relay] error: unhandled rejection: ${message}\n`);
|
|
62
|
+
shutdown("unhandledRejection");
|
|
63
|
+
});
|
|
55
64
|
process.on("SIGINT", () => {
|
|
56
65
|
shutdown("SIGINT");
|
|
57
66
|
});
|
|
@@ -61,4 +70,4 @@ process.on("SIGTERM", () => {
|
|
|
61
70
|
|
|
62
71
|
//#endregion
|
|
63
72
|
export { };
|
|
64
|
-
//# sourceMappingURL=cli.
|
|
73
|
+
//# sourceMappingURL=cli.mjs.map
|
package/dist/cli.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { parseCliOptions } from './cli-utils.js';\nimport { LocalRelayMcpServer } from './mcpRelayServer.js';\n\nlet options: ReturnType<typeof parseCliOptions>;\ntry {\n options = parseCliOptions(process.argv.slice(2));\n} catch (err) {\n process.stderr.write(\n `[webmcp-local-relay] error: ${err instanceof Error ? err.message : String(err)}\\n`\n );\n process.exit(1);\n}\n\nif (options.allowedOrigins.includes('*')) {\n process.stderr.write(\n '[webmcp-local-relay] WARNING: accepting connections from ALL host page origins. Use --widget-origin to restrict.\\n'\n );\n}\n\nconst bridgeOptions = {\n host: options.host,\n port: options.port,\n portExplicitlySet: options.portExplicitlySet,\n allowedOrigins: options.allowedOrigins,\n ...(options.label ? { label: options.label } : {}),\n ...(options.relayId ? { relayId: options.relayId } : {}),\n ...(options.workspace ? { workspace: options.workspace } : {}),\n};\n\nconst relay = new LocalRelayMcpServer({\n bridgeOptions,\n});\n\ntry {\n await relay.start();\n} catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (message.includes('EACCES')) {\n process.stderr.write(\n `[webmcp-local-relay] error: insufficient permissions to bind to ${options.host}:${options.port}.\\n`\n );\n } else {\n process.stderr.write(`[webmcp-local-relay] error: failed to start bridge server: ${message}\\n`);\n }\n process.exit(1);\n}\n\ntry {\n await relay.startStdio();\n} catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n process.stderr.write(`[webmcp-local-relay] error: failed to start stdio transport: ${message}\\n`);\n process.exit(1);\n}\n\nif (relay.bridge.mode === 'server') {\n process.stderr.write(\n `[webmcp-local-relay] server mode: listening on ws://${options.host}:${relay.bridge.port} (allowed origins: ${options.allowedOrigins.join(', ')})\\n`\n );\n} else {\n process.stderr.write(\n `[webmcp-local-relay] client mode: proxying through existing relay at ws://${options.host}:${relay.bridge.port}\\n`\n );\n}\n\n/**\n * Gracefully shuts down bridge and MCP server for process termination signals.\n */\nconst shutdown = async (signal: string) => {\n if (shuttingDown) {\n return;\n }\n shuttingDown = true;\n process.stderr.write(`[webmcp-local-relay] received ${signal}, shutting down\\n`);\n try {\n await relay.stop();\n } catch (err) {\n process.stderr.write(\n `[webmcp-local-relay] error during shutdown: ${err instanceof Error ? err.message : err}\\n`\n );\n process.exit(1);\n }\n process.exit(0);\n};\n\nlet shuttingDown = false;\n\nprocess.on('uncaughtException', (err) => {\n process.stderr.write(\n `[webmcp-local-relay] error: uncaught exception: ${err.stack ?? err.message}\\n`\n );\n void shutdown('uncaughtException');\n});\nprocess.on('unhandledRejection', (reason) => {\n const message = reason instanceof Error ? (reason.stack ?? reason.message) : String(reason);\n process.stderr.write(`[webmcp-local-relay] error: unhandled rejection: ${message}\\n`);\n void shutdown('unhandledRejection');\n});\n\nprocess.on('SIGINT', () => {\n void shutdown('SIGINT');\n});\nprocess.on('SIGTERM', () => {\n void shutdown('SIGTERM');\n});\n"],"mappings":";;;;AAKA,IAAI;AACJ,IAAI;AACF,WAAU,gBAAgB,QAAQ,KAAK,MAAM,EAAE,CAAC;SACzC,KAAK;AACZ,SAAQ,OAAO,MACb,+BAA+B,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CAAC,IACjF;AACD,SAAQ,KAAK,EAAE;;AAGjB,IAAI,QAAQ,eAAe,SAAS,IAAI,CACtC,SAAQ,OAAO,MACb,qHACD;AAaH,MAAM,QAAQ,IAAI,oBAAoB,EACpC,eAXoB;CACpB,MAAM,QAAQ;CACd,MAAM,QAAQ;CACd,mBAAmB,QAAQ;CAC3B,gBAAgB,QAAQ;CACxB,GAAI,QAAQ,QAAQ,EAAE,OAAO,QAAQ,OAAO,GAAG,EAAE;CACjD,GAAI,QAAQ,UAAU,EAAE,SAAS,QAAQ,SAAS,GAAG,EAAE;CACvD,GAAI,QAAQ,YAAY,EAAE,WAAW,QAAQ,WAAW,GAAG,EAAE;CAC9D,EAIA,CAAC;AAEF,IAAI;AACF,OAAM,MAAM,OAAO;SACZ,KAAK;CACZ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAChE,KAAI,QAAQ,SAAS,SAAS,CAC5B,SAAQ,OAAO,MACb,mEAAmE,QAAQ,KAAK,GAAG,QAAQ,KAAK,KACjG;KAED,SAAQ,OAAO,MAAM,8DAA8D,QAAQ,IAAI;AAEjG,SAAQ,KAAK,EAAE;;AAGjB,IAAI;AACF,OAAM,MAAM,YAAY;SACjB,KAAK;CACZ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAChE,SAAQ,OAAO,MAAM,gEAAgE,QAAQ,IAAI;AACjG,SAAQ,KAAK,EAAE;;AAGjB,IAAI,MAAM,OAAO,SAAS,SACxB,SAAQ,OAAO,MACb,uDAAuD,QAAQ,KAAK,GAAG,MAAM,OAAO,KAAK,qBAAqB,QAAQ,eAAe,KAAK,KAAK,CAAC,KACjJ;IAED,SAAQ,OAAO,MACb,6EAA6E,QAAQ,KAAK,GAAG,MAAM,OAAO,KAAK,IAChH;;;;AAMH,MAAM,WAAW,OAAO,WAAmB;AACzC,KAAI,aACF;AAEF,gBAAe;AACf,SAAQ,OAAO,MAAM,iCAAiC,OAAO,mBAAmB;AAChF,KAAI;AACF,QAAM,MAAM,MAAM;UACX,KAAK;AACZ,UAAQ,OAAO,MACb,+CAA+C,eAAe,QAAQ,IAAI,UAAU,IAAI,IACzF;AACD,UAAQ,KAAK,EAAE;;AAEjB,SAAQ,KAAK,EAAE;;AAGjB,IAAI,eAAe;AAEnB,QAAQ,GAAG,sBAAsB,QAAQ;AACvC,SAAQ,OAAO,MACb,mDAAmD,IAAI,SAAS,IAAI,QAAQ,IAC7E;AACD,CAAK,SAAS,oBAAoB;EAClC;AACF,QAAQ,GAAG,uBAAuB,WAAW;CAC3C,MAAM,UAAU,kBAAkB,QAAS,OAAO,SAAS,OAAO,UAAW,OAAO,OAAO;AAC3F,SAAQ,OAAO,MAAM,oDAAoD,QAAQ,IAAI;AACrF,CAAK,SAAS,qBAAqB;EACnC;AAEF,QAAQ,GAAG,gBAAgB;AACzB,CAAK,SAAS,SAAS;EACvB;AACF,QAAQ,GAAG,iBAAiB;AAC1B,CAAK,SAAS,UAAU;EACxB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
1
2
|
import { CallToolRequestParamsSchema, CallToolResult, CallToolResult as CallToolResult$1, CallToolResultSchema, Tool, Tool as Tool$1, ToolAnnotations, ToolAnnotations as ToolAnnotations$1, ToolAnnotationsSchema, ToolSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
2
3
|
import { z } from "zod/v4";
|
|
3
|
-
import { EventEmitter } from "node:events";
|
|
4
4
|
import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
|
|
5
5
|
|
|
6
6
|
//#region src/protocol.d.ts
|
|
@@ -198,6 +198,10 @@ declare const BrowserToRelayMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
|
|
|
198
198
|
result: z.ZodUnknown;
|
|
199
199
|
}, z.core.$strip>, z.ZodObject<{
|
|
200
200
|
type: z.ZodLiteral<"pong">;
|
|
201
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
202
|
+
type: z.ZodLiteral<"elicitation-request">;
|
|
203
|
+
callId: z.ZodString;
|
|
204
|
+
params: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
201
205
|
}, z.core.$strip>]>;
|
|
202
206
|
/**
|
|
203
207
|
* Browser-to-relay message payload.
|
|
@@ -240,6 +244,28 @@ declare const ServerHelloMessageSchema: z.ZodObject<{
|
|
|
240
244
|
* Server hello payload.
|
|
241
245
|
*/
|
|
242
246
|
type ServerHelloMessage = z.infer<typeof ServerHelloMessageSchema>;
|
|
247
|
+
/**
|
|
248
|
+
* Schema for acceptance of a browser source hello message.
|
|
249
|
+
*/
|
|
250
|
+
declare const RelayHelloAcceptedMessageSchema: z.ZodObject<{
|
|
251
|
+
type: z.ZodLiteral<"hello/accepted">;
|
|
252
|
+
}, z.core.$strip>;
|
|
253
|
+
/**
|
|
254
|
+
* Acceptance payload for a browser source hello message.
|
|
255
|
+
*/
|
|
256
|
+
type RelayHelloAcceptedMessage = z.infer<typeof RelayHelloAcceptedMessageSchema>;
|
|
257
|
+
/**
|
|
258
|
+
* Schema for rejection of a browser source hello message.
|
|
259
|
+
*/
|
|
260
|
+
declare const RelayHelloRejectedMessageSchema: z.ZodObject<{
|
|
261
|
+
type: z.ZodLiteral<"hello/rejected">;
|
|
262
|
+
reason: z.ZodString;
|
|
263
|
+
message: z.ZodString;
|
|
264
|
+
}, z.core.$strip>;
|
|
265
|
+
/**
|
|
266
|
+
* Rejection payload for a browser source hello message.
|
|
267
|
+
*/
|
|
268
|
+
type RelayHelloRejectedMessage = z.infer<typeof RelayHelloRejectedMessageSchema>;
|
|
243
269
|
/**
|
|
244
270
|
* Union schema for all relay-to-browser protocol messages.
|
|
245
271
|
*/
|
|
@@ -253,6 +279,12 @@ declare const RelayToBrowserMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
|
|
|
253
279
|
type: z.ZodLiteral<"server-hello">;
|
|
254
280
|
service: z.ZodLiteral<"webmcp-local-relay">;
|
|
255
281
|
version: z.ZodLiteral<1>;
|
|
282
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
283
|
+
type: z.ZodLiteral<"hello/accepted">;
|
|
284
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
285
|
+
type: z.ZodLiteral<"hello/rejected">;
|
|
286
|
+
reason: z.ZodString;
|
|
287
|
+
message: z.ZodString;
|
|
256
288
|
}, z.core.$strip>, z.ZodObject<{
|
|
257
289
|
type: z.ZodLiteral<"invoke">;
|
|
258
290
|
callId: z.ZodString;
|
|
@@ -262,6 +294,10 @@ declare const RelayToBrowserMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
|
|
|
262
294
|
type: z.ZodLiteral<"ping">;
|
|
263
295
|
}, z.core.$strip>, z.ZodObject<{
|
|
264
296
|
type: z.ZodLiteral<"reload">;
|
|
297
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
298
|
+
type: z.ZodLiteral<"elicitation-response">;
|
|
299
|
+
callId: z.ZodString;
|
|
300
|
+
result: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
265
301
|
}, z.core.$strip>]>;
|
|
266
302
|
/**
|
|
267
303
|
* Relay-to-browser message payload.
|
|
@@ -832,6 +868,10 @@ declare class RelayBridgeServer extends EventEmitter {
|
|
|
832
868
|
* and browser-protocol messages to the existing browser handler.
|
|
833
869
|
*/
|
|
834
870
|
private onSocketMessage;
|
|
871
|
+
/**
|
|
872
|
+
* Sends an elicitation response back to the browser source that requested it.
|
|
873
|
+
*/
|
|
874
|
+
sendElicitationResponse(connectionId: string, callId: string, result: Record<string, unknown>): void;
|
|
835
875
|
/**
|
|
836
876
|
* Handles relay-protocol messages from relay client connections.
|
|
837
877
|
*/
|
|
@@ -868,6 +908,8 @@ declare class RelayBridgeServer extends EventEmitter {
|
|
|
868
908
|
*/
|
|
869
909
|
private toWireTools;
|
|
870
910
|
private isHostOriginAllowed;
|
|
911
|
+
private sendHelloAccepted;
|
|
912
|
+
private sendHelloRejected;
|
|
871
913
|
/**
|
|
872
914
|
* Validates browser tool results against CallToolResultSchema.
|
|
873
915
|
* Non-conforming payloads are wrapped as error results with diagnostic text.
|
|
@@ -1055,5 +1097,5 @@ declare function buildPublicToolName(options: {
|
|
|
1055
1097
|
disambiguate?: boolean;
|
|
1056
1098
|
}): string;
|
|
1057
1099
|
//#endregion
|
|
1058
|
-
export { type AggregatedTool, type BrowserToRelayMessage, BrowserToRelayMessageSchema, CallToolRequestParamsSchema, type CallToolResult, CallToolResultSchema, type CliOptions, DEFAULT_TOOL_INPUT_SCHEMA, HelloRequiredError, InboundToolSchema, LocalRelayMcpServer, type LocalRelayMcpServerOptions, NormalizedToolSchema, RelayBridgeServer, type RelayBridgeServerOptions, type RelayCallToolResult, type RelayClientToServerMessage, RelayClientToServerMessageSchema, type RelayDescriptor, RelayDescriptorSchema, type RelayInvokeArgs, RelayInvokeArgsSchema, RelayRegistry, type RelayServerToClientMessage, RelayServerToClientMessageSchema, type RelaySourceInfo, RelaySourceInfoSchema, type RelayToBrowserMessage, RelayToBrowserMessageSchema, type RelayTool, type RelayToolAnnotations, type ResolvedInvocation, type ServerHelloMessage, ServerHelloMessageSchema, type SourceInfo, type Tool, type ToolAnnotations, ToolAnnotationsSchema, ToolSchema, buildPublicToolName, extractSanitizedDomain, normalizeInboundTool, parseCliOptions, printHelp, sanitizeName };
|
|
1059
|
-
//# sourceMappingURL=index.d.
|
|
1100
|
+
export { type AggregatedTool, type BrowserToRelayMessage, BrowserToRelayMessageSchema, CallToolRequestParamsSchema, type CallToolResult, CallToolResultSchema, type CliOptions, DEFAULT_TOOL_INPUT_SCHEMA, HelloRequiredError, InboundToolSchema, LocalRelayMcpServer, type LocalRelayMcpServerOptions, NormalizedToolSchema, RelayBridgeServer, type RelayBridgeServerOptions, type RelayCallToolResult, type RelayClientToServerMessage, RelayClientToServerMessageSchema, type RelayDescriptor, RelayDescriptorSchema, type RelayHelloAcceptedMessage, RelayHelloAcceptedMessageSchema, type RelayHelloRejectedMessage, RelayHelloRejectedMessageSchema, type RelayInvokeArgs, RelayInvokeArgsSchema, RelayRegistry, type RelayServerToClientMessage, RelayServerToClientMessageSchema, type RelaySourceInfo, RelaySourceInfoSchema, type RelayToBrowserMessage, RelayToBrowserMessageSchema, type RelayTool, type RelayToolAnnotations, type ResolvedInvocation, type ServerHelloMessage, ServerHelloMessageSchema, type SourceInfo, type Tool, type ToolAnnotations, ToolAnnotationsSchema, ToolSchema, buildPublicToolName, extractSanitizedDomain, normalizeInboundTool, parseCliOptions, printHelp, sanitizeName };
|
|
1101
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/protocol.ts","../src/schemas.ts","../src/registry.ts","../src/bridgeServer.ts","../src/cli-utils.ts","../src/mcpRelayServer.ts","../src/naming.ts"],"mappings":"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"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { C as NormalizedToolSchema, D as normalizeInboundTool, E as ToolSchema, S as InboundToolSchema, T as ToolAnnotationsSchema, _ as extractSanitizedDomain, a as BrowserToRelayMessageSchema, b as CallToolResultSchema, c as RelayHelloAcceptedMessageSchema, d as RelaySourceInfoSchema, f as RelayToBrowserMessageSchema, g as buildPublicToolName, h as RelayRegistry, i as RelayBridgeServer, l as RelayHelloRejectedMessageSchema, m as HelloRequiredError, n as parseCliOptions, o as RelayClientToServerMessageSchema, p as ServerHelloMessageSchema, r as printHelp, s as RelayDescriptorSchema, t as LocalRelayMcpServer, u as RelayServerToClientMessageSchema, v as sanitizeName, w as RelayInvokeArgsSchema, x as DEFAULT_TOOL_INPUT_SCHEMA, y as CallToolRequestParamsSchema } from "./mcpRelayServer-BL8kNwIK.mjs";
|
|
2
|
+
|
|
3
|
+
export { BrowserToRelayMessageSchema, CallToolRequestParamsSchema, CallToolResultSchema, DEFAULT_TOOL_INPUT_SCHEMA, HelloRequiredError, InboundToolSchema, LocalRelayMcpServer, NormalizedToolSchema, RelayBridgeServer, RelayClientToServerMessageSchema, RelayDescriptorSchema, RelayHelloAcceptedMessageSchema, RelayHelloRejectedMessageSchema, RelayInvokeArgsSchema, RelayRegistry, RelayServerToClientMessageSchema, RelaySourceInfoSchema, RelayToBrowserMessageSchema, ServerHelloMessageSchema, ToolAnnotationsSchema, ToolSchema, buildPublicToolName, extractSanitizedDomain, normalizeInboundTool, parseCliOptions, printHelp, sanitizeName };
|