{"id":"airtable","kind":"sdk","name":"Airtable","slug":"airtable","description":"JavaScript client for the Airtable API.","vendor":"Airtable","languages":["javascript","typescript","nodejs"],"categories":["database","devtools"],"homepage":"https://airtable.com/developers","docsUrl":"https://airtable.com/developers/web/api/introduction","githubUrl":"https://github.com/Airtable","packages":[{"registry":"npm","name":"airtable","url":"https://www.npmjs.com/package/airtable"}],"tags":["spreadsheet","api"],"skills":[{"name":"airtable-overview","url":"https://skills.sh/airtable/skills/airtable-overview","install":"npx skills add airtable/skills","sdk":"airtable","key":"airtable/airtable-overview","description":"Explains what Airtable is and how data is structured — bases, tables, fields, records, views, automations, and interfaces. Use when you need context about the Airtable data model.","hasContent":true,"content":"---\nname: airtable-overview\ndescription: Explains what Airtable is and how data is structured — bases, tables, fields, records, views, automations, and interfaces. Use when you need context about the Airtable data model.\nlicense: MIT\nmetadata:\n    version: '1.0.0'\n    author: airtable\n---\n\n# Airtable Overview\n\nAirtable is a no-code platform where teams build custom applications and AI-powered workflows from structured data. Users organize their data into bases, define tables with typed fields, set up automations to act on changes, and create interfaces that give different audiences tailored views of the same data.\n\n## Data model\n\n### Bases\n\nA base is an Airtable database. It is the top-level container for all related data. A base contains one or more tables.\n\n### Tables\n\nA table is a collection of structured data within a base, similar to a sheet in a spreadsheet or a table in a relational database. Each table has a defined set of fields and contains records.\n\n### Fields\n\nA field defines a named, typed property on every record in a table.\n\n### Records\n\nA record is a single entry in a table. Each record has a unique ID and stores a cell value for each field defined on that table.\n\n### Views\n\nA view is a saved configuration for how to display records in a table. Views can filter, sort, group, and hide fields without changing the underlying data. Multiple views can exist on the same table, each showing the data differently.\n\n## Automations\n\nAn automation is a workflow that runs in response to a defined trigger (e.g. a record entering a view) and executes one or more actions (e.g. sending an email or updating a record).\n\n## Interfaces\n\nInterfaces are custom app-like pages built on top of base data. They provide tailored, user-friendly ways to view and interact with records without exposing the full base structure or all of its data. A base can have multiple interfaces, each designed for a specific workflow or audience.\n\nSome users can only access a base through its interfaces and cannot read or modify the underlying tables directly.\n","contentSource":"https://raw.githubusercontent.com/airtable/skills/main/plugins/airtable/skills/airtable-overview/SKILL.md","contentFetchedAt":"2026-07-27T09:02:29.045Z"},{"name":"airtable-cli","url":"https://skills.sh/airtable/skills/airtable-cli","install":"npx skills add airtable/skills --skill airtable-cli","sdk":"airtable","key":"airtable/airtable-cli","description":"Lists bases, reads and writes records, manages tables and fields, filters and searches data in Airtable via the `airtable-mcp` CLI. Use when the task involves Airtable data or the user mentions airtable-mcp, bases, tables, records, or fields.","hasContent":true,"content":"---\nname: airtable-cli\ndescription: Lists bases, reads and writes records, manages tables and fields, filters and searches data in Airtable via the `airtable-mcp` CLI. Use when the task involves Airtable data or the user mentions airtable-mcp, bases, tables, records, or fields.\nlicense: MIT\nmetadata:\n    version: '1.0.0'\n    author: airtable\n---\n\n# airtable-mcp\n\n## Self-discovery\n\nTools are fetched from the MCP server at runtime, so the CLI never has a hardcoded command list. Discover what's available:\n\n```sh\nairtable-mcp tools            # human-readable list\nairtable-mcp tools --json     # machine-parseable list\nairtable-mcp <tool> --help    # show flags and descriptions for a tool\n```\n\nRun `airtable-mcp tools` before assuming a tool exists. Tool names, arguments, and output shapes can change between server releases without a CLI update.\n\n## Install\n\n```sh\nnpm install -g @airtable/mcp-cli\n```\n\n## Auth\n\nThe CLI needs an Airtable personal access token (PAT). Two paths:\n\n**Environment variable (preferred for scripts/agents):**\n\n```sh\nexport AIRTABLE_TOKEN=pat_xxx\n```\n\n**Interactive configure (stores token in `~/.airtable/cli.json` with 0600 permissions):**\n\n```sh\nairtable-mcp configure\n```\n\nCreate tokens at https://airtable.com/create/tokens. Ensure the token has the scopes required by the tools being called.\n\n`AIRTABLE_TOKEN` takes precedence over saved profiles when no `--profile` flag is set. Never log or echo tokens.\n\n## Quick reference\n\n| Task                   | Command                                                 |\n| ---------------------- | ------------------------------------------------------- |\n| Set up credentials     | `airtable-mcp configure`                                |\n| Add a named profile    | `airtable-mcp configure --profile work`                 |\n| Check auth status      | `airtable-mcp whoami`                                   |\n| Remove credentials     | `airtable-mcp logout`                                   |\n| Remove all profiles    | `airtable-mcp logout --all`                             |\n| List available tools   | `airtable-mcp tools`                                    |\n| Run a tool             | `airtable-mcp <tool> --flagName value`                  |\n| Get tool help          | `airtable-mcp <tool> --help`                            |\n| Pass args via stdin    | `echo '{\"key\":\"val\"}' \\| airtable-mcp <tool> --input -` |\n| Bypass tool cache      | `airtable-mcp <tool> --refresh`                         |\n| Suppress status msgs   | `airtable-mcp <tool> -q`                                |\n| Raw text output        | `airtable-mcp <tool> --output raw`                      |\n| Use a specific profile | `airtable-mcp <tool> --profile work`                    |\n\nTool names use hyphens on the CLI (`list-records`) but underscores in MCP (`list_records`). The CLI translates automatically.\n\n## Workflow\n\n1. **Auth** — set `AIRTABLE_TOKEN` or run `airtable-mcp configure`\n2. **Discover** — run `airtable-mcp tools` to see available tools\n3. **Inspect** — run `airtable-mcp <tool> --help` for flags and descriptions\n4. **Check access** — in `tools --json` output, check the `access` field: `read-only`, `write`, or `destructive`. Confirm with the user before running `destructive` tools.\n5. **Execute** — run `airtable-mcp <tool> --flagName value`\n\n## Output & automation\n\n-   Default output is formatted JSON to stdout. Status messages go to stderr.\n-   `--json` on `tools` gives a JSON array of `{name, title, access}`.\n-   `-q` / `--quiet` suppresses stderr status messages (cache warnings, etc).\n-   `--output raw` returns the raw server response text instead of parsed JSON.\n-   `--input -` reads tool arguments as a JSON object from stdin, bypassing flag parsing.\n-   Exit codes: `0` success, `1` error (auth, tool failure, not found), `2` usage error (bad flags, bad input).\n\n## Common tasks\n\n**Find a base and list its tables:**\n\n```sh\nairtable-mcp search-bases --searchQuery \"Project Tracker\" -q\nairtable-mcp list-tables-for-base --baseId appEXAMPLEbase001 -q\n```\n\n**List records with specific fields:**\n\n```sh\nairtable-mcp list-records-for-table \\\n  --baseId appEXAMPLEbase001 --tableId tblEXAMPLEtable01 \\\n  --fieldIds '[\"Name\",\"Status\"]' --pageSize 10 -q\n```\n\n**Filter records** — filters use structured JSON, not formula strings. Wrap conditions in an `operands` array; the top-level `operator` defaults to `and` if omitted:\n\n```sh\nairtable-mcp list-records-for-table \\\n  --baseId appEXAMPLEbase001 --tableId tblEXAMPLEtable01 \\\n  --filters '{\"operator\":\"and\",\"operands\":[{\"operator\":\"=\",\"operands\":[\"Status\",\"Done\"]}]}' -q\n```\n\nFor select fields, filter by choice ID (from `get-table-schema`), not the display name. The `airtable-filters` skill covers compound filters, date filters, and operator-by-field-type details.\n\n**Search records** — use `search-records` for free-text/fuzzy queries on large tables. Use `list-records-for-table` with `--filters` when filtering by exact field values:\n\n```sh\nairtable-mcp search-records \\\n  --baseId appEXAMPLEbase001 --table tblEXAMPLEtable01 \\\n  --query \"acme\" --fields '[\"Name\",\"Notes\"]' -q\n```\n\nPass `--fields ALL_SEARCHABLE_FIELDS` to search across every indexed field. Date, rating, checkbox, and button fields are not searchable.\n\n**Update records** — complex args are easier via `--input -`:\n\n```sh\necho '{\"baseId\":\"appEXAMPLEbase001\",\"tableId\":\"tblEXAMPLEtable01\",\"records\":[{\"id\":\"recEXAMPLErecord1\",\"fields\":{\"fldEXAMPLEfield01\":\"Done\"}}]}' \\\n  | airtable-mcp update-records-for-table --input - -q\n```\n\nSelect field values are returned as objects (`{\"id\":\"sel...\",\"name\":\"Done\"}`) but must be written as plain strings (`\"Done\"`). Record field keys in create/update currently require field IDs (`fldEXAMPLEfield02`) — use `get-table-schema` to resolve names to IDs before writing. Note that `fieldIds`, `sort`, and `filters` accept both names and IDs.\n\n## Gotchas\n\n| Problem                                      | Cause                                                              | Fix                                                                      |\n| -------------------------------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------------ |\n| `Unknown tool: X`                            | Tool name doesn't exist on the server or cache is stale            | Run `airtable-mcp tools --refresh` to refresh, then retry                |\n| `Authentication failed`                      | Token expired, revoked, or wrong                                   | Run `airtable-mcp configure` or check `AIRTABLE_TOKEN`                   |\n| `Access denied`                              | Token missing required scopes                                      | Add scopes at https://airtable.com/create/tokens                         |\n| `Connection timed out`                       | Server unreachable (10s timeout)                                   | Check network; CLI falls back to stale cache if available                |\n| Boolean flags take no value                  | `--dryRun true` passes `\"true\"` as next arg                        | Use `--dryRun` alone (booleans are presence-based)                       |\n| Array/object args fail                       | Value isn't valid JSON                                             | Pass as JSON string: `--fieldMappings '{\"a\":\"b\"}'`                       |\n| Filter rejected at top level                 | Single condition passed without `operands` wrapper                 | Wrap in `{\"operands\":[...]}` (`operator` defaults to `and`)              |\n| Sort key is `fieldId` not `field`            | `--sort '[{\"field\":\"Name\"}]'` silently ignored                     | Use `{\"fieldId\":\"Name\",\"direction\":\"asc\"}` — accepts field IDs or names  |\n| Select filter returns no matches             | Filtering by display name instead of choice ID                     | Run `get-table-schema` first to get `sel...` choice IDs                  |\n| `INVALID_RECORDS` on batch write             | Batch limit is 10 records per request (default; varies by account) | Split into chunks of ≤10 and check `<tool> --help` for the current limit |\n| Permission error on `list-records-for-table` | User has interface-only access to the base                         | Use `list-records-for-page` / `get-record-for-page` instead              |\n| Endpoints restricted                         | CLI only allows HTTPS on `*.airtable.com`                          | Cannot point at arbitrary servers (security constraint)                  |\n","contentSource":"https://raw.githubusercontent.com/airtable/skills/main/plugins/airtable/skills/airtable-cli/SKILL.md","contentFetchedAt":"2026-07-27T09:02:29.314Z"},{"name":"airtable-filters","url":"https://skills.sh/airtable/skills/airtable-filters","install":"npx skills add airtable/skills --skill airtable-filters","sdk":"airtable","key":"airtable/airtable-filters","description":"Builds Airtable filters parameters for the MCP tools that list or display records — field-type-aware comparison operators, choice and collaborator IDs, date ranges, and nested AND/OR logic. Use when the user wants to find, filter, narrow down, or search Airtable records by field values, even when they don't explicitly say \"filter.","hasContent":true,"content":"---\nname: airtable-filters\ndescription: Builds Airtable filters parameters for the MCP tools that list or display records — field-type-aware comparison operators, choice and collaborator IDs, date ranges, and nested AND/OR logic. Use when the user wants to find, filter, narrow down, or search Airtable records by field values, even when they don't explicitly say \"filter.\"\nlicense: MIT\nmetadata:\n    version: '1.0.0'\n    author: airtable\n---\n\n# Airtable MCP Filters\n\nMCP tools that list or display records from tables or interface pages accept an optional `filters` parameter, using the same schema.\n\nWhen querying records from an interface page, these filters are combined with the page's built-in filters using AND.\n\n## Schema shape\n\nWhen no top-level `operator` is specified, conditions are combined with AND. The first element in a condition's `operands` array is always a **field ID** — look up the table's schema to find field IDs before filtering.\n\n## Field type categories\n\n-   **Text-like**: singleLineText, multilineText, email, url, phoneNumber, richText, barcode\n-   **Numeric**: number, percent, currency, rating, duration, autoNumber, count\n-   **Date**: date, dateTime, createdTime, lastModifiedTime\n-   **Single select**: singleSelect\n-   **Multiple selects**: multipleSelects\n-   **Single collaborator**: singleCollaborator\n-   **Multiple collaborators**: multipleCollaborators\n-   **Linked records**: multipleRecordLinks\n-   **Attachment**: multipleAttachments\n-   **Checkbox**: checkbox\n\nComputed fields (formula, rollup, lookup) support whichever operators match their result type.\n\n## Comparison operators\n\n| Operator                | Second operand                     | Field categories                                                                                                                   |\n| ----------------------- | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |\n| `=`                     | string, number, boolean, choice ID | text-like, numeric, date, checkbox, single select, multiple selects, single collaborator, multiple collaborators, linked records   |\n| `!=`                    | string, number, choice ID          | text-like, numeric, date, single select, single collaborator                                                                       |\n| `<`, `>`, `<=`, `>=`    | number or date value object        | numeric, date                                                                                                                      |\n| `contains`              | string                             | text-like, linked records                                                                                                          |\n| `doesNotContain`        | string                             | text-like, linked records                                                                                                          |\n| `doesNotContain`        | array of IDs                       | multiple selects, multiple collaborators                                                                                           |\n| `isEmpty`, `isNotEmpty` | _(none)_                           | text-like, numeric, date, single select, multiple selects, single collaborator, multiple collaborators, linked records, attachment |\n| `hasAnyOf`, `hasAllOf`  | array of IDs                       | multiple selects, multiple collaborators, linked records                                                                           |\n| `isAnyOf`               | array of IDs                       | single select, single collaborator                                                                                                 |\n| `isNoneOf`              | array of IDs                       | single select, single collaborator, linked records                                                                                 |\n| `isWithin`              | date range object                  | date                                                                                                                               |\n| `filename`, `fileType`  | string or `\"image\"`/`\"text\"`       | attachment                                                                                                                         |\n\nWhen matching a field against multiple values, prefer dedicated operators (`isAnyOf`, `isNoneOf`, `hasAnyOf`, `hasAllOf`) over combining multiple `=` conditions with `or`/`and`, when those operators are available for the field type.\n\n## Field-type rules\n\n### Select fields\n\nFor select fields, operand values must be **choice IDs** (e.g., `\"selEXAMPLEchoice1\"`), not display names. Look up the table's schema to find choice IDs before filtering.\n\n### Collaborator fields\n\nWhen filtering by a collaborator group ID, use `operatorOptions` to match individual members of the group instead of the literal group ID. See the tool's `operatorOptions` parameter for details.\n\nExample operand: `{\"operator\": \"hasAnyOf\", \"operands\": [\"fldEXAMPLEfield03\", \"ugpEXAMPLEgroup01\"], \"operatorOptions\": {\"matchGroupsByMembership\": true}}`\n\n### Attachment fields\n\nUse `fileType` to filter attachments by type (e.g., `\"image\"`, `\"text\"`) rather than `isNotEmpty` when the user specifies a file type.\n\n### Date fields\n\nDate comparisons (`=`, `!=`, `<`, `>`, `<=`, `>=`) use a date value object instead of a raw date string, and `isWithin` uses a date range object. The tool schema defines the available modes for each. Always include `timeZone`.\n\n## Composing conditions\n\nA filter's top-level operands array can contain two or more conditions, which are combined with the top-level operator (AND by default). For simple multi-condition filters, this flat structure is sufficient.\n\nWhen the logic requires mixing AND and OR, nest a filter object as one of the operands. Each nested filter has its own operator and operands.\n\n**OR inside AND** — useful when one condition is fixed and another allows multiple alternatives:\n\n> \"Scripted videos that are either in Writing or Pre-Production\"\n> → Bucket = Scripted AND (Status = Writing OR Status = Pre-Production)\n\n**AND inside OR** — useful when you want records matching either a simple condition or a combination:\n\n> \"Approved videos, or videos assigned to Bailey that are in Cut 2\"\n> → Status = Approved OR (Editor = Bailey AND Status = Cut 2 Ready)\n\nWhen combining many conditions on different fields, prefer a flat AND rather than unnecessary nesting. Only nest when the logic genuinely requires mixed AND/OR at different levels.\n\nPrefer composing all conditions into a single `filters` object rather than splitting them across multiple calls. A single call with a composed filter is more efficient and returns the correct result set directly.\n\n## Examples\n\nFilter where a text field equals \"orange\" OR a number field is greater than 5:\n\n```json\n{\n    \"operator\": \"or\",\n    \"operands\": [\n        {\"operator\": \"=\", \"operands\": [\"fldEXAMPLEfield01\", \"orange\"]},\n        {\"operator\": \">\", \"operands\": [\"fldEXAMPLEfield04\", 5]}\n    ]\n}\n```\n\nFilter for records where a date field is within the past week:\n\n```json\n{\n    \"operands\": [\n        {\n            \"operator\": \"isWithin\",\n            \"operands\": [\"fldEXAMPLEdate001\", {\"mode\": \"pastWeek\", \"timeZone\": \"America/New_York\"}]\n        }\n    ]\n}\n```\n","contentSource":"https://raw.githubusercontent.com/airtable/skills/main/plugins/airtable/skills/airtable-filters/SKILL.md","contentFetchedAt":"2026-07-27T09:02:29.639Z"}],"official":true,"generatedAt":"2026-07-27T09:02:29.956Z"}