SkillAgentSearch skills...

airtable-kit

A better ts/js airtable toolkit for the Airtable Web API

Install / Use

claude mcp add NickCrews -- npx -y github:NickCrews/airtable-kit

If the server publishes to npm under a different name, use that package instead — check the repo README.

About this skill
🔌

MCP Server

Model Context Protocol server

Quality Score

76/100

Supported Platforms

Claude Code
Claude Desktop

Our assessment of airtable-kit

airtable-kit scores 76/100 on our quality scale, 3703rd of 4,659 Development & Engineering skills we index.

Its MCP Server is 13 KB long, well organised into 15 sections with 10 code examples: a thorough specification that gives an agent plenty to work with.

It has 3 GitHub stars, so there is little community track record yet; judge it on its content.

Substance
30/30
Structure
20/20
Description
8/15
Adoption
3/20
Freshness
15/15

Maintenance, license and trust

  • The repository was last updated 23 days ago, so airtable-kit is actively maintained.
  • It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
  • Its trust signals score 87/100, with 2 cautions from licensing, adoption, age or documentation. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.

airtable-kit compared with similar skills

All 4 of these similar skills score higher than airtable-kit; compare them before choosing.

SkillScoreStarsUpdatedFormat
airtable-kit (this skill)by NickCrews76323d agoMCP Server
Agent-Reachby Panniantong100106.4k5d agoCLAUDE.md
taste-skillby Leonxlnx100105.7ktodayCLAUDE.md
headroomby headroomlabs-ai10078.3ktodayCLAUDE.md
ai-job-searchby ai-job-search-dev10067.6k2d agoCLAUDE.md

Frequently asked questions

How do I install airtable-kit?
Run claude mcp add NickCrews -- npx -y github:NickCrews/airtable-kit. The install tabs above show the steps for each supported agent.
Which AI agents does airtable-kit work with?
It is written for Claude Code and Claude Desktop, as a MCP Server file. Other agents that read the same format can often use it too.
Is airtable-kit safe to use?
It is MIT-licensed and scores 87/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
Is airtable-kit still maintained?
The repository was last updated 23 days ago, so airtable-kit is actively maintained.

airtable-kit

A type-safe, fully-featured, and standards-centric Airtable API client for TypeScript and JavaScript. Plus a CLI!

Status: Beta. The basic shape of most functions is fairly stable. But I will still make breaking changes, you should pin your version.

Motivation

There are other type-safe airtable clients out there (see the Comparison section), but they all start from the premise of starting from typescript interfaces to define the shape of records in each table. This package takes a different approach: everything is derived directly from the Airtable Base's JSON schema, as directly provided by the Airtable API. We then provide some typescript generic magic so that we infer that e.g. a singleSelect field with options "To Do", "In Progress", and "Done" maps to the union type "To Do" | "In Progress" | "Done" in typescript.

This has several advantages:

  • It is trivial to codegen the schema files from existing bases since you pretty much write the JSON directly to a file, instead of needing to translate it to typescript interfaces. This makes it easy to create/update base schemas.
  • You get runtime validation and JSONschema (eg for API docs/MCP servers/etc) for free. Most of these other libraries assume you know at compile time which bases you are working with. This package allows you to fetch a base's schema just-in-time at runtime, and still have type-mapping and runtime validation.
  • Since we preserve the full JSON schema, you can inspect and manipulate the base's schema at runtime, eg generate a Zod validator. This is useful for e.g. building MCP tools for AI agents, since now they can see the exact schema of the base they are working with.

Other Features

  • Rename-Resistant: When someone modifies the name of a field in airtable, your code won't break because the client always sends field IDs to the API under the hood.
  • Complete Type-Safety: Not just the basics. Eg get type safety on the valid options for single-select and multi-select fields, date formats, etc.
  • More-sane read behavior: The raw API (and vanilla airtable.js) don't include "falsy" values when reading records. We fill in those missing values with sane defaults, eg the empty string for text-like fields, empty arrays for multi-value fields, or an explicit null for eg number and date fields.
  • Typesafe Formula Builder: Build Airtable formulas programmatically with full type-safety and autocompletion, eg formulaToString(tableSchema, ["<=", { field: "Due Date" }, ["DATEADD", ["TODAY"], 7, "days"]]) yields {fld123xyz} <= DATEADD(TODAY(), 7, "days").
  • Both Functional and OOP APIs: Use either the functional API that is a 1:1 mapping to the Airtable REST API, or the OOP-style client with methods like base.tables.myTable.create(records).
  • Zero-Dependencies: No required dependencies! zod is optional if you want runtime validation (eg for MCP tools).
  • Portable: Works in Node.js, Deno, and the browser, including in sandboxed environments, e.g. where process.env and os.homedir() are not available.
  • Runtime Validation: Optionally, dynamically generate Zod validators from the schema to validate all data sent to Airtable at runtime.
  • MCP Tools: Ready-to-use MCP tools for LLM integration.

