Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,32 @@ docs/api/
tmp/
intermediate-findings/

# Environment + logs
.env
.env.*
!.env.example
!.env.sample
!.env.template
*.log

# Coverage + caches
coverage/
.nyc_output/
.cache/
.eslintcache
.stylelintcache
.turbo/

# Playwright
playwright-report/
test-results/
__pycache__/
*.pyc
*.pyc

# Browser test screenshots
tests/browser/__screenshots__/

# Planning/proposal docs (not for commit)
proposal/
docs/http-adapter-error-handling-plan.md
docs/project-notes.md
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ The [`examples/`](https://github.com/modelcontextprotocol/ext-apps/tree/main/exa
| [![Basic](examples/basic-server-react/grid-cell.png "Starter template")](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/basic-server-react) | The same app built with different frameworks — pick your favorite!<br><br>[React](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/basic-server-react) · [Vue](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/basic-server-vue) · [Svelte](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/basic-server-svelte) · [Preact](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/basic-server-preact) · [Solid](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/basic-server-solid) · [Vanilla JS](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/basic-server-vanillajs) |
<!-- prettier-ignore-end -->

Additional example:

- [**Hono React Server**](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/hono-react-server) — Dual-mode HTTP pattern (Hono + React, type-safe `hc` client).

### Running the Examples

#### With basic-host
Expand Down Expand Up @@ -414,6 +418,13 @@ Then configure your MCP client to build and run the local server. Replace `~/cod
"cd ~/code/ext-apps/examples/customer-segmentation-server && npm run build >&2 && node dist/index.js --stdio"
]
},
"hono-react": {
"command": "bash",
"args": [
"-c",
"cd ~/code/ext-apps/examples/hono-react-server && npm run build >&2 && node dist/main.js --stdio"
]
},
"map": {
"command": "bash",
"args": [
Expand Down
16 changes: 16 additions & 0 deletions build.bun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ function buildJs(
}

await Promise.all([
buildJs("src/generated/schema.ts", {
outdir: "dist/src/generated",
external: ["zod"],
}),
buildJs("src/app.ts", {
outdir: "dist/src",
external: ["@modelcontextprotocol/sdk"],
Expand All @@ -51,4 +55,16 @@ await Promise.all([
outdir: "dist/src/server",
external: ["@modelcontextprotocol/sdk"],
}),
buildJs("src/http-adapter/init.ts", {
outdir: "dist/src/http-adapter",
external: ["@modelcontextprotocol/sdk"],
}),
buildJs("src/http-adapter/fetch-wrapper/fetch.ts", {
outdir: "dist/src/http-adapter/fetch-wrapper",
external: ["@modelcontextprotocol/sdk"],
}),
buildJs("src/http-adapter/xhr-wrapper/xhr.ts", {
outdir: "dist/src/http-adapter/xhr-wrapper",
external: ["@modelcontextprotocol/sdk"],
}),
]);
1 change: 1 addition & 0 deletions examples/basic-host/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ This basic host can also be used to test MCP Apps during local development.
- [`index.html`](index.html) / [`src/index.tsx`](src/index.tsx) - React UI host with tool selection, parameter input, and iframe management
- [`sandbox.html`](sandbox.html) / [`src/sandbox.ts`](src/sandbox.ts) - Outer iframe proxy with security validation and bidirectional message relay
- [`src/implementation.ts`](src/implementation.ts) - Core logic: server connection, tool calling, and AppBridge setup
- [`http-adapter-host.test.html`](http-adapter-host.test.html) / [`http-adapter-app.test.html`](http-adapter-app.test.html) - Test-only harness for HTTP adapter E2E coverage

## Getting Started

Expand Down
22 changes: 22 additions & 0 deletions examples/basic-host/http-adapter-app.test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>HTTP Adapter App</title>
<style>
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
margin: 16px;
}
#status {
font-size: 14px;
color: #333;
}
</style>
</head>
<body>
<div id="status">Booting HTTP adapter app…</div>
<script type="module" src="/src/http-adapter-app.ts"></script>
</body>
</html>
30 changes: 30 additions & 0 deletions examples/basic-host/http-adapter-host.test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>HTTP Adapter Host Test</title>
<style>
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
margin: 16px;
}
#status {
font-size: 14px;
color: #333;
margin-bottom: 12px;
}
#app-frame {
width: 100%;
height: 240px;
border: 1px solid #ddd;
border-radius: 8px;
}
</style>
</head>
<body>
<div id="status">Booting HTTP adapter host…</div>
<iframe id="app-frame" title="HTTP Adapter App"></iframe>
<script type="module" src="/src/http-adapter-host.ts"></script>
</body>
</html>
5 changes: 3 additions & 2 deletions examples/basic-host/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"version": "1.0.1",
"type": "module",
"scripts": {
"build": "tsc --noEmit && concurrently \"cross-env INPUT=index.html vite build\" \"cross-env INPUT=sandbox.html vite build\"",
"watch": "concurrently \"cross-env INPUT=index.html vite build --watch\" \"cross-env INPUT=sandbox.html vite build --watch\"",
"build": "tsc --noEmit && concurrently \"cross-env INPUT=index.html vite build\" \"cross-env INPUT=sandbox.html vite build\" \"cross-env INPUT=http-adapter-host.test.html vite build\" \"cross-env INPUT=http-adapter-app.test.html vite build\"",
"watch": "concurrently \"cross-env INPUT=index.html vite build --watch\" \"cross-env INPUT=sandbox.html vite build --watch\" \"cross-env INPUT=http-adapter-host.test.html vite build --watch\" \"cross-env INPUT=http-adapter-app.test.html vite build --watch\"",
"serve": "bun --watch serve.ts",
"start": "cross-env NODE_ENV=development npm run build && npm run serve",
"dev": "cross-env NODE_ENV=development concurrently \"npm run watch\" \"npm run serve\""
Expand All @@ -26,6 +26,7 @@
"concurrently": "^9.2.1",
"cors": "^2.8.5",
"express": "^5.1.0",
"msw": "^2.12.7",
"prettier": "^3.6.2",
"typescript": "^5.9.3",
"vite": "^6.0.0",
Expand Down
Loading