Landmark
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., "@LandmarkWhat's the total for Engineering in the budget file?"
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.
Landmark
An MCP server that lets you ask a spreadsheet questions out loud, instead of walking it cell by cell.
Built for the Alexa+ track of the Amazon Developer Hackathon 2026.
MIT licensed. Spec revision 2025-11-25 over Streamable HTTP, self-hosted.
The problem, stated accurately
It is tempting to write "screen readers lose header context." That is not true, and getting it wrong would be the fastest way to lose the trust of anyone who actually uses one. JAWS and NVDA both announce headers in Excel.
The real difficulty is narrower and harder:
Header association is manual, per worksheet, and does not travel. Headers set up for one reader do not carry to another — NVDA #11801, open since November 2020, is about exactly that.
Most files never declare structure at all. The WebAIM Million, February 2026 observed 948,225 tables and found valid data-table markup on 19% of them. Section508.gov puts it plainly: "Excel does not provide tools to make complex tables accessible."
Even with headers announced, questions cost traversal. "What is the total?" is O(rows). "Which region did best?" is O(rows × cols). There is no cheap way to learn a table's shape before committing to walking it.
A sighted reader answers all three with a glance, which costs nothing and is not sequential. Landmark reconstructs the structure the file never declared, so the same questions can be asked rather than traversed.
Related MCP server: mcp-excel
What it does
"What's in the budget file?"
→ "FY2026 Departmental Budget has 5 rows and 3 columns. The columns are
Department, Line item and Amount. 3 cells take their label from a merged
block, so they are not the blanks they look like."
"Total for Engineering?"
→ "560 thousand. That is the total of Amount across 3 rows."
"How do you know?"
→ "That came from C3 through C5 on Budget. Each one is Amount."The third exchange is the one that matters. CHI 2026 research on blind spreadsheet
users found they never fully trust an AI-produced
number they cannot verify — and over audio there is no cell to glance at. So every
answer carries the cells it was computed from, and table_explain reads them back.
Why this is not a basic MCP wrapper
The Alexa+ track rules name "a basic MCP wrapper around an existing API" as the obvious shape of entry, against a creative list that includes cross-session state, autonomous orchestration and MCP Apps. That is a fair challenge to put to a project shaped like this one, so here is the answer in specifics.
1. It infers structure that is not in the file. A spreadsheet declares a grid, not
a table. Landmark detects table regions separated by blank rows, scores which rows are
headers and reports its confidence rather than guessing silently, resolves merged
blocks, and reconstructs a full header path for every column. Four columns all labelled
Revenue come back as 2026, Q1, Revenue … 2025, Q2, Revenue. There is no API to
wrap here — this is the work.
2. Provenance is a protocol affordance, not a log line. Every aggregate records its source cells, the rows it excluded, and why. Nothing is recomputed on explain, because a recomputation that disagreed with what was already spoken would be worse than no provenance at all. Excluded rows are said out loud: "the total across 47 of the 52 rows; five were empty" is a different claim from "the total".
3. The result-size governance is in the server, not the prompt. Every tool returns a
spoken field inside a word budget, capped at five items with a continuation token,
with numbers scaled for listening and identifiers stripped. A voice product whose
brevity depends on the model remembering to be brief is a chatbot that happens to be
read aloud.
4. State survives the session. table_bookmark and table_resume keep a place in a
long table across days, backed by KV rather than conversation history, and re-orient
before reading — because the user may not have been here for a week.
5. It orchestrates across sheets. table_compare runs two aggregations in different
regions or different files and returns the difference and its direction in one sentence,
so nobody has to hold two numbers in their head and subtract them.
And what it deliberately does not do: there is no get_cell, get_row or
get_column. Those would rebuild the cell-by-cell maze in tool form and hand the
traversal problem back to the model.
Prior art, conceded
The intersection is unoccupied; none of the neighbourhoods are.
~50 spreadsheet MCP servers exist in the official registry ( | They exist to save an LLM tokens. Their consumer is a developer. None mention accessibility, blind users, voice or speech. |
VoxLens (CHI 2022) and VERSE (ASSETS 2019) did voice and sonified access to data for screen-reader users years ago | Both require the data's publisher to instrument the content. An MCP server inverts that: the user brings their own file and needs nobody's cooperation. |
Copilot in Excel works with a screen reader today | It documents a prerequisite of AutoSave and OneDrive. It does not help with a CSV someone emailed you, and it returns a chat pane you must then navigate. |
The one checkable claim, and reproducible by anyone: as of 2026-09-08 the official MCP
registry's accessibility servers are all axe/WCAG auditing tools built for sighted
developers. Query registry.modelcontextprotocol.io for accessibility and read the
descriptions. There is no assistive MCP server whose consumer is a disabled end user.
Run it
npm install
npm run fixtures # generate the sample spreadsheets
npm run ingest -- test/fixtures/*.xlsx test/fixtures/*.csv
npm run serve # http://localhost:8787/mcpA demo index ships in data/index.json, so npm run serve works immediately after
npm install. Point any MCP client at http://localhost:8787/mcp; GET /health
reports the negotiated protocol revision and the corpus size.
npm test # 60 tests
npm run typecheck # strict, noUncheckedIndexedAccess, exactOptionalPropertyTypes
npm run demo # prints what the voice agent actually saysHow it is put together
spreadsheet ──[ ingest CLI, Node ]──▶ data/index.json ──[ Worker ]──▶ MCP toolsThe split is forced and useful. ExcelJS needs Node streams and Buffer, which Cloudflare Workers do not have. Rather than shim it, everything expensive happens once, offline, and the server does pure computation over plain JSON — which is what keeps a grouped aggregate over 2,000 rows at p95 under 5 ms against a 500 ms budget, with no cold start to pay because V8 isolates do not have one.
Path | What lives there |
| Region detection, header scoring, merge resolution, header paths, type inference |
| Readers for xlsx/csv/tsv and the index builder — Node only |
| Deterministic filtering and aggregation, with exclusion accounting |
| Spoken formatting, word budgets, number scaling |
| The eight tools and the answer/bookmark store |
| Web-standard fetch handler — the same code locally and on Workers |
The eight tools
Tool | For |
| What files are available |
| Orientation: shape, columns, types, gaps — call it first |
| Filter and aggregate; returns a spoken sentence plus provenance |
| Read back the exact cells behind a previous answer |
| Individual rows, five at a time, when a summary will not do |
| Two measures, across columns, sheets or files |
| Save a place |
| Come back to it, re-oriented |
Status and honest limits
Header detection is heuristic and says so. Where confidence is low the server tells the user out loud rather than guessing silently — an audible "I could not find a header row, so I am calling the columns by position" is both better engineering and better accessibility than a confident wrong answer nobody can spot.
Alexa+ device integration is not possible for anyone outside Amazon's partner program: the MCP Toolkit is documented as "available to select partners only" and "available in the United States". The MCP server is the deliverable the track asks for; the accompanying voice client stands in for device access.
No blind co-designer yet. Every study cited above ran with 12–99 participants; this has run with none, and that gap is real. A feedback session is being arranged and will be credited here by name.
Licence
MIT — see LICENSE. Dependency audit notes are in
docs/SECURITY-NOTES.md; the two moderate advisories npm audit
reports are analysed rather than suppressed.
This server cannot be deployed
Maintenance
Related MCP Connectors
Ask questions in plain language, get answers from your business database. No SQL required.
Ask data questions in natural language. Get SQL, insights, and charts from your databases.
Ask business questions in plain English. Get instant answers from your database, no SQL needed.
Open, inspect, filter, edit and convert xlsx and csv files from your AI chat. Processing is local.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables users to ask questions about their spreadsheets in plain English and receive instant answers using DuckDB-powered analytics, supporting multiple file formats like Excel, CSV, and Parquet.2MIT
- AlicenseNot gradedqualityDmaintenanceEnables querying Excel and CSV files using SQL via natural language, allowing AI assistants to analyze data without manual SQL writing.1MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to query tabular data (CSV/TSV) using natural language with cell-level citations, supporting multi-tenant workspaces, access control, and semantic search.27MIT
- AlicenseNot gradedqualityDmaintenanceEnables querying your spreadsheet using natural language questions; provides read-only tools for schema, sample data, and structured query execution with auditable computation traces.MIT