Skip to content

Commit 3c0aec9

Browse files
committed
Merge main into swift-sdk
2 parents 4f7916c + 8550545 commit 3c0aec9

Some content is hidden

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

57 files changed

+5610
-3038
lines changed

.github/workflows/ci.yml

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ on:
66
pull_request:
77
branches: [main]
88

9+
permissions:
10+
contents: read
11+
912
jobs:
1013
build:
1114
runs-on: ubuntu-latest
@@ -30,7 +33,6 @@ jobs:
3033
- name: Verify generated schemas are up-to-date
3134
run: |
3235
npm run generate:schemas
33-
npm run prettier:fix
3436
git diff --exit-code src/generated/ || (echo "Generated schemas are out of date. Run 'npm run generate:schemas' and commit." && exit 1)
3537
3638
- run: npm test
@@ -70,3 +72,32 @@ jobs:
7072
- name: Test Kotlin SDK
7173
working-directory: kotlin
7274
run: ./gradlew test
75+
76+
e2e:
77+
runs-on: ubuntu-latest
78+
steps:
79+
- uses: actions/checkout@v4
80+
81+
- uses: oven-sh/setup-bun@v2
82+
with:
83+
bun-version: latest
84+
85+
- uses: actions/setup-node@v4
86+
with:
87+
node-version: "20"
88+
89+
- run: npm ci
90+
91+
- name: Install Playwright browsers
92+
run: npx playwright install --with-deps chromium
93+
94+
- name: Run E2E tests
95+
run: npx playwright test --reporter=list
96+
97+
- name: Upload test results
98+
uses: actions/upload-artifact@v4
99+
if: failure()
100+
with:
101+
name: test-results
102+
path: test-results/
103+
retention-days: 7

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,8 @@ bun.lockb
66
.vscode/
77
docs/api/
88
tmp/
9+
intermediate-findings/
10+
11+
# Playwright
12+
playwright-report/
13+
test-results/

.prettierrc.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"semi": true,
3+
"trailingComma": "all",
4+
"singleQuote": false,
5+
"printWidth": 80,
6+
"tabWidth": 2
7+
}

CONTRIBUTING.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,45 @@ Or build and run examples:
4040
npm run examples:start
4141
```
4242

43+
## Testing
44+
45+
### Unit Tests
46+
47+
Run unit tests with Bun:
48+
49+
```bash
50+
npm test
51+
```
52+
53+
### E2E Tests
54+
55+
E2E tests use Playwright to verify all example servers work correctly with screenshot comparisons.
56+
57+
```bash
58+
# Run all E2E tests
59+
npm run test:e2e
60+
61+
# Run a specific server's tests
62+
npm run test:e2e -- --grep "Budget Allocator"
63+
64+
# Run tests in interactive UI mode
65+
npm run test:e2e:ui
66+
```
67+
68+
### Updating Golden Screenshots
69+
70+
When UI changes are intentional, update the golden screenshots:
71+
72+
```bash
73+
# Update all screenshots
74+
npm run test:e2e:update
75+
76+
# Update screenshots for a specific server
77+
npm run test:e2e:update -- --grep "Three.js"
78+
```
79+
80+
**Note**: Golden screenshots are platform-agnostic. Tests use canvas masking and tolerance thresholds to handle minor cross-platform rendering differences.
81+
4382
## Code of Conduct
4483

4584
This project follows our [Code of Conduct](CODE_OF_CONDUCT.md). Please review it before contributing.

docs/quickstart.md

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ import cors from "cors";
102102
import express from "express";
103103
import fs from "node:fs/promises";
104104
import path from "node:path";
105-
import { z } from "zod";
105+
import * as z from "zod";
106106

107107
const server = new McpServer({
108108
name: "My MCP App Server",
@@ -130,17 +130,22 @@ server.registerTool(
130130
},
131131
);
132132

133-
server.registerResource(resourceUri, resourceUri, {}, async () => {
134-
const html = await fs.readFile(
135-
path.join(import.meta.dirname, "dist", "mcp-app.html"),
136-
"utf-8",
137-
);
138-
return {
139-
contents: [
140-
{ uri: resourceUri, mimeType: "text/html;profile=mcp-app", text: html },
141-
],
142-
};
143-
});
133+
server.registerResource(
134+
resourceUri,
135+
resourceUri,
136+
{ mimeType: "text/html;profile=mcp-app" },
137+
async () => {
138+
const html = await fs.readFile(
139+
path.join(import.meta.dirname, "dist", "mcp-app.html"),
140+
"utf-8",
141+
);
142+
return {
143+
contents: [
144+
{ uri: resourceUri, mimeType: "text/html;profile=mcp-app", text: html },
145+
],
146+
};
147+
},
148+
);
144149

145150
// Express server for MCP endpoint
146151
const app = express();

examples/basic-host/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"@modelcontextprotocol/sdk": "^1.22.0",
1616
"react": "^19.2.0",
1717
"react-dom": "^19.2.0",
18-
"zod": "^3.25.0"
18+
"zod": "^4.1.13"
1919
},
2020
"devDependencies": {
2121
"@types/express": "^5.0.0",

examples/basic-host/src/implementation.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,19 @@ export async function initializeApp(
186186
log.info("Sending tool call input to MCP App:", input);
187187
appBridge.sendToolInput({ arguments: input });
188188

189-
// Schedule tool call result to be sent to MCP App
190-
resultPromise.then((result) => {
191-
log.info("Sending tool call result to MCP App:", result);
192-
appBridge.sendToolResult(result);
193-
});
189+
// Schedule tool call result (or cancellation) to be sent to MCP App
190+
resultPromise.then(
191+
(result) => {
192+
log.info("Sending tool call result to MCP App:", result);
193+
appBridge.sendToolResult(result);
194+
},
195+
(error) => {
196+
log.error("Tool call failed, sending cancellation to MCP App:", error);
197+
appBridge.sendToolCancelled({
198+
reason: error instanceof Error ? error.message : String(error),
199+
});
200+
},
201+
);
194202
}
195203

196204
/**

examples/basic-host/src/index.module.css

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,32 @@
9292
flex-direction: column;
9393
margin: 0;
9494
font-size: 1.5rem;
95+
position: relative;
9596

9697
.toolName {
9798
font-family: monospace;
9899
}
100+
101+
.closeButton {
102+
position: absolute;
103+
top: 0;
104+
right: 0;
105+
width: 1.5rem;
106+
height: 1.5rem;
107+
padding: 0;
108+
border: none;
109+
border-radius: 4px;
110+
background: #e0e0e0;
111+
font-size: 1.25rem;
112+
line-height: 1;
113+
color: #666;
114+
cursor: pointer;
115+
116+
&:hover {
117+
background: #d0d0d0;
118+
color: #333;
119+
}
120+
}
99121
}
100122
}
101123

0 commit comments

Comments
 (0)