Airtable Sheet Port MCP Server
This MCP server enables safe local access to tables and spreadsheets for AI agents, providing typed tools for reading, previewing, and committing table changes through a permission-brokered interface.
README
Airtable - Sheet Port
Airtable - Sheet Port is a safe local port for AI agents to access tables and spreadsheets.
It is a desktop permission broker for Google Sheets and local table workflows. The app owns tokens and local policy, while AI agents interact only through a narrow local MCP server with typed tools for reading, previewing, and committing table changes.
Current Status
Working end to end today (against the built-in mock connector):
- The entire broker is Rust. Two local processes share one SQLite database (WAL):
the Tauri desktop app and the Rust MCP sidecar (
crates/sheet-port-mcp). Both are thin shells over one core crate (crates/sheet-port-core) that owns all broker logic. No direct IPC; each process reads fresh state from the DB. - MCP sidecar with 9 typed tools (
list_sources,list_tables,describe_table,read_table,find_records,preview_update_records,append_records,commit_change,get_audit_log) with strict input bounds. - Enforced approval flow: writes become pending changes with diffs;
commit_changerefuses changes that require confirmation until the user approves them in the desktop app; status transitions are atomic guarded UPDATEs; permissions are re-checked at commit time. - Desktop UI live-wired via typed Tauri IPC (
docs/ipc.md): Dashboard (sidecar heartbeat status), Data Sources, Tables, Permissions editor, Changes (approve/reject with diff viewer), Audit Log, and Settings with a dual light/dark theme (Light / Dark / System, persisted in localStorage). Custom titlebar (decorations: false), tight CSP, minimal capabilities. - Persistent audit log written by both processes (agent tool calls, user decisions, permission edits).
- SQLite-backed mock connector shared by the desktop UI and the sidecar; committed changes persist and show up in both.
- Keyring stub (service
sheet-port): the desktop reports whether token entries exist; secrets never leave the Rust process or the OS keychain.
Not yet: real Google OAuth, functional Google Sheets / provider connectors, delete flows, DB encryption at rest.
Tech Stack
- Broker: Rust workspace (
Cargo.tomlat the repo root)crates/sheet-port-core: permissions, change lifecycle, audit, connectors, heartbeat, keychain vault, shared SQLite access (rusqlite with bundled SQLite)crates/sheet-port-mcp: stdio MCP sidecar built onrmcp(tool schemas viaschemars, async runtimetokio)apps/desktop/src-tauri: Tauri 2 shell; thin#[tauri::command]wrappers over the core crate
- Frontend: React 18 + Vite, Tailwind CSS, TanStack Query + Table, Radix primitives
(
packages/ui), lucide-react; TypeScript types mirrored inpackages/shared - Persistence: shared SQLite (WAL); schema/seed live once at
crates/sheet-port-core/sql/and are embedded viainclude_str! - Secrets: OS keychain via the
keyringcrate (stub for now) - Monorepo glue: pnpm workspaces for the frontend packages only
Repo Structure
crates/
sheet-port-core/ Broker core: db.rs, permissions.rs, changes.rs, audit.rs,
heartbeat.rs, mock_data.rs, sources.rs, vault.rs, connectors/
sql/ schema.sql + seed.sql (single source of truth)
sheet-port-mcp/ Rust MCP sidecar (stdio), the 9 typed tools, heartbeat task
apps/
desktop/ React/Vite frontend + Tauri 2 Rust shell
src/ Screens (incl. Settings/theme), hooks, typed IPC client
(browser demo fallback)
src-tauri/ commands.rs (thin wrappers over sheet-port-core)
packages/
shared/ TypeScript types for the frontend (mirrors docs/ipc.md)
ui/ Small React UI primitives (Radix-based)
docs/ Scope, architecture, security, MCP tools, connectors,
development, IPC contract (docs/ipc.md is canonical)
examples/ Claude Desktop config
scripts/ e2e-smoke.mjs (protocol-level MCP smoke test)
Quick Start
Build the MCP sidecar (requires the Rust toolchain):
cargo build --release -p sheet-port-mcp
Run the desktop app (requires Node 20+, pnpm 9, and the Tauri 2 prerequisites):
pnpm install
pnpm --filter @sheet-port/desktop tauri:dev
Run tests:
cargo test --workspace # all broker logic (core + MCP crates)
cargo build -p sheet-port-mcp # debug binary needed by the e2e smoke
pnpm test # frontend vitest + MCP e2e smoke
Connect Claude Desktop: copy examples/claude-desktop-config.json into your Claude
Desktop configuration and adjust the absolute path. The config launches the release
binary at target/release/sheet-port-mcp.exe (sheet-port-mcp on macOS/Linux), so
run cargo build --release -p sheet-port-mcp first.
Both processes share the same database
(Windows %APPDATA%\sheet-port\sheet-port.db; see docs/development.md for macOS and
Linux paths and the SHEET_PORT_DB override).
Dev Scripts
| Command | What it does |
|---|---|
cargo build --release -p sheet-port-mcp |
Build the MCP sidecar binary |
cargo test --workspace |
Rust unit tests for the whole broker |
cargo clippy --workspace |
Rust lints |
pnpm dev |
Frontend packages in watch mode (parallel) |
pnpm build |
Build the TS packages and the frontend |
pnpm typecheck |
Strict TypeScript, no emit |
pnpm test |
Frontend vitest + MCP e2e smoke (scripts/e2e-smoke.mjs) |
pnpm test:e2e |
MCP e2e smoke only (needs cargo build -p sheet-port-mcp) |
pnpm lint / pnpm format |
Lint / Prettier |
pnpm --filter @sheet-port/desktop dev |
Frontend only at http://127.0.0.1:8477 (demo fixtures) |
pnpm --filter @sheet-port/desktop tauri:dev |
Full desktop app (Rust + React) |
Releases and Auto-Update
The desktop app self-updates via tauri-plugin-updater: it checks a signed manifest on
GitHub at launch and surfaces an "Update Available" prompt in the sidebar (and a manual
"Check for Updates" control in Settings). Releases are cut by pushing a git tag:
| Tag pattern | Result |
|---|---|
release-v<x.y.z> |
Stable release |
develop-v<x.y.z> |
Prerelease build |
git tag release-v0.0.2
git push origin release-v0.0.2
The .github/workflows/build-release.yml workflow builds the Windows/Linux/macOS
(x64 + arm64) matrix, signs the bundles, publishes a GitHub Release, and commits the
regenerated updater.json back to main. This requires the maintainer to set the
TAURI_SIGNING_PRIVATE_KEY (and, if used, TAURI_SIGNING_PRIVATE_KEY_PASSWORD)
repository secrets once. See docs/development.md for key generation and full details.
Security Note
Agents never receive provider OAuth tokens, API keys, raw provider API access, shell
execution, JavaScript execution, or unrestricted writes. The whole broker path is Rust:
tokens stay between the OS keychain and the Rust process, and no npm package ever runs
inside the broker. Every write is a pending change with a diff; changes flagged by
policy require user approval in the desktop app before commit_change succeeds,
permissions are re-checked at commit, and everything is audited to SQLite. See
docs/security.md.
Roadmap
- Real Google OAuth in Tauri with OS keychain token storage (next up)
- Functional Google Sheets connector (range-to-record mapping)
- Additional provider connector (bases, field type mapping, rate limits)
- Delete flow with explicit confirmation semantics
- Database encryption at rest
- UI polish: approval notifications, policy presets, richer diff views
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。