Skip to content

Commit ea5b153

Browse files
Make MCP server browser-portable with a Web-standard handler (#136)
Replace the Hono-only Node handler with a Fetch-API handler that runs on Node, Bun, Deno, Cloudflare Workers, and in-page Web Workers. Restructure @eclipse-glsp/server-mcp into a browser/common/node split mirroring @eclipse-glsp/server. - New browser entry point with a Web Worker integration helper. - VS Code web-extension bundle no longer transitively pulls Node-only deps. - Mutating tools report dispatched-command counts for cross-call undo / redo. - Port-agnostic Host-header validation — matches the SDK's older Express middleware that the Fetch transport regressed. - Workflow example ships an end-to-end browser demo of the portable handler in its own private `workflow-server-mcp-demo` workspace; `workflow-server-bundled-web` stays narrow and ships only the worker bundle. The Service Worker scaffolding lives with the demo, not as a published asset of `@eclipse-glsp/server-mcp`. - Root `start:mcp-demo` script builds the worker bundle and launches the demo in one step. - Non-loopback auth and shared session state remain adopter responsibility. - ARCHITECTURE.md refreshed for the portable handler and for the IDE integrations that now register the GLSP MCP server with the host IDE. Part of eclipse-glsp/glsp#1546
1 parent bed0bb0 commit ea5b153

115 files changed

Lines changed: 4385 additions & 1561 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ wf-glsp-server-node.js
1919
wf-glsp-server-node.js.map
2020
wf-glsp-server-webworker.js
2121
wf-glsp-server-webworker.js.map
22+
examples/workflow-server-bundled-web/mcp-service-worker.js
23+
examples/workflow-server-bundled-web/index.bundle.js
24+
examples/workflow-server-bundled-web/index.bundle.js.map
2225

2326
.claude/settings.local.json
2427
CLAUDE.local.md

.prettierignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ dist/
88
# Generated files
99
*.min.js
1010
*.min.css
11+
examples/*/wf-glsp-server-webworker.js
12+
examples/*/wf-glsp-server-webworker.js.map
13+
examples/*/index.bundle.js
14+
examples/*/index.bundle.js.map
1115

1216
# Lock files
1317
package-lock.json

examples/workflow-server-bundled-web/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ See [our project website](https://www.eclipse.org/glsp/documentation/#workflowov
1414

1515
<https://user-images.githubusercontent.com/588090/154459938-849ca684-11b3-472c-8a59-98ea6cb0b4c1.mp4>
1616

17+
## MCP demo
18+
19+
A self-contained dev demo that drives this bundle through `@eclipse-glsp/server-mcp` lives in
20+
its own private workspace at
21+
[`examples/workflow-server-mcp-demo`](../workflow-server-mcp-demo). See its README for how to run.
22+
1723
## More information
1824

1925
For more information, please visit the [Eclipse GLSP Umbrella repository](https://github.com/eclipse-glsp/glsp) and the [Eclipse GLSP Website](https://www.eclipse.org/glsp/).
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Populated by `yarn start` (verbatim assets + synced worker bundle + webpack output)
2+
dist/
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Workflow Server MCP Demo (browser)
2+
3+
A browser demo for the `@eclipse-glsp/server-mcp` portable Fetch handler. The page opens a
4+
workflow GLSP session inside an in-page Web Worker and drives the MCP server through a
5+
Service Worker that intercepts `fetch('/mcp', …)` and proxies the request to the Worker via
6+
`MessageChannel`.
7+
8+
This package is **private** — it ships nothing; it's a local demo and manual test bench for
9+
the portable handler.
10+
11+
## Why only a browser demo?
12+
13+
The browser variant needs a custom harness because **external MCP clients can't reach an
14+
in-page launcher**: a browser tab doesn't accept inbound network traffic. The Service Worker
15+
in this demo is what makes the in-page launcher reachable to a same-origin MCP client.
16+
17+
For the **Node variant**, no demo is needed in this repo — the launcher binds a real HTTP
18+
listener and announces its URL via stdout (`[GLSP-MCP-Server]:Ready. {…}`). Point any MCP
19+
client at that URL:
20+
21+
- The official **[MCP Inspector](https://github.com/modelcontextprotocol/inspector)** is the
22+
best manual debug tool — runs as a local web UI and lets you exercise tools, prompts and
23+
resources interactively.
24+
- **Claude Code**, **Cursor**, or any other MCP-aware client also work.
25+
26+
The Node path is additionally covered by the automated end-to-end spec at
27+
`packages/server-mcp/src/node/server/mcp-http-transport-e2e.spec.ts`, which runs an MCP SDK
28+
`Client` over real HTTP against the launcher.
29+
30+
## Running
31+
32+
From the repository root:
33+
34+
```bash
35+
yarn start:mcp-demo
36+
```
37+
38+
This builds the workflow server, copies the worker bundle from
39+
`@eclipse-glsp-examples/workflow-server-bundled-web`, builds the page-side bundle, and serves
40+
the directory on `http://localhost:8000/`.
41+
42+
Open `http://localhost:8000/` in any modern browser. Step through the buttons
43+
top-to-bottom; the workflow auto-renders once MCP is initialized, and **Create task**
44+
mutates the live session.
45+
46+
## What it exercises
47+
48+
1. The page acts as a minimal GLSP JSON-RPC client over `postMessage` to the in-page Web
49+
Worker (using `vscode-jsonrpc/browser`, bundled).
50+
2. GLSP `initialize` carries `mcpServer: {}` — the Worker's per-connection child container
51+
activates `BrowserMcpServerModule`'s launcher as a `GLSPServerInitializer`.
52+
3. `initializeClientSession` opens a real workflow GLSP session with
53+
`diagramType: workflow-diagram`.
54+
4. A Service Worker (`mcp-service-worker.js`) intercepts `fetch('/mcp', …)` and proxies the
55+
request through a `MessageChannel` to the Worker.
56+
5. MCP tools (`initialize`, `tools/list`, `session-info`, `query-elements`, `diagram-model`,
57+
`create-nodes`) round-trip end-to-end against the live session.
58+
59+
The on-page SVG is a minimal schematic renderer — **not** the GLSP client; its only purpose
60+
is to make the MCP handlers' output visible so the demo can be eyeballed end-to-end.
61+
62+
## Hard reset
63+
64+
If a stale Service Worker is misbehaving: DevTools → Application → Service Workers →
65+
Unregister, then close the tab and re-open. The page's Worker bundle URL is cache-busted per
66+
load, but the SW itself updates only on full lifecycle restart.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "@eclipse-glsp-examples/workflow-server-mcp-demo",
3+
"version": "2.7.0-next",
4+
"private": true,
5+
"description": "Browser demo that drives the @eclipse-glsp/server-mcp portable Fetch handler against the workflow web server bundle.",
6+
"homepage": "https://www.eclipse.org/glsp/",
7+
"bugs": "https://github.com/eclipse-glsp/glsp/issues",
8+
"repository": {
9+
"type": "git",
10+
"url": "https://github.com/eclipse-glsp/glsp-server-node.git"
11+
},
12+
"license": "(EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0)",
13+
"author": {
14+
"name": "Eclipse GLSP"
15+
},
16+
"scripts": {
17+
"build": "webpack",
18+
"clean": "rimraf dist",
19+
"prestart": "node ./scripts/prepare-dist.mjs && yarn build",
20+
"start": "npx -y serve -l 8000 ./dist"
21+
},
22+
"dependencies": {
23+
"@eclipse-glsp-examples/workflow-server-bundled-web": "2.7.0-next"
24+
},
25+
"devDependencies": {
26+
"vscode-jsonrpc": "8.2.0",
27+
"webpack": "^5.75.0",
28+
"webpack-cli": "^5.0.1"
29+
}
30+
}

0 commit comments

Comments
 (0)