The Web, Readable.
Charlotte is an MCP server that renders web pages into structured, agent-readable representations using headless Chromium. Navigation, observation, and interaction — without vision models or brittle selectors.
What Charlotte Returns
Every page is decomposed into a structured representation optimized for token efficiency. Agents receive landmarks, headings, interactive elements, bounding boxes, and form structures.
{
"url": "https://example.com/dashboard",
"title": "Dashboard",
"viewport": { "width": 1280, "height": 720 },
"snapshot_id": 1,
"structure": {
"landmarks": [
{ "role": "banner", "label": "Site header",
"bounds": { "x": 0, "y": 0, "w": 1280, "h": 64 } },
{ "role": "main", "label": "Content",
"bounds": { "x": 240, "y": 64, "w": 1040, "h": 656 } }
],
"headings": [
{ "level": 1, "text": "Dashboard", "id": "h-1" }
],
"content_summary": "main: 2 headings, 5 links, 1 form"
},
"interactive": [
{
"id": "btn-a3f1",
"type": "button",
"label": "Create Project",
"bounds": { "x": 960, "y": 80, "w": 160, "h": 40 },
"state": { "enabled": true, "visible": true }
}
],
"forms": [],
"alerts": [],
"errors": { "console": [], "network": [] }
}Detail Levels
minimalsummaryfullStable Element IDs
Hash-based IDs survive DOM mutations and element reordering.
btn-a3f1buttoninp-c7e2text inputlnk-d4b9linksel-e8a3selectchk-f1a2checkboxfrm-b1d4form30 Tools, 6 Categories
Everything an agent needs to navigate, understand, and interact with the web.
Navigation
4Browse the web. Go to URLs, traverse history, refresh pages.
navigatebackforwardreloadObservation
4Understand pages. Three detail levels, spatial search, visual capture, structural diffing.
observefindscreenshotdiffInteraction
9Act on pages. Click, type, submit forms, scroll, and poll for async conditions.
clicktypeselecttogglesubmitscrollhoverkeywait_forSession
9Manage browser state. Tabs, viewports, network throttling, cookies, headers.
tabstab_opentab_switchtab_closeviewportnetworkset_cookiesset_headersconfigureDev Mode
3Local development. Static server with hot reload, CSS/JS injection, accessibility audits.
dev_servedev_injectdev_auditUtility
1Execute arbitrary JavaScript in page context. Read computed values, trigger events.
evaluateUsage Examples
Once connected as an MCP server, agents can use Charlotte's tools directly.
Browse a website
// Navigate to a page
navigate({ url: "https://example.com" })
// See what's on the page
observe({ detail: "summary" })
// Find a specific element
find({ type: "link", text: "About" })
// Click it
click({ element_id: "lnk-a3f1" })Quick Start
Get Charlotte running in under a minute. Requires Node.js >= 22 and npm.
1Install & Build
git clone https://github.com/TickTockBent/charlotte.git
cd charlotte
npm install
npm run build2Configure Your MCP Client
Claude Code — create .mcp.json in your project root:
{
"mcpServers": {
"charlotte": {
"type": "stdio",
"command": "node",
"args": ["/path/to/charlotte/dist/index.js"],
"env": {}
}
}
}Claude Desktop — add to claude_desktop_config.json:
{
"mcpServers": {
"charlotte": {
"command": "node",
"args": ["/path/to/charlotte/dist/index.js"]
}
}
}3Verify It Works
navigate({ url: "https://example.com" })
// Returns: title "Example Domain", landmarks, headings, 1 link
observe({ detail: "minimal" })
// Returns: landmarks + interactive elements onlyThis page was built by an agent.
An AI agent designed this entire website, wrote every component, and shipped it in a single session — with no human reviewing screenshots or testing on a phone.
It didn't need to. Charlotte gave it eyes.
The agent served the site locally with dev_serve, inspected the rendered page with observe, and ran dev_audit to check accessibility, SEO, and contrast. It switched to a mobile viewport, detected that code blocks were overflowing past the edge of the screen by reading element bounding boxes, fixed the CSS, and verified the fix — all without a human ever looking at the page.
Charlotte caught 16 unlabeled SVG icons that would have been invisible to sighted reviewers but broken for screen readers. It found a 204-pixel horizontal overflow on mobile that would have shipped unnoticed. Both bugs were fixed in the same session they were introduced.
That's what it means to make the web readable.