kepler-mcp-demo
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., "@kepler-mcp-demoLoad the NYC taxi CSV and color the points by fare"
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.
kepler-mcp-demo
Drive the kepler.gl demo map from Claude / Codex through the
@kepler.gl/mcp map
surface — mapping-only, no analysis engine, no API key.
claude/codex ──Streamable HTTP MCP──▶ kepler-mcp-demo daemon (node)
(or stdio spawn) │ /mcp JSON-RPC for agents
│ /ws ▲ outbound (reverse connect)
│ /files data for map.load-data
https://kepler.gl/demo ──────────┘The kepler.gl demo page owns the map. It registers the map.* commands from
@kepler.gl/mcp (getKeplerCommands(ctx)) against its own redux store and
serves them over a WebSocket bridge. This node process is deliberately map-agnostic:
the tool catalog comes from the page's connection, so the map surface is wholly
owned by @kepler.gl/mcp.
What you get
The map.* commands the demo page serves (the DuckDB-free subset):
Tool (MCP name) | Command | Needs |
|
| current view bbox |
|
| load a CSV/GeoJSON/... from a URL (see |
|
| add point/h3/hexagon/... layer |
|
| recolor a layer |
|
| change the basemap style |
| … | more |
| (built-in) | is a page connected? |
map.create-table / map.add-column / map.save-data need a DuckDB connector
and are intentionally not exposed by the mapping-only bridge.
Related MCP server: Felt MCP
Run (daemon mode — recommended)
First install and build (and rebuild after any source change — a long-running
daemon serves stale dist/):
pnpm install
pnpm buildStart the server
Foreground:
node dist/index.js --port 8765 --token mytoken --demo-url https://kepler.gl/demoDetached (survives the terminal closing; log lands in /tmp/kepler-mcp-demo.log):
cd /path/to/kepler-mcp-demo && nohup node dist/index.js --port 8765 --token mytoken \
--demo-url https://kepler.gl/demo > /tmp/kepler-mcp-demo.log 2>&1 &Flags:
Flag | Default | Purpose |
|
| port for |
| random | shared secret — the page and MCP clients must present it. Pick a fixed one ( |
|
| the page the daemon tells agents/users to open — e.g. |
Check it's up:
curl -s http://localhost:8765/ # status page
lsof -nP -i :8765 -sTCP:LISTEN # or check the listener
tail -f /tmp/kepler-mcp-demo.log # see the banner + page connect/disconnectStop it:
lsof -ti :8765 | xargs killStart-once lifecycle
The daemon must be started once — not per session. Sessions (and
claude mcp list health checks) just connect to it; the page stays connected
across session restarts. You only need to run the start command again after a
reboot, after killing the process, or after pnpm build.
Register the HTTP MCP server (once; pick the token so the page can use it):
claude mcp add --transport http kepler-demo http://127.0.0.1:8765/mcp \ --header "x-kepler-demo-token: <yours>"Connect the page (once): open
https://kepler.gl/demo(or the local demo-app) with?mcp=<token>&mcpPort=8765, or toggle Connect to map harness and paste the token. It stays connected across session restarts — nothing to redo per session.Start sessions freely. Each session initially sees only
harness_status; the page's catalog arrives via a livetools/list_changed. Because the daemon owns the port, parallel sessions and health checks (claude mcp list) no longer collide.
Tip: register with
-s user(claude mcp add -s user --transport http …) so the server is visible from any directory, not just the one you ranclaude mcp addin.
Optional: auto-start with launchd (macOS)
To never think about starting the daemon again — it comes back after every
reboot — create ~/Library/LaunchAgents/com.kepler-mcp-demo.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
<key>Label</key><string>com.kepler-mcp-demo</string>
<key>ProgramArguments</key><array>
<string>/usr/local/bin/node</string> <!-- or `which node` -->
<string>/path/to/kepler-mcp-demo/dist/index.js</string>
<string>--port</string><string>8765</string>
<string>--token</string><string>mytoken</string>
</array>
<key>KeepAlive</key><true/>
<key>RunAtLoad</key><true/>
<key>StandardOutPath</key><string>/tmp/kepler-mcp-demo.log</string>
<key>StandardErrorPath</key><string>/tmp/kepler-mcp-demo.log</string>
</dict></plist>Then: launchctl load ~/Library/LaunchAgents/com.kepler-mcp-demo.plist.
Run (stdio — per-session spawn, also supported)
claude mcp add kepler-demo -- node /abs/path/to/kepler-mcp-demo/dist/index.js --port 8765 --token <yours>Pass --port/--token so the page can connect to the instance the client
spawns. The session starts first and the page connects second; the bridge
pushes tools/list_changed so the map tools appear without a restart. Note the
single-instance rule: while one such session is open, port 8765 is taken (the
server exits with a legible message if not).
Security: the WS bridge requires the per-launch token; the static file server only
serves the files/ directory (path-traversal blocked); the page connects out to
your localhost, so a remote Claude cannot reach your browser.
Examples
examples/random-points.prompt.md— the "generate 10,000 random points in the current map view" session.
Verify headlessly
pnpm smokeSpawns the server, connects a fake page over WS, and exercises the MCP
tools/list / tools/call round trip through the bridge.
Available Tools
1 toolharness_statusARead-onlyIdempotent
Check the bridge status. Returns whether a kepler.gl demo page is currently connected to this bridge, and which map.* commands the page is serving.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is established. The description adds meaningful behavioral context by disclosing what the return value tells the caller: current connection status and the active command surface. This is especially useful given no output schema is present.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences with no redundant words. The core purpose is front-loaded, and the additional return-value detail is provided in the second sentence without padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only status tool with no output schema and no siblings, the description fully covers what an agent needs: the action, the resource, and the nature of the returned information. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters and the input schema is empty, so there is nothing for the description to add. Per the baseline for zero-parameter tools, this is adequate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Check'), a clear resource ('bridge status'), and states exactly what the answer will contain: connection state and the map.* commands being served. It is unambiguous and fully distinguishes the tool from any potential alternative, even with no sibling tools present.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The intended use is clear: call this tool when you need to know whether a kepler.gl demo page is connected to the bridge and what map.* commands are available. There are no sibling tools to contrast against, so explicit exclusions are not necessary; the context is sufficiently clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
With only one tool, there is no possibility of confusion or overlap. The single tool has a clear, specific purpose.
The single tool name 'harness_status' is clear and there are no other names to compare against, so no inconsistency exists.
One tool is too few for the apparent scope of a kepler.gl bridge that should serve multiple map.* commands. The minimal count severely limits the server's utility.
The server only provides a status check, while the tool description implies a broader set of map.* commands that are not exposed. Agents cannot actually interact with the kepler.gl demo page beyond checking its status.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Let AI agents query data and act across all your business apps via MCP.
Hosted MCP server for live public-data APIs and Skills for AI agents.
OCR, transcription, file extraction, and image generation for AI agents via MCP.
MCP server for building and testing AI agents with multi-model experimentation and insights.
Related MCP Servers
- AlicenseBqualityAmaintenanceAI-powered 3D globe control via Model Context Protocol. Connect any MCP-compatible AI agent to CesiumJS — camera, layers, entities, spatial analysis through 19 natural language tools.33134MIT
- AlicenseAqualityDmaintenanceEnables to interact with Felt maps programmatically through an MCP server. Supports listing, retrieving details, and creating maps with natural language.4MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to perceive and control a live MapLibre GL map over MCP, allowing querying rendered features, reading popups, navigating, and toggling layers.1MIT
- FlicenseBqualityCmaintenanceEnables file IO operations and terminal commands via agentic actions using the MCP protocol.9
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- 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/geodaai/kepler-mcp-demo'
If you have feedback or need assistance with the MCP directory API, please join our Discord server