MCP Apps Testing Server
Provides 3D globe rendering using CesiumJS with OpenStreetMap tiles for geographic visualization.
Uses OpenStreetMap Nominatim for geocoding and OSM tiles for map display in the Weather Dashboard and Globe Viewer.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP Apps Testing Servershow weather dashboard"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP Apps Testing Server
Comprehensive MCP Apps capability testing suite featuring a Weather Dashboard and 3D Globe viewer. This project systematically tests and demonstrates all Model Context Protocol (MCP) Apps features.
Table of Contents
Related MCP server: MCP Server Basic Example
π― Project Purpose
This server demonstrates and tests the full spectrum of MCP Apps capabilities through interactive UI applications that communicate bidirectionally with MCP servers and host applications.
π Recent Updates
Progressive Weather Streaming Analysis (Latest)
β¨ New Tool:
uzir-weather-stream- Progressive 5-phase weather analysisπ Real-time Updates: Data streams in at 1-second intervals
π¨ Beautiful UI: Full-screen modal with progress bar and animated phase arrivals
π 5 Analysis Phases: Conditions β Patterns β Historical β Forecast β Recommendations
π App-Only: Tool is hidden from model, only callable by the app
π± Compact Design: Optimized viewport (790px base, 20% smaller on mobile)
β Persistence: Favorites and search history with localStorage
π Documentation: New CUSTOM-API-GUIDE.md with implementation details
Try it: Load weather for any city, click "π Stream Analysis" button!
π¦ What's Included
1. Weather Dashboard (Primary Test App)
Interactive weather application with comprehensive MCP Apps API testing.
2. 3D Globe Viewer
CesiumJS-based globe with OpenStreetMap tiles for geographic visualization.
β MCP Apps Features - Testing Progress
Fully Implemented & Tested β
Feature | API | Implementation | Status |
Tool Calling from UI |
| Search box + Quick city buttons | β Complete |
Chat Integration |
| "Tell Claude" button | β Complete |
External Links |
| "Open Weather.com" button | β Complete |
Structured Logging |
| Activity log panel (3 levels) | β Complete |
Size Hints |
| Dynamic viewport height | β Complete |
Tool Results |
| Initial weather data handler | β Complete |
Tool Input |
| Parameter handling | β Complete |
Error Handling |
| App-level error handler | β Complete |
Teardown |
| Cleanup handler | β Complete |
UI Resources |
| 2 UI resources (weather + map) | β Complete |
CSP Configuration |
| External domain whitelisting | β Complete |
Tool Metadata |
| Weather data + viewUUID | β Complete |
Display Modes |
| Fullscreen/inline with toggle button | β Complete |
Host Context |
| Display mode and theme detection | β Complete |
Keyboard Shortcuts | Event handlers | Esc (exit fullscreen), Ctrl+Enter (toggle) | β Complete |
Theme Detection |
| Light/dark theme adaptation | β Complete |
State Persistence | localStorage | Favorites, history, bookmarks with notes | β Complete |
Progressive Streaming | Custom tool | 5-phase streaming analysis | β Complete |
Model Context Updates |
| Weather summary sent to Claude | β Complete |
Bookmarks with Notes | localStorage + UI | Save locations with custom notes | β Complete |
Tool List Changes |
| Animated toast notifications for tool updates | β Complete |
Partially Implemented π§
Feature | Status | Notes |
PiP Display Mode | π‘ Partial | CSS ready, awaiting host support |
Not Yet Implemented β
Feature | Priority | Effort | Notes |
Real-time Updates | Medium | Medium | Auto-refresh, live weather data |
Comparison Mode | Low | High | Multiple locations side-by-side |
Advanced Forms | Low | Medium | Multi-step forms, validation |
Accessibility | Low | Medium | Full ARIA, screen reader support |
Offline Mode | Low | High | Service worker, caching |
Performance Metrics | Low | Low | Telemetry and monitoring |
π¦οΈ Weather Dashboard Features
The Weather Dashboard is the primary testing application demonstrating core MCP Apps capabilities:
Interactive Features
π Location Search - Search any city or place using
callServerTool()π Quick Cities - One-click weather for 6 popular cities
π¬ Tell Claude - Send weather summaries to chat via
sendMessage()π Open Weather.com - External browser links via
sendOpenLink()π Activity Log - Real-time structured logging with
sendLog()βΆ Fullscreen Mode - Toggle display modes with
requestDisplayMode()π¨ Theme Detection - Responds to light/dark mode changes
β¨οΈ Keyboard Shortcuts - Ctrl+Enter (toggle fullscreen), Escape (exit)
π Progressive Streaming Analysis - Live 5-phase weather analysis with real-time updates
β Favorites & History - Save favorite locations and search history (localStorage)
π§ Model Context Updates - Sends weather data to Claude's context via
updateModelContext()π Bookmarks with Notes - Save locations with custom notes, timestamps, and full edit/delete support
Weather Data
Current conditions with temperature, humidity, wind speed, UV index
7-day forecast with high/low temperatures (collapsible)
Weather condition icons
Geo-coordinates display
Progressive Streaming Analysis π
The weather dashboard includes an advanced streaming tool that demonstrates progressive data delivery:
5 Streaming Phases - Data arrives in real-time over 5 seconds
Current Conditions (1s) - Live temperature, humidity, wind, pressure
Pattern Analysis (2s) - Temperature trends, precipitation risk
Historical Comparison (3s) - Deviations from averages, unusual factors
Forecast Predictions (4s) - Short-term and medium-term forecasts
Recommendations (5s) - Clothing and activity suggestions
Beautiful Streaming UI
Full-screen modal with animated phase arrivals
Progress bar showing completion status
Real-time timestamps for each phase
Color-coded sections with green gradient headers
Responsive grid layouts for data display
App-Only Tool -
uzir-weather-streamis hidden from the model and only callable by the appSimulated Real-Time Updates - Demonstrates "multiple values over time" pattern
How to test: Load any weather location, click "π Stream Analysis" button, watch phases arrive progressively!
Technical Details
Uses Open-Meteo API (no API key required)
OpenStreetMap Nominatim for geocoding
Compact viewport height (790px base, expands dynamically)
Mobile-optimized design (20% smaller on β€600px screens)
Responsive design with media queries
Theme adaptation (light/dark backgrounds)
Error handling and recovery
localStorage persistence for favorites and search history
πΊοΈ Globe Viewer Features
Interactive 3D globe with geographic visualization:
3D Globe Rendering - CesiumJS with OpenStreetMap tiles
Geocoding Integration - Search and locate places
Camera Persistence - Saves view state in localStorage
Display Modes - Fullscreen and inline support
Model Context Updates - Sends screenshots to Claude
Shuffle Cities - Random city exploration
Keyboard Shortcuts - Esc, Ctrl+Enter for fullscreen control
π Getting Started
Installation
npm installBuild
npm run buildDevelopment
npm run devRuns both Vite watcher and HTTP server concurrently with hot reload.
Production
npm run start # or npm run start:httpServer runs at http://localhost:3001/mcp
For stdio transport:
npm run start:stdioπ§ͺ Conformance Tests
The project includes 5 conformance test apps that run as a separate MCP server, testing core MCP Apps spec compliance:
Test App | Tool | What It Tests |
Lifecycle |
| MCP Apps Β§3 β init, teardown, tool input/result |
Host Context |
| MCP Apps Β§4 β theme, display mode, context changes |
Messaging |
| MCP Apps Β§5 β sendMessage, sendLog, sendOpenLink |
Domain & CORS |
| MCP Apps Β§2.4 β domain declaration, CORS preflight |
Theming |
| MCP Apps Β§4.5 β CSS variables, theme adaptation |
Additional server-only tools: echo-tool, slow-task, slow-echo, test-resources-notification, test-tools-notification.
Running with Docker
# Build and start the conformance server on port 3002
docker compose up -d --build
# Verify it's running
curl http://localhost:3002/health
# β {"status":"ok"}
# View logs
docker compose logs -f
# Stop
docker compose downRunning without Docker
npm run build
npm run start:conformanceClaude Desktop Configuration (WSL2)
Add both servers to claude_desktop_config.json (%APPDATA%\Claude\claude_desktop_config.json on Windows):
{
"mcpServers": {
"mcp-map-server": {
"command": "wsl",
"args": ["/home/<user>/.nvm/versions/node/<version>/bin/node", "/path/to/mcp-map-server-ui/dist/index.js", "--stdio"]
},
"mcp-conformance-tests": {
"command": "wsl",
"args": ["/home/<user>/.nvm/versions/node/<version>/bin/node", "/path/to/mcp-map-server-ui/dist/conformance-index.js", "--stdio"]
}
}
}Note: Use the full path to
node(e.g. fromwhich node) since WSL launched by Claude Desktop doesn't load your shell profile.
Test Prompts
"Show lifecycle tests"
"Show host context tests"
"Show messaging tests"
"Show domain cors tests"
"Show theming tests"
π§ͺ Testing
Option 1: Basic-Host Test Interface
The ext-apps basic-host provides a simple test UI:
# Clone ext-apps repo
git clone https://github.com/modelcontextprotocol/ext-apps
cd ext-apps/examples/basic-host
# Install and start
npm install
SERVERS='["http://localhost:3001/mcp"]' npm startOpen http://localhost:8080 and test the tools.
Option 2: Claude (Web or Desktop) - Recommended for Model Context Testing
Use custom connectors to connect Claude to your deployed server.
For local testing with Claude Desktop:
// Add to claude_desktop_config.json
{
"mcpServers": {
"weather-map": {
"command": "node",
"args": ["/path/to/mcp-map-server-ui/dist/index.js", "--stdio"]
}
}
}For Claude Web with local server:
npx cloudflared tunnel --url http://localhost:3001Add the generated URL as a custom connector in Claude settings.
For Claude Web with Azure deployment:
Add custom connector with URL:
https://mcp-apps-020426.azurewebsites.net/mcp
Testing Model Context Updates:
Say: "Show me the weather in Tokyo"
Then ask: "What's the current temperature?" or "Should I bring an umbrella?"
Claude should answer using the model context! β¨
See TESTING_GUIDE.md for detailed testing instructions.
Option 3: VS Code (Insiders)
VS Code Insiders supports MCP Apps. Configure your server in VS Code settings.
π¬ How to See Each MCP Apps Function Being Tested
This section provides specific prompts and observable behaviors for testing each MCP Apps API.
1. ontoolresult - Initial Tool Result Handler
How It's Tested: Receives weather data when tool is first called
Prompt:
Show me the weather in SeattleWhat to Observe:
β Weather dashboard loads immediately
β Current temperature, conditions, and 7-day forecast display
β Activity log shows: "Initial weather data rendered for Seattle"
β No errors in console
Behind the Scenes:
The ontoolresult handler receives the show-weather tool result containing weather data in _meta.weatherData, then renders the UI.
2. callServerTool() - Search Box
How It's Tested: Search input calls show-weather tool from the UI
Prompt:
First get the weather dashboard loaded (use prompt above)
In the search box, type:
TokyoClick "π Search" or press Enter
What to Observe:
β Search button shows loading spinner
β Weather updates to Tokyo
β Activity log shows:
Searching for location: Tokyo Weather tool result received Weather rendered for Tokyoβ Search button re-enables after completion
Behind the Scenes:
The UI calls app.callServerTool({ name: "show-weather", arguments: { location: "Tokyo" }}) which makes a round-trip to the MCP server.
3. callServerTool() - Quick City Buttons
How It's Tested: City chips call show-weather tool with preset locations
Prompt:
Load weather dashboard
Click any city chip (e.g., "Paris", "London", "Dubai")
What to Observe:
β Weather immediately updates to selected city
β Activity log shows: "Searching for location: [City]"
β All UI elements update (temp, forecast, location header)
β Button remains clickable (no loading state needed for presets)
Behind the Scenes:
Each city chip triggers callServerTool() with a known city name, testing batch tool calls.
4. sendMessage() - Tell Claude Button
How It's Tested: Sends weather summary to chat
Prompt:
Load weather dashboard for any location
Click "π¬ Tell Claude" button
What to Observe:
β A new message appears in the chat from you (the user):
The weather in Tokyo is currently 12Β°C and partly cloudy. It feels like 10Β°C with 65% humidity.β Activity log shows:
Sending message to chat [message content] Message sent to chat successfullyβ Claude can now respond to this weather information
Behind the Scenes:
The UI calls app.sendMessage({ content: [{ type: "text", text: message }], role: "user" }) which posts a message to the chat as if you typed it.
5. sendOpenLink() - Open Weather.com Button
How It's Tested: Opens external URL in browser
Prompt:
Load weather dashboard for any location
Click "π View on Weather.com" button
What to Observe:
β Browser opens a new tab/window with Weather.com
β URL includes coordinates:
https://weather.com/weather/today/l/[lat],[lon]β Weather.com shows the same location
β Activity log shows:
Opening Weather.com for Tokyo https://weather.com/weather/today/l/35.68,139.69 Link opened successfully
Behind the Scenes:
The UI calls app.sendOpenLink({ url: "https://weather.com/..." }) which requests the host to open the URL.
6. sendLog() - Activity Log Panel
How It's Tested: All app activities are logged with different levels
Prompt:
Load weather dashboard
Perform various actions (search, click cities, tell Claude, etc.)
Click "π Activity Log" header to expand
What to Observe:
β Log panel shows all activities with timestamps
β Color-coded entries:
Blue (info): Normal operations (searches, renders)
Yellow (warning): Warnings (no data, edge cases)
Red (error): Errors (failed API calls, exceptions)
β Auto-scrolls to latest entry
β Log count updates: "(12)" shows number of log entries
β Can collapse/expand with βΌ/βΆ arrow
Behind the Scenes:
Every significant action calls app.sendLog({ level: "info"|"warning"|"error", data: message, logger: "weather-app" }) which sends structured logs to the host.
7. sendSizeChanged() - Viewport Height Hint
How It's Tested: App requests preferred height on load
Prompt:
Show me the weather in any cityWhat to Observe:
β Weather dashboard renders at 1200px height
β No scrolling needed inside the viewport
β All content (search, forecast, log) is visible without scrolling
β Activity log shows: "Sent initial size 1200"
Behind the Scenes:
On initialization, the app calls app.sendSizeChanged({ height: 1200 }) to tell the host its preferred size.
8. ontoolinput - Tool Parameter Handler
How It's Tested: Receives tool parameters before result
Prompt:
Show me the weather in Paris with coordinates 48.8566, 2.3522What to Observe:
β Weather loads for Paris
β Activity log may show tool input received (if logged)
β Parameters are processed correctly
Behind the Scenes:
The ontoolinput handler receives parameters before the tool executes, allowing the UI to prepare or show loading states.
9. onerror - Error Handler
How It's Tested: Handles app-level errors gracefully
Prompt:
Load weather dashboard
Search for invalid/nonsense location:
asdfghjkl12345
What to Observe:
β Error message displays in the UI
β App doesn't crash
β Activity log shows red error entry
β Search box remains functional
β Can search for valid location after error
Behind the Scenes:
The onerror handler catches unhandled errors and logs them via sendLog() instead of crashing.
10. onteardown - Cleanup Handler
How It's Tested: Called when app is being destroyed
Prompt:
Load weather dashboard
Navigate away or close the chat
What to Observe:
β Activity log shows: "App is being torn down" (before navigation)
β No memory leaks or errors
β Clean shutdown
Behind the Scenes:
The onteardown handler performs cleanup (clear timers, close connections) before the app is removed.
11. UI Resources - Weather Dashboard HTML
How It's Tested: Server serves bundled HTML via registerAppResource()
Prompt:
Show me the weather in BerlinWhat to Observe:
β Complete weather UI loads (not raw HTML)
β All styles and scripts are embedded
β Interactive elements work (buttons, inputs)
β Single HTML file (no external JS/CSS)
Behind the Scenes:
The server's registerAppResource() serves the bundled weather-app.html which includes all CSS/JS inline (via vite-plugin-singlefile).
12. Tool Metadata - Weather Data in _meta
How It's Tested: Server includes weather data in tool result metadata
Prompt:
Show me the weather in SydneyWhat to Observe:
β Weather data loads correctly
β All fields present (temp, humidity, forecast, etc.)
β No "undefined" values in UI
Behind the Scenes:
The server's show-weather tool returns:
{
content: [...],
_meta: {
viewUUID: "...",
weatherData: { location: "Sydney", current: {...}, forecast: [...] }
}
}13. CSP Configuration - External API Access
How It's Tested: App can fetch from Open-Meteo and OSM via CSP whitelist
Prompt:
Show me the weather in MumbaiWhat to Observe:
β Weather data loads (from Open-Meteo API)
β Geocoding works (from OSM Nominatim)
β No CSP errors in browser console
β All images/icons load
Behind the Scenes: The server's resource registration includes:
_meta: {
ui: {
csp: {
connectDomains: ["https://api.open-meteo.com", "https://*.openstreetmap.org"],
resourceDomains: [...]
}
}
}14. requestDisplayMode() - Fullscreen Toggle
How It's Tested: Fullscreen button switches display modes
Prompt:
Load weather dashboard for any location
Click the fullscreen button (βΆ) in the top-right corner
Or press Ctrl+Enter (or Cmd+Enter on Mac)
What to Observe:
β Weather dashboard expands to fullscreen
β Fullscreen button icon changes to compress icon (βΆ β β)
β Button tooltip updates: "Exit fullscreen"
β Activity log shows: "Requesting display mode: fullscreen"
β Press Escape or click button again to exit fullscreen
β Activity log shows: "Requesting display mode: inline"
Behind the Scenes:
The UI calls app.requestDisplayMode({ mode: "fullscreen" }) which asks the host to change the display mode. The host responds via onhostcontextchanged.
15. onhostcontextchanged - Display Mode & Theme
How It's Tested: App responds to host context changes
Prompt:
Load weather dashboard
Change your system theme (light β dark) or display mode
What to Observe:
β Activity log shows: "Host context changed { theme: 'light'|'dark', displayMode: '...' }"
β Background gradient adapts:
Light theme: Purple gradient (#667eea β #764ba2)
Dark theme: Dark blue gradient (#2c3e50 β #34495e)
β Display mode CSS classes applied to body
β UI responds immediately without reload
Behind the Scenes:
The onhostcontextchanged handler receives context updates from the host and applies theme/mode classes to document.body.
16. Keyboard Shortcuts - Display Mode Control
How It's Tested: Keyboard commands for fullscreen
Actions:
Load weather dashboard
Press Ctrl+Enter (or Cmd+Enter on Mac)
Press Escape when in fullscreen
What to Observe:
β Ctrl+Enter: Toggles fullscreen on/off
β Escape: Exits fullscreen (only works when in fullscreen)
β Activity log shows mode change requests
β Fullscreen button state syncs with keyboard actions
β Search input shortcuts still work (Enter to search)
Behind the Scenes:
Global keydown event listener detects shortcuts and calls toggleFullscreen() which uses requestDisplayMode().
17. Tool List Changed Notifications - Dynamic Tool Updates
How It's Tested: Apps receive and display notifications when server tools change
Prompt:
Load weather dashboard or globe viewer
Call the
test-tools-notificationtool (this simulates the server adding/removing tools)
What to Observe:
β Beautiful animated toast notification slides in from top-right
β Purple gradient background with spinning refresh icon (π)
β Message displays: "Tools Updated - New tools are now available"
β Notification auto-dismisses after 5 seconds
β Can manually close with Γ button
β Activity log shows: "Received notifications/tools/list_changed"
β Multiple notifications stack properly if tools change frequently
Behind the Scenes:
Apps register notification handler:
app.setNotificationHandler(ToolListChangedNotificationSchema, handler)When server calls
server.server.notification({ method: "notifications/tools/list_changed" }), all connected apps receive itThe
showToolsChangedNotification()function creates an animated DOM element with the notification UICSS animations provide smooth slide-in from right and fade-out on dismiss
Note: This notification is primarily intended for MCP host applications. In production, the host receives the notification and can either:
Refresh its tool list automatically
Forward the notification to connected apps (as demonstrated here)
Show its own UI notification to the user
See TEST_RESULTS.md for detailed testing documentation with Playwright MCP.
π― Testing Checklist
Use this checklist to verify all MCP Apps features:
Core APIs (Phase 1):
ontoolresult - Weather loads on initial call
callServerTool - Search box updates weather
callServerTool - Quick city buttons work
sendMessage - Tell Claude sends message to chat
sendOpenLink - Weather.com opens in browser
sendLog - Activity log shows all actions
sendSizeChanged - UI is 1200px tall, no scrolling
ontoolinput - Parameters handled correctly
onerror - Invalid searches show errors gracefully
onteardown - Clean shutdown on navigation
UI Resources - Complete dashboard loads
Tool Metadata - All weather data displays
CSP Config - External APIs work without errors
Display & Themes (Phase 2):
requestDisplayMode - Fullscreen button toggles mode
onhostcontextchanged - Theme and display mode changes applied
Keyboard Shortcuts - Ctrl+Enter toggles, Escape exits fullscreen
Theme Detection - Light/dark theme switching works
Fullscreen Button - Icon updates, tooltip changes
Notifications (Phase 4):
Tool List Changed - Toast notification appears when tools update
Animated UI - Notification slides in smoothly with spinning icon
Auto-dismiss - Notification disappears after 5 seconds
Manual Close - Γ button closes notification immediately
All features passing? β MCP Apps APIs fully tested!
π§ Available Tools
show-weather
Display weather dashboard for a location.
Parameters:
location(string, optional) - City or place namelatitude(number, optional) - Latitude coordinatelongitude(number, optional) - Longitude coordinate
Example:
{
"location": "Paris"
}Returns weather dashboard UI with current conditions and 7-day forecast.
uzir-weather-stream (App-Only)
Progressive weather analysis streaming tool with 5 phases of data delivered over time.
Visibility: App-only (hidden from model)
Parameters:
location(string, optional) - City or place namelatitude(number, optional) - Latitude coordinatelongitude(number, optional) - Longitude coordinate
Example:
{
"location": "Tokyo"
}Returns: Streaming analysis with 5 phases:
Current Conditions (temperature, humidity, wind, pressure)
Pattern Analysis (trends, precipitation risk)
Historical Comparison (deviations, unusual factors)
Forecast Predictions (short-term, medium-term)
Recommendations (clothing, activities)
Data arrives progressively at 1-second intervals, demonstrating "multiple values over time" streaming pattern.
show-map
Display 3D globe at a bounding box location.
Parameters:
west(number) - Western longitudesouth(number) - Southern latitudeeast(number) - Eastern longitudenorth(number) - Northern latitudelabel(string, optional) - Location label
Example:
{
"west": 2.29,
"south": 48.85,
"east": 2.3,
"north": 48.86,
"label": "Eiffel Tower"
}shuffle-cities
Display a random city on the map.
Parameters: None
geocode
Search for places and get coordinates.
Parameters:
query(string) - Place name or address
Example:
{
"query": "Golden Gate Bridge"
}Returns up to 5 matches with coordinates and bounding boxes.
test-tools-notification
Trigger a tools/list_changed notification to test dynamic tool list updates.
Parameters: None
What It Does:
Sends
notifications/tools/list_changedto all connected clientsSimulates what happens when the server dynamically adds or removes tools
Connected apps display a notification: "Tools Updated - New tools are now available"
Demonstrates protocol-level notifications from server to apps
Example Usage:
Call the test-tools-notification toolExpected Result:
Tool returns: "Sent tools/list_changed notification to all connected clients"
Apps show animated toast notification in top-right corner
Notification auto-dismisses after 5 seconds
Use Case: Testing notification handlers and demonstrating that apps can respond to server-side tool list changes in real-time.
ποΈ Architecture
βββββββββββββββββββββββββββββββββββββββββββ
β MCP Host (Claude, VS Code, etc.) β
β β
β βββββββββββββββββββββββββββββββββββββ β
β β MCP App UI (Sandboxed iframe) β β
β β βββββββββββββββββββββββββββββββ β β
β β β Weather Dashboard β β β
β β β - Search box β β β
β β β - Quick cities β β β
β β β - Tell Claude button β β β
β β β - Open web button β β β
β β β - Activity log β β β
β β βββββββββββββββββββββββββββββββ β β
β β β β
β β postMessage β AppBridge β β
β βββββββββββββββββββββββββββββββββββββ β
β β
β HTTP/SSE β β
βββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββ
β MCP Server (Node.js + Express) β
β - show-weather tool β
β - show-map tool β
β - geocode tool β
β - UI resources (bundled HTML) β
β - Open-Meteo API integration β
β - Nominatim geocoding β
βββββββββββββββββββββββββββββββββββββββββββπ MCP Client Configuration
For stdio transport:
{
"mcpServers": {
"weather-map": {
"command": "node",
"args": ["/path/to/dist/index.js", "--stdio"]
}
}
}For HTTP transport with Claude:
Add as a custom connector:
Name: Weather & Maps
URL:
https://your-server.com/mcp(or cloudflared tunnel URL)
π Learning Resources
π Project Structure
mcp-map-server-ui/
βββ apps/
β βββ globe/ # CesiumJS 3D globe app
β βββ weather/ # Weather dashboard app
β βββ clock/ # Clock timer app
β βββ lifecycle/ # Conformance: lifecycle tests
β βββ host-context/ # Conformance: host context tests
β βββ messaging/ # Conformance: messaging tests
β βββ domain-cors/ # Conformance: domain & CORS tests
β βββ theming/ # Conformance: theming tests
β βββ shared/ # Shared test utilities
βββ server.ts # Main MCP server (globe, weather, clock)
βββ main.ts # Main server HTTP entrypoint
βββ conformance-server.ts # Conformance MCP server (5 test apps)
βββ conformance-main.ts # Conformance server HTTP entrypoint
βββ Dockerfile # Multi-stage Docker build
βββ docker-compose.yml # Runs conformance server on port 3002
βββ .dockerignore
βββ dist/ # Built artifacts
β βββ apps/ # Bundled HTML apps
β βββ server.js # Compiled main server
β βββ index.js # Compiled main entrypoint
β βββ conformance-server.js # Compiled conformance server
β βββ conformance-index.js # Compiled conformance entrypoint
βββ package.json
βββ vite.config.ts
βββ tsconfig.json
βββ TESTING_GUIDE.md # Detailed testing instructions
βββ CUSTOM-API-GUIDE.md # Progressive streaming API extension guide
βββ README.md # This fileπ’ Deployment
This server can be deployed to any Node.js hosting platform:
Azure App Service (see
.github/workflows/)AWS Lambda / ECS
Google Cloud Run
Heroku
Railway
Vercel / Netlify (with serverless functions)
Ensure your deployment exposes the /mcp endpoint and supports:
HTTP POST requests
SSE (Server-Sent Events) for streaming
CORS headers
JSON request/response bodies
π Roadmap
Phase 1: Core Features (β Complete)
Tool calling from UI
Chat integration
External links
Structured logging
Error handling
Phase 2: Display & Themes (β Complete)
Inline display mode
Fullscreen mode (both apps)
Theme detection (light/dark)
Keyboard shortcuts (Esc, Ctrl+Enter)
Host context change handling
Responsive layouts per mode
PiP mode CSS (ready for host support)
Phase 3: Persistence & Context (β Complete)
Favorites management (β star button)
Search history (localStorage)
Cross-session persistence (viewUUID-based keys)
Progressive streaming analysis (5 phases)
Compact viewport design (790px, mobile-optimized)
Model context updates (weather app sends current weather to Claude)
Bookmark locations with notes (π button with custom notes)
Phase 4: Advanced Features (π§ Partially Complete)
Progressive streaming tool (uzir-weather-stream)
Real-time phase-based updates
Tool list change notifications (animated toast UI)
Notification handler registration (
setNotificationHandler)Test tool for notifications (
test-tools-notification)Comparison mode (multiple locations)
Advanced forms and validation
Keyboard shortcuts (weather-specific)
Phase 5: Polish & Production
Full accessibility (ARIA, screen reader)
Offline mode with service workers
Performance monitoring
Analytics and telemetry
E2E testing suite
π€ Contributing
This is a testing and demonstration project for MCP Apps capabilities. Contributions welcome!
π License
MIT
π Links
Live Demo: TBD (coming soon)
MCP Apps Docs: https://modelcontextprotocol.io/docs/extensions/apps
GitHub Issues: Report bugs and request features
Testing Guide: See TESTING_GUIDE.md for detailed testing instructions
Built with: Node.js, TypeScript, Express, Vite, CesiumJS, MCP SDK, Open-Meteo API, OpenStreetMap
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/uzirthapa/mcp-map-server-ui'
If you have feedback or need assistance with the MCP directory API, please join our Discord server