Cursor là IDE tích hợp AI agent (Agent Mode) trực tiếp trong editor, khác với Claude Code CLI hay Gemini CLI vốn chạy chủ yếu ở terminal. Điểm mạnh khi gắn Airtable MCP vào Cursor là bạn có thể vừa xem code, vừa xem diff, vừa để agent đọc/ghi Airtable trong cùng một cửa sổ — rất hợp cho các tác vụ như generate type từ schema Airtable, hoặc giữ đồng bộ feature flag giữa code và bảng requirement. Bài này hướng dẫn kết nối Airtable MCP vào Cursor Agent Mode, cách generate type/config từ schema Airtable, cách giữ đồng bộ feature flag và requirement status, cùng các hạn chế và cách workaround khi dùng Airtable MCP trong Cursor.
Kết Nối Airtable MCP Vào Cursor Agent Mode
Cursor quản lý MCP server qua Settings UI (Cursor Settings → MCP) hoặc trực tiếp qua file .cursor/mcp.json trong project (khuyến khích cho team vì file này commit được vào repo, dùng biến môi trường cho phần nhạy cảm).
{
"mcpServers": {
"airtable": {
"command": "npx",
"args": ["-y", "airtable-mcp-server"],
"env": {
"AIRTABLE_API_KEY": "patXXXXXXXXXXXXXX.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
}
}
Sau khi lưu file, vào Cursor Settings → MCP để xác nhận server airtable hiện trạng thái xanh (connected) và danh sách tool đã load (thường thấy list_bases, list_tables, list_records, create_record, update_records...). Nếu server hiện đỏ, thường do thiếu Node.js trong PATH mà Cursor dùng để spawn process — kiểm tra bằng cách mở terminal tích hợp trong Cursor và chạy thử npx -y airtable-mcp-server trực tiếp để xem lỗi thật.
Để dùng MCP tool trong lúc chat với agent, chuyển sang Agent Mode (không phải Chat/Ask mode thông thường) ở góc dưới composer — chỉ ở Agent Mode, Cursor mới cho phép model tự gọi tool bên ngoài như Airtable MCP thay vì chỉ trả lời dựa trên code context.
Kiểm tra nhanh:
@airtable liệt kê các base tôi đang có quyền truy cập.
Cú pháp @airtable (gõ @ rồi chọn tên MCP server) giúp bạn chỉ định rõ ràng agent phải dùng tool từ server nào, hữu ích khi bạn có nhiều MCP server cùng lúc (Airtable, GitHub, Linear...) và không muốn agent chọn nhầm nguồn dữ liệu.
Mẹo: Luôn commit file
.cursor/mcp.jsonvào repo nhưng để trống hoặc dùng biến môi trường (${AIRTABLE_API_KEY}) cho phần token — mỗi dev tự set token cá nhân qua file.envlocal, tránh commit nhầm token thật lên Git (đây là lỗi bảo mật rất phổ biến trong các repo mới setup MCP).
Generate Type Và Config Từ Airtable Schema
Một use case rất thực dụng cho engineer: giữ type definition trong code luôn khớp với schema thật trên Airtable, để tránh runtime error khi field bị đổi tên/type mà code không biết.
Prompt yêu cầu generate TypeScript type từ schema:
Đọc schema table "Requirements" trong base "Product Roadmap" qua
Airtable MCP. Generate một TypeScript interface RequirementRecord
tương ứng, map đúng type:
- Single select → union string literal type
- Multi select → array của union string literal type
- Linked record → string[] (danh sách recordId)
- Checkbox → boolean
- Number → number
- Text/Long text → string
Đặt file vào src/types/airtable/requirement.ts
Kết quả mẫu:
// src/types/airtable/requirement.ts
// Auto-generated from Airtable schema — table "Requirements"
// Regenerate with: cursor agent + Airtable MCP, do not edit by hand.
export type RequirementStatus =
| "New"
| "In Review"
| "In Progress"
| "Blocked"
| "Done"
| "Archived";
export type RequirementPriority = "Low" | "Medium" | "High";
export interface RequirementRecord {
id: string;
title: string;
description: string;
status: RequirementStatus;
priority: RequirementPriority;
assignee?: string;
linkedPRIds: string[];
effortPoints?: number;
isBlocking: boolean;
}
Với dòng comment "Auto-generated... do not edit by hand", bạn thiết lập convention rõ ràng cho cả team: khi schema Airtable đổi, chạy lại đúng prompt trên để regenerate, không sửa tay file type — giống hệt tinh thần của các tool generate type từ OpenAPI/GraphQL schema mà nhiều team đã quen.
Generate config validation (ví dụ Zod schema) đi kèm, hữu ích khi code của bạn nhận dữ liệu ghi ngược từ Airtable webhook hoặc job đồng bộ:
Từ interface RequirementRecord vừa tạo, generate thêm một Zod schema
tương ứng để validate dữ liệu nhận từ Airtable webhook, đặt cùng file.
Mẹo: Thêm một npm script (ví dụ
npm run sync:airtable-types) gọi lại đúng prompt generate type này qua Cursor CLI headless (nếu có) hoặc ghi rõ hướng dẫn chạy tay trong README — biến việc "đồng bộ type với schema" thành một quy trình lặp lại được, không phụ thuộc vào việc ai đó nhớ phải làm khi schema đổi.
Đồng Bộ Feature Flag Và Requirement Status Ngay Từ Cursor
Nhiều team lưu feature flag trong Airtable (thay vì service riêng như LaunchDarkly, cho quy mô nhỏ) — mỗi flag là một record trong table Feature Flags, có field Key, Enabled Environments (multi select: dev/staging/prod), Linked Requirement. Cursor Agent Mode rất hợp để giữ đồng bộ giữa flag trong code và record trong Airtable vì agent nhìn thấy cả code hiện tại và Airtable trong cùng một context.
Đồng bộ khi thêm flag mới trong code:
Tôi vừa thêm feature flag "new_checkout_flow" trong file
src/config/flags.ts (xem code hiện tại).
Kiểm tra xem record với Key = "new_checkout_flow" đã tồn tại trong
table "Feature Flags" chưa. Nếu chưa, tạo mới với Enabled
Environments = ["dev"], Linked Requirement = record có Title
chứa "checkout flow" (nếu tìm được).
Đồng bộ ngược — khi PM đổi trạng thái flag trên Airtable, cập nhật code cho khớp:
Đọc record "new_checkout_flow" trong table "Feature Flags".
So sánh Enabled Environments hiện tại với giá trị đang hard-code
trong src/config/flags.ts. Nếu khác, cập nhật code cho khớp và
giải thích rõ những gì đã thay đổi.
Giữ Requirement Status tự cập nhật theo trạng thái rollout thật:
Với flag "new_checkout_flow" đã Enabled Environments chứa "prod",
tìm Linked Requirement tương ứng trong table "Requirements",
cập nhật Status = "Done" nếu đang ở "In Progress" hoặc "In Review".
Điểm cần cẩn trọng: đồng bộ hai chiều rất dễ tạo race condition thực tế nếu bạn chạy các prompt này không có convention rõ ràng về "nguồn sự thật" — ví dụ code vừa đổi flag sang ["dev","staging"] cùng lúc PM cũng vừa sửa Airtable sang ["dev"]. Nên xác định rõ ngay từ đầu: Airtable là nguồn sự thật cho môi trường nào được enable (PM/product quyết định), còn code chỉ đọc và implement logic dựa theo giá trị đó, tránh để cả hai chiều cùng "ghi" vào cùng một field một cách tự động không giám sát.
Mẹo: Ghi rõ trong README hoặc file rule của Cursor (
.cursor/rules) quy ước "nguồn sự thật" cho từng loại dữ liệu đồng bộ (ví dụ: Airtable là nguồn sự thật cho Enabled Environments, code là nguồn sự thật cho flag key và default value) — quy ước này giúp agent (và người review) luôn biết chiều đồng bộ đúng khi có xung đột.
Hạn Chế Đã Biết Và Cách Workaround Airtable MCP Trong Cursor
- Agent Mode có thể tự động chạy tool call ghi dữ liệu nếu bạn đã tắt chế độ approval. Cursor cho phép cấu hình mức độ tự động chạy tool (
auto-run) khá cao; nếu bạn đã bật auto-run cho MCP tool để tiện, một prompt mơ hồ có thể khiến agent update/xóa record mà không hỏi lại. Workaround: giữ tool ghi dữ liệu (create_record,update_records,delete_records) ở chế độ cần approval thủ công trong Cursor Settings, chỉ auto-run các tool đọc (list_records,get_record). - Context window giới hạn khi schema quá lớn. Nếu base có nhiều table với hàng chục field mỗi table, việc agent tự
describe_tabletoàn bộ trước khi làm task nhỏ có thể tốn context không cần thiết. Workaround: trong prompt, chỉ định rõ đúng table cần dùng, tránh câu hỏi mở kiểu "xem qua toàn bộ base rồi cho tôi biết nên làm gì". - Không có tool "diff" schema có sẵn. Muốn biết schema Airtable đã đổi gì so với lần generate type gần nhất, MCP không tự cung cấp diff — bạn phải để agent generate lại rồi tự so với bản cũ qua git diff của file type. Workaround: luôn commit file type generated vào Git, dùng
git diffsau khi regenerate để thấy rõ field nào thêm/đổi/mất. - Linked record hiển thị recordId, không hiển thị tên record liên kết theo mặc định trong một số version MCP server. Agent cần thêm một bước
get_record/list_recordsở bảng đích để "dịch" recordId thành tên dễ đọc. Workaround: luôn yêu cầu rõ trong prompt "hiển thị tên record liên kết, không chỉ recordId" khi cần đọc dữ liệu để báo cáo cho người. - Rate limit 5 req/giây áp dụng chung, không riêng cho Cursor. Khi nhiều tab Cursor cùng mở agent chat và cùng gọi Airtable MCP (ví dụ nhiều dev dùng chung một token), dễ chạm giới hạn hơn dự kiến. Workaround: mỗi dev dùng PAT riêng như đã nêu ở bài tổng quan Airtable MCP, không dùng chung một token cho cả team.
Mẹo: Bật approval thủ công cho mọi tool ghi dữ liệu trong Cursor Settings ngay từ ngày đầu setup Airtable MCP, và chỉ nới rộng auto-run sau khi bạn đã quan sát agent hành xử đúng ý qua nhiều lần chạy thủ công — đừng bật auto-run "cho tiện" ngay từ đầu với một MCP server có quyền ghi dữ liệu sản phẩm thật.
Mẹo Thực Chiến
- Dùng
.cursor/mcp.jsoncommit vào repo, chỉ để token qua biến môi trường, không hard-code token thật trong file commit. - Dùng cú pháp
@airtablekhi có nhiều MCP server để tránh agent chọn nhầm nguồn dữ liệu. - Generate type/config từ schema Airtable và biến việc regenerate thành một quy trình lặp lại được (script hoặc hướng dẫn rõ trong README), không làm tay một lần rồi bỏ quên.
- Xác định rõ "nguồn sự thật" cho mỗi loại dữ liệu đồng bộ hai chiều (feature flag, requirement status) trước khi để agent tự động hóa việc đồng bộ.
- Giữ chế độ approval thủ công cho các tool ghi dữ liệu (create/update/delete), chỉ auto-run tool đọc.
Mẹo: Review định kỳ (ví dụ mỗi tháng) danh sách MCP server và token đang cấu hình trong
Cursor Settings → MCPcủa cả team — token PAT không tự hết hạn theo mặc định, dễ bị quên revoke khi một dev rời team hoặc đổi máy, tạo lỗ hổng bảo mật âm thầm nếu không ai chủ động dọn dẹp.