CLI Usage

We ship a CLI in the style of gh, for performing verbs such as list, get, create, and update on each of the airtable nouns of base, table, field, and record.

Try it with no installation by npx airtable-kit --help, which gives:

Usage: airtable-kit [options] [command]

A better TypeScript Airtable toolkit

Options:
  --version          output the version number
  --api-key <key>    Airtable API key
  -h, --help         display help for command

Commands:
  base               Manage Airtable bases
  table              Manage Airtable tables
  field              Manage Airtable fields
  record             Manage Airtable records
  openapi [options]  Generate an OpenAPI 3 spec for a base.
  codegen [options]  Generate ts/js schema files for all bases. Shortcut for running "base codegen <baseId>" command with all bases sequentially.

Generate an OpenAPI spec

Generate an OpenAPI 3 document describing the Airtable REST API for one of your bases (record CRUD, comments, attachments, webhooks, and base/table metadata):

AIRTABLE_API_KEY=... npx airtable-kit openapi <baseId>   # prints JSON to stdout
npx airtable-kit openapi <baseId> --out airtable.json    # or write to a file

Or programmatically, for full control over which surfaces are included:

import { baseToOpenApi } from 'airtable-kit/openapi';
import { getBaseSchema } from 'airtable-kit/bases';

const base = await getBaseSchema({ baseId: 'appXXXXXXXXXXXXXX' });
const spec = baseToOpenApi(base, {
  title: 'My API',
  include: { records: true, webhooks: false }, // every surface defaults to true
});
console.log(JSON.stringify(spec, null, 2));

Installation

This is available on npm:

pnpm add airtable-kit

Quick Start

Use Case 1: Statically Typed Client for a Known Base

Option A: Use the Web App (No Installation Required)

Visit https://nickcrews.github.io/airtable-kit/ to generate schema files directly in your browser. Just enter your API key, select a base, and copy/download the generated code.

Option B: Use the CLI

Run the codegen CLI to fetch and save all your base schemas to local files:

npx airtable-kit codegen all --api-key YOUR_API_KEY

This will fetch all the bases that the API key has access for, and create files under ./schemas/, one per base. (If you instead wanted to just generate a single base schema, see npx airtable-kit codegen base --help.) Here is an example generated schema file for a base called Project Tracker, saved as schemas/projectTracker.ts:

export default {
  "id": "appXXXXXXXXXXXXXX",
  "name": "projectTracker",
  "tables": [
    {
      "id": "tblXXXXXXXXXXXXXX",
      "name": "tasks",
      "primaryFieldId": "fldXXXXXXXXXXXXXX",
      "fields": [
        {
          "id": "fldXXXXXXXXXXXXXX",
          "name": "name",
          "type": "singleLineText",
        },
        {
          "id": "fldYYYYYYYYYYYYYY",
          "name": "status",
          "type": "singleSelect",
          "options": {
            "choices": [
              { "id": "selAAAAAAAAAAAAAA", "name": "To Do", "color": "red" },
              { "id": "selBBBBBBBBBBBBBB", "name": "In Progress", "color": "blue" },
              { "id": "selCCCCCCCCCCCCCC", "name": "Done", "color": "green" }
            ]
          }
        },
        {
          "id": "fldZZZZZZZZZZZZZZ",
          "name": "dueDate",
          "type": "date",
          "options": {
            "dateFormat": "iso",
            "timeFormat": "24hour",
            "timeZone": "client"
          }
        },
      ]
    }
  ]
} as const;

Note how this is almost a direct 1:1 correspondence with the raw JSON from the GET https://api.airtable.com/v0/meta/bases/{baseId}/tables endpoint. There are a few minor differences, such as table and field names are converted to camelCase for easier consumption in javascript/TypeScript, and we add the top-level id: "appXXXXXXXXXXXXXX" and name: "projectTracker" fields, which aren't present in the raw JSON.

If you dropped the as const you would have a plain javascript file if you are working with javascript. You can get the CLI to do this with the --format js flag.

Now, use the generated schema to create a type-safe Airtable client:

import { makeBaseClient } from 'airtable-kit/bases';
import projectTrackerSchema from './schemas/projectTracker.ts';

