airtable-user-mcp
v2.4.12
Published
Community MCP server for Airtable. Schema inspection, table / field / view CRUD (including merge-safe filter / sort / group updates), formula validation, and extension management. Not affiliated with Airtable Inc.
Maintainers
Readme
airtable-user-mcp
Community add-on to the official Airtable MCP — 66 tools your AI assistant can't get from the public REST API
Not affiliated with Airtable Inc. This is a community-maintained project.
Active development — Breaking changes may land between minor versions. Pin to a version if you need stability.
TL;DR
npx -y airtable-user-mcp login # one browser login
claude mcp add airtable --scope user -- npx -y airtable-user-mcpDone. Your AI assistant can now do things like:
"Create a rollup field on Projects called Total Spend that sums
{Amount}from the linked Invoices table, and add a filter to theActiveview that hides rows where Total Spend = 0."
The official Airtable MCP can't — its REST API doesn't expose those surfaces. Run both MCPs side-by-side and your AI client sees every tool from each.
Why this is an add-on, not a replacement
The official Airtable MCP is a thin wrapper over the public Web API. That API — by design — never exposed some of the most-requested automation surfaces in Airtable. airtable-user-mcp uses Airtable's internal API (the same one the web UI calls) to close the gap. The two servers cover different surfaces, so the intended setup is both installed at once — your MCP client sees the union of their tool sets.
Coverage map
| Capability | Official Airtable MCP | airtable-user-mcp |
|---|---|---|
| Total tools | ~17 | 66 |
| Auth | PAT or OAuth, per-scope | Log in once with your normal account (SSO/2FA supported) |
| Transport | HTTP (remote) | stdio (local, private) |
| Data routing | Through mcp.airtable.com | Direct from your machine |
| Schema read | Partial | Full incl. view state |
| Read records (up to 1 000/call, resolved values) | ❌ | ✅ query_records |
| Search records by text (incl. lookup & rollup fields) | ❌ filterByFormula silently fails on lookup fields | ✅ query_records.search — works on all field types |
| Duplicate records | ❌ | ✅ duplicate_records |
| Create formula fields | ❌ | ✅ |
| Create rollup / lookup / count fields | ❌ UNSUPPORTED_FIELD_TYPE_FOR_CREATE | ✅ |
| Update a formula's text | ❌ | ✅ |
| Validate a formula before apply | ❌ | ✅ |
| Rename / duplicate fields | Limited | ✅ |
| Safe delete with dependency preview | ❌ | ✅ expectedName + viewFilters/Sorts/Groupings summary |
| Create views (7 types) | ❌ API has no endpoint | ✅ grid / form / kanban / calendar / gallery / gantt / list |
| Set/append view filters (nested AND/OR) | ❌ | ✅ |
| Set sorts / grouping / row height | ❌ | ✅ |
| Change column order | ❌ | ✅ |
| Show / hide columns | ❌ | ✅ |
| Duplicate a view with full config | ❌ | ✅ |
| View descriptions, cell wrap, covers, color config, calendar dates, frozen columns | ❌ | ✅ |
| Sidebar sections (create, rename, move, delete) | ❌ | ✅ |
| Record templates (create, pre-fill, duplicate, apply, delete) | ❌ | ✅ |
| Form metadata (description, redirect, attribution, branding) | ❌ | ✅ |
| Extension & dashboard page management | ❌ | ✅ install, enable, rename, duplicate, remove |
| Tool profiles & per-tool toggles | ❌ | ✅ read-only / safe-write / full / custom |
| Install effort | Manual PAT + JSON edit per client | Single claude mcp add or JSON snippet |
| Price | Free | Free, MIT |
Backed by Airtable's MCP docs, the Web API reference, and the rollup-field UNSUPPORTED_FIELD_TYPE_FOR_CREATE thread.
Demo
Quick Start
npx airtable-user-mcpThat's it. Your MCP client connects via stdio and gets access to all 66 tools.
When the daemon is running (started automatically by the VS Code extension, or via npx airtable-user-mcp daemon start),
subsequent npx airtable-user-mcp invocations transparently proxy their stdio to the shared daemon —
so all clients share one Chromium session. To skip the daemon and run in-process: AIRTABLE_NO_DAEMON=1 npx airtable-user-mcp.
Run alongside the official Airtable MCP
airtable-user-mcp is designed to add capabilities, not replace anything. The official Airtable MCP handles records over HTTP with PAT/OAuth; this one handles schema, formulas, views, and extensions locally via Airtable's internal API. Register both in your MCP client so your AI assistant sees the union of their tool sets.
Add this entry to your mcpServers block:
{
"mcpServers": {
"airtable-user-mcp": {
"command": "npx",
"args": ["-y", "airtable-user-mcp"]
}
}
}Then register the official server following Airtable's setup guide. The two servers are independent and share nothing — they just coexist under different names in your MCP client.
Supported Clients
Works with any MCP-compatible client. Tested with:
| | | | | | | |:---:|:---:|:---:|:---:|:---:|:---:| | Claude Desktop | Claude Code | Cursor | Windsurf | Cline | Amp |
Advanced GUI
For a visual management experience, install the Airtable Formula VS Code extension. It bundles this MCP server and adds:
- One-click MCP registration for Cursor, Windsurf, Claude Code, Cline, and Amp
- Dashboard with session status, version info, and setup wizard
- Airtable login with credentials in OS keychain and auto-refresh
- Formula editor with syntax highlighting, IntelliSense, and beautify/minify
Claude Quick Start (no VS Code extension)
Five commands take you from zero → a working Airtable MCP in Claude Desktop or Claude Code. Everything below runs from a normal terminal.
Prerequisites
- Node.js 18 or newer —
node -vto check. Install from nodejs.org if missing. - An Airtable account (personal, team, or enterprise — anything you can log into at airtable.com).
1. Check what's already on your machine
npx -y airtable-user-mcp@latest doctordoctor prints your Node version, platform, config dir, and whether the browser engine is installed. If Patchright: not installed appears, continue to step 2. If it says installed, skip to step 3.
2. Install the browser engine (one-time, ~170 MB)
npx -y airtable-user-mcp install-browserThis downloads Patchright (a stealth Chromium fork used only for the login flow). You only need to run this once per machine. If you already have Chrome, Edge, or Chromium installed and prefer not to download another browser, see Browser Choice below.
3. Log in to Airtable
npx -y airtable-user-mcp loginA browser window opens on airtable.com/login. Sign in like you normally would — password, SSO, 2FA, whatever your account uses. The window closes automatically when login is detected. Your session is stored in ~/.airtable-user-mcp/.chrome-profile/ and reused by every tool call.
Verify the session landed:
npx -y airtable-user-mcp statusYou should see Session: found.
4. Configure your Claude client
Open claude_desktop_config.json:
| OS | Path |
|:--|:--|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
| Linux | ~/.config/Claude/claude_desktop_config.json |
Tip: in Claude Desktop, Settings → Developer → Edit Config opens this file.
Add the airtable entry to mcpServers:
{
"mcpServers": {
"airtable": {
"command": "npx",
"args": ["-y", "airtable-user-mcp"]
}
}
}Save, then fully quit and reopen Claude Desktop (closing the window is not enough). A hammer/plug icon in the chat input confirms the server is connected — click it to see the 66 tools.
Use the built-in claude mcp add command:
# Add for all projects on this machine:
claude mcp add airtable --scope user -- npx -y airtable-user-mcp
# OR — add to the current project only (creates .mcp.json, safe to commit):
claude mcp add airtable --scope project -- npx -y airtable-user-mcpVerify:
claude mcp listYou should see airtable: npx -y airtable-user-mcp - ✓ Connected. Start a Claude Code session in that directory and the 66 tools are available.
5. Try it out
Ask your Claude client:
"List all tables in my Airtable base
appXXXXXXXXXXXXXX."
It will call list_tables and return the names and IDs.
Troubleshooting
| Symptom | Fix |
|:--|:--|
| Session: not found | Re-run npx -y airtable-user-mcp login |
| Login window never loads | Check network / firewall, then doctor |
| Browser download fails on Windows | Run PowerShell as Admin once, then retry install-browser |
| Tools don't appear after config change | Fully quit and reopen Claude Desktop (not just the window) |
| command not found: npx | Install Node.js from nodejs.org |
Run npx -y airtable-user-mcp doctor at any time for a full diagnostic.
Browser Choice
If you already have Chrome, Edge, or a system Chromium and want to skip the 170 MB download:
# point the server at an existing Chromium-family browser
export AIRTABLE_BROWSER_PATH="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" # macOS
# or on Windows (PowerShell):
$env:AIRTABLE_BROWSER_PATH = "C:\Program Files\Google\Chrome\Application\chrome.exe"Useful environment variables
| Variable | Purpose |
|:--|:--|
| AIRTABLE_USER_MCP_HOME | Override config dir (default: ~/.airtable-user-mcp) |
| AIRTABLE_NO_BROWSER | Skip Patchright entirely — uses cached cookies only (CI/headless) |
| AIRTABLE_HEADLESS_ONLY | Run the browser without a visible window |
| AIRTABLE_LOG_LEVEL | debug | info | warn | error |
| AIRTABLE_NO_DAEMON | Skip daemon; run in-process stdio directly (backwards-compatible mode) |
Installation
Via npx (recommended)
Already covered above — the claude mcp add command or the mcpServers JSON entry both use npx -y airtable-user-mcp under the hood.
Via VS Code / Windsurf / Cursor
Install the Airtable Formula extension — it bundles this server and registers it automatically across all your IDEs. Login and status live in a visual dashboard.
Global install
npm install -g airtable-user-mcp
airtable-user-mcp loginThen reference the binary directly in any MCP config:
{ "mcpServers": { "airtable": { "command": "airtable-user-mcp" } } }From source
{
"mcpServers": {
"airtable": {
"command": "node",
"args": ["/path/to/airtable-user-mcp/src/index.js"]
}
}
}All CLI commands
npx airtable-user-mcp Start MCP server (stdio) ← what your Claude client runs
npx airtable-user-mcp login Log in to Airtable via browser
npx airtable-user-mcp logout Clear saved session
npx airtable-user-mcp status Show session & browser info
npx airtable-user-mcp doctor Run diagnostics
npx airtable-user-mcp install-browser Download Chromium (~170 MB)
npx airtable-user-mcp --version Print version
npx airtable-user-mcp --help Show this help
npx airtable-user-mcp daemon start Start the shared background daemon
npx airtable-user-mcp daemon stop Stop the running daemon
npx airtable-user-mcp daemon status Show daemon status and port (JSON)Tools (66)
Schema Read (11)
| Tool | Description |
|:-----|:------------|
| get_base_schema | Full schema of all tables, fields, and views in a base |
| list_tables | List all tables in a base with IDs and names |
| get_table_schema | Full schema for a single table |
| list_fields | All fields in a table with types and configuration |
| list_views | All views in a table with IDs, names, and types |
| get_view | Read a single view's full state — filters, sorts, grouping, visibility, description |
| validate_formula | Validate a formula expression before applying |
| list_view_sections | List sidebar sections for a table with their view membership |
| list_record_templates | List record templates (saved row scaffolds) for a table |
| download_formula_field | Download a formula field to a local .formula file with an AT: metadata header. Pass outputPath to save; omit to read inline. |
| download_base_formulas | Download all formula fields in a base to .formula files, organised into per-table subfolders. Each file includes the AT: header for one-click upload. |
Record Read (1)
Reads resolved record data via Airtable's internal readQueries endpoint — bypasses the REST API
filterByFormula limitation that silently fails on lookup and rollup fields.
| Tool | Description |
|:-----|:------------|
| query_records | Fetch up to 1 000 records from a view with all field values already resolved (lookup fields return the linked record's display string, not a raw ID). Pass search for case-insensitive substring matching across every field value including lookups, rollups, formula fields, and multi-select arrays. Increase limit (max 1 000) to widen the search window. |
Why query_records instead of the Official MCP's record search
// ❌ REST API filterByFormula — silently fails for lookup fields
// FIND() operates on the raw cell value, not the resolved display string
filterByFormula: "FIND('John Smith', {Name Lookup})" // returns 0 results
// ✅ query_records.search — works on all field types
{ "search": "john smith", "limit": 500 } // matches any field containing "john smith"Record Write (1)
| Tool | Description |
|:-----|:------------|
| duplicate_records | Duplicate one or more existing records within the same table. Pass sourceRowIds array; returns the new record IDs. |
Table Management (3)
| Tool | Description |
|:-----|:------------|
| create_table | Create a new table with default fields |
| rename_table | Rename a table |
| delete_table | Delete a table (requires expectedName safety guard) |
Field Management (9)
| Tool | Description |
|:-----|:------------|
| create_field | Create a field — auto-maps url / email / phone / dateTime aliases, plus formula, rollup, lookup, count |
| create_formula_field | Create a formula field (shorthand) |
| update_formula_field | Update the formula text of an existing field |
| update_field_config | Update configuration of any computed field |
| rename_field | Rename a field with pre-validation |
| delete_field | Delete with safety guards and a compact dependency summary |
| delete_fields | Bulk-delete multiple fields in 1–2 API calls. Takes a fields array of {fieldId, expectedName} pairs; validates names before deleting. Use force: true to override dependency blocks. Optional checkpointFile writes progress after each batch so interrupted runs can resume. |
| duplicate_field | Clone a field, optionally copying cell values |
| update_field_description | Set or update a field's description text |
View Configuration (20)
| Tool | Description |
|:-----|:------------|
| create_view | Create grid, form, kanban, calendar, gallery, gantt, or list view |
| duplicate_view | Clone a view with all configuration |
| rename_view | Rename a view |
| delete_view | Delete a view (cannot delete last view) |
| update_view_description | Set or clear a view's description |
| update_view_filters | Set or append filter conditions (AND/OR, nested groups, isEmpty/isNotEmpty auto-normalized for text/formula(text)/lookup/rollup) |
| reorder_view_fields | Change column order — accepts a partial map and merges with current order |
| show_or_hide_view_columns | Toggle visibility for an explicit list of columns |
| apply_view_sorts | Set or clear sort conditions |
| update_view_group_levels | Set or clear grouping. For Kanban views, "stack by" is implemented as a single group level |
| update_view_row_height | Change row height (small / medium / large / xlarge) |
| set_view_columns | One-shot: hide all + show a curated list in left-to-right order + optional frozen-column count |
| show_or_hide_all_columns | Bulk hide-all / show-all primitive |
| move_visible_columns | Move column(s) to a target index in the visible-only ordering |
| move_overall_columns | Move column(s) to a target index in the overall (visible + hidden) ordering |
| update_frozen_column_count | Set the frozen-column divider position |
| set_view_cover | Set or clear cover-image field and fit vs crop (Kanban + Gallery) |
| set_view_color_config | Apply a color config (currently selectColumn type — cards colored by a single-select field's choice colors) |
| set_view_cell_wrap | Toggle whether long cell values wrap or truncate |
| set_calendar_date_columns | Set Calendar dateColumnRanges (single-date or range; multiple overlays supported) |
Sidebar Sections (4)
| Tool | Description |
|:-----|:------------|
| create_view_section | Create a new sidebar section in a table |
| rename_view_section | Rename a sidebar section |
| move_view_to_section | Move view INTO a section, OUT to ungrouped, reorder within a section, or reorder sections among each other |
| delete_view_section | Destroy a section. Contained views are auto-promoted to ungrouped at the section's former position |
Record Templates (8)
Saved row scaffolds Airtable surfaces under "+ Add record" and the row-create extension. Cell values can be static, linked rows, or references to other templates.
| Tool | Description |
|:-----|:------------|
| create_record_template | Create a new record template (client-side rtp... ID) |
| rename_record_template | Rename a template |
| update_record_template_description | Set or clear a template's description |
| set_record_template_cell | Set a cell value — static (text/number/select), linkedRows, or linkedTemplates |
| set_record_template_visible_columns | Choose which columns the template surfaces in its UI |
| duplicate_record_template | Clone an existing template |
| apply_record_template | Apply a template to create a new record using its cell defaults |
| delete_record_template | Delete a template |
Form Metadata (2 — legacy form views only)
| Tool | Description |
|:-----|:------------|
| set_form_metadata | Bundled tool for description, afterSubmitMessage, redirectUrl, refreshAfterSubmit, shouldAllowRequestCopyOfResponse, shouldAttributeResponses, isAirtableBrandingRemoved |
| set_form_submission_notification | Per-user email-on-submit toggle |
Extension Management (7)
| Tool | Description |
|:-----|:------------|
| create_extension | Register a new extension/block in a base |
| create_extension_dashboard | Create a new dashboard page |
| install_extension | Install an extension onto a dashboard page |
| update_extension_state | Enable or disable an installed extension |
| rename_extension | Rename an installed extension |
| duplicate_extension | Clone an installed extension |
| remove_extension | Remove an extension from a dashboard |
Usage Examples
Inspect a base schema
Tool: list_tables
Args: { "appId": "appXXXXXXXXXXXXXX" }Create and validate a formula
Tool: validate_formula
Args: { "appId": "appXXX", "tableId": "tblXXX", "formulaText": "IF({Price}>0,{Price}*{Qty},0)" }
Tool: create_formula_field
Args: { "appId": "appXXX", "tableId": "tblXXX", "name": "Total", "formulaText": "IF({Price}>0,{Price}*{Qty},0)" }Search records (including lookup fields)
Tool: query_records
Args: {
"appId": "appXXXXXXXXXXXXXX",
"tableId": "tblXXX",
"viewId": "viwXXX",
"search": "john smith",
"limit": 500
}Returns every record in the view where any field value contains "john smith" — including fields
whose value comes from a lookup, rollup, or formula. The Official Airtable MCP's filterByFormula
with FIND() or SEARCH() silently fails on lookup fields; query_records does not.
Configure view filters
Tool: update_view_filters
Args: {
"appId": "appXXX",
"viewId": "viwXXX",
"filters": {
"filterSet": [
{ "columnId": "fldXXX", "operator": "isNotEmpty" }
],
"conjunction": "and"
}
}Safety
- Destructive operations (
delete_table,delete_field,delete_fields,delete_view,remove_extension) include built-in safety guards delete_table,delete_field, and each entry indelete_fieldsall require anexpectedNamethat must match the current field name exactly — prevents accidentally deleting the wrong object after a renamedelete_fieldchecks for downstream dependencies and returns a compact summary (viewGroupings,viewSorts,viewFilters,fields) before committing; setforce: trueto delete anywaydelete_fieldsis the preferred tool for bulk deletion (dozens to hundreds of fields). It uses Airtable's native batch endpoint, so N fields from the same table cost 1–2 API calls instead of N×3. Setforce: trueto delete even fields with downstream dependencies.- Formula validation is available and recommended before creating/updating formulas
- All tools accept
debug: truefor raw response inspection
ID Format Reference
| Entity | Prefix | Example |
|:-------|:-------|:--------|
| Base / App | app | appXXXXXXXXXXXXXX |
| Table | tbl | tblXXXXXXXXXXXXXX |
| Field | fld | fldXXXXXXXXXXXXXX |
| View | viw | viwXXXXXXXXXXXXXX |
| Block | blk | blkXXXXXXXXXXXXXX |
| Block Installation | bli | bliXXXXXXXXXXXXXX |
| Dashboard Page | bip | bipXXXXXXXXXXXXXX |
Transport Modes
airtable-user-mcp supports three transport modes. The default behaviour is automatic — MCP clients
do not need to change their configuration when the daemon is present.
| Mode | How to use | When to use |
|:-----|:-----------|:------------|
| stdio standalone | AIRTABLE_NO_DAEMON=1 npx airtable-user-mcp | Backwards-compatible; one process per client; no daemon |
| stdio-proxy | npx airtable-user-mcp (default when daemon lock exists) | Transparent; stdin/stdout bridged to the running daemon |
| HTTP (daemon direct) | http://127.0.0.1:{port}/mcp with Authorization: Bearer {token} | VS Code extension and other HTTP-capable clients |
The daemon stores its port and bearer token in ~/.airtable-user-mcp/daemon.lock.
Protocol
| | |
|:--|:--|
| Transport | stdio + HTTP (StreamableHTTPServerTransport) |
| MCP Version | 2025-11-25 |
| SDK | @modelcontextprotocol/sdk v1.27.1 |
Find Us
| Registry | Link |
|:---------|:-----|
| npm | airtable-user-mcp |
| VS Code Marketplace | Nskha.airtable-formula |
| GitHub | Automations-Project/VSCode-Airtable-Formula |
| MCP Registry | io.github.automations-project/airtable-user-mcp |
| Glama | glama.ai/mcp/servers |
| PulseMCP | pulsemcp.com |
| MCP.so | mcp.so |
Related
- Official Airtable MCP — Airtable's first-party remote server for records over HTTP; this add-on runs alongside it
- Airtable Formula VS Code Extension — Dashboard, formula editor, MCP installer, and AI skills
- Model Context Protocol — The open standard for AI tool integration
Support This Project
This project is built and maintained with the help of AI coding tools. If you find it useful and want to support continued development (new tools, updates, bug fixes), you can contribute by gifting Claude Code credits — the primary tool used to build this project.
Interested? Open an issue or reach out to discuss feature requests and sponsorship.
