Commit graph ext-apps/package.json
Author SHA1 Message Date
Olivier Chafik
2d4311a25d
chore: bump version to 0.4.2 (#334)
* Adding a simple (bad) pdf icon for directory (#330)

* chore: bump version to 0.4.2

- Update package version from 0.4.1 to 0.4.2
- Pin @types/node to 22.10.0 for dev compatibility
- Override seroval to ^1.4.1 to fix security vulnerabilities
- Use '*' for workspace SDK dependency (works with unpublished versions)

* fix(e2e): update Map Server display name to CesiumJS Map Server (#324)

* fix(test): update map-server test to expect 'CesiumJS Map Server'

The server name was renamed but the E2E test config was not updated.

* fix: change in another file

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Olivier Chafik <ochafik@anthropic.com>

* feat(server): add getUiCapability helper for capability negotiation (#313)

* feat(server): add hasUiSupport/getUiCapability for experimental+extensions

Support double-tagging for MCP Apps capability negotiation:
- Check both experimental and extensions fields in client capabilities
- Add hasUiSupport() to easily check if client supports MCP Apps
- Add getUiCapability() to retrieve the capability settings
- Update spec to document both capability locations

This enables forward compatibility as MCP transitions from experimental
to the extensions field (SEP-1724).

Claude-Generated-By: Claude Code (cli/claude-opus-4-5=100%)
Claude-Steers: 0
Claude-Permission-Prompts: 0
Claude-Escapes: 0

* fix: update @types/node version in package-lock.json

Replace invalid 22.19.5/22.19.6/22.19.7 versions with valid 22.19.3

* docs(spec): clarify hosts SHOULD double-tag, servers SHOULD check both

- Hosts SHOULD advertise capabilities in both experimental and extensions
- Servers SHOULD check both locations, preferring extensions when present
- Updated example to show double-tagging pattern

* chore: remove double-tagging recommendation, keep hasUiSupport helper

Reverts the spec changes that recommended clients double-tag capabilities
in both experimental and extensions fields. The helper functions remain
as they're useful for checking capability in either location.

* refactor(server): simplify to only getUiCapability, remove hasUiSupport

- Remove hasUiSupport function (use getUiCapability directly)
- Remove double-tagging logic (only check extensions field)
- Add ClientCapabilitiesWithExtensions type using SDK's ClientCapabilities
- Update spec to use getUiCapability
- Simplify tests

* fix: update @see link to getUiCapability

* refactor(server): inline ClientCapabilitiesWithExtensions type in getUiCapability

* refactor: move McpUiClientCapabilities to spec.types.ts

* fix: update playwright docker image to v1.58.0

* fix: use -i instead of -it for docker commands (no TTY needed)

* fix: Python server dependency resolution and Docker host validation (#333)

* fix(say-server): add --index flag to uv run for PyPI resolution

The pocket-tts dependency wasn't resolving without explicit --index flag
when invoked via npm scripts.

* fix(qr-server): allow Docker bridge IP in transport security

Add 172.17.0.1:* to allowed_hosts to fix 421 Misdirected Request errors
when the server is accessed from Docker containers.

* feat(basic-host): Add theme toggle and MCP style variables (#336)

* feat(basic-host): add theme toggle and MCP style variables

Add theme support to basic-host example:
- theme.ts: Global theme manager with light/dark toggle
- host-styles.ts: Full set of MCP CSS variables using light-dark()
- ThemeToggle component with sun/moon icons
- Theme-aware CSS using CSS custom properties
- Pass theme + styles to apps via hostContext
- Notify apps when theme changes via sendHostContextChange

Apps now receive:
- hostContext.theme: 'light' | 'dark'
- hostContext.styles.variables: All 60+ MCP CSS variables
- onhostcontextchanged notifications when theme changes

* test: update e2e goldens for theme changes

* [MCP Apps] Add appCapabilities.availableDisplayModes documentation to spec (#331)

* Add appCapabilities.availableDisplayModes documentation to spec

Document the availableDisplayModes field in McpUiAppCapabilities that allows
apps to declare which display modes they support. This enables hosts to
compute the intersection of host and app capabilities and only offer
appropriate display mode controls.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Address PR review feedback

- Change "Guest UI" to "View" terminology
- Add "View" prefix to availableDisplayModes heading for disambiguation
- Remove intersection logic - host only checks its own supported modes
- Remove assumption that apps must support inline mode
- Simplify host behavior to honor/reject based on its own capabilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add appCapabilities.availableDisplayModes to types

- Add `availableDisplayModes` field to `McpUiAppCapabilities` so apps can
  declare which display modes they support
- Change `HostContext.availableDisplayModes` type from `string[]` to
  `McpUiDisplayMode[]` for type safety
- Regenerate schemas

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Address Olivier's feedback - consolidate display mode docs

- Remove separate "App Capabilities" section for availableDisplayModes
- Add display mode requirements to existing ui/request-display-mode section:
  - Host MUST NOT switch View to mode not in appCapabilities.availableDisplayModes
  - Host MAY decline requests from Views that didn't declare modes
  - View MUST declare supported modes during initialization

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Restore McpUiAppCapabilities docs and fix display mode clause

- Restore McpUiAppCapabilities interface documentation with availableDisplayModes
- Restore "View MUST check if the requested mode is in availableDisplayModes
  from host context" clause that was accidentally removed

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Create unified Display Modes section

Consolidate all display mode documentation into a single section:
- Display mode types (inline, fullscreen, pip)
- Declaring support from View (appCapabilities.availableDisplayModes)
- Declaring support from Host (HostContext.availableDisplayModes)
- Requesting changes (ui/request-display-mode)
- Notifying changes (ui/notifications/host-context-changed)
- All MUST/SHOULD requirements for View and Host behavior

The ui/request-display-mode in Requests section now references
the Display Modes section for behavior details.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Remove mode coercion clause from display modes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Regenerate schemas with correct version

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

* feat(say-server): add light/dark theme support (#338)

- Add importmap entry for main SDK exports (applyDocumentTheme, etc.)
- Import and apply host theme and styles on context changes
- Apply initial host context theme/styles when app connects
- Update CSS to use [data-theme="dark"] selector for host-provided themes
- Keep @media prefers-color-scheme as fallback for standalone mode
- Add color-scheme meta tag for native element theming

* fix: followup app -> view terminology (#339)

* chore: husky env fix, version pins, update-lock:docker script (#341)

* fix(husky): load Node.js env for GUI apps + add update-lock:docker script

Cherry-picked non-e2e changes from ochafik/fix-e2e-flaky-tests:
- Load nvm/fnm/volta/homebrew paths in pre-commit for GitHub Desktop
- Add update-lock:docker script to regenerate lockfile with public registry

* pin package versions for dev compatibility

- solid-js: 1.9.10
- caniuse-lite: 1.0.30001763
- cheerio: 1.1.2
- electron-to-chromium: 1.5.267
- @playwright/test: 1.57.0
- playwright: 1.57.0
- playwright-core: 1.57.0

* regen

* fix: pin @types/node to existing version and regenerate lockfile

- Fix @types/node 20.19.28 -> 20.19.27 (typo, version didn't exist)
- Regenerate package-lock.json to resolve versions available on both
  public npm and Anthropic artifactory registries

* fix(basic-server-solid): bump solid-js 1.9.10 -> 1.9.11 to fix seroval vulnerabilities

* fix: pin seroval to 1.4.1 for dev compatibility

* Refactor server startup functions

Rename `startServer` to `startStreamableHTTPServer` and add a new
`startStdioServer` helper to make the transport type explicit. Remove
the `ServerOptions` interface in favor of reading `PORT` directly from
the environment inside the function (defaulting to `3001`).

Also update Python examples to default to port `3001` for consistency.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Support full-file inclusion in synced code snippets

Previously, the script only supported extracting regions from `.ts/.tsx`
files using the `#regionName` syntax. Now it also supports including
entire files without a region specifier, enabling sync of any file type
(JSON, YAML, shell scripts, etc.) into documentation.

Changes:
- Make `#regionName` optional in the `source=""` attribute
- Accept any fence language (not just `ts`/`tsx`)
- Simplify cache to flat map with composite keys
- Add validation error for region extraction on non-TypeScript files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Rewrite Quickstart guide with type-checked code examples

Rewrites the Quickstart tutorial to provide a more focused, step-by-step
introduction to building MCP Apps. The guide now uses synced code fences
that pull from `examples/quickstart/`, ensuring all code shown in the
documentation is type-checked and tested.

Key improvements:
- Clearer project setup instructions with explicit commands
- Streamlined explanations of the tool + resource registration pattern
- Added screenshot showing the completed app
- E2E test coverage validates the example works end-to-end

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Add MCP Apps Overview document

Adds `docs/overview.md` covering the core concepts: architecture,
lifecycle, UI resources, bidirectional communication, theming, display
modes, and security. Includes mermaid flowchart and sequence diagrams.

Also adds the `@boneskull/typedoc-plugin-mermaid` TypeDoc plugin for
mermaid diagram support. However, the plugin handles HTML entities from
TypeDoc incorrectly, so `scripts/typedoc-plugin-fix-mermaid-entities.mjs`
decodes HTML entities before the plugin processes them.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Add Agent Skills installation guide

Add `docs/agent-skills.md` with installation instructions for multiple AI
coding agents including Claude Code, VS Code/Copilot, Gemini CLI, Cline,
and Goose. The guide provides three installation methods: Claude Code
plugin, Vercel Skills CLI (`npx skills add`), and manual installation.

Update `README.md` to link to the new guide and reframe the plugin
section around the broader "Agent Skills" concept.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Polish OpenAI migration reference for readability

Add framing prose to the migration guide to improve navigation:
- Expanded intro describing document purpose and how to use it
- Added note about features marked "Not yet implemented"
- Added brief transition sentences before Server-Side and Client-Side sections

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Fix mermaid diagram arrowheads not rendering

The `@boneskull/typedoc-plugin-mermaid` creates both dark and light theme
variants of each diagram, each with identical marker IDs (e.g., `#arrowhead`).
When mermaid renders SVGs at runtime, lines reference `url(#arrowhead)`, but
the browser resolves this to the first match in document order — the hidden
dark-theme SVG — causing arrows to be invisible.

The fix removes dark-theme `<div class="mermaid dark">` elements at build time,
leaving only one SVG per diagram with unique marker IDs. A CSS filter
(`filter: invert(1) hue-rotate(180deg)`) handles dark mode styling instead.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(docs): improve OpenAI migration guide accuracy (#349)

- Add missing setOpenInAppUrl API to 'Not Yet in MCP Apps' section
- Clarify Event Handling table: specify exact OpenAI properties
  (toolInput/toolOutput) instead of vague 'window.openai.*'
- Improve notes to distinguish sync property reads vs callbacks

* Add Testing MCP Apps guide

Document how to test MCP Apps using `basic-host` and MCP Apps-compatible
hosts like Claude.ai and VS Code Copilot. Cover debugging features for
`basic-host`, and using `cloudflared` to expose local servers for remote
hosts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Fix `onhostcontextchanged` handler invocation in examples

`App.onhostcontextchanged` is a setter-only property with no getter.
TypeScript doesn't prevent reading from setter-only properties, so
`app.onhostcontextchanged?.(ctx)` compiles but silently returns
`undefined` at runtime.

Extract the handler into a named `handleHostContextChanged()` function
and call it directly after `connect()`, matching the pattern used in
`basic-server-vanillajs` and other examples.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Expand Agent Skills guide

Add intro explaining what Agent Skills are and link to the two skill
files (`create-mcp-app`, `migrate-oai-app`). Reorganize headings and add
"Invoke a Skill" and "Test Your App" sections. Update `README.md` link
text and add tip to quickstart suggesting agent skills as an alternative.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(e2e): improve test stability and developer experience (#337)

* fix(e2e): add masks for dynamic content and increase timeouts for slow servers

- Add HOST_MASKS for Tool Input/Result panels with dynamic timestamps
- Add say-server to SLOW_SERVERS (10s) for TTS model download
- Add say-server to EXTRA_WAIT_MS (30s) in generate-grid-screenshots

* feat: add update-lock:docker script to regenerate lockfile with public registry

* pin package versions for dev compatibility

* feat(basic-host): add ?theme=hide query param to hide theme toggle in screenshots

- Add hideThemeToggle param to getQueryParams()
- Conditionally render ThemeToggle based on ?theme=hide
- Update e2e tests to use ?theme=hide for consistent screenshots

* update screenshots

* update screenshots

* fix(husky): load Node.js environment for GUI apps like GitHub Desktop

* fix(e2e): increase map-server wait time to 15s for tile loading

* fix(e2e): increase waitForAppLoad timeout to 30s for nested iframe loading

* ci: add workflow to update e2e snapshots

* ci: trigger snapshot update on push to this branch

* chore: update e2e snapshots [skip ci]

* ci: trigger CI after snapshot update

* style: fix prettier formatting in update-snapshots workflow

* fix: pin seroval, seroval-plugins, and solid-js for dev compatibility

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Improve README structure and clarity

Add "Why MCP Apps?" section to explain the motivation upfront. Reorganize
the "How It Works" section to lead with tool definition. Rename "Overview"
to "Using the SDK" and add "For" prefix to audience headings.

Restructure the Examples section with clearer subsections for running
examples with `basic-host` vs MCP clients using stdio transport. Move the
`qr` server note outside the collapsed details block.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Add Codex and Goose to documentation

Add Codex to the list of agents supporting skills in `agent-skills.md`.
Add Goose to the list of supported clients in `testing-mcp-apps.md` and
rename "VS Code Copilot" to "VS Code (Insiders)" for accuracy.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: regenerate lockfile with public registry, use ^0.4.2 for ext-apps deps

* fix: update quickstart example to use workspace reference

* chore: remove internal registry references from lockfile

* feat(ci): add /update-snapshots comment trigger for PRs

- Comment '/update-snapshots' on any PR to update E2E snapshots
- Adds rocket reaction to acknowledge the command
- Comments back with result (updated or no changes needed)
- Removes hardcoded branch trigger
- Keeps workflow_dispatch for manual runs

* docs: document /update-snapshots PR comment trigger

* fix: pin @hono/node-server to 1.19.7 for dev compatibility

SDK 1.25.3 requires @hono/node-server@^1.19.9 which doesn't exist
on the public npm registry (latest is 1.19.7).

* fix: pin @modelcontextprotocol/sdk to 1.25.2

SDK 1.25.3 has broken dependency on @hono/node-server@^1.19.9
which doesn't exist on public npm registry.

* fix: restore flexible SDK peerDep range (^1.24.0)

devDependencies stays pinned to 1.25.2 for our builds,
but peerDependencies should allow users flexibility.

* fix: pin @types/node to avoid unpublished versions

- Pin quickstart @types/node to 22.19.5 (latest public 22.x)
- Add @types/node override to root package.json
- Regenerate lockfile with public registry only

---------

Co-authored-by: Tobin South <tobin.south@gmail.com>
Co-authored-by: Liad Yosef <liady@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: martinalong <martinalong10@gmail.com>
Co-authored-by: Ido Salomon <idosalomon@gmail.com>
Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-26 14:30:00 +00:00
Olivier Chafik
e479497371
fix(e2e): improve test stability and developer experience (#337)
* fix(e2e): add masks for dynamic content and increase timeouts for slow servers

- Add HOST_MASKS for Tool Input/Result panels with dynamic timestamps
- Add say-server to SLOW_SERVERS (10s) for TTS model download
- Add say-server to EXTRA_WAIT_MS (30s) in generate-grid-screenshots

* feat: add update-lock:docker script to regenerate lockfile with public registry

* pin package versions for dev compatibility

* feat(basic-host): add ?theme=hide query param to hide theme toggle in screenshots

- Add hideThemeToggle param to getQueryParams()
- Conditionally render ThemeToggle based on ?theme=hide
- Update e2e tests to use ?theme=hide for consistent screenshots

* update screenshots

* update screenshots

* fix(husky): load Node.js environment for GUI apps like GitHub Desktop

* fix(e2e): increase map-server wait time to 15s for tile loading

* fix(e2e): increase waitForAppLoad timeout to 30s for nested iframe loading

* ci: add workflow to update e2e snapshots

* ci: trigger snapshot update on push to this branch

* chore: update e2e snapshots [skip ci]

* ci: trigger CI after snapshot update

* style: fix prettier formatting in update-snapshots workflow

* fix: pin seroval, seroval-plugins, and solid-js for artifactory compatibility

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-25 22:18:38 +02:00
Jonathan Hefner
d856b8bda6
Add MCP Apps Overview document
Adds `docs/overview.md` covering the core concepts: architecture,
lifecycle, UI resources, bidirectional communication, theming, display
modes, and security. Includes mermaid flowchart and sequence diagrams.

Also adds the `@boneskull/typedoc-plugin-mermaid` TypeDoc plugin for
mermaid diagram support. However, the plugin handles HTML entities from
TypeDoc incorrectly, so `scripts/typedoc-plugin-fix-mermaid-entities.mjs`
decodes HTML entities before the plugin processes them.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 14:05:00 -06:00
Olivier Chafik
9557d41ce7
chore: husky env fix, version pins, update-lock:docker script (#341)
* fix(husky): load Node.js env for GUI apps + add update-lock:docker script

Cherry-picked non-e2e changes from ochafik/fix-e2e-flaky-tests:
- Load nvm/fnm/volta/homebrew paths in pre-commit for GitHub Desktop
- Add update-lock:docker script to regenerate lockfile with public registry

* pin package versions for dev compatibility

- solid-js: 1.9.10
- caniuse-lite: 1.0.30001763
- cheerio: 1.1.2
- electron-to-chromium: 1.5.267
- @playwright/test: 1.57.0
- playwright: 1.57.0
- playwright-core: 1.57.0

* regen

* fix: pin @types/node to existing version and regenerate lockfile

- Fix @types/node 20.19.28 -> 20.19.27 (typo, version didn't exist)
- Regenerate package-lock.json to resolve versions available on both
  public npm and Anthropic artifactory registries

* fix(basic-server-solid): bump solid-js 1.9.10 -> 1.9.11 to fix seroval vulnerabilities
2026-01-24 01:35:45 +00:00
Jonathan Hefner
58019a48ce
Replace {@includeCode} with synced code fences
Migrate JSDoc and markdown documentation from `{@includeCode ./file#region}`
tags to inline code fences with `source="./file#region"` attributes.
Code examples are now visible directly in source files while remaining
type-checked via their `.examples.ts` source files.

Add `scripts/sync-snippets.ts` to extract code from `//#region` blocks
and sync it into labeled fences. Run with `npm run sync:snippets`.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 07:34:56 -06:00
Jonathan Hefner
eb803723ef
Use typedoc-github-theme for API documentation
Configure TypeDoc to use the GitHub-styled theme for better visual
consistency with the project's GitHub presence. Also reorganize the
config options and enable group navigation for improved documentation
structure.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 13:24:01 -06:00
Olivier Chafik
801e1b043a
add EXAMPLE=folder-name support for tests & basic-host (#292)
* add EXAMPLE=folder-name support for tests & basic-host

* style: format e2e test files

* style: format threejs-server files
2026-01-19 20:16:37 +00:00
Olivier Chafik
8c3b1daf7e
chore: bump version to 0.4.1 (#282) 2026-01-15 16:11:53 +00:00
Anton Pidkuiko MacBook
0927445025
feat(qr-server): migrate to uv with PEP 723 inline dependencies
- Replace requirements.txt with inline script dependencies in server.py
- Add package.json with npm scripts for run-all.ts integration
- Update CI workflow to install uv via astral-sh/setup-uv@v5
- Update Docker commands to install uv for e2e tests
- Add Playwright golden screenshot for qr-server
- Update README with uv installation and usage instructions
2026-01-14 20:27:35 +00:00
Olivier Chafik
96daa46a1d
examples: add PDF viewer w/ chunked data loading, full-screen, model context updates, private tool (#267)
* feat(pdf-server): Interactive PDF viewer example

PDF viewer with PDF.js featuring:
- Chunked binary loading with progress bar
- Text extraction for AI context
- arXiv paper support (fetch by ID)
- Page navigation with keyboard shortcuts
- Zoom controls (including Ctrl+0 reset)
- Fullscreen mode support
- Horizontal swipe for page changes (disabled when zoomed)
- Page persistence in localStorage
- Text selection via PDF.js TextLayer
- Clickable title link to source URL
- Rounded corners and subtle border styling

* chore: Add pdf-server to screenshot generation list

* refactor(pdf-server): Simplify and generalize PDF loading

- Accept any HTTP(s) URLs instead of ArXiv-only
- Use HTTP Range requests for chunked binary loading
- Remove ArXiv-specific code (arxiv.ts, metadata fetching)
- Remove CLAUDE.md index generation
- Flatten hierarchical folder structure to simple entries list
- Remove dead code: getPdfSummary, httpFileSizes
- Simplify base64 encoding using Buffer
- Simplify chunk extraction using slice()
- Consolidate DEFAULT_PDF_URL constant

The server now works with any PDF URL, not just arXiv papers.
HTTP Range requests stream chunks on-demand when supported.

* feat(pdf-server): Include title and selection in model context

- Add pdfTitle to updateModelContext structuredContent
- Include selection position (text, start, end) when text is selected
- Add debounced selectionchange listener to update context on selection

* fix(pdf-server): Restore default URL in view_pdf schema

The UI needs the default value in the schema to show it properly.

* refactor(pdf-server): Further simplifications

- Remove hard-coded test paths from main()
- Remove unused resources: pdfs://metadata/{pdfId}, pdfs://content/{pdfId}
- Remove unused metadata fields: subject, creator, producer, creationDate, modDate
- Remove unused entry fields: relativePath, estimatedTextSize
- Remove filterEntriesByFolder and folder filter from list_pdfs
- Remove redundant output schema validation (trust typed returns)
- Simplify scanDirectory and createLocalEntry signatures

Total: 1836 → 1666 lines (-170 lines, -9%)

* refactor(pdf-server): Major simplification for didactic focus

Simplified the example to focus on key MCP Apps SDK patterns:
- Chunked data through size-limited tool calls
- Model context updates (page text + selection)
- Display modes (fullscreen vs inline)
- External links (openLink)

Changes:
- Remove local file support (HTTP URLs only)
- Restrict dynamic URLs to arxiv.org for security
- Simplify types: url instead of sourcePath/sourceType
- Simplify indexer: 168 → 44 lines
- Simplify loader: 318 → 171 lines
- Simplify server: 337 → 233 lines
- Fix selection text normalization
- Rewrite README with didactic focus

Total: 1836 → 1236 lines (-33%)

* feat(pdf-server): Add file:// URL support for local files

- Local paths are converted to file:// URLs on startup
- file:// URLs must be in the initial list (strict validation)
- Dynamic URLs still restricted to arxiv.org only
- Updated README with local file examples

* fix(pdf-server): Improve selection detection with logging

- Add logging to selectionchange handler to verify it fires
- Add fallback matching without spaces (TextLayer spans may lack spaces)
- Log selection detection success/failure for debugging

The issue: PDF.js TextLayer renders text as positioned spans without
space characters between them. When selecting across spans:
- pageText has spaces (items joined with ' ')
- sel.toString() may not have spaces
- indexOf fails to match

The fix tries exact match first, then falls back to spaceless matching.

* feat(pdf-server): Format model context as markdown with front matter

Model context now looks like:
```markdown
---
url: https://arxiv.org/pdf/...
page: 5/144
---

Page text with <pdf-selection>selected text</pdf-selection> inline.
```

This is cleaner for the model to parse and includes the source URL.

* refactor(pdf-server): Extract smart truncation helpers

Added two well-designed helpers:

formatPageContent(text, maxLength, selection?)
- Centers truncation window around selection if present
- Adds <truncated-content/> markers at elision points
- Wraps selection in <pdf-selection> tags
- Allocates 60% context before, 40% after for readability

findSelectionInText(pageText, selectedText)
- Tries exact match first
- Falls back to spaceless match for TextLayer quirks
- Returns { start, end } or undefined

Example output with selection:
```
<truncated-content/>
...context before... <pdf-selection>selected text</pdf-selection> ...context after...
<truncated-content/>
```

* fix(pdf-server): Truncate inside selection tags when selection too long

When selection is too large for the budget:
<truncated-content/><pdf-selection><truncated-content/>start...end<truncated-content/></pdf-selection><truncated-content/>

This keeps the selection structure intact while showing beginning and end.

* refactor(pdf-server): Remove unused read_pdf_text, use Attention paper as default

- Remove read_pdf_text tool (viewer extracts text client-side with pdfjs)
- Remove PdfTextChunk and ReadPdfTextInput types
- Remove loadPdfTextChunk from pdf-loader
- Change default PDF to 'Attention Is All You Need' (1706.03762)
- Update README with modest language

* refactor(pdf-server): Simplify to use URL as ID, rename view_pdf to display_pdf

Major simplifications:
- Use URL directly as identifier (no hashing)
- Remove displayName - show elided URL with full URL as tooltip
- Rename view_pdf to display_pdf with better description
- Update all references from pdfId to url
- Simplify storage key and model context

The tool description now explains it displays an interactive viewer in the chat.

* feat(pdf-server): Normalize arxiv URLs to PDF format

arxiv.org/abs/... -> arxiv.org/pdf/...

Applied both at startup and when loading dynamic URLs.

* docs(pdf-server): Add prompt engineering to display_pdf description

* fix(pdf-server): Sharp rendering on retina displays

Account for devicePixelRatio when rendering canvas:
- Scale canvas dimensions by dpr
- Scale context by dpr
- Keep CSS size at logical pixels

* fix(pdf-server): Normalize arxiv URLs in read_pdf_bytes too

* add to e2e spec

* add to e2e spec

* add to e2e spec

* add to e2e spec

* regen

* chore: regenerate package-lock.json and fix hono vulnerability

* docs: add pdf-server screenshot to READMEs

* regen

* ci: add missing examples to pkg-pr-new publish

* ci: add pdf-server to npm publish examples

* Update README.md

* pdf-server: improve tool response text for better model context

* revert unrelated screenshot changes

* pdf-server: dynamically add arxiv URLs in read_pdf_bytes

Fixes 'PDF not found' error when server restarts between display_pdf
(which adds the entry) and read_pdf_bytes (which previously only looked
up existing entries). Now read_pdf_bytes mirrors display_pdf's logic
and dynamically adds arxiv URLs to the index.
2026-01-14 14:25:24 +00:00
Olivier Chafik
574a768e09
feat: add example gallery with auto-generated screenshots (#253)
* feat: add script to generate 300x300 grid-cell.png screenshots for examples

- Add generate-grid-screenshots.spec.ts Playwright test to capture screenshots
- Add npm run generate:screenshots command (Docker-based for Santa compatibility)
- Add sharp dependency for image resizing with centered-fill mode
- Generate grid-cell.png for 14 example servers (only React for basic-server-* series)

The screenshots are 300x300 PNG images cropped with centered fill mode,
suitable for use in a grid layout showcasing the examples.

* docs: add example gallery grid to README

Add a 3-column visual grid showcasing 14 example MCP Apps with:
- Thumbnail screenshots (300x300 grid-cell.png)
- Clickable links to example directories
- Hover tooltips with brief descriptions

Organized by visual impact: 3D/WebGL examples first, then
visualizations, charts, monitoring, and starter templates.

* fix: use aspect-fit instead of crop for screenshots

Change from fit: 'cover' (crops) to fit: 'contain' (letterbox)
so the full app content is visible without cropping.

* feat: improve screenshot generation

- Constrain viewport to 500px width for consistent rendering
- Wait 5 seconds for full app load (tiles, animations, data)
- Screenshot just the inner iframe (no extra whitespace)
- Save both screenshot.png (full-size) and grid-cell.png (300x300 thumbnail)
- Use contain mode to preserve aspect ratio

* fix: use cover mode with top alignment for grid thumbnails

No letterboxing - crops to fill 300x300, aligned to top so headers
and important content are always visible.

* feat: improve screenshot gallery

- Remove integration-server from gallery (it's for E2E testing only)
- Add 30s extra wait for Map and Video servers to load fully
- Improve Three.js default scene: isometric rotation + better lighting
- Update README: Starter Templates row with links to all framework variants
  (React, Vue, Svelte, Preact, Solid, Vanilla JS)
- Regenerate all screenshots with updated settings

* fix: improve README gallery layout

- Fix uneven column widths by using minimal separator
- Move Starter Templates to separate 2-cell table with description
- Add screenshot.png to top of each example README (13 examples)
- Shorten tooltips for cleaner table

* revert to document.write again; cesiumjs doesn't like srcdoc, period.

* fix: map-server screenshot now renders properly

- Merged ochafik/post-fixes which reverts sandbox from srcdoc to document.write
  (CesiumJS doesn't work with srcdoc iframes)
- Fixed map-server name in screenshot test ('Map Server' not 'CesiumJS Map Server')
- Simplified screenshot generation script (removed complex debugging code)
- Increased map-server wait time to 45s for reliable tile loading
- Regenerated all 13 screenshots

* fix: remove redundant screenshots from READMEs

Remove the simple \![Screenshot](screenshot.png) line from READMEs that
already had nicer HTML table screenshots. Keep it only for examples
that didn't have existing screenshots.

* docs: move gallery to Examples section

- Move screenshot gallery from top of README to Examples section
- Remove redundant list of basic examples (now shown visually in gallery)
- Clean up duplicate run instructions

* fix: remove empty header row from starter templates table

* fix: remove empty header rows from both tables

* fix: add prettier-ignore to prevent table header expansion

* feat: use custom screenshot for video-resource-server

- Use better screenshot from PR #253 comment showing actual video playback
- Skip video-resource-server in screenshot generation script
- Add SKIP_SERVERS set for manually maintained screenshots

* fix: revert unrelated map-server name change

* fix: use correct server name 'CesiumJS Map Server' in screenshot test
2026-01-13 15:12:18 +00:00
Olivier Chafik
231f23fd72
chore: release 0.4.0 (#249)
* chore: release 0.4.0

* chore: add new examples to npm publish workflow

Add map-server, shadertoy-server, and transcript-server to the
publish-examples matrix.
2026-01-12 22:40:24 +00:00
Olivier Chafik
9a9ecf27d4
feat(examples): add --watch to bun serve commands for auto-restart, and have npm start hit dev mode of all examples (#246)
* feat(examples): add --watch to bun serve commands for auto-restart on file changes

* Update package.json

* regen
2026-01-12 22:17:12 +00:00
Olivier Chafik
4c51eb0301
chore: release 0.3.1 (#224)
* chore: release 0.3.1
2026-01-09 18:22:27 +00:00
Olivier Chafik
f8e31eb97f
fix: ensure lib is built before examples:build (#185)
* fix: ensure lib is built before examples:build

Add preexamples:build hook to automatically run `npm run build` before
`examples:build`. This ensures examples always type-check against the
latest library code, catching breaking changes during development.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add version consistency check for examples

Add scripts/check-versions.mjs to verify that example package.json files
reference the correct version of @modelcontextprotocol/ext-apps.

- Allows "../.." (local dev) or "^{root-version}" as valid dependencies
- Runs in CI before npm install to catch mismatches early
- Available locally via `npm run check:versions`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: regenerate package-lock.json for cross-platform compatibility

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-09 01:36:42 +00:00
Olivier Chafik
e078250adf
build app-with-deps (#221) 2026-01-09 01:26:31 +00:00
Olivier Chafik
ecc593bcec
chore: release 0.3.0 (#204)
* chore: bump version to 0.3.0

Breaking changes:
- `viewport` replaced with `containerDimensions` in host context

New examples:
- video-resource-server
- sheet-music-server

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(video-resource-server): add missing server-utils and fix import path

The video-resource-server was importing from a non-existent
../shared/server-utils.js path. Added the server-utils.ts file
and fixed the import to use ./src/server-utils.js like other examples.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: update ext-apps version refs to 0.3.0

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-09 00:55:45 +00:00
Jerome
c25d464d18
feat: publish example servers to npm (#184)
* feat: publish example servers to npm

Make example MCP App servers publishable to npm under the
@modelcontextprotocol scope:

- server-basic-react
- server-basic-vanillajs
- server-budget-allocator
- server-cohort-heatmap
- server-customer-segmentation
- server-scenario-modeler
- server-system-monitor
- server-threejs
- server-wiki-explorer

Changes:
- Remove `private: true` from example package.json files
- Add proper npm metadata (description, repository, license, files)
- Update ext-apps dependency from relative to ^0.2.2
- Copy server-utils.ts into each package for standalone use
- Add publish-examples job to npm-publish.yml workflow

The examples will be published automatically when a GitHub release
is created, after the main SDK package is published.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: publish examples with pkg-pr-new for PR testing

* feat: export createServer from example servers

* style: format integration-server/server.ts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: update e2e snapshots for basic-server examples

Update golden screenshots for basic-react and basic-vanillajs after
the tool output was simplified from JSON to plain text in #182.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* merge

* refactor: update sheet-music-server and video-resource-server to new publishing pattern

- Move server-utils.ts from src/ to root level
- Add npm publishing metadata (scoped name, repository, license, files)
- Change ext-apps dependency from local to versioned ^0.2.2
- Update server.ts to handle stdio mode inline

* update package-lock

* fix: update package-lock.json for renamed server packages

* feat: add NASA public domain video to video-resource-server

Added 'nasa-earth' option - NASA ISS Earth observations (6.4MB).
Source: archive.org/details/NASA-Ultra-High-Definition (public domain)

* fix: add default videoId for video-resource-server

* fix: use existing bunny-1mb as default video, remove nasa-earth

* refactor: update new framework examples to publishing pattern

Add publishing metadata for:
- @modelcontextprotocol/server-basic-preact
- @modelcontextprotocol/server-basic-solid
- @modelcontextprotocol/server-basic-svelte
- @modelcontextprotocol/server-basic-vue

Changes:
- Move server-utils.ts from src/ to root
- Add npm publishing metadata
- Update ext-apps dep to versioned ^0.2.2
- Add stdio mode support in main()

* fix: add missing @rollup/rollup-win32-arm64-msvc to optionalDependencies

This fixes the Windows ARM64 CI build failure caused by npm's optional
dependency bug. The package.json was missing this platform-specific
rollup binding.

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Olivier Chafik <ochafik@anthropic.com>
2026-01-08 20:08:50 +00:00
Jonathan Hefner
3222c87c56
Add npm start alias for examples:start (#183)
Allows running `npm start` as a shorthand for `npm run examples:start`,
providing a conventional entry point to launch the example servers.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 11:36:02 +00:00
Nicholas Lim
9963d0f17d
fix: move prettier to dev dependency (#179) 2025-12-18 17:10:49 +00:00
Olivier Chafik
82ab3c894c
chore: bump to 0.2.2 + make Zod schemas version-agnostic (v3.25+/v4) (#178)
* feat: make generated Zod schemas version-agnostic (v3.25+/v4)

- Change generated schema imports from `zod/v4` to standard `zod`
- Replace v4-only `z.looseObject()` with `z.object().passthrough()`
- Works with both Zod v3.25+ and v4, matching MCP TS SDK approach
- Bump version to 0.2.2

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: regenerate package-lock.json in Docker

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-17 20:55:59 +00:00
Olivier Chafik
bbea41f27b
chore: release 0.2.1 - widen @oven/bun-* version range (#176)
* fix: widen @oven/bun-* version range to improve install compatibility

Lower the minimum version of @oven/bun-* optional dependencies from
^1.3.4 to ^1.2.21. This is the lowest common version available across
all platform-specific packages, improving compatibility for contributors
who may not have access to the latest package versions.

The caret range (^) still allows npm to install newer versions when
available.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: bump version to 0.2.1

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-17 15:56:17 +00:00
Olivier Chafik
894f7936f5
chore: bump version to 0.2.0 (#170) 2025-12-16 22:23:50 +00:00
Olivier Chafik
d9006bd69a
feat: make MCP SDK a peer dependency (#168)
* feat: make MCP SDK a peer dependency

- Move @modelcontextprotocol/sdk from dependencies to peerDependencies (^1.20.0)
- Add to devDependencies for local development (^1.24.3)
- Externalize SDK from all build entry points (app, app-bridge, react, server)

Benefits:
- Consumers control their SDK version
- Deduplication when consumer already has SDK
- Follows pattern of react/zod peer deps

* fix: require SDK ^1.24.0 for Zod 4 compatibility

Earlier SDK versions have Zod type incompatibilities that cause build errors.

* chore: update examples to SDK ^1.24.0 to match peer dep
2025-12-16 22:09:59 +00:00
Olivier Chafik
bea0ae27f5
feat: add server helpers, make connect() to default to parent post transport (#165)
* feat: add server helpers and optional connect() transport

Add `src/server/` with convenience functions for registering MCP App tools
and resources:

- `registerAppTool(server, name, config, handler)`
- `registerAppResource(server, name, uri, config, callback)`

The `transport` parameter in `App.connect()` is now optional, defaulting to
`PostMessageTransport(window.parent)`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Update src/server/index.ts

Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>

* fix: refine server helper types

- Make RESOURCE_URI_META_KEY required in McpUiAppToolConfig (tools need a UI resource)
- Make _meta optional in McpUiAppResourceConfig (not all resources need custom metadata)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: simplify RESOURCE_URI_META_KEY re-export

* refactor: consolidate export statements

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
2025-12-16 21:25:26 +00:00
Olivier Chafik
31e05d31fa
fix: make react a peer dependency to support multiple versions (#163) (#164)
Move react and react-dom from dependencies to peerDependencies with
support for React 17, 18, and 19. This allows consumers to use their
preferred React version instead of forcing v19.

- Added peerDependencies for react/react-dom (^17 || ^18 || ^19)
- Marked react dependencies as optional in peerDependenciesMeta
- Moved react/react-dom to devDependencies for local development
- React is already externalized in the build (build.bun.ts)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-16 19:33:05 +00:00
Olivier Chafik
974862237b
fix: Windows compatibility - bun as optional dep, cross-env for examples (#145)
* fix: Windows compatibility for npm scripts and cross-platform CI

Fixes #142 - Windows PowerShell install bug

Changes:
- Replace single quotes with escaped double quotes in generate:schemas
  (cmd.exe passes single quotes literally, breaking prettier glob matching)
- Simplify prettier scripts: remove redundant --ignore-path flags
  (prettier auto-loads .gitignore and .prettierignore by default)
- Remove $(pwd) from prettier scripts (bash-only syntax)
- Add cross-platform CI matrix: Linux x64, Windows x64, macOS ARM64, macOS x64
- Use shell: bash for grep commands in CI (not available in Windows cmd.exe)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: remove bun npm package from all workspaces

The bun npm package tries to install platform-specific binaries which
fails on Windows CI. Since bun is installed via oven-sh/setup-bun action
in CI (and developers install it globally), we don't need the npm package.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: skip examples:build on Windows (uses Unix-only INPUT=... syntax)

The examples use `INPUT=mcp-app.html vite build` which is bash syntax
for setting environment variables. This doesn't work on Windows cmd.exe.
Since examples aren't published to npm, we can skip building them on Windows.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: force LF line endings for cross-platform prettier consistency

Git on Windows auto-converts line endings to CRLF, causing prettier to
report formatting issues. Force LF for all text files.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* ci: add test for git-based npm install (cross-platform)

This verifies that `npm install git+https://...` works on all platforms,
which triggers the prepare script and requires bun to be available.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* ci: add Linux ARM64 and Windows ARM64 to CI matrix

- Added ubuntu-24.04-arm (Linux ARM64)
- Added windows-11-arm (Windows ARM64)

Note: WSL is not available on GitHub-hosted runners (requires nested
virtualization which isn't supported).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* ci: disable Windows ARM64 (Bun lacks stable ARM64 binaries)

The oven-sh/setup-bun action fails with 404 when trying to download
Bun for Windows ARM64. Re-enable when Bun adds proper support.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* ci: add Windows WSL build test

Uses Vampire/setup-wsl action to install Ubuntu-24.04 in WSL and run
the full build/test cycle. This tests the Linux-in-Windows scenario
that was reported in issue #142.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* ci: fix WSL build - install unzip for Bun installer

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* ci: add setup-bun to publish.yml workflow

The pkg-pr-new publish workflow was missing bun setup, causing
"bun: not found" errors during npm ci (which triggers prepare script).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* ci: enable Windows ARM64 with x64-baseline Bun (via emulation)

Windows ARM64 can run x64 binaries via emulation. Use bun-download-url
to force x64-baseline build since native ARM64 Bun isn't available yet.

Reference: https://github.com/oven-sh/bun/issues/9824

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* ci: remove macOS x64 (macos-13 runner retired)

The macos-13 based runner images are now retired.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: add Bun installation instructions per platform

Documents that Bun is required for development, with platform-specific
install commands in collapsible sections.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: note Bun requirement in README examples section

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add bun as optional dependency (no global install required)

- Add @oven/bun-* platform packages as optionalDependencies
- Create postinstall script to set up bun binary from optional deps
- Handle Windows ARM64 by downloading x64-baseline for emulation
- Remove setup-bun from CI workflows (npm install handles it now)
- Remove manual Bun install instructions from docs

This alternative approach eliminates the need for global Bun installation
or setup-bun action in CI. npm install automatically installs the
platform-appropriate bun binary.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: add debug logging to setup-bun script

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: force stdout flush in setup-bun for CI debugging

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: add more debugging to setup-bun

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: remove accidental test artifacts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: run setup-bun in prepare script (before build)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: use cross-env for Windows-compatible example builds

- Add cross-env to devDependencies
- Update all example package.json scripts to use cross-env for INPUT and NODE_ENV
- Enable examples:build on Windows in CI (no longer Unix-only)
- Add examples:build to WSL CI job

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: remove unused imports in setup-bun.mjs

Address github-code-quality bot comments.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: use run-bun.mjs wrapper for prepare hook compatibility

During npm install's prepare hook, node_modules/.bin is not in PATH,
so calling 'bun' directly fails. The new run-bun.mjs wrapper finds
bun at node_modules/.bin/bun and runs it with the correct path.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* ci: restore setup-bun action for build jobs

- Add setup-bun action to build and test-git-install jobs
- Disable Windows ARM64 (Bun doesn't support this platform)
- Add bun installation to WSL build

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: remove bun devDep, add libc detection for Linux ARM64

- Remove 'bun' from devDependencies (its postinstall fails on Windows ARM64)
- Add libc detection (glibc vs musl) to setup-bun.mjs
- Only try compatible binaries based on detected libc
- Re-enable Windows ARM64 in CI (now uses x64 emulation fallback)
- Remove setup-bun action from CI (no longer needed)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* ci: simplify WSL build - let setup-bun.mjs handle bun installation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-16 14:07:38 +00:00
Olivier Chafik
6f14cf301d
fix: ensure E2E screenshot tests work consistently across CI and local (#150)
- Remove platform-specific browser channel (was using Chrome on macOS,
  Chromium in CI) - now uses default Chromium everywhere
- Add Docker-based test scripts for CI-identical local testing:
  - `npm run test:e2e:docker` - run tests in Docker
  - `npm run test:e2e:docker:update` - regenerate golden screenshots
- Regenerate golden screenshots using Docker/Linux environment

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 15:12:36 +00:00
Olivier Chafik
54344552b7
api: optional Client in AppBridge (allow custom forwarding), better protocol types (AppRequest, AppNotification, AppResult) (#146)
* Add setter-based handlers for MCP request/notification forwarding

- Add oncalltool, onlistresources, onlistresourcetemplates, onreadresource, onlistprompts setters for Guest UI → Host requests
- Add sendToolListChanged, sendResourceListChanged, sendPromptListChanged methods for Host → Guest UI notifications
- Refactor connect() to use new setters with inlined callbacks
- Update documentation to clarify optional client parameter behavior
- Remove unused forwardRequest/forwardNotification helper methods
- Add comprehensive tests for AppBridge without MCP client (manual handlers)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Potential fix for pull request finding 'Unused variable, import, function or class'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>

* fix: move prettier to dependencies for git-based installs

* fix: add explicit prettierrc to prevent inheriting parent configs during git-based installs

* Apply suggestions from code review

Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>

* refactor(tests): factor out test values and add missing assertions

Address PR review feedback:
- Factor out test value objects (toolCall, resultContent, etc.) for clearer tests
- Add missing assertions on receivedRequests[0] for list handlers
- Improve test readability by defining expected values at the top of each test

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: improve TypeDoc formatting and use `as const` for notification methods

- Use proper TypeDoc syntax with `@param callback.params` and `@param callback.extra`
- Add {@link ResultType} references for return types
- Replace `as Notification` with `as const` on method literals where possible
  (sendResourceListChanged, sendPromptListChanged)
- Simplify sendHostContextChange cast syntax

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(types): use explicit type unions for AppBridge protocol types

- Add AppBridgeRequest, AppBridgeNotification, AppBridgeResult type unions
  that explicitly list all valid types for the protocol
- Replace generic SDK Request/Notification/Result with our specific types
- Remove all type casts by using `as const` on method literals
- Add index signature to McpUiHostContext for forward compatibility

This improves type safety and documents exactly what the AppBridge supports.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: move AppRequest/AppNotification/AppResult to types.ts

Move protocol type unions from app-bridge.ts to types.ts where they
belong with other type definitions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: regenerate schemas with clean npm install

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
2025-12-13 21:07:13 +00:00
Olivier Chafik
c9e37204de
tests: add Playwright E2E tests with screenshot golden testing (+ fix examples session handling) (#115)
* Add Playwright E2E tests with screenshot golden testing

- Add E2E tests for all 8 MCP server examples
- Screenshot golden images for visual regression testing
- CI workflow for running E2E tests
- npm scripts: test:e2e, test:e2e:update, test:e2e:ui

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add default demo code for Three.js example

When no code is provided, show a rotating green cube demo.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add E2E testing documentation to CONTRIBUTING.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Update Three.js golden screenshot with 3D cube

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add explicit permissions to CI workflow

Set minimal read-only permissions for security best practices.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix test.setTimeout() to be inside describe blocks

Playwright requires setTimeout to be called within a test or describe block.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Simplify E2E tests - remove excessive timeouts

- Remove explicit setTimeout calls (default 30s is sufficient)
- Replace waitForTimeout(5000/6000) with proper waitForAppLoad()
- Wait for inner iframe visibility instead of fixed delays
- Keep only 500ms stabilization for screenshot animations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Auto-generate missing snapshots in CI

Use updateSnapshots: 'missing' in CI to handle cross-platform
screenshot differences (macOS vs Linux).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Use platform-agnostic golden screenshots

- Remove -chromium-darwin suffix from snapshot filenames
- Configure snapshotPathTemplate for cross-platform compatibility
- Increase tolerance to 5% for rendering differences between platforms

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Refactor tests to use forEach instead of for-of loop

May help with Playwright test discovery issues in CI.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Use npm ci and list reporter in CI

- Use npm ci for exact package versions
- Use --reporter=list instead of html to avoid potential re-evaluation issues
- Only upload test-results on failure

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Exclude e2e tests from bun test

Run bun test only on src/ directory to avoid running Playwright tests
with Bun's test runner.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix prettier formatting

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add interaction tests for basic server apps

Test that clicking buttons in the MCP App triggers the corresponding
host callbacks:
- Send Message → host logs "Message from MCP App"
- Send Log → host logs "Log message from MCP App"
- Open Link → host logs "Open link request"

Tests both React and Vanilla JS implementations.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Mask dynamic content in E2E screenshot tests

Add Playwright mask option to handle servers with dynamic/random content:
- basic-react/vanillajs: mask server time display
- system-monitor: mask CPU chart, memory stats, uptime
- cohort-heatmap: mask heatmap grid (random data)
- customer-segmentation: mask scatter chart (random data)

This addresses PR feedback about handling examples with non-deterministic
output. Masking replaces the previous 10% tolerance with proper exclusion
of dynamic elements, allowing tighter 1% tolerance for the rest of the UI.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add wiki-explorer to E2E tests with default URL param

- Add default URL "https://en.wikipedia.org/wiki/Model_Context_Protocol" to
  wiki-explorer-server's get-first-degree-links tool inputSchema
- Update basic-host to automatically populate input field with tool defaults
  extracted from inputSchema.properties
- Add wiki-explorer-server to E2E test suite with dynamic masking for the
  force-directed graph

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Use .default() for threejs tool schema instead of .optional()

This exposes the default code and height values in the JSON Schema,
allowing basic-host to auto-populate the input field with defaults.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Enable parallel E2E tests with timeouts and canvas masking

- Enable fullyParallel with 4 workers locally (2 in CI)
- Add 30s timeout per test
- Mask threejs canvas for stable screenshots
- Update snapshots to reflect default values in input fields

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add pre-commit check for private registry URLs in package-lock.json

Same check as in CI to catch issues before push.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Increase screenshot diff tolerance to 6% for cross-platform rendering

Font rendering differs between macOS and Linux, causing ~5% pixel differences.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Revert pre-commit artifactory check (moved to separate PR #133)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Format threejs server.ts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Update CONTRIBUTING.md to reflect platform-agnostic screenshots

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(e2e): use factory pattern for MCP servers to support parallel connections

McpServer only supports one transport at a time. When multiple browser
contexts connected in parallel, calling server.connect(transport) for
each session overwrote the previous transport's callbacks, causing
connection corruption and test timeouts.

Changes:
- server-utils.ts: accept factory function instead of single instance
- All 9 example servers: wrap server creation in createServer() function
- playwright.config.ts: re-enable parallel execution (4 workers)
- servers.spec.ts: add toBeEnabled wait for server connection
- Update screenshot baselines for basic-vanillajs and cohort-heatmap

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-13 20:57:27 +00:00
Frédéric Barthelet
e99517d75c Implement BYO zod v3 or v4
Following recommendations from https://zod.dev/library-authors
2025-12-12 11:29:02 +01:00
Olivier Chafik
0408a6e9c7
release: 0.1.1 (prettier fix to unlock release) (#138)
* fix: prettify generated files on the fly

- Add prettier --write to generate:schemas script to format generated
  files immediately after generation
- Remove redundant prettier:fix from CI schema verification step
  (now that generation includes formatting)

This fixes the release CI failure where generated files weren't
formatted. Previously, PR CI masked this by running prettier:fix
before the final prettier check, while release CI ran the check
directly on freshly-generated (unformatted) files.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* format

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-12 00:44:04 +01:00
Olivier Chafik
736da14e38
release: 0.1.0 (#137) 2025-12-11 23:21:20 +01:00
Olivier Chafik
24722394a5
chore: update @modelcontextprotocol/sdk to 1.24.3 (#117)
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-10 03:22:26 +01:00
Olivier Chafik
f06340b6d9
build: auto-generate Zod schemas from TypeScript types using ts-to-zod (#116)
* feat: add ts-to-zod schema generation from spec.types.ts

Add automated Zod schema generation using ts-to-zod:
- New npm script `generate:schemas` to regenerate schemas from spec.types.ts
- Post-processing script for Zod v4 compatibility and MCP SDK type imports
- src/spec.types.ts: Pure TypeScript interface definitions (source of truth)
- src/schemas.generated.ts: Auto-generated Zod schemas
- src/schemas.ts: Re-exports with PascalCase naming for backwards compatibility

The generated schemas provide a simpler alternative to the hand-written schemas
in types.ts, useful for lighter validation or reference implementations.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: types.ts now re-exports from spec.types.ts and schemas.generated.ts

- types.ts imports and re-exports types from spec.types.ts (source of truth)
- types.ts imports and re-exports schemas from schemas.generated.ts
- Added compile-time VerifySchemaMatches checks to flag mismatches between
  interfaces and generated schemas
- Removed redundant schemas.ts (types.ts now handles all re-exports)
- Applied prettier formatting to schemas.generated.ts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: use ts-to-zod as library with integration tests

Replace CLI-based schema generation with library API:

- scripts/generate-schemas.ts: New script using ts-to-zod library API
  - Detailed documentation of why each post-processing step is needed
  - Generates integration tests via getIntegrationTestFile()
  - Better error reporting and control

- src/schemas.generated.test.ts: Auto-generated integration tests
  - Compile-time verification that schemas match TypeScript types
  - Uses expectType<> pattern for bidirectional type checking

- Removed scripts/postprocess-schemas.ts (merged into generate-schemas.ts)

- Fixed McpUiResourceTeardownResult to include index signature for MCP SDK
  Protocol compatibility (detected by the new integration tests)

Post-processing rationale (documented in generate-schemas.ts):
1. zod → zod/v4: Explicit v4 subpath for version clarity
2. z.any() → MCP SDK schemas: External types need real validation
3. z.record().and() → z.looseObject(): Index signatures need Zod v4 idiom

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: regenerate schemas during build + CI check

- build script now runs generate:schemas before bun build
- CI workflow verifies generated schemas are up-to-date
  (fails if spec.types.ts changed but schemas weren't regenerated)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: generate PascalCase schemas, move verification to tests

- Add getSchemaName option to generate PascalCase schema names directly
  (McpUiOpenLinkRequestSchema instead of mcpUiOpenLinkRequestSchema)
- Remove redundant compile-time verification from types.ts
  (already handled by generated test file's bidirectional expectType checks)
- Simplify types.ts from 235 to 57 lines (just re-exports)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: add missing csp field, simplify schema generation

- Add missing csp field to McpUiSandboxResourceReadyNotification (regression from merge)
- Simplify generate-schemas.ts - remove complex .describe() conversion
- Document that ts-to-zod supports @description JSDoc tags for .describe()
- Improve z.looseObject() replacement with brace-counting for nested objects

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add @description JSDoc tags for .describe() on schemas

Added @description tags to all interfaces and fields in spec.types.ts.
ts-to-zod now generates .describe() calls on all schema fields, making
descriptions available at runtime for introspection and JSON Schema generation.

Example:
  /** @description URL to open in the host's browser */
  url: string;

Generates:
  url: z.string().describe("URL to open in the host's browser")

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: generate JSON Schema from Zod schemas

Added JSON Schema generation to the schema generation pipeline:
- Uses Zod v4's built-in toJSONSchema() to convert schemas
- Generates src/schema.json with all message types in $defs
- Includes descriptions from @description JSDoc tags
- Added export "./schema.json" to package.json
- Updated CI to verify schema.json is up-to-date

Use cases:
- Language-agnostic validation (Python, Go, Rust)
- Documentation generation (Redoc, Swagger UI)
- Code generation (quicktype)
- IDE autocomplete for JSON/YAML

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: rename schema.json to schema.generated.json

Renamed to match other generated files naming convention.
Export path unchanged: ./schema.json -> ./dist/src/schema.generated.json

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: rename schemas.generated.* to schema.generated.* (singular)

Consistent singular naming for all generated files:
- schema.generated.ts
- schema.generated.test.ts
- schema.generated.json

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: rename schemas.generated.* to schema.generated.* (singular)

Consistent singular naming for all generated files:
- schema.generated.ts
- schema.generated.test.ts
- schema.generated.json

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: move generated files to src/generated/ with simpler names

Moved:
- src/schema.generated.ts → src/generated/schema.ts
- src/schema.generated.test.ts → src/generated/schema.test.ts
- src/schema.generated.json → src/generated/schema.json

Benefits:
- Cleaner organization (generated files isolated)
- Simpler names without .generated suffix
- Easier to gitignore if desired later

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: add missing type exports for backwards compatibility

Added missing exports that existed in main:
- McpUiTheme, McpUiThemeSchema
- McpUiDisplayMode, McpUiDisplayModeSchema
- McpUiResourceCsp, McpUiResourceCspSchema
- McpUiResourceMeta, McpUiResourceMetaSchema

Also fixed theme/displayMode to match original values:
- theme: 'light' | 'dark' (removed 'system')
- displayMode: 'inline' | 'fullscreen' | 'pip' (removed 'carousel')

Verified: all 47 exports from main are preserved with compatible types.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: stage generated files after prettier in pre-commit hook

The pre-commit hook runs build (which generates schemas) then prettier
(which formats them). The formatted generated files weren't being staged,
causing CI to fail with 'Generated schemas are out of date'.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* update generated files

* fix: run prettier after regenerating schemas in CI verification

CI was comparing unformatted generated output against formatted committed
files, causing false 'out of date' failures.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-10 01:05:49 +01:00
Olivier Chafik
03cf620f77
release: 0.0.7 (#114) 2025-12-09 20:44:16 +01:00
Olivier Chafik
9d21d8bc08
release: 0.0.6 (#112)
* release: fix NPM_SECRET reference

* release: 0.0.5

* Add repository field to package.json

Required for npm provenance verification to link the package
to the GitHub repository.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* release: 0.0.6

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-09 20:17:22 +01:00
Olivier Chafik
6b9bedaa5b
release: 0.0.5 (fix release config again) (#110)
* release: fix NPM_SECRET reference

* release: 0.0.5
2025-12-09 20:07:26 +01:00
Olivier Chafik
c03e99df59
release: v0.0.4 (try using node token again) (#102)
* release: reinstate NODE_AUTH_TOKEN

* v0.0.4
2025-12-09 01:29:06 +01:00
Olivier Chafik
5c9665325d
release: 0.0.3, switched to npm trusted publishing (#101)
* version: 0.0.2

* Switch to npm trusted publishing (OIDC)

- Remove NPM_TOKEN secret requirement from npm-publish workflow
- Uses OIDC for authentication (more secure, no long-lived tokens)
- Update CONTRIBUTING.md with trusted publisher setup instructions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* 0.0.3

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-09 00:52:52 +01:00
Anton Pidkuiko
4736621512
Merge pull request #97 from jonathanhefner/running-all-examples
Add `examples/run-all.ts` script
2025-12-08 23:37:44 +00:00
Olivier Chafik
94d45a1f60
version: 0.0.2 (#98) 2025-12-08 23:40:31 +01:00
Jonathan Hefner
8bff1dff68 Add dynamic example orchestration script
Replace hardcoded port assignments and npm scripts with run-all.ts that:
- Auto-discovers example directories and assigns ports
- Passes server URLs to basic-host via SERVERS env var
- Supports start, dev, and build commands

Update basic-host to fetch server list from /api/servers endpoint
and display server names from MCP server metadata.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 16:34:52 -06:00
Anton Pidkuiko
2b53efda5a
Merge pull request #94 from modelcontextprotocol/add-threejs-server
Add Three.js example server
2025-12-08 21:40:33 +00:00
Olivier Chafik
2d842a31fa
Add npm publish workflow (#89)
* Add npm publish workflow

- Add .github/workflows/npm-publish.yml triggered on GitHub releases
  - Runs build and test jobs before publishing
  - Uses NPM_TOKEN secret with OIDC provenance
  - Smart npm tagging: latest, beta, or release-X.Y
- Add prepack hook to package.json for automatic builds
- Move bun from dependencies to devDependencies
- Add npm test step to CI workflow

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add CONTRIBUTING.md with maintainer publishing guide

- Getting started and development process for contributors
- Pull request guidelines
- Maintainer section with:
  - Repository setup (NPM_TOKEN, release environment)
  - Step-by-step release publishing instructions
  - npm tag documentation (latest, beta, release-X.Y)
  - Maintenance release workflow
  - Pre-release testing via pkg-pr-new

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* ...

* Potential fix for code scanning alert no. 9: Workflow does not contain permissions

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-12-08 22:23:57 +01:00
Anton Pidkuiko MacBook
2755438dba
Add Three.js marketing example server
New example demonstrating interactive 3D scene rendering with:
- show_threejs_scene tool with streaming code preview
- learn_threejs documentation tool
- Full WidgetProps interface for MCP App integration
- Reusable mcp-app-wrapper.tsx pattern

Also adds bun.lockb to .gitignore.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 21:19:42 +00:00
Olivier Chafik
42265d85a3
add license (#96)
* add license

* Update LICENSE
2025-12-08 21:51:19 +01:00
Olivier Chafik
f6ebefe238
Add server selector to basic-host example (#95)
* Add server selector to basic-host example

- Add ServerSelector component to switch between MCP servers
- Run all example servers concurrently on ports 3101-3107
- Update examples:start to launch all servers with assigned ports

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Move server selector into tool call panel

- Server selector now in same component as tool selector
- Tool call results persist across server switches
- Connection caching avoids reconnects when switching servers
- Display server name with tool name in results (ServerName:ToolName)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-08 18:45:50 +01:00
Jonathan Hefner
a9d6ecd20c Make examples:build dynamically discover all examples
Replace hardcoded workspace list with find + xargs to automatically
build all examples in parallel. New examples are picked up without
manual script updates.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 14:33:14 -06:00
Jonathan Hefner
4b5b0c7d79 Add basic-server-vanillajs example
Demonstrates MCP App SDK usage with vanilla JavaScript (no framework),
providing parity with the existing basic-server-react example.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 14:28:27 -06:00