<div align="center">
<br>
MCP Airtable
<br>
Production-ready MCP server for Airtable integration
<br>
   
<br>
Built with FastMCP — Works with Claude Desktop & Claude.ai
<br>
---
<br>
</div>
Overview
A minimal, enterprise-grade MCP server enabling AI assistants to interact with Airtable. Features 21 tools covering complete CRUD operations, batch processing, schema management, and file attachments—built with meticulous precision and strategic clarity.
<br>
Δ Capabilities
<table> <tr> <td width="50%" valign="top">
Core
21 Tools — Full CRUD, batch operations, attachments Streamable HTTP — Claude Desktop 2025+ native support Header Auth — Multi-tenant ready architecture
</td> <td width="50%" valign="top">
Reliability
Circuit Breaker — Cascading failure prevention Auto-Retry — Exponential backoff with jitter Health Checks — K8s liveness & readiness probes
</td> </tr> <tr> <td width="50%" valign="top">
Security
Input Validation — Zod schemas everywhere Injection Prevention — Formula & path attacks blocked Audit Ready — Full security documentation
</td> <td width="50%" valign="top">
Performance
Connection Pooling — Keep-alive via undici Request Deduplication — Shares concurrent results Response Caching — 5-10min TTL for metadata
</td> </tr> </table>
<br>
Quick Start
npm install && npm run build
npm start
Server runs at http://localhost:3000/mcp
<br>
Configuration
<details> <summary><b>Local Development (stdio)</b></summary> <br>
{
"mcpServers": {
"mcp-airtable": {
"command": "node",
"args": ["/path/to/mcp-airtable/dist/index.js", "--stdio"],
"env": {
"AIRTABLE_API_KEY": "patXXXXX.XXXXX..."
}
}
}
}
</details>
<details> <summary><b>Remote HTTP (mcp-remote)</b></summary> <br>
{
"mcpServers": {
"mcp-airtable": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://your-server.com/mcp",
"--header", "x-airtable-api-key:patXXXXX.XXXXX...",
"--header", "x-airtable-workspace-id:wspXXXXXXXXXXX"
]
}
}
}
</details>
<details> <summary><b>Claude.ai Web</b></summary> <br>
- Deploy:
npm start - Claude.ai → Settings → Connectors
- Add URL:
https://your-server.com/mcp - Add header:
x-airtable-api-key: patXXXXX...
</details>
<br>
| Platform | Config Path | |:---------|:------------| | macOS | ~/Library/Application Support/Claude/claude_desktop_config.json | | Windows | %APPDATA%\Claude\claude_desktop_config.json |
<br>
β Tools
| Category | Tools | |:---------|:------| | Bases & Workspaces | list_workspaces° · list_bases · get_base_schema · create_base | | Tables | list_tables · create_table · update_table | | Fields | create_field · update_field · upload_attachment | | Records | get_records · get_record · create_records · update_record · delete_record | | Batch | upsert_records · delete_records | | Comments | list_comments · create_comment · update_comment · delete_comment | | Health | health_check · liveness · readiness |
° Enterprise Scale plan required
<br>
Usage
"List all my Airtable bases"
"Get records from Tasks where Status = 'Active'"
"Create a task with Name='Review PR' and Priority='High'"
"Upload the PDF to the Attachments field on record rec123"
<br>
Authentication
| Priority | API Key | Workspace ID | |:--------:|:--------|:-------------| | 1 | x-airtable-api-key header | x-airtable-workspace-id header | | 2 | Authorization: Bearer header | workspaceId parameter | | 3 | airtableApiKey parameter | AIRTABLE_WORKSPACE_ID env | | 4 | AIRTABLE_API_KEY env | — |
<br>
Airtable Plan Requirements
<details> <summary><b>API Scopes by Plan</b></summary> <br>
| Scope | Free | Team | Business | Enterprise | |:------|:----:|:----:|:--------:|:----------:| | data.records:read | ✅ | ✅ | ✅ | ✅ | | data.records:write | ✅ | ✅ | ✅ | ✅ | | data.recordComments:read | ✅ | ✅ | ✅ | ✅ | | data.recordComments:write | ✅ | ✅ | ✅ | ✅ | | schema.bases:read | ✅ | ✅ | ✅ | ✅ | | schema.bases:write | ✅ | ✅ | ✅ | ✅ | | webhook:manage | ✅ | ✅ | ✅ | ✅ | | user.email:read | ✅ | ✅ | ✅ | ✅ | | workspacesAndBases:read | ❌ | ❌ | ✅ | ✅ | | enterprise.* scopes | ❌ | ❌ | ❌ | ✅ |
</details>
<details> <summary><b>API Rate Limits by Plan</b></summary> <br>
| Plan | Monthly Calls | Rate Limit | Overage Behavior | |:-----|:--------------|:-----------|:-----------------| | Free | 1,000/month | 5 req/sec | 30-day grace period (once), then blocked | | Team | 100,000/month | 5 req/sec | Throttled to 2 req/sec until reset | | Business | Unlimited | 5 req/sec | — | | Enterprise | Unlimited | 5 req/sec | — |
</details>
<details> <summary><b>Tool Compatibility</b></summary> <br>
| Tool | Required Scope | Min Plan | |:-----|:---------------|:---------| | list_workspaces | workspacesAndBases:read | Enterprise° | | list_bases | schema.bases:read | Free | | get_base_schema | schema.bases:read | Free | | create_base | schema.bases:write | Free | | list_tables | schema.bases:read | Free | | create_table | schema.bases:write | Free | | update_table | schema.bases:write | Free | | create_field | schema.bases:write | Free | | update_field | schema.bases:write | Free | | get_records | data.records:read | Free | | get_record | data.records:read | Free | | create_records | data.records:write | Free | | update_record | data.records:write | Free | | delete_record | data.records:write | Free | | upsert_records | data.records:write | Free | | delete_records | data.records:write | Free | | upload_attachment | data.records:write | Free | | list_comments | data.recordComments:read | Free | | create_comment | data.recordComments:write | Free | | update_comment | data.recordComments:write | Free | | delete_comment | data.recordComments:write | Free |
° Returns 404 on non-Enterprise plans. Workaround: Get workspace ID from Airtable UI URL (airtable.com/wspXXX/...)
</details>
<br>
Stability & Resilience
<details> <summary><b>Retry with Exponential Backoff</b></summary> <br>
- Auto-retries on HTTP 429, 500, 502, 503, 504
- Handles network errors (ECONNRESET, ETIMEDOUT, ECONNREFUSED)
- Respects
Retry-Afterheaders - Configurable max retries, delays, jitter
</details>
<details> <summary><b>Circuit Breaker Pattern</b></summary> <br>
Prevents cascading failures:
- CLOSED — Normal operation
- OPEN — Fast-fail mode
- HALF_OPEN — Recovery testing
</details>
<details> <summary><b>Request Management</b></summary> <br>
- Timeout: 30s default (AbortController)
- Deduplication: Shares identical concurrent GETs
- Queue: Limits to 5 concurrent requests
- Keep-Alive: Connection pooling via undici
</details>
<details> <summary><b>Health Checks</b></summary> <br>
Kubernetes-ready probes:
health_check— Full status reportliveness— Alive checkreadiness— Traffic ready
</details>
<br>
Deployment
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY dist ./dist
EXPOSE 3000
CMD ["node", "dist/index.js"]
docker build -t mcp-airtable .
docker run -p 3000:3000 mcp-airtable
<details> <summary><b>Environment Variables</b></summary> <br>
# Server
PORT=3000
NODE_ENV=production
# Auth (prefer headers in production)
AIRTABLE_API_KEY=
AIRTABLE_WORKSPACE_ID=
# Rate Limiting
RATE_LIMIT_ENABLED=true
RATE_LIMIT_REQUESTS_PER_MINUTE=60
# Caching
CACHE_ENABLED=true
CACHE_TTL_BASES=300
CACHE_TTL_SCHEMA=600
CACHE_TTL_TABLES=300
# Logging
LOG_LEVEL=info
# Sentry (Optional)
SENTRY_DSN=
SENTRY_DEBUG=false
SENTRY_ENVIRONMENT=production
</details>
<br>
Architecture
src/
├── index.ts # Entry point
├── server.ts # FastMCP init
├── tools/ # 21 tools
│ ├── bases.ts
│ ├── tables.ts
│ ├── fields.ts
│ ├── records.ts
│ ├── batch.ts
│ └── comments.ts
└── lib/ # Core
├── airtable/ # API client
├── retry.ts # Backoff
├── circuit-breaker.ts # Failure prevention
├── health.ts # K8s probes
├── deduplication.ts # Request dedup
└── ...
~2,500 lines · 272 unit tests · 25 e2e tests
<br>
References
| | | |:--|:--| | MCP Specification | modelcontextprotocol.io | | FastMCP | github.com/punkpeye/fastmcp | | mcp-remote | npmjs.com/package/mcp-remote | | Airtable API | airtable.com/developers |
<br>
---
<div align="center">
<br>
Security · Examples · Changelog
<br>
MIT License
<br>
DELTΔ & βETΑ
From Change to What's Next
<br>
</div>











