* chore: add stable spec release 2026-01-26
- Use git mv to copy specification from draft to specification/2026-01-26/apps.mdx (preserves history)
- Update status from 'Draft' to 'Stable (2026-01-26)'
- Add specification version table to README
- Update Resources section with links to both stable and draft specs
* chore: bump version to 1.0.0
- Update main package version from 0.4.2 to 1.0.0
- Update all example package versions to 1.0.0
- Regenerate package-lock.json
* prettier
* chore: align protocol version with spec release 2026-01-26
- Add 'Protocol Version: 2026-01-26' to spec header
- Update LATEST_PROTOCOL_VERSION from '2025-11-21' to '2026-01-26'
- Update spec examples to use '2026-01-26' protocol version
- Add '2025-11-21' to SUPPORTED_PROTOCOL_VERSIONS for backwards compatibility
* chore: update spec references to stable 2026-01-26
- Update typedoc.config.mjs navigation link
- Update docs/overview.md spec links (10 occurrences)
- Update plugins/mcp-apps/skills/create-mcp-app/SKILL.md spec link
- Update src/spec.types.ts @see links
- Update AGENTS.md spec path
- Regenerate src/generated/schema.ts with updated links
* chore: simplify versioning - first stable release
- Remove backwards compatibility version (2025-11-21) - this is the first stable release
- Remove redundant 'Protocol Version' header - spec version IS the protocol version
* chore: add history reference comment to stable spec
* docs: add local development MCP client configuration to READMEs
Add instructions for configuring MCP clients to use locally-cloned
and modified servers. This allows developers to test local changes
with MCP clients like Claude Desktop or VS Code.
- Top-level README: Added 'Local Development' section after npx config
- All TypeScript examples: Added 'Local Development' subsection with
bash one-liner that builds and runs the server
- Python examples (qr-server, say-server): Added local path config
* docs: include all servers in local development config
* docs: use bash wrapper for Python server configs to enable tilde expansion
Add stdio transport configuration snippets near the top of each example
README to help users quickly set up the servers in their MCP clients.
- Node.js examples use npx with the published npm packages
- Python qr-server uses uv with local path
- Removed Claude Desktop-specific references from qr-server
* 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 \ 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
* feat: Add CesiumJS map server example
A WebGL-based 3D globe example that demonstrates:
- CesiumJS integration with MCP Apps
- CSP configuration for external tile servers
- worker-src directive usage for tile decoding
Tools:
- geocode: Search places via OpenStreetMap Nominatim
- show-map: Display interactive 3D globe at coordinates
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* comment out app.registerTool call for now
* prettier
* fix error handling in server-utils.ts
* refactor: rename cesium-map-server to map-server
- Rename examples/cesium-map-server to examples/map-server
- Update package name to @modelcontextprotocol/server-map
- Add README.md with documentation
* style: add min-height of 400px to map container
* feat(map-server): add fullscreen support, clean UI, sharp rendering
- Add fullscreen toggle button (only shown if host supports it)
- Use autoResize: false and manually send height of 400px
- Hide Cesium UI controls (home, scene mode picker)
- Remove location label (gets stale quickly)
- Use full device pixel ratio for sharp rendering on high-DPI displays
- Resize Cesium viewer when display mode changes
* feat(map-server): add reverse geocoding (logging only) and rounded corners
- Add camera move end listener for reverse geocoding
- Debounce Nominatim API calls (1.5s) to respect rate limits
- Log location name to console on camera move
- Add nominatim.openstreetmap.org to CSP connectDomains
- Add 8px rounded corners to map container
* fix(map-server): fix pixelated rendering on high-DPI displays
- Set canvas imageRendering to 'auto' (CesiumJS defaults to pixelated)
- Set resolutionScale to window.devicePixelRatio for native resolution
* tweaks
* update model context w/ current location
* fix(map-server): improve rendering quality and add visible extent logging
Rendering fixes:
- Remove incorrect resolutionScale = devicePixelRatio which was doubling
the scaling factor on Retina displays (2x2=4x), causing blurriness
- Disable FXAA anti-aliasing which can cause blurriness on high-DPI displays
- Keep useBrowserRecommendedResolution: false to use native devicePixelRatio
Reverse geocoding improvements:
- Add getVisibleExtent() using camera.computeViewRectangle() to get the
visible bounding box (west, south, east, north)
- Add getScaleDimensions() to calculate visible area in km
- Add calculateNominatimZoom() to map visible extent to appropriate
Nominatim zoom level (3=country to 18=building)
- Log visible extent with dimensions on each camera move
- Pass zoom parameter to Nominatim for context-aware geocoding results
- Update model context with visible area dimensions
* fix(map-server): direct positioning + wait for tiles before showing
Changes:
- Remove zoom granularity logic from reverse geocoding (was not working)
- Keep extent logging in both console and model context
- Replace flyTo animation with instant setView positioning
- Add waitForTilesLoaded() to detect when tiles finish loading
- Keep loading spinner visible until:
1. Tool input positions camera to destination
2. Tiles at destination are fully loaded
- Add 5-second fallback timeout if no tool input received
- Add 10-second timeout for tile loading to prevent infinite wait
* feat(map-server): use viewbox search to find visible places
Replace center-point reverse geocoding with Nominatim viewbox search:
- Add searchPlacesInBox() that queries Nominatim with bounded viewbox
- Uses layer=address&featuretype=settlement to find cities/towns
- Returns up to 5 visible places in the current view
- Update model context with 'Visible places: City1, City2, ...'
- Still includes center coordinates and extent dimensions
This provides better context about what's actually visible on the map
rather than just the address at the center point.
* fix(map-server): use CARTO @2x retina tiles for sharp rendering
Root cause: Standard OSM tiles are 256x256 pixels. On Retina displays
(devicePixelRatio=2), these get scaled up 2x, making them look pixelated.
Solution: Switch to CARTO Voyager tiles which provide @2x retina support:
- Detect high-DPI displays using window.devicePixelRatio
- Use 512x512 tiles with @2x suffix on Retina displays
- Use 256x256 tiles on standard displays
- Set tileWidth/tileHeight to match actual tile size
- Use CARTO subdomains (a,b,c,d) for load balancing
- Update CSP to allow CARTO tile domains
CARTO Voyager provides clean OSM-based tiles with free @2x retina support,
no API key required.
* fix(map-server): use OSM tiles and fix reverse geocoding
- Switch back from CARTO to standard OSM tiles (tile.openstreetmap.org)
for better detail and label rendering
- Fix geocoding: use reverse geocode API instead of search API
(search API requires a q= parameter, returns 400 without it)
- Update CSP domains for OSM tile server
* fix(map-server): use *.openstreetmap.org wildcard in CSP
Simplify CSP to use wildcard for both tiles and geocoding:
- connectDomains: *.openstreetmap.org covers tile.* and nominatim.*
- resourceDomains: *.openstreetmap.org for tile images
* feat(map-server): multi-point sampling for visible places
- Sample multiple points in visible extent to discover places
- Adaptive sampling based on extent size:
- < 30km: center only (city zoom)
- 30-100km: center + 2 corners
- > 100km: center + 4 quadrants
- Proper rate limiting for Nominatim (1.1s between requests)
- Shows 'Visible places: City1, City2, ...' in model context
- Fix: move geocode tool registration inside createServer()
* format
* fix(map-server): fix Express listen callback + add e2e tests
- Fix incorrect Express listen() callback signature (err param doesn't exist)
- Add map-server to e2e test suite with SLOW_SERVERS timeout (5s for tiles)
- Improve comment about experimental ui/update-model-context API
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>