maidr-mcp
OfficialIntegrates with ChatGPT/OpenAI as an MCP App host, allowing charts to appear in ChatGPT conversations through developer-mode apps or Secure MCP Tunnel, with model-driven chart navigation and reader position updates.
Click on "Deploy 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., "@maidr-mcpshow a bar chart of quarterly sales and take me to the highest bar"
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.
maidr-mcp
An MCP server that shows accessible maidr charts inside ChatGPT and Claude conversations, and lets the conversation's model move the reader through them.
The model calls show_chart with the data, and the chart appears in the conversation as an MCP App. A blind or low-vision reader Tabs into it and explores it the way they explore any maidr chart: arrow keys, screen reader, sonification, braille. Two things then happen through the model:
The model can take the reader somewhere. When the reader asks for "the highest bar", the model calls
maidr_get_layer_datato find it andmaidr_navigateto move there, and maidr announces the point by speech, braille and sound.The model knows where the reader is. As the reader moves, the chart tells the model their position, so "what is this point?" needs no tool call.
Experimental. Checked end to end in the MCP Apps SDK's reference host (below). Not yet checked in claude.ai or ChatGPT.
How it works
show_chartdraws the chart on the server with matplotlib and py-maidr, so the model sends numbers rather than an SVG. The SVG reaches the chart view in the tool result's_meta, which is not added to the model's context.The view loads maidr.js and the MCP Apps SDK from
cdn.jsdelivr.net, the only domain its CSP declares, at pinned versions.maidr.js registers its own WebMCP tools on
document.modelContext. No host hands a view's tools to the model yet (ext-apps#797), so the view suppliesdocument.modelContextitself. Each server tool of the same name relays its call to the view that is open:the model calls the server tool;
the view long-polls an app-only tool, picks up the call, runs maidr's tool, and posts maidr's answer back;
that answer becomes the model's tool result.
If hosts adopt WebMCP for MCP Apps, as ext-apps#798 proposes, maidr's tools reach the model directly and the relay can go.
On each key the reader presses in the chart, the view sends their position with
ui/update-model-context.
Related MCP server: Accessibility MCP Server
Tools
Tool | Called by | Does |
| model | Draws the chart and shows it. Returns the |
| model | Returns the chart's layers, point counts, and where the reader is. Silent. |
| model | Returns a page of a layer's points, each with the |
| model | Moves the reader to a point and announces it. |
| the chart view only | Carry the relay, and the SVG for hosts that drop |
show_chart takes one of these chart types. Each maps onto the maidr layer type shown:
| Fields | maidr layer |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Every type also takes title, x_label and y_label.
Use it
What the server needs depends on how the host reaches it:
Host | How it connects | What the server needs |
Claude (web, Desktop, mobile) | a custom connector, which takes a remote MCP server | a public HTTPS address |
ChatGPT | a developer-mode app | a public HTTPS address, or Secure MCP Tunnel to your own machine |
ChatGPT desktop app | its own MCP servers, started over STDIO | nothing hosted; see below for what is untested |
With a public address
uvx --from git+https://github.com/xability/maidr-mcp maidr-mcp --host 0.0.0.0 --port 8000
# or
docker build -t maidr-mcp . && docker run -p 8000:8000 maidr-mcpThe endpoint is /mcp, over Streamable HTTP.
Run one instance. The relay keeps each chart's queue in memory.
Restarts are tolerated. An open chart registers itself again on its next poll after a restart.
Claude. Add a custom connector: Customize > Connectors > Add custom connector, with https://<your-host>/mcp.
Plans: custom connectors work on every plan; Free allows one.
Team and Enterprise: an Owner adds it.
Where charts render: on web, Desktop, and iOS/Android once the connector is added.
ChatGPT. Turn on developer mode, then create an app for https://<your-host>/mcp. Developer mode is available on the web for Plus, Pro, Business, Enterprise and Education accounts.
ChatGPT without a public address
Your own machine, through Secure MCP Tunnel. ChatGPT calls an app's MCP server from OpenAI's side, so it cannot reach localhost directly. OpenAI's Secure MCP Tunnel connects it to a server that stays off the internet:
Server: runs on your machine, either
maidr-mcp(HTTP at127.0.0.1:8000/mcp) ormaidr-mcp --stdio.Tunnel client: OpenAI's open-source client runs next to the server and opens only outbound HTTPS to OpenAI. It needs a
tunnel_idfrom the Platform's tunnel settings and a runtime API key.App: you add it in developer mode through the tunnel, as that guide describes.
Uptime: the machine has to stay on while the chart is in use.
The ChatGPT desktop app's own MCP servers. The desktop app can start a local server itself. Open Settings > MCP servers > Add server, choose STDIO, and give it this command, which needs uv:
uvx --from git+https://github.com/xability/maidr-mcp maidr-mcp --stdioThe desktop app shares this configuration with the Codex CLI and IDE extension. There are two caveats:
Whether the app draws an MCP App's UI for a server added this way is not documented.
This route has not been tried with maidr-mcp, so it is not known whether the chart appears.
Try it in the reference host
e2e/run.sh checks the whole loop without a ChatGPT or Claude account. It does three things:
Builds the reference host from ext-apps (
examples/basic-host, at tagv2.0.3).Starts this server.
Drives both with Playwright the way a model and a reader would.
cd e2e && npm install && npx playwright-core install chromium && cd ..
bash e2e/run.shIt checks:
the chart appears;
the model's calls are answered by maidr inside the chart;
a move made while the reader is in the chat waits, and is announced when they Tab in;
the arrow keys announce, and the reader's position reaches the host as model context;
a move made while the reader is in the chart is announced at once;
there are no console errors or CSP violations.
Limits
The model learns the reader's position one turn late. It sees the position on its next turn, not in the middle of one.
Moves wait until the reader is in the chart. maidr never moves focus. A move made while the reader is typing to the model is kept, and announced when they Tab back into the chart.
maidr_navigatesays so (applied: "on-next-focus"), and the model should tell them.Each
show_chartcall adds a chart. Claude mounts a new view for every call, and earlier views stay.The relay keeps a request open. The view's poll holds a request for up to 20 seconds. Whether a given host limits calls made from a view is not yet known.
There is no authentication. Anyone with the server's URL can draw charts. A chart can only be read or driven with its
viewId, a random 24-character token.Six chart families so far. The server does not take plotting code.
Network and data
The server: receives the data the model sends to draw a chart. It keeps the chart's SVG in memory until the chart has gone 15 minutes without polling, and logs nothing about the data beyond the HTTP access log.
The chart view: loads maidr.js and the MCP Apps SDK from
cdn.jsdelivr.net. maidr's own AI chat inside the chart works as it does anywhere else, with a key the reader adds.
Development
uv sync
uv run ruff check . && uv run ruff format --check .
uv run pytest
bash e2e/run.shLicense
GPL-3.0-or-later, like the rest of maidr.
This server cannot be deployed
Maintenance
Related MCP Connectors
Renders interactive Chart.js charts and dashboards inline in AI conversations.
Renders interactive Chart.js charts and dashboards inline in AI conversations. Supports bar, line, area, pie, doughnut, scatter, and radar charts with multi-chart dashboard grids.
AI visibility & recommendation monitoring for ChatGPT, Claude, Gemini & Perplexity.
Let Claude, Cursor, or ChatGPT author Mermaid diagrams your team can read and share.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables creating interactive data visualizations from natural language queries using DuckDB for local databases or Databricks for enterprise data warehouses. Supports multiple chart types, CSV imports, SQL queries, and automatic statistical analysis through Claude Desktop.19MIT
- AlicenseAqualityCmaintenanceProvides conversational, actionable accessibility testing for AI agents, including auditing, prioritization, and code-level fixes.2218 npmMIT
- FlicenseNot gradedqualityDmaintenanceEnables interactive Google Analytics 4 visualizations inside Claude conversations, supporting ad-hoc queries with line, bar, pie charts and data tables.-
- AlicenseBqualityDmaintenanceEnables AI agents to render branded charts as inline images and persistent hosted URLs, supporting explicit chart types and automatic chart suggestion from data.243 npmMIT