const client = makeBaseClient({
  baseSchema: projectTrackerSchema,
  fetcher: 'YOUR_API_KEY',
});
// if you tried `client.tables.nonExistentTable` you would get a type error here
client.tables.tasks.createRecords([
  {
    // You can use either the field IDs or names as keys
    fldXXXXXXXXXXXXXX: "Finish report",
    status: "In Progress",
    // This would give a type error because its not a valid select option
    // status: "in progress",
    // You can either provide a Date object or an ISO string
    dueDate: new Date("2024-12-31"), // or "2024-12-31" works too
    // This would give a type error because 42 is not a valid date
    // dueDate: 42
    // This would give a type error because dueBy is not a field
    // dueBy: "2024-12-31"
  },
]);
const tasks = await client.tables.tasks.listRecords({
  // You can build formulas programmatically with type-safety
  // All tasks due in the next 7 days that are not done.
  // This is compiled to the string:
  // AND(
  //   {fldZZZZZZZZZZZZZZ} >= TODAY(),
  //   {fldZZZZZZZZZZZZZZ} <= DATEADD(TODAY(), 7, "days"),
  //   OR(
  //     {fldYYYYYYYYYYYYYY} = "To Do",
  //     {fldYYYYYYYYYYYYYY} = "In Progress"
  //   )
  // )
  filterByFormula: [
    "AND",
    [">=", { field: "dueDate" }, ["TODAY"]],
    ["<=", { field: "dueDate" }, ["DATEADD", ["TODAY"], 7, "days"]],
    ["OR",
      ["=", { field: "status" }, "To Do"],
      ["=", { field: "status" }, "In Progress"],
    ],
  ],
});
console.log(tasks);

This also supports multi-base clients!

import { makeOrgClient } from 'airtable-kit/bases';
import projectTrackerSchema from './schemas/projectTracker.ts';
import otherBase from './schemas/otherBase.ts';

const client = makeOrgClient({
  bases: [projectTrackerSchema, otherBase],
  fetcher: 'YOUR_API_KEY',
});
client.bases.otherBase.tables.someTable.createRecords([ ... ]);
// `client.bases.<base name>` is an instance of BaseClient, like above.
// `client.bases.nonExistentBase` would be a type error

Use Case 2: Dynamic Client for Unknown Bases, eg an MCP Tool

import { getBaseSchema, makeBaseClient } from 'airtable-kit/bases';
import { makeListTool } from 'airtable-kit/mcp';

const fetcher = 'YOUR_API_KEY';
const baseSchema = await getBaseSchema({ baseId: 'appXXXXXXXXXXXXXX', fetcher });
const client = makeBaseClient({ baseSchema, fetcher });
const listTool = makeListTool(client);

// Now you can pass this off to an AI agent framework, eg Vercel's AI SDK (https://github.com/vercel/ai)
import { tool, ToolLoopAgent } from 'ai'
const agent = new ToolLoopAgent({
  model: 'openai/gpt-5-codex',
  system: 'Help the user find info in their Airtable base.',
  tools: {
    listRecords: tool({
      description: listTool.description,
      inputSchema: listTool.zodInputValidator,
      execute: listTool.execute,
    })
  },
});

Use Case 3: Use the functional API for simple uses

import { createField } from 'airtable-kit/fields';
import { updateRecords } from 'airtable-kit/records';

createField(
  {
    baseId: 'appZZZZZZZZZZZ',
    tableId: 'tblAAAAAAAAAAAAAA',
    field: {
      name: 'newField',
      type: 'singleLineText',
    },
    fetcher: 'YOUR_API_KEY',
  }
)

updateRecords(
  {
    records: [
      {id: 'recXXXXXXXXXXXX', fields: { 'fldYYYYYYYYYYYYYY': 47 } },
    ],
    baseId: 'appZZZZZZZZZZZ',
    tableId: 'tblAAAAAAAAAAAAAA',
    fetcher: 'YOUR_API_KEY',
    // TODO: This is currently required to do value conversion when reading
    // and writing to the API, but ideally this would be optional, in which
    // case we would just pass through values as-is.
    // See the "more sane read behavior" feature above.
    fields: [{
      id: 'fldYYYYYYYYYYYYYY',
      name: 'priority',
      type: 'number',
    }]
  }
)

Comparison to Other Airtable Libraries

airtable-ts

I was using this before building this library, and it is a great library.

  • Also type-safe
  • Deri

Truncated for display — read the full file on GitHub.

Related Skills

View on GitHub
GitHub Stars3
CategoryDevelopment
Updated23d ago
Forks0

Languages

TypeScript

Trust signals

87/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

2 low