#
tokens: 41242/50000 13/15 files (page 1/3)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 1 of 3. Use http://codebase.md/felores/airtable-mcp?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .gitignore
├── .npmignore
├── docs
│   ├── Airtable API Documentation.md
│   ├── Airtable API field types and cell values.md
│   ├── Airtable_MCP_server_guide_for_LLMs.md
│   ├── mcp-llm-guide.md
│   └── MCP-llms-full.md
├── LICENSE
├── package-lock.json
├── package.json
├── prompts
│   ├── project-knowledge.md
│   └── system-prompt.md
├── README.md
├── scripts
│   └── post-build.js
├── src
│   ├── index.ts
│   └── types.ts
└── tsconfig.json
```

# Files

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
1 | node_modules/
2 | build/
3 | .env
4 | *.log
5 | 
```

--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------

```
 1 | # Source
 2 | src/
 3 | 
 4 | # Development files
 5 | .git/
 6 | .github/
 7 | .gitignore
 8 | .vscode/
 9 | .idea/
10 | *.log
11 | 
12 | # Test files
13 | test/
14 | __tests__/
15 | *.test.ts
16 | *.spec.ts
17 | 
18 | # Configuration files
19 | tsconfig.json
20 | .eslintrc*
21 | .prettierrc*
22 | 
23 | # Documentation
24 | docs/
25 | *.md
26 | !README.md
27 | 
28 | # Build artifacts
29 | *.tsbuildinfo 
```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Airtable MCP Server
  2 | 
  3 | A Model Context Protocol server that provides tools for interacting with Airtable's API. This server enables programmatic management of Airtable bases, tables, fields, and records through Claude Desktop or other MCP clients.
  4 | 
  5 | This MCP server features a specialized implementation that allows it to build tables in stages, leveraging Claude's agentic capabilities and minimizing the failure rate typically seen in other MCP servers for Airtable when building complex tables. It also includes [system prompt](https://github.com/felores/airtable-mcp/blob/main/prompts/system-prompt.md) and [project knowledge](https://github.com/felores/airtable-mcp/blob/main/prompts/project-knowledge.md) markdown files to provide additional guidance for the LLM when leveraging projects in Claude Desktop.
  6 | 
  7 | ## Requirements: Node.js
  8 | 
  9 | 1. Install Node.js (version 18 or higher) and npm from [nodejs.org](https://nodejs.org/)
 10 | 2. Verify installation:
 11 |    ```bash
 12 |    node --version
 13 |    npm --version
 14 |    ```
 15 | 
 16 | ⚠️ **Important**: Before running, make sure to setup your Airtable API key
 17 | 
 18 | ## Obtaining an Airtable API Key
 19 | 
 20 | 1. Log in to your Airtable account at [airtable.com](https://airtable.com)
 21 | 2. Create a personal access token at [Airtable's Builder Hub](https://airtable.com/create/tokens)
 22 | 3. In the Personal access token section select these scopes: 
 23 |      - data.records:read
 24 |      - data.records:write
 25 |      - schema.bases:read
 26 |      - schema.bases:write
 27 | 4. Select the workspace or bases you want to give access to the personal access token
 28 | 5. Keep this key secure - you'll need it for configuration
 29 | 
 30 | ## Installation
 31 | 
 32 | ### Method 1: Using npx (Recommended)
 33 | 1. Navigate to the Claude configuration directory:
 34 | 
 35 |    - Windows: `C:\Users\NAME\AppData\Roaming\Claude`
 36 |    - macOS: `~/Library/Application Support/Claude/`
 37 |    
 38 |    You can also find these directories inside the Claude Desktop app: Claude Desktop > Settings > Developer > Edit Config
 39 | 
 40 | 2. Create or edit `claude_desktop_config.json`:
 41 | ```json
 42 | {
 43 |   "mcpServers": {
 44 |     "airtable": {
 45 |       "command": "npx",
 46 |       "args": ["@felores/airtable-mcp-server"],
 47 |       "env": {
 48 |         "AIRTABLE_API_KEY": "your_api_key_here"
 49 |       }
 50 |     }
 51 |   }
 52 | }
 53 | ```
 54 | Note: For Windows paths, use double backslashes (\\) or forward slashes (/).
 55 | 
 56 | ### Method 2: Using mcp-installer:
 57 | mcp-installer is a MCP server to install other MCP servers.
 58 | 1. Install [mcp-installer](https://github.com/anaisbetts/mcp-installer)
 59 | 2. Install the Airtable MCP server by prompting Claude Desktop:
 60 | ```bash
 61 | Install @felores/airtable-mcp-server set the environment variable AIRTABLE_API_KEY to 'your_api_key'
 62 | ```
 63 | Claude will install the server, modify the configuration file and set the environment variable AIRTABLE_API_KEY to your Airtable API key.
 64 | 
 65 | ### Method 3: Local Development Installation
 66 | If you want to contribute or modify the code run this in your terminal:
 67 | ```bash
 68 | # Clone the repository
 69 | git clone https://github.com/felores/airtable-mcp.git
 70 | cd airtable-mcp
 71 | 
 72 | # Install dependencies
 73 | npm install
 74 | 
 75 | # Build the server
 76 | npm run build
 77 | 
 78 | # Run locally
 79 | node build/index.js
 80 | ```
 81 | Then modify the Claude Desktop configuration file to use the local installation:
 82 | ```json
 83 | {
 84 |   "mcpServers": {
 85 |     "airtable": {
 86 |       "command": "node",
 87 |       "args": ["path/to/airtable-mcp/build/index.js"],
 88 |       "env": {
 89 |         "AIRTABLE_API_KEY": "your_api_key_here"
 90 |       }
 91 |     }
 92 |   }
 93 | }
 94 | ```
 95 | 
 96 | ### Verifying Installation
 97 | 
 98 | 1. Start Claude Desktop
 99 | 2. The Airtable MCP server should be listed in the "Connected MCP Servers" section
100 | 3. Test with a simple command:
101 | ```
102 | List all bases
103 | ```
104 | 
105 | ## Features
106 | 
107 | ### Available Operations
108 | 
109 | #### Base Management
110 | - `list_bases`: List all accessible Airtable bases
111 | - `list_tables`: List all tables in a base
112 | - `create_table`: Create a new table with fields
113 | - `update_table`: Update a table's name or description
114 | 
115 | #### Field Management
116 | - `create_field`: Add a new field to a table
117 | - `update_field`: Modify an existing field
118 | 
119 | #### Record Operations
120 | - `list_records`: Retrieve records from a table
121 | - `create_record`: Add a new record
122 | - `update_record`: Modify an existing record
123 | - `delete_record`: Remove a record
124 | - `search_records`: Find records matching criteria
125 | - `get_record`: Get a single record by its ID
126 | 
127 | ### Field Types
128 | - `singleLineText`: Single line text field
129 | - `multilineText`: Multi-line text area
130 | - `email`: Email address field
131 | - `phoneNumber`: Phone number field
132 | - `number`: Numeric field with optional precision
133 | - `currency`: Money field with currency symbol
134 | - `date`: Date field with format options
135 | - `singleSelect`: Single choice from options
136 | - `multiSelect`: Multiple choices from options
137 | 
138 | ### Field Colors
139 | Available colors for select fields:
140 | - `blueBright`, `redBright`, `greenBright`
141 | - `yellowBright`, `purpleBright`, `pinkBright`
142 | - `grayBright`, `cyanBright`, `orangeBright`
143 | - `blueDark1`, `greenDark1`
144 | 
145 | ## Contributing
146 | 
147 | We welcome contributions to improve the Airtable MCP server! Here's how you can contribute:
148 | 
149 | 1. Fork the Repository
150 |    - Visit https://github.com/felores/airtable-mcp
151 |    - Click the "Fork" button in the top right
152 |    - Clone your fork locally:
153 |      ```bash
154 |      git clone https://github.com/your-username/airtable-mcp.git
155 |      ```
156 | 
157 | 2. Create a Feature Branch
158 |    ```bash
159 |    git checkout -b feature/your-feature-name
160 |    ```
161 | 
162 | 3. Make Your Changes
163 |    - Follow the existing code style
164 |    - Add tests if applicable
165 |    - Update documentation as needed
166 | 
167 | 4. Commit Your Changes
168 |    ```bash
169 |    git add .
170 |    git commit -m "feat: add your feature description"
171 |    ```
172 | 
173 | 5. Push to Your Fork
174 |    ```bash
175 |    git push origin feature/your-feature-name
176 |    ```
177 | 
178 | 6. Create a Pull Request
179 |    - Go to your fork on GitHub
180 |    - Click "New Pull Request"
181 |    - Select your feature branch
182 |    - Describe your changes in detail
183 | 
184 | ### Development Guidelines
185 | 
186 | - Use TypeScript for new code
187 | - Follow semantic commit messages
188 | - Update documentation for new features
189 | - Add examples for new functionality
190 | - Test your changes thoroughly
191 | 
192 | ### Getting Help
193 | 
194 | - Open an issue for bugs or feature requests
195 | - Join discussions in existing issues
196 | - Ask questions in pull requests
197 | 
198 | Your contributions help make this tool better for everyone. Whether it's:
199 | - Adding new features
200 | - Fixing bugs
201 | - Improving documentation
202 | - Suggesting enhancements
203 | 
204 | We appreciate your help in making the Airtable MCP server more powerful and user-friendly!
205 | 
206 | ## License
207 | 
208 | [MIT](LICENSE)
209 | 
210 | ---
211 | 
212 | Made with ❤️ by the Airtable MCP community
213 | 
```

--------------------------------------------------------------------------------
/scripts/post-build.js:
--------------------------------------------------------------------------------

```javascript
1 | import { chmod } from 'fs/promises';
2 | import { platform } from 'os';
3 | 
4 | if (platform() !== 'win32') {
5 |   await chmod('build/index.js', '755');
6 | } 
```

--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "compilerOptions": {
 3 |     "target": "ES2022",
 4 |     "module": "Node16",
 5 |     "moduleResolution": "Node16",
 6 |     "outDir": "./build",
 7 |     "rootDir": "./src",
 8 |     "strict": true,
 9 |     "esModuleInterop": true,
10 |     "skipLibCheck": true,
11 |     "forceConsistentCasingInFileNames": true
12 |   },
13 |   "include": ["src/**/*"],
14 |   "exclude": ["node_modules"]
15 | }
16 | 
```

--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "@felores/airtable-mcp-server",
 3 |   "version": "0.3.0",
 4 |   "description": "An Airtable Model Context Protocol Server",
 5 |   "type": "module",
 6 |   "bin": {
 7 |     "airtable-server": "build/index.js"
 8 |   },
 9 |   "files": [
10 |     "build",
11 |     "scripts"
12 |   ],
13 |   "scripts": {
14 |     "build": "tsc && node scripts/post-build.js",
15 |     "prepare": "npm run build",
16 |     "watch": "tsc --watch",
17 |     "inspector": "npx @modelcontextprotocol/inspector build/index.js"
18 |   },
19 |   "dependencies": {
20 |     "@modelcontextprotocol/sdk": "0.6.0",
21 |     "axios": "^1.7.9"
22 |   },
23 |   "devDependencies": {
24 |     "@types/node": "^20.11.24",
25 |     "typescript": "^5.3.3"
26 |   },
27 |   "author": "Felipe Restrepo",
28 |   "license": "MIT",
29 |   "repository": {
30 |     "type": "git",
31 |     "url": "https://github.com/felores/airtable-mcp"
32 |   },
33 |   "keywords": [
34 |     "airtable",
35 |     "mcp",
36 |     "model-context-protocol",
37 |     "claude",
38 |     "api"
39 |   ],
40 |   "engines": {
41 |     "node": ">=16.0.0"
42 |   }
43 | }
44 | 
```

--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------

```typescript
 1 | // Field type definitions for Airtable
 2 | 
 3 | export type FieldType =
 4 |   | 'singleLineText'
 5 |   | 'multilineText'
 6 |   | 'number'
 7 |   | 'singleSelect'
 8 |   | 'multiSelect'
 9 |   | 'date'
10 |   | 'checkbox'
11 |   | 'email'
12 |   | 'phoneNumber'
13 |   | 'currency';
14 | 
15 | export interface FieldOption {
16 |   name: string;
17 |   type: FieldType;
18 |   description?: string;
19 |   options?: Record<string, any>;
20 | }
21 | 
22 | export const fieldRequiresOptions = (type: FieldType): boolean => {
23 |   switch (type) {
24 |     case 'number':
25 |     case 'singleSelect':
26 |     case 'multiSelect':
27 |     case 'date':
28 |     case 'currency':
29 |       return true;
30 |     default:
31 |       return false;
32 |   }
33 | };
34 | 
35 | export const getDefaultOptions = (type: FieldType): Record<string, any> | undefined => {
36 |   switch (type) {
37 |     case 'number':
38 |       return { precision: 0 };
39 |     case 'date':
40 |       return { dateFormat: { name: 'local' } };
41 |     case 'currency':
42 |       return { precision: 2, symbol: '$' };
43 |     default:
44 |       return undefined;
45 |   }
46 | };
47 | 
```

--------------------------------------------------------------------------------
/prompts/system-prompt.md:
--------------------------------------------------------------------------------

```markdown
  1 | You are an AI assistant specialized in creating and managing Airtable tables through the Model Context Protocol (MCP). Follow these guidelines when handling table creation requests:
  2 | 
  3 | ## Core Principles
  4 | 
  5 | 1. **Incremental Creation**
  6 |    - Always create tables in stages, starting with basic fields
  7 |    - Add one complex field at a time
  8 |    - Verify each operation before proceeding
  9 |    - Handle errors gracefully and provide clear feedback
 10 | 
 11 | 2. **Field Type Categories**
 12 | 
 13 |    Basic Fields (No Options Required):
 14 |    - `singleLineText`: Single line of text
 15 |    - `multilineText`: Multiple lines of text
 16 |    - `email`: Valid email address
 17 |    - `phoneNumber`: Phone number in any format
 18 |    - `richText`: Text with formatting
 19 |    - `url`: Valid URL
 20 | 
 21 |    Complex Fields (Require Options):
 22 |    - `number`: Requires precision (0-8)
 23 |    - `currency`: Requires precision and symbol
 24 |    - `percent`: Requires precision (0-8)
 25 |    - `rating`: Requires max value (1-10) and icon/color
 26 |    - `duration`: Requires format
 27 |    - `date`: Requires dateFormat
 28 |    - `dateTime`: Requires dateFormat and timeFormat
 29 |    - `singleSelect`: Requires choices with names and colors
 30 |    - `multipleSelects`: Requires choices with names and colors
 31 |    - `checkbox`: Optional icon and color
 32 |    - `barcode`: Supports various formats
 33 |    - `button`: Configurable actions
 34 |    - `count`: Automatic counter
 35 |    - `autoNumber`: Automatic unique counter
 36 |    - `formula`: Computed values
 37 |    - `rollup`: Aggregated values from linked records
 38 |    - `lookup`: Values from linked records
 39 |    - `multipleRecordLinks`: Links to other records
 40 |    - `attachment`: File attachments
 41 | 
 42 | 3. **Creation Order**
 43 |    1. Create table with basic text fields
 44 |    2. Add numeric fields (number, currency, percent)
 45 |    3. Add date/time fields
 46 |    4. Add select/choice fields
 47 |    5. Add computed fields (formula, rollup, lookup)
 48 |    6. Add relationship fields (record links)
 49 |    7. Verify each field after creation
 50 | 
 51 | ## Field Configuration Reference
 52 | 
 53 | 1. **Number Fields**
 54 | ```json
 55 | {
 56 |   "type": "number",
 57 |   "options": {
 58 |     "precision": 0  // 0 for integers, 1-8 for decimals
 59 |   }
 60 | }
 61 | ```
 62 | 
 63 | 2. **Currency Fields**
 64 | ```json
 65 | {
 66 |   "type": "currency",
 67 |   "options": {
 68 |     "precision": 2,
 69 |     "symbol": "$"  // Currency symbol
 70 |   }
 71 | }
 72 | ```
 73 | 
 74 | 3. **Date Fields**
 75 | ```json
 76 | {
 77 |   "type": "date",
 78 |   "options": {
 79 |     "dateFormat": {
 80 |       "name": "local"  // Options: local, friendly, us, european, iso
 81 |     }
 82 |   }
 83 | }
 84 | ```
 85 | 
 86 | 4. **DateTime Fields**
 87 | ```json
 88 | {
 89 |   "type": "dateTime",
 90 |   "options": {
 91 |     "dateFormat": {
 92 |       "name": "local"  // Options: local, friendly, us, european, iso
 93 |     },
 94 |     "timeFormat": {
 95 |       "name": "12hour"  // Options: 12hour, 24hour
 96 |     }
 97 |   }
 98 | }
 99 | ```
100 | 
101 | 5. **Select Fields**
102 | ```json
103 | {
104 |   "type": "singleSelect",
105 |   "options": {
106 |     "choices": [
107 |       {
108 |         "name": "Option Name",
109 |         "color": "colorName"  // Colors: blueBright, greenBright, redBright, yellowBright, pinkBright, purpleBright, cyanBright, grayBright
110 |       }
111 |     ]
112 |   }
113 | }
114 | ```
115 | 
116 | 6. **Rating Fields**
117 | ```json
118 | {
119 |   "type": "rating",
120 |   "options": {
121 |     "max": 5,  // 1-10
122 |     "color": "yellowBright",  // Standard color options
123 |     "icon": "star"  // Options: star, heart, thumbsUp, flag, dot
124 |   }
125 | }
126 | ```
127 | 
128 | ## Implementation Steps
129 | 
130 | 1. **Create Table with Basic Fields**
131 | ```json
132 | {
133 |   "name": "create_table",
134 |   "arguments": {
135 |     "base_id": "your_base_id",
136 |     "table_name": "Your Table Name",
137 |     "description": "Table description",
138 |     "fields": [
139 |       {
140 |         "name": "Title",
141 |         "type": "singleLineText",
142 |         "description": "Title field"
143 |       },
144 |       {
145 |         "name": "Notes",
146 |         "type": "multilineText",
147 |         "description": "Notes field"
148 |       }
149 |     ]
150 |   }
151 | }
152 | ```
153 | 
154 | 2. **Add Complex Fields (One at a Time)**
155 | ```json
156 | {
157 |   "name": "create_field",
158 |   "arguments": {
159 |     "base_id": "your_base_id",
160 |     "table_id": "your_table_id",
161 |     "field": {
162 |       "name": "Field Name",
163 |       "type": "field_type",
164 |       "description": "Field description",
165 |       "options": {
166 |         // Field-specific options here
167 |       }
168 |     }
169 |   }
170 | }
171 | ```
172 | 
173 | ## Error Handling & Best Practices
174 | 
175 | 1. **Validation**
176 |    - Verify each field after creation
177 |    - Test with sample data
178 |    - Check field options are correctly applied
179 |    - Validate field names and descriptions
180 |    - Ensure required options are provided
181 |    - Verify field type compatibility
182 | 
183 | 2. **Error Recovery**
184 |    - If field creation fails, do not proceed to next field
185 |    - Verify field options match specifications exactly
186 |    - Retry failed field creation with corrected options
187 |    - Log errors for debugging
188 |    - Provide clear error messages
189 | 
190 | 3. **Testing**
191 |    - Create test records after adding fields
192 |    - Update records to verify field behavior
193 |    - Test field constraints and validations
194 |    - Verify computed fields
195 |    - Test relationships between tables
196 | 
197 | 4. **Security**
198 |    - Validate all inputs
199 |    - Sanitize field names and descriptions
200 |    - Use appropriate field types for sensitive data
201 |    - Implement proper access controls
202 |    - Follow rate limiting guidelines
203 | 
204 | ## Response Format
205 | 
206 | When responding to table creation requests:
207 | 
208 | 1. Acknowledge the request and outline the plan
209 | 2. Create the table with basic fields first
210 | 3. Add complex fields one at a time
211 | 4. Verify each step
212 | 5. Report success or handle errors
213 | 6. Provide guidance for next steps
214 | 
215 | Example response format:
216 | ```
217 | I'll help you create the [table_name] table with the following steps:
218 | 
219 | 1. Create table with basic fields:
220 |    - [field1]: [type]
221 |    - [field2]: [type]
222 | 
223 | 2. Add complex fields:
224 |    - [field3]: [type] with [options]
225 |    - [field4]: [type] with [options]
226 | 
227 | I'll proceed with each step and verify completion before moving to the next one.
228 | ```
229 | 
230 | Remember to:
231 | - Be explicit about each action
232 | - Verify each step
233 | - Handle errors gracefully
234 | - Provide clear feedback
235 | - Guide the user through the process 
```

--------------------------------------------------------------------------------
/docs/mcp-llm-guide.md:
--------------------------------------------------------------------------------

```markdown
  1 | # MCP Development Guide for LLMs
  2 | 
  3 | This guide provides structured information for LLMs to assist in creating, modifying, and using Model Context Protocol (MCP) servers.
  4 | 
  5 | ## 1. Core Concepts
  6 | 
  7 | ### Protocol Overview
  8 | - MCP enables standardized communication between LLM applications and integrations
  9 | - Uses client-server architecture with JSON-RPC 2.0 message format
 10 | - Latest protocol version: 2024-11-05
 11 | - Supports stdio and SSE transports
 12 | 
 13 | ### Key Components
 14 | 1. **Hosts**: LLM applications that initiate connections (e.g., Claude Desktop)
 15 | 2. **Clients**: Maintain 1:1 connections with servers
 16 | 3. **Servers**: Provide context, tools, and prompts to clients
 17 | 4. **Resources**: File-like data that can be read by clients
 18 | 5. **Tools**: Functions that can be called by the LLM
 19 | 6. **Prompts**: Pre-written templates for specific tasks
 20 | 
 21 | ## 2. Server Implementation Guidelines
 22 | 
 23 | ### Server Structure
 24 | 1. Core Server Class:
 25 | ```typescript
 26 | class Server extends Protocol<ServerRequest, ServerNotification, ServerResult> {
 27 |     constructor(serverInfo: Implementation, options: ServerOptions)
 28 |     // Must implement base protocol methods
 29 | }
 30 | ```
 31 | 
 32 | 2. Required Capabilities:
 33 | ```typescript
 34 | interface ServerCapabilities {
 35 |     experimental?: object;
 36 |     logging?: object;
 37 |     prompts?: { listChanged?: boolean };
 38 |     resources?: { 
 39 |         subscribe?: boolean;
 40 |         listChanged?: boolean 
 41 |     };
 42 |     tools?: { listChanged?: boolean };
 43 | }
 44 | ```
 45 | 
 46 | ### Essential Implementation Steps
 47 | 
 48 | 1. **Server Initialization**:
 49 | ```typescript
 50 | const server = new Server(
 51 |     {
 52 |         name: "your-server-name",
 53 |         version: "1.0.0"
 54 |     },
 55 |     {
 56 |         capabilities: {
 57 |             // Declare supported capabilities
 58 |             resources: {},
 59 |             tools: {},
 60 |             prompts: {}
 61 |         }
 62 |     }
 63 | );
 64 | ```
 65 | 
 66 | 2. **Request Handlers**:
 67 | ```typescript
 68 | // Example tool handler
 69 | server.setRequestHandler(ListToolsRequestSchema, async () => ({
 70 |     tools: [
 71 |         {
 72 |             name: "tool-name",
 73 |             description: "Tool description",
 74 |             inputSchema: {
 75 |                 type: "object",
 76 |                 properties: {
 77 |                     // Define parameters
 78 |                 }
 79 |             }
 80 |         }
 81 |     ]
 82 | }));
 83 | ```
 84 | 
 85 | 3. **Transport Setup**:
 86 | ```typescript
 87 | const transport = new StdioServerTransport();
 88 | await server.connect(transport);
 89 | ```
 90 | 
 91 | ## 3. Core Features Implementation
 92 | 
 93 | ### Resources
 94 | ```typescript
 95 | interface Resource {
 96 |     uri: string;
 97 |     name: string;
 98 |     description?: string;
 99 |     mimeType?: string;
100 | }
101 | 
102 | // Handler example
103 | server.setRequestHandler(ListResourcesRequestSchema, async () => ({
104 |     resources: [
105 |         {
106 |             uri: "custom://resource",
107 |             name: "Resource Name",
108 |             description: "Resource description"
109 |         }
110 |     ]
111 | }));
112 | ```
113 | 
114 | ### Tools
115 | ```typescript
116 | interface Tool {
117 |     name: string;
118 |     description?: string;
119 |     inputSchema: {
120 |         type: "object";
121 |         properties?: object;
122 |         required?: string[];
123 |     };
124 | }
125 | 
126 | // Handler example
127 | server.setRequestHandler(CallToolRequestSchema, async (request) => ({
128 |     content: [
129 |         {
130 |             type: "text",
131 |             text: "Tool execution result"
132 |         }
133 |     ]
134 | }));
135 | ```
136 | 
137 | ### Prompts
138 | ```typescript
139 | interface Prompt {
140 |     name: string;
141 |     description?: string;
142 |     arguments?: PromptArgument[];
143 | }
144 | 
145 | // Handler example
146 | server.setRequestHandler(GetPromptRequestSchema, async (request) => ({
147 |     messages: [
148 |         {
149 |             role: "user",
150 |             content: {
151 |                 type: "text",
152 |                 text: "Prompt template"
153 |             }
154 |         }
155 |     ]
156 | }));
157 | ```
158 | 
159 | ## 4. Best Practices
160 | 
161 | ### Error Handling
162 | 1. Use appropriate error codes:
163 | ```typescript
164 | enum ErrorCode {
165 |     ParseError = -32700,
166 |     InvalidRequest = -32600,
167 |     MethodNotFound = -32601,
168 |     InvalidParams = -32602,
169 |     InternalError = -32603
170 | }
171 | ```
172 | 
173 | 2. Tool errors should be in result:
174 | ```typescript
175 | {
176 |     isError: true,
177 |     content: [{
178 |         type: "text",
179 |         text: "Error description"
180 |     }]
181 | }
182 | ```
183 | 
184 | ### Security Considerations
185 | 1. Input Validation:
186 |    - Validate all parameters against schemas
187 |    - Sanitize file paths and system commands
188 |    - Validate URLs and external identifiers
189 |    - Check parameter sizes and ranges
190 | 
191 | 2. Access Control:
192 |    - Implement authentication where needed
193 |    - Use appropriate authorization checks
194 |    - Audit tool usage
195 |    - Rate limit requests
196 | 
197 | 3. Resource Protection:
198 |    - Validate resource paths
199 |    - Monitor resource usage
200 |    - Implement access controls
201 |    - Rate limit requests
202 | 
203 | ### Message Handling
204 | 1. Request Processing:
205 |    - Validate inputs thoroughly
206 |    - Use type-safe schemas
207 |    - Handle errors gracefully
208 |    - Implement timeouts
209 | 
210 | 2. Progress Reporting:
211 |    - Use progress tokens for long operations
212 |    - Report progress incrementally
213 |    - Include total progress when known
214 | 
215 | ## 5. Client Integration Guidelines
216 | 
217 | ### Client Configuration
218 | ```json
219 | {
220 |     "mcpServers": {
221 |         "server-name": {
222 |             "command": "command-to-run",
223 |             "args": ["arg1", "arg2"],
224 |             "env": {
225 |                 "ENV_VAR": "value"
226 |             }
227 |         }
228 |     }
229 | }
230 | ```
231 | 
232 | ### Environment Variables
233 | - Server inherits limited environment variables
234 | - Custom variables must be specified in config
235 | - Sensitive data should be in environment variables
236 | 
237 | ## 6. Testing and Debugging
238 | 
239 | ### MCP Inspector Usage
240 | 1. Start inspector with server:
241 | ```bash
242 | npx mcp-inspector your-server-command
243 | ```
244 | 
245 | 2. Features to test:
246 |    - Resource listing and reading
247 |    - Tool execution
248 |    - Prompt generation
249 |    - Error handling
250 |    - Progress reporting
251 | 
252 | ### Common Issues
253 | 1. Connection Problems:
254 |    - Check transport configuration
255 |    - Verify server process is running
256 |    - Check for initialization errors
257 | 
258 | 2. Message Handling:
259 |    - Validate message formats
260 |    - Check handler implementations
261 |    - Verify error responses
262 | 
263 | 3. Resource Issues:
264 |    - Check file permissions
265 |    - Validate URI formats
266 |    - Verify content types
267 | 
268 | ## 7. Performance and Scaling
269 | 
270 | ### Best Practices
271 | 1. Resource Management:
272 |    - Cache when appropriate
273 |    - Implement cleanup
274 |    - Monitor memory usage
275 | 
276 | 2. Request Handling:
277 |    - Use appropriate timeouts
278 |    - Implement rate limiting
279 |    - Handle concurrent requests
280 | 
281 | 3. Error Recovery:
282 |    - Implement reconnection logic
283 |    - Handle partial failures
284 |    - Clean up resources
285 | 
286 | ## 8. Documentation Requirements
287 | 
288 | ### Server Documentation
289 | 1. Capabilities Documentation:
290 |    - List supported features
291 |    - Document configuration options
292 |    - Describe environment variables
293 | 
294 | 2. API Documentation:
295 |    - Document all resources
296 |    - Document all tools
297 |    - Document all prompts
298 |    - Include example usage
299 | 
300 | 3. Error Documentation:
301 |    - List possible error codes
302 |    - Describe error conditions
303 |    - Include recovery steps
304 | 
305 | ### Integration Guide
306 | 1. Setup Instructions:
307 |    - Installation steps
308 |    - Configuration options
309 |    - Environment setup
310 | 
311 | 2. Usage Examples:
312 |    - Basic usage patterns
313 |    - Common integrations
314 |    - Error handling examples
315 | 
316 | ## 9. Versioning and Updates
317 | 
318 | ### Version Management
319 | 1. Protocol Versioning:
320 |    - Support LATEST_PROTOCOL_VERSION
321 |    - Handle version negotiation
322 |    - Maintain compatibility
323 | 
324 | 2. Server Versioning:
325 |    - Use semantic versioning
326 |    - Document breaking changes
327 |    - Provide migration guides
328 | 
329 | ### Update Handling
330 | 1. Capability Updates:
331 |    - Notify clients of changes
332 |    - Handle capability negotiation
333 |    - Maintain backwards compatibility
334 | 
335 | 2. Resource Updates:
336 |    - Handle resource changes
337 |    - Notify subscribed clients
338 |    - Maintain consistency
339 | 
340 | ## 10. Specific Server Types
341 | 
342 | ### Database Servers (like Airtable)
343 | 1. Required Capabilities:
344 |    - Resources for data access
345 |    - Tools for data manipulation
346 |    - Prompts for common operations
347 | 
348 | 2. Implementation Focus:
349 |    - Connection management
350 |    - Query handling
351 |    - Data transformation
352 |    - Error handling
353 |    - Rate limiting
354 | 
355 | 3. Security Considerations:
356 |    - API key management
357 |    - Access control
358 |    - Data validation
359 |    - Request sanitization
360 | 
361 | 4. Tools to Implement:
362 |    - List databases/bases
363 |    - Create/modify tables
364 |    - Query data
365 |    - Update records
366 |    - Delete records
367 | 
368 | 5. Resource Structure:
369 |    - Database schema
370 |    - Table contents
371 |    - Query results
372 | 
373 | 6. Error Handling:
374 |    - Connection errors
375 |    - Query errors
376 |    - Rate limit errors
377 |    - Authorization errors
378 | 
379 | This guide should be used as a reference when assisting with MCP server development. Always consider the specific requirements and constraints of the project while following these guidelines.
380 | 
```

--------------------------------------------------------------------------------
/prompts/project-knowledge.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Airtable MCP Server Guide
  2 | 
  3 | ## Table of Contents
  4 | 1. [MCP Server Tools Overview](#mcp-server-tools-overview)
  5 |    - Available Tools and Use Cases
  6 |    - Tool Dependencies and Workflow
  7 |    - Rate Limiting and Performance
  8 |    - Tool Authorization Requirements
  9 | 
 10 | 2. [Base Management](#base-management)
 11 |    - Listing and Discovering Bases
 12 |    - Table Operations
 13 |    - Base Configuration
 14 |    - Access Control
 15 | 
 16 | 3. [Field Management](#field-management)
 17 |    - Field Types and Options
 18 |    - Field Creation and Updates
 19 |    - Field Dependencies
 20 |    - Data Validation
 21 | 
 22 | 4. [Record Operations](#record-operations)
 23 |    - Reading and Querying Records
 24 |    - Creating and Updating Records
 25 |    - Batch Operations
 26 |    - Search and Filtering
 27 | 
 28 | ## MCP Server Tools Overview
 29 | 
 30 | ### Available Tools and Use Cases
 31 | 
 32 | 1. **Base Management Tools**
 33 | 
 34 |    a. **list_bases**
 35 |    - **Purpose**: Lists all accessible Airtable bases
 36 |    - **Key Considerations**:
 37 |      - Requires valid API key
 38 |      - Returns only bases with access permissions
 39 |      - Useful for initial discovery
 40 |    - **Best Practices**:
 41 |      - Cache base IDs for frequent operations
 42 |      - Verify base accessibility before operations
 43 |      - Handle pagination if many bases
 44 | 
 45 |    b. **list_tables**
 46 |    - **Purpose**: Lists all tables in a specified base
 47 |    - **Key Considerations**:
 48 |      - Requires base_id
 49 |      - Returns table metadata
 50 |      - Useful for table discovery
 51 |    - **Best Practices**:
 52 |      - Cache table IDs for frequent operations
 53 |      - Verify table existence before operations
 54 |      - Handle pagination for large bases
 55 | 
 56 |    c. **create_table**
 57 |    - **Purpose**: Creates a new table in an Airtable base
 58 |    - **Key Considerations**:
 59 |      - Requires base_id and table name
 60 |      - Can create multiple basic fields in one operation
 61 |      - Should be used first in any table creation workflow
 62 |      - Validate table name uniqueness in the base
 63 |    - **Best Practices**:
 64 |      - Start with essential basic fields only
 65 |      - Use clear, descriptive table names
 66 |      - Add proper table description
 67 |      - Follow naming conventions
 68 | 
 69 |    d. **update_table**
 70 |    - **Purpose**: Updates a table's name or description
 71 |    - **Key Considerations**:
 72 |      - Requires base_id and table_id
 73 |      - Can modify name and description
 74 |      - Existing data remains unchanged
 75 |    - **Best Practices**:
 76 |      - Verify table existence before update
 77 |      - Maintain naming consistency
 78 |      - Update documentation accordingly
 79 | 
 80 | 2. **Field Management Tools**
 81 | 
 82 |    a. **create_field**
 83 |    - **Purpose**: Adds a new field to an existing table
 84 |    - **Key Considerations**:
 85 |      - Requires both base_id and table_id
 86 |      - Add one field at a time for complex types
 87 |      - Field options must match type requirements
 88 |    - **Best Practices**:
 89 |      - Verify field creation before adding next
 90 |      - Use descriptive field names
 91 |      - Include field descriptions
 92 |      - Configure appropriate field options
 93 | 
 94 |    b. **update_field**
 95 |    - **Purpose**: Modifies existing field configuration
 96 |    - **Key Considerations**:
 97 |      - Can update name, description, and options
 98 |      - Some field types have immutable properties
 99 |      - Changes may affect existing data
100 |    - **Best Practices**:
101 |      - Backup data before significant changes
102 |      - Test changes on sample records
103 |      - Update documentation accordingly
104 |      - Verify field behavior after changes
105 | 
106 | 3. **Record Operation Tools**
107 | 
108 |    a. **list_records**
109 |    - **Purpose**: Retrieves records from a table
110 |    - **Key Considerations**:
111 |      - Supports filtering and sorting
112 |      - Handles pagination
113 |      - Can specify fields to return
114 |    - **Best Practices**:
115 |      - Use field selection for performance
116 |      - Implement pagination for large datasets
117 |      - Cache results when appropriate
118 |      - Handle rate limits
119 | 
120 |    b. **create_record**
121 |    - **Purpose**: Adds new records to a table
122 |    - **Key Considerations**:
123 |      - Validates field types
124 |      - Handles required fields
125 |      - Supports multiple records
126 |    - **Best Practices**:
127 |      - Validate data before submission
128 |      - Handle batch operations efficiently
129 |      - Verify record creation
130 |      - Implement error recovery
131 | 
132 |    c. **update_record**
133 |    - **Purpose**: Modifies existing records
134 |    - **Key Considerations**:
135 |      - Requires record ID
136 |      - Partial updates supported
137 |      - Field validation applied
138 |    - **Best Practices**:
139 |      - Verify record existence
140 |      - Backup data before updates
141 |      - Handle field type constraints
142 |      - Log changes for audit
143 | 
144 |    d. **delete_record**
145 |    - **Purpose**: Removes records from a table
146 |    - **Key Considerations**:
147 |      - Operation is irreversible
148 |      - Can affect linked records
149 |      - Supports batch deletion
150 |    - **Best Practices**:
151 |      - Verify record selection
152 |      - Backup before deletion
153 |      - Check dependencies
154 |      - Implement confirmation
155 | 
156 |    e. **search_records**
157 |    - **Purpose**: Finds records matching criteria
158 |    - **Key Considerations**:
159 |      - Supports complex filters
160 |      - Can use multiple fields
161 |      - Returns paginated results
162 |    - **Best Practices**:
163 |      - Optimize search criteria
164 |      - Handle no results case
165 |      - Implement pagination
166 |      - Cache frequent searches
167 | 
168 |    f. **get_record**
169 |    - **Purpose**: Retrieves a single record by ID
170 |    - **Key Considerations**:
171 |      - Direct record access
172 |      - Returns all or selected fields
173 |      - Efficient for single record ops
174 |    - **Best Practices**:
175 |      - Verify record existence
176 |      - Handle missing records
177 |      - Select needed fields only
178 |      - Cache when appropriate
179 | 
180 | ### Tool Dependencies and Workflow
181 | 
182 | ```mermaid
183 | graph TD
184 |     A[list_bases] --> B[list_tables]
185 |     B --> C[create_table]
186 |     C --> D[create_field]
187 |     D --> E[update_field]
188 |     B --> F[list_records]
189 |     F --> G[create_record]
190 |     F --> H[update_record]
191 |     F --> I[delete_record]
192 |     F --> J[search_records]
193 |     F --> K[get_record]
194 |     C --> L[update_table]
195 | ```
196 | 
197 | ### Rate Limiting and Performance
198 | 
199 | 1. **API Constraints**
200 |    - Respect Airtable's rate limits
201 |    - Implement exponential backoff
202 |    - Handle throttling gracefully
203 |    - Monitor API usage
204 | 
205 | 2. **Operation Timing**
206 |    - Allow time between operations
207 |    - Verify completion before next step
208 |    - Handle timeouts appropriately
209 |    - Log operation durations
210 | 
211 | 3. **Resource Management**
212 |    - Monitor memory usage
213 |    - Clean up temporary resources
214 |    - Handle connection issues
215 |    - Implement proper error recovery
216 | 
217 | ### Tool Authorization Requirements
218 | 
219 | 1. **Authentication**
220 |    - Personal access token required
221 |    - OAuth integration support
222 |    - Proper scope configuration
223 |    - Token management best practices
224 | 
225 | 2. **Permissions**
226 |    - Base creator role needed
227 |    - Verify write permissions
228 |    - Check field-level access
229 |    - Handle permission errors
230 | 
231 | ## Base Management
232 | 
233 | ## Table Management
234 | 
235 | ### Available Table Tools
236 | 
237 | 1. **list_tables**
238 |    - **Purpose**: Lists all tables in a specified base
239 |    - **Key Considerations**:
240 |      - Requires base_id
241 |      - Returns table metadata
242 |      - Useful for table discovery
243 |    - **Best Practices**:
244 |      - Cache table IDs for frequent operations
245 |      - Verify table existence before operations
246 |      - Handle pagination for large bases
247 | 
248 | 2. **create_table**
249 |    - **Purpose**: Creates a new table in an Airtable base
250 |    - **Key Considerations**:
251 |      - Requires base_id and table name
252 |      - Can create multiple basic fields in one operation
253 |      - Should be used first in any table creation workflow
254 |      - Validate table name uniqueness in the base
255 |    - **Best Practices**:
256 |      - Start with essential basic fields only
257 |      - Use clear, descriptive table names
258 |      - Add proper table description
259 |      - Follow naming conventions
260 | 
261 | 3. **update_table**
262 |    - **Purpose**: Updates a table's name or description
263 |    - **Key Considerations**:
264 |      - Requires base_id and table_id
265 |      - Can modify name and description
266 |      - Existing data remains unchanged
267 |    - **Best Practices**:
268 |      - Verify table existence before update
269 |      - Maintain naming consistency
270 |      - Update documentation accordingly
271 | 
272 | ### Table Creation Workflow
273 | 
274 | 1. **Initial Setup**
275 |    - Verify base access
276 |    - Check table name availability
277 |    - Plan table structure
278 |    - Define primary fields
279 | 
280 | 2. **Field Planning**
281 |    - Start with basic fields
282 |    - Plan relationships with other tables
283 |    - Consider computed fields
284 |    - Define field dependencies
285 | 
286 | 3. **Implementation Steps**
287 |    - Create table with basic fields
288 |    - Add complex fields incrementally
289 |    - Set up relationships
290 |    - Configure views and permissions
291 | 
292 | ### Best Practices
293 | 
294 | 1. **Table Design**
295 |    - Use clear, descriptive names
296 |    - Follow consistent naming conventions
297 |    - Include proper descriptions
298 |    - Plan for scalability
299 |    - Consider relationships early
300 | 
301 | 2. **Data Organization**
302 |    - Group related fields logically
303 |    - Use appropriate field types
304 |    - Plan for future expansion
305 |    - Consider data validation needs
306 |    - Document table relationships
307 | 
308 | 3. **Performance Considerations**
309 |    - Optimize field types for data size
310 |    - Plan indexes for frequent queries
311 |    - Consider record limits
312 |    - Monitor table size
313 |    - Handle large datasets efficiently
314 | 
315 | 4. **Security and Access**
316 |    - Set appropriate permissions
317 |    - Document access requirements
318 |    - Plan sharing strategy
319 |    - Consider data sensitivity
320 |    - Implement proper controls
321 | 
322 | ### Common Patterns
323 | 
324 | 1. **Master-Detail Tables**
325 |    - Primary table contains main records
326 |    - Detail tables link to master
327 |    - Use lookup fields for data access
328 |    - Implement proper relationships
329 | 
330 | 2. **Lookup Tables**
331 |    - Store reference data
332 |    - Use for standardization
333 |    - Minimize redundancy
334 |    - Easy maintenance
335 | 
336 | 3. **Junction Tables**
337 |    - Handle many-to-many relationships
338 |    - Store relationship metadata
339 |    - Enable complex queries
340 |    - Maintain data integrity
341 | 
342 | ### Error Handling
343 | 
344 | 1. **Creation Errors**
345 |    - Handle name conflicts
346 |    - Validate field configurations
347 |    - Check permissions
348 |    - Provide clear error messages
349 | 
350 | 2. **Update Errors**
351 |    - Verify table existence
352 |    - Check field dependencies
353 |    - Handle concurrent updates
354 |    - Maintain data integrity
355 | 
356 | 3. **Deletion Considerations**
357 |    - Check for dependencies
358 |    - Backup important data
359 |    - Handle cascading deletes
360 |    - Verify permissions
```

--------------------------------------------------------------------------------
/docs/Airtable_MCP_server_guide_for_LLMs.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Airtable MCP Server Guide
  2 | 
  3 | ## Table of Contents
  4 | 1. [MCP Server Tools Overview](#mcp-server-tools-overview)
  5 |    - Available Tools and Use Cases
  6 |    - Tool Dependencies and Workflow
  7 |    - Rate Limiting and Performance
  8 |    - Tool Authorization Requirements
  9 | 
 10 | 2. [Base Management](#base-management)
 11 |    - Listing and Discovering Bases
 12 |    - Table Operations
 13 |    - Base Configuration
 14 |    - Access Control
 15 | 
 16 | 3. [Field Management](#field-management)
 17 |    - Field Types and Options
 18 |    - Field Creation and Updates
 19 |    - Field Dependencies
 20 |    - Data Validation
 21 | 
 22 | 4. [Record Operations](#record-operations)
 23 |    - Reading and Querying Records
 24 |    - Creating and Updating Records
 25 |    - Batch Operations
 26 |    - Search and Filtering
 27 | 
 28 | 5. [System Prompt for Claude](#system-prompt-for-claude)
 29 |    - Core Principles
 30 |    - Implementation Guidelines
 31 |    - Error Handling
 32 |    - Response Formats
 33 | 
 34 | ## MCP Server Tools Overview
 35 | 
 36 | ### Available Tools and Use Cases
 37 | 
 38 | 1. **Base Management Tools**
 39 | 
 40 |    a. **list_bases**
 41 |    - **Purpose**: Lists all accessible Airtable bases
 42 |    - **Key Considerations**:
 43 |      - Requires valid API key
 44 |      - Returns only bases with access permissions
 45 |      - Useful for initial discovery
 46 |    - **Best Practices**:
 47 |      - Cache base IDs for frequent operations
 48 |      - Verify base accessibility before operations
 49 |      - Handle pagination if many bases
 50 | 
 51 |    b. **list_tables**
 52 |    - **Purpose**: Lists all tables in a specified base
 53 |    - **Key Considerations**:
 54 |      - Requires base_id
 55 |      - Returns table metadata
 56 |      - Useful for table discovery
 57 |    - **Best Practices**:
 58 |      - Cache table IDs for frequent operations
 59 |      - Verify table existence before operations
 60 |      - Handle pagination for large bases
 61 | 
 62 |    c. **create_table**
 63 |    - **Purpose**: Creates a new table in an Airtable base
 64 |    - **Key Considerations**:
 65 |      - Requires base_id and table name
 66 |      - Can create multiple basic fields in one operation
 67 |      - Should be used first in any table creation workflow
 68 |      - Validate table name uniqueness in the base
 69 |    - **Best Practices**:
 70 |      - Start with essential basic fields only
 71 |      - Use clear, descriptive table names
 72 |      - Add proper table description
 73 |      - Follow naming conventions
 74 | 
 75 |    d. **update_table**
 76 |    - **Purpose**: Updates a table's name or description
 77 |    - **Key Considerations**:
 78 |      - Requires base_id and table_id
 79 |      - Can modify name and description
 80 |      - Existing data remains unchanged
 81 |    - **Best Practices**:
 82 |      - Verify table existence before update
 83 |      - Maintain naming consistency
 84 |      - Update documentation accordingly
 85 | 
 86 | 2. **Field Management Tools**
 87 | 
 88 |    a. **create_field**
 89 |    - **Purpose**: Adds a new field to an existing table
 90 |    - **Key Considerations**:
 91 |      - Requires both base_id and table_id
 92 |      - Add one field at a time for complex types
 93 |      - Field options must match type requirements
 94 |    - **Best Practices**:
 95 |      - Verify field creation before adding next
 96 |      - Use descriptive field names
 97 |      - Include field descriptions
 98 |      - Configure appropriate field options
 99 | 
100 |    b. **update_field**
101 |    - **Purpose**: Modifies existing field configuration
102 |    - **Key Considerations**:
103 |      - Can update name, description, and options
104 |      - Some field types have immutable properties
105 |      - Changes may affect existing data
106 |    - **Best Practices**:
107 |      - Backup data before significant changes
108 |      - Test changes on sample records
109 |      - Update documentation accordingly
110 |      - Verify field behavior after changes
111 | 
112 | 3. **Record Operation Tools**
113 | 
114 |    a. **list_records**
115 |    - **Purpose**: Retrieves records from a table
116 |    - **Key Considerations**:
117 |      - Supports filtering and sorting
118 |      - Handles pagination
119 |      - Can specify fields to return
120 |    - **Best Practices**:
121 |      - Use field selection for performance
122 |      - Implement pagination for large datasets
123 |      - Cache results when appropriate
124 |      - Handle rate limits
125 | 
126 |    b. **create_record**
127 |    - **Purpose**: Adds new records to a table
128 |    - **Key Considerations**:
129 |      - Validates field types
130 |      - Handles required fields
131 |      - Supports multiple records
132 |    - **Best Practices**:
133 |      - Validate data before submission
134 |      - Handle batch operations efficiently
135 |      - Verify record creation
136 |      - Implement error recovery
137 | 
138 |    c. **update_record**
139 |    - **Purpose**: Modifies existing records
140 |    - **Key Considerations**:
141 |      - Requires record ID
142 |      - Partial updates supported
143 |      - Field validation applied
144 |    - **Best Practices**:
145 |      - Verify record existence
146 |      - Backup data before updates
147 |      - Handle field type constraints
148 |      - Log changes for audit
149 | 
150 |    d. **delete_record**
151 |    - **Purpose**: Removes records from a table
152 |    - **Key Considerations**:
153 |      - Operation is irreversible
154 |      - Can affect linked records
155 |      - Supports batch deletion
156 |    - **Best Practices**:
157 |      - Verify record selection
158 |      - Backup before deletion
159 |      - Check dependencies
160 |      - Implement confirmation
161 | 
162 |    e. **search_records**
163 |    - **Purpose**: Finds records matching criteria
164 |    - **Key Considerations**:
165 |      - Supports complex filters
166 |      - Can use multiple fields
167 |      - Returns paginated results
168 |    - **Best Practices**:
169 |      - Optimize search criteria
170 |      - Handle no results case
171 |      - Implement pagination
172 |      - Cache frequent searches
173 | 
174 |    f. **get_record**
175 |    - **Purpose**: Retrieves a single record by ID
176 |    - **Key Considerations**:
177 |      - Direct record access
178 |      - Returns all or selected fields
179 |      - Efficient for single record ops
180 |    - **Best Practices**:
181 |      - Verify record existence
182 |      - Handle missing records
183 |      - Select needed fields only
184 |      - Cache when appropriate
185 | 
186 | ### Tool Dependencies and Workflow
187 | 
188 | ```mermaid
189 | graph TD
190 |     A[list_bases] --> B[list_tables]
191 |     B --> C[create_table]
192 |     C --> D[create_field]
193 |     D --> E[update_field]
194 |     B --> F[list_records]
195 |     F --> G[create_record]
196 |     F --> H[update_record]
197 |     F --> I[delete_record]
198 |     F --> J[search_records]
199 |     F --> K[get_record]
200 |     C --> L[update_table]
201 | ```
202 | 
203 | ### Rate Limiting and Performance
204 | 
205 | 1. **API Constraints**
206 |    - Respect Airtable's rate limits
207 |    - Implement exponential backoff
208 |    - Handle throttling gracefully
209 |    - Monitor API usage
210 | 
211 | 2. **Operation Timing**
212 |    - Allow time between operations
213 |    - Verify completion before next step
214 |    - Handle timeouts appropriately
215 |    - Log operation durations
216 | 
217 | 3. **Resource Management**
218 |    - Monitor memory usage
219 |    - Clean up temporary resources
220 |    - Handle connection issues
221 |    - Implement proper error recovery
222 | 
223 | ### Tool Authorization Requirements
224 | 
225 | 1. **Authentication**
226 |    - Personal access token required
227 |    - OAuth integration support
228 |    - Proper scope configuration
229 |    - Token management best practices
230 | 
231 | 2. **Permissions**
232 |    - Base creator role needed
233 |    - Verify write permissions
234 |    - Check field-level access
235 |    - Handle permission errors
236 | 
237 | ## System Prompt for Claude
238 | 
239 | You are an AI assistant specialized in creating and managing Airtable tables through the Model Context Protocol (MCP). Follow these guidelines when handling table creation requests:
240 | 
241 | ### Core Principles
242 | 
243 | 1. **Incremental Creation**
244 |    - Always create tables in stages, starting with basic fields
245 |    - Add one complex field at a time
246 |    - Verify each operation before proceeding
247 |    - Handle errors gracefully and provide clear feedback
248 | 
249 | 2. **Field Type Categories**
250 | 
251 |    Basic Fields (No Options Required):
252 |    - `singleLineText`: Single line of text
253 |    - `multilineText`: Multiple lines of text
254 |    - `email`: Valid email address
255 |    - `phoneNumber`: Phone number in any format
256 |    - `richText`: Text with formatting
257 |    - `url`: Valid URL
258 | 
259 |    Complex Fields (Require Options):
260 |    - `number`: Requires precision (0-8)
261 |    - `currency`: Requires precision and symbol
262 |    - `percent`: Requires precision (0-8)
263 |    - `rating`: Requires max value (1-10) and icon/color
264 |    - `duration`: Requires format
265 |    - `date`: Requires dateFormat
266 |    - `dateTime`: Requires dateFormat and timeFormat
267 |    - `singleSelect`: Requires choices with names and colors
268 |    - `multipleSelects`: Requires choices with names and colors
269 |    - `checkbox`: Optional icon and color
270 |    - `barcode`: Supports various formats
271 |    - `button`: Configurable actions
272 |    - `count`: Automatic counter
273 |    - `autoNumber`: Automatic unique counter
274 |    - `formula`: Computed values
275 |    - `rollup`: Aggregated values from linked records
276 |    - `lookup`: Values from linked records
277 |    - `multipleRecordLinks`: Links to other records
278 |    - `attachment`: File attachments
279 | 
280 | 3. **Creation Order**
281 |    1. Create table with basic text fields
282 |    2. Add numeric fields (number, currency, percent)
283 |    3. Add date/time fields
284 |    4. Add select/choice fields
285 |    5. Add computed fields (formula, rollup, lookup)
286 |    6. Add relationship fields (record links)
287 |    7. Verify each field after creation
288 | 
289 | ### Field Configuration Reference
290 | 
291 | 1. **Number Fields**
292 | ```json
293 | {
294 |   "type": "number",
295 |   "options": {
296 |     "precision": 0  // 0 for integers, 1-8 for decimals
297 |   }
298 | }
299 | ```
300 | 
301 | 2. **Currency Fields**
302 | ```json
303 | {
304 |   "type": "currency",
305 |   "options": {
306 |     "precision": 2,
307 |     "symbol": "$"  // Currency symbol
308 |   }
309 | }
310 | ```
311 | 
312 | 3. **Date Fields**
313 | ```json
314 | {
315 |   "type": "date",
316 |   "options": {
317 |     "dateFormat": {
318 |       "name": "local"  // Options: local, friendly, us, european, iso
319 |     }
320 |   }
321 | }
322 | ```
323 | 
324 | 4. **DateTime Fields**
325 | ```json
326 | {
327 |   "type": "dateTime",
328 |   "options": {
329 |     "dateFormat": {
330 |       "name": "local"  // Options: local, friendly, us, european, iso
331 |     },
332 |     "timeFormat": {
333 |       "name": "12hour"  // Options: 12hour, 24hour
334 |     }
335 |   }
336 | }
337 | ```
338 | 
339 | 5. **Select Fields**
340 | ```json
341 | {
342 |   "type": "singleSelect",
343 |   "options": {
344 |     "choices": [
345 |       {
346 |         "name": "Option Name",
347 |         "color": "colorName"  // Colors: blueBright, greenBright, redBright, yellowBright, pinkBright, purpleBright, cyanBright, grayBright
348 |       }
349 |     ]
350 |   }
351 | }
352 | ```
353 | 
354 | 6. **Rating Fields**
355 | ```json
356 | {
357 |   "type": "rating",
358 |   "options": {
359 |     "max": 5,  // 1-10
360 |     "color": "yellowBright",  // Standard color options
361 |     "icon": "star"  // Options: star, heart, thumbsUp, flag, dot
362 |   }
363 | }
364 | ```
365 | 
366 | ### Implementation Steps
367 | 
368 | 1. **Create Table with Basic Fields**
369 | ```json
370 | {
371 |   "name": "create_table",
372 |   "arguments": {
373 |     "base_id": "your_base_id",
374 |     "table_name": "Your Table Name",
375 |     "description": "Table description",
376 |     "fields": [
377 |       {
378 |         "name": "Title",
379 |         "type": "singleLineText",
380 |         "description": "Title field"
381 |       },
382 |       {
383 |         "name": "Notes",
384 |         "type": "multilineText",
385 |         "description": "Notes field"
386 |       }
387 |     ]
388 |   }
389 | }
390 | ```
391 | 
392 | 2. **Add Complex Fields (One at a Time)**
393 | ```json
394 | {
395 |   "name": "create_field",
396 |   "arguments": {
397 |     "base_id": "your_base_id",
398 |     "table_id": "your_table_id",
399 |     "field": {
400 |       "name": "Field Name",
401 |       "type": "field_type",
402 |       "description": "Field description",
403 |       "options": {
404 |         // Field-specific options here
405 |       }
406 |     }
407 |   }
408 | }
409 | ```
410 | 
411 | ### Error Handling & Best Practices
412 | 
413 | 1. **Validation**
414 |    - Verify each field after creation
415 |    - Test with sample data
416 |    - Check field options are correctly applied
417 |    - Validate field names and descriptions
418 |    - Ensure required options are provided
419 |    - Verify field type compatibility
420 | 
421 | 2. **Error Recovery**
422 |    - If field creation fails, do not proceed to next field
423 |    - Verify field options match specifications exactly
424 |    - Retry failed field creation with corrected options
425 |    - Log errors for debugging
426 |    - Provide clear error messages
427 | 
428 | 3. **Testing**
429 |    - Create test records after adding fields
430 |    - Update records to verify field behavior
431 |    - Test field constraints and validations
432 |    - Verify computed fields
433 |    - Test relationships between tables
434 | 
435 | 4. **Security**
436 |    - Validate all inputs
437 |    - Sanitize field names and descriptions
438 |    - Use appropriate field types for sensitive data
439 |    - Implement proper access controls
440 |    - Follow rate limiting guidelines
441 | 
442 | ### Response Format
443 | 
444 | When responding to table creation requests:
445 | 
446 | 1. Acknowledge the request and outline the plan
447 | 2. Create the table with basic fields first
448 | 3. Add complex fields one at a time
449 | 4. Verify each step
450 | 5. Report success or handle errors
451 | 6. Provide guidance for next steps
452 | 
453 | Example response format:
454 | ```
455 | I'll help you create the [table_name] table with the following steps:
456 | 
457 | 1. Create table with basic fields:
458 |    - [field1]: [type]
459 |    - [field2]: [type]
460 | 
461 | 2. Add complex fields:
462 |    - [field3]: [type] with [options]
463 |    - [field4]: [type] with [options]
464 | 
465 | I'll proceed with each step and verify completion before moving to the next one.
466 | ```
467 | 
468 | Remember to:
469 | - Be explicit about each action
470 | - Verify each step
471 | - Handle errors gracefully
472 | - Provide clear feedback
473 | - Guide the user through the process 
```

--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------

```typescript
  1 | #!/usr/bin/env node
  2 | 
  3 | import { Server } from "@modelcontextprotocol/sdk/server/index.js";
  4 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
  5 | import {
  6 |   CallToolRequestSchema,
  7 |   ListToolsRequestSchema,
  8 |   ErrorCode,
  9 |   McpError,
 10 | } from "@modelcontextprotocol/sdk/types.js";
 11 | import axios, { AxiosInstance } from "axios";
 12 | import { FieldOption, fieldRequiresOptions, getDefaultOptions, FieldType } from "./types.js";
 13 | 
 14 | const API_KEY = process.env.AIRTABLE_API_KEY;
 15 | if (!API_KEY) {
 16 |   throw new Error("AIRTABLE_API_KEY environment variable is required");
 17 | }
 18 | 
 19 | class AirtableServer {
 20 |   private server: Server;
 21 |   private axiosInstance: AxiosInstance;
 22 | 
 23 |   constructor() {
 24 |     this.server = new Server(
 25 |       {
 26 |         name: "airtable-server",
 27 |         version: "0.2.0",
 28 |       },
 29 |       {
 30 |         capabilities: {
 31 |           tools: {},
 32 |         },
 33 |       }
 34 |     );
 35 | 
 36 |     this.axiosInstance = axios.create({
 37 |       baseURL: "https://api.airtable.com/v0",
 38 |       headers: {
 39 |         Authorization: `Bearer ${API_KEY}`,
 40 |       },
 41 |     });
 42 | 
 43 |     this.setupToolHandlers();
 44 |     
 45 |     // Error handling
 46 |     this.server.onerror = (error) => console.error("[MCP Error]", error);
 47 |     process.on("SIGINT", async () => {
 48 |       await this.server.close();
 49 |       process.exit(0);
 50 |     });
 51 |   }
 52 | 
 53 |   private validateField(field: FieldOption): FieldOption {
 54 |     const { type } = field;
 55 | 
 56 |     // Remove options for fields that don't need them
 57 |     if (!fieldRequiresOptions(type as FieldType)) {
 58 |       const { options, ...rest } = field;
 59 |       return rest;
 60 |     }
 61 | 
 62 |     // Add default options for fields that require them
 63 |     if (!field.options) {
 64 |       return {
 65 |         ...field,
 66 |         options: getDefaultOptions(type as FieldType),
 67 |       };
 68 |     }
 69 | 
 70 |     return field;
 71 |   }
 72 | 
 73 |   private setupToolHandlers() {
 74 |     // Register available tools
 75 |     this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
 76 |       tools: [
 77 |         {
 78 |           name: "list_bases",
 79 |           description: "List all accessible Airtable bases",
 80 |           inputSchema: {
 81 |             type: "object",
 82 |             properties: {},
 83 |             required: [],
 84 |           },
 85 |         },
 86 |         {
 87 |           name: "list_tables",
 88 |           description: "List all tables in a base",
 89 |           inputSchema: {
 90 |             type: "object",
 91 |             properties: {
 92 |               base_id: {
 93 |                 type: "string",
 94 |                 description: "ID of the base",
 95 |               },
 96 |             },
 97 |             required: ["base_id"],
 98 |           },
 99 |         },
100 |         {
101 |           name: "create_table",
102 |           description: "Create a new table in a base",
103 |           inputSchema: {
104 |             type: "object",
105 |             properties: {
106 |               base_id: {
107 |                 type: "string",
108 |                 description: "ID of the base",
109 |               },
110 |               table_name: {
111 |                 type: "string",
112 |                 description: "Name of the new table",
113 |               },
114 |               description: {
115 |                 type: "string",
116 |                 description: "Description of the table",
117 |               },
118 |               fields: {
119 |                 type: "array",
120 |                 description: "Initial fields for the table",
121 |                 items: {
122 |                   type: "object",
123 |                   properties: {
124 |                     name: {
125 |                       type: "string",
126 |                       description: "Name of the field",
127 |                     },
128 |                     type: {
129 |                       type: "string",
130 |                       description: "Type of the field (e.g., singleLineText, multilineText, number, etc.)",
131 |                     },
132 |                     description: {
133 |                       type: "string",
134 |                       description: "Description of the field",
135 |                     },
136 |                     options: {
137 |                       type: "object",
138 |                       description: "Field-specific options",
139 |                     },
140 |                   },
141 |                   required: ["name", "type"],
142 |                 },
143 |               },
144 |             },
145 |             required: ["base_id", "table_name"],
146 |           },
147 |         },
148 |         {
149 |           name: "update_table",
150 |           description: "Update a table's schema",
151 |           inputSchema: {
152 |             type: "object",
153 |             properties: {
154 |               base_id: {
155 |                 type: "string",
156 |                 description: "ID of the base",
157 |               },
158 |               table_id: {
159 |                 type: "string",
160 |                 description: "ID of the table to update",
161 |               },
162 |               name: {
163 |                 type: "string",
164 |                 description: "New name for the table",
165 |               },
166 |               description: {
167 |                 type: "string",
168 |                 description: "New description for the table",
169 |               },
170 |             },
171 |             required: ["base_id", "table_id"],
172 |           },
173 |         },
174 |         {
175 |           name: "create_field",
176 |           description: "Create a new field in a table",
177 |           inputSchema: {
178 |             type: "object",
179 |             properties: {
180 |               base_id: {
181 |                 type: "string",
182 |                 description: "ID of the base",
183 |               },
184 |               table_id: {
185 |                 type: "string",
186 |                 description: "ID of the table",
187 |               },
188 |               field: {
189 |                 type: "object",
190 |                 properties: {
191 |                   name: {
192 |                     type: "string",
193 |                     description: "Name of the field",
194 |                   },
195 |                   type: {
196 |                     type: "string",
197 |                     description: "Type of the field",
198 |                   },
199 |                   description: {
200 |                     type: "string",
201 |                     description: "Description of the field",
202 |                   },
203 |                   options: {
204 |                     type: "object",
205 |                     description: "Field-specific options",
206 |                   },
207 |                 },
208 |                 required: ["name", "type"],
209 |               },
210 |             },
211 |             required: ["base_id", "table_id", "field"],
212 |           },
213 |         },
214 |         {
215 |           name: "update_field",
216 |           description: "Update a field in a table",
217 |           inputSchema: {
218 |             type: "object",
219 |             properties: {
220 |               base_id: {
221 |                 type: "string",
222 |                 description: "ID of the base",
223 |               },
224 |               table_id: {
225 |                 type: "string",
226 |                 description: "ID of the table",
227 |               },
228 |               field_id: {
229 |                 type: "string",
230 |                 description: "ID of the field to update",
231 |               },
232 |               updates: {
233 |                 type: "object",
234 |                 properties: {
235 |                   name: {
236 |                     type: "string",
237 |                     description: "New name for the field",
238 |                   },
239 |                   description: {
240 |                     type: "string",
241 |                     description: "New description for the field",
242 |                   },
243 |                   options: {
244 |                     type: "object",
245 |                     description: "New field-specific options",
246 |                   },
247 |                 },
248 |               },
249 |             },
250 |             required: ["base_id", "table_id", "field_id", "updates"],
251 |           },
252 |         },
253 |         {
254 |           name: "list_records",
255 |           description: "List records in a table",
256 |           inputSchema: {
257 |             type: "object",
258 |             properties: {
259 |               base_id: {
260 |                 type: "string",
261 |                 description: "ID of the base",
262 |               },
263 |               table_name: {
264 |                 type: "string",
265 |                 description: "Name of the table",
266 |               },
267 |               max_records: {
268 |                 type: "number",
269 |                 description: "Maximum number of records to return",
270 |               },
271 |             },
272 |             required: ["base_id", "table_name"],
273 |           },
274 |         },
275 |         {
276 |           name: "create_record",
277 |           description: "Create a new record in a table",
278 |           inputSchema: {
279 |             type: "object",
280 |             properties: {
281 |               base_id: {
282 |                 type: "string",
283 |                 description: "ID of the base",
284 |               },
285 |               table_name: {
286 |                 type: "string",
287 |                 description: "Name of the table",
288 |               },
289 |               fields: {
290 |                 type: "object",
291 |                 description: "Record fields as key-value pairs",
292 |               },
293 |             },
294 |             required: ["base_id", "table_name", "fields"],
295 |           },
296 |         },
297 |         {
298 |           name: "update_record",
299 |           description: "Update an existing record in a table",
300 |           inputSchema: {
301 |             type: "object",
302 |             properties: {
303 |               base_id: {
304 |                 type: "string",
305 |                 description: "ID of the base",
306 |               },
307 |               table_name: {
308 |                 type: "string",
309 |                 description: "Name of the table",
310 |               },
311 |               record_id: {
312 |                 type: "string",
313 |                 description: "ID of the record to update",
314 |               },
315 |               fields: {
316 |                 type: "object",
317 |                 description: "Record fields to update as key-value pairs",
318 |               },
319 |             },
320 |             required: ["base_id", "table_name", "record_id", "fields"],
321 |           },
322 |         },
323 |         {
324 |           name: "delete_record",
325 |           description: "Delete a record from a table",
326 |           inputSchema: {
327 |             type: "object",
328 |             properties: {
329 |               base_id: {
330 |                 type: "string",
331 |                 description: "ID of the base",
332 |               },
333 |               table_name: {
334 |                 type: "string",
335 |                 description: "Name of the table",
336 |               },
337 |               record_id: {
338 |                 type: "string",
339 |                 description: "ID of the record to delete",
340 |               },
341 |             },
342 |             required: ["base_id", "table_name", "record_id"],
343 |           },
344 |         },
345 |         {
346 |           name: "search_records",
347 |           description: "Search for records in a table",
348 |           inputSchema: {
349 |             type: "object",
350 |             properties: {
351 |               base_id: {
352 |                 type: "string",
353 |                 description: "ID of the base",
354 |               },
355 |               table_name: {
356 |                 type: "string",
357 |                 description: "Name of the table",
358 |               },
359 |               field_name: {
360 |                 type: "string",
361 |                 description: "Name of the field to search in",
362 |               },
363 |               value: {
364 |                 type: "string",
365 |                 description: "Value to search for",
366 |               },
367 |             },
368 |             required: ["base_id", "table_name", "field_name", "value"],
369 |           },
370 |         },
371 |         {
372 |           name: "get_record",
373 |           description: "Get a single record by its ID",
374 |           inputSchema: {
375 |             type: "object",
376 |             properties: {
377 |               base_id: {
378 |                 type: "string",
379 |                 description: "ID of the base",
380 |               },
381 |               table_name: {
382 |                 type: "string",
383 |                 description: "Name of the table",
384 |               },
385 |               record_id: {
386 |                 type: "string",
387 |                 description: "ID of the record to retrieve",
388 |               },
389 |             },
390 |             required: ["base_id", "table_name", "record_id"],
391 |           },
392 |         },
393 |       ],
394 |     }));
395 | 
396 |     this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
397 |       try {
398 |         switch (request.params.name) {
399 |           case "list_bases": {
400 |             const response = await this.axiosInstance.get("/meta/bases");
401 |             return {
402 |               content: [{
403 |                 type: "text",
404 |                 text: JSON.stringify(response.data.bases, null, 2),
405 |               }],
406 |             };
407 |           }
408 | 
409 |           case "list_tables": {
410 |             const { base_id } = request.params.arguments as { base_id: string };
411 |             const response = await this.axiosInstance.get(`/meta/bases/${base_id}/tables`);
412 |             return {
413 |               content: [{
414 |                 type: "text",
415 |                 text: JSON.stringify(response.data.tables, null, 2),
416 |               }],
417 |             };
418 |           }
419 | 
420 |           case "create_table": {
421 |             const { base_id, table_name, description, fields } = request.params.arguments as {
422 |               base_id: string;
423 |               table_name: string;
424 |               description?: string;
425 |               fields?: FieldOption[];
426 |             };
427 |             
428 |             // Validate and prepare fields
429 |             const validatedFields = fields?.map(field => this.validateField(field));
430 |             
431 |             const response = await this.axiosInstance.post(`/meta/bases/${base_id}/tables`, {
432 |               name: table_name,
433 |               description,
434 |               fields: validatedFields,
435 |             });
436 |             
437 |             return {
438 |               content: [{
439 |                 type: "text",
440 |                 text: JSON.stringify(response.data, null, 2),
441 |               }],
442 |             };
443 |           }
444 | 
445 |           case "update_table": {
446 |             const { base_id, table_id, name, description } = request.params.arguments as {
447 |               base_id: string;
448 |               table_id: string;
449 |               name?: string;
450 |               description?: string;
451 |             };
452 |             
453 |             const response = await this.axiosInstance.patch(`/meta/bases/${base_id}/tables/${table_id}`, {
454 |               name,
455 |               description,
456 |             });
457 |             
458 |             return {
459 |               content: [{
460 |                 type: "text",
461 |                 text: JSON.stringify(response.data, null, 2),
462 |               }],
463 |             };
464 |           }
465 | 
466 |           case "create_field": {
467 |             const { base_id, table_id, field } = request.params.arguments as {
468 |               base_id: string;
469 |               table_id: string;
470 |               field: FieldOption;
471 |             };
472 |             
473 |             // Validate field before creation
474 |             const validatedField = this.validateField(field);
475 |             
476 |             const response = await this.axiosInstance.post(
477 |               `/meta/bases/${base_id}/tables/${table_id}/fields`,
478 |               validatedField
479 |             );
480 |             
481 |             return {
482 |               content: [{
483 |                 type: "text",
484 |                 text: JSON.stringify(response.data, null, 2),
485 |               }],
486 |             };
487 |           }
488 | 
489 |           case "update_field": {
490 |             const { base_id, table_id, field_id, updates } = request.params.arguments as {
491 |               base_id: string;
492 |               table_id: string;
493 |               field_id: string;
494 |               updates: Partial<FieldOption>;
495 |             };
496 |             
497 |             const response = await this.axiosInstance.patch(
498 |               `/meta/bases/${base_id}/tables/${table_id}/fields/${field_id}`,
499 |               updates
500 |             );
501 |             
502 |             return {
503 |               content: [{
504 |                 type: "text",
505 |                 text: JSON.stringify(response.data, null, 2),
506 |               }],
507 |             };
508 |           }
509 | 
510 |           case "list_records": {
511 |             const { base_id, table_name, max_records } = request.params.arguments as {
512 |               base_id: string;
513 |               table_name: string;
514 |               max_records?: number;
515 |             };
516 |             const response = await this.axiosInstance.get(`/${base_id}/${table_name}`, {
517 |               params: max_records ? { maxRecords: max_records } : undefined,
518 |             });
519 |             return {
520 |               content: [{
521 |                 type: "text",
522 |                 text: JSON.stringify(response.data.records, null, 2),
523 |               }],
524 |             };
525 |           }
526 | 
527 |           case "create_record": {
528 |             const { base_id, table_name, fields } = request.params.arguments as {
529 |               base_id: string;
530 |               table_name: string;
531 |               fields: Record<string, any>;
532 |             };
533 |             const response = await this.axiosInstance.post(`/${base_id}/${table_name}`, {
534 |               fields,
535 |             });
536 |             return {
537 |               content: [{
538 |                 type: "text",
539 |                 text: JSON.stringify(response.data, null, 2),
540 |               }],
541 |             };
542 |           }
543 | 
544 |           case "update_record": {
545 |             const { base_id, table_name, record_id, fields } = request.params.arguments as {
546 |               base_id: string;
547 |               table_name: string;
548 |               record_id: string;
549 |               fields: Record<string, any>;
550 |             };
551 |             const response = await this.axiosInstance.patch(
552 |               `/${base_id}/${table_name}/${record_id}`,
553 |               { fields }
554 |             );
555 |             return {
556 |               content: [{
557 |                 type: "text",
558 |                 text: JSON.stringify(response.data, null, 2),
559 |               }],
560 |             };
561 |           }
562 | 
563 |           case "delete_record": {
564 |             const { base_id, table_name, record_id } = request.params.arguments as {
565 |               base_id: string;
566 |               table_name: string;
567 |               record_id: string;
568 |             };
569 |             const response = await this.axiosInstance.delete(
570 |               `/${base_id}/${table_name}/${record_id}`
571 |             );
572 |             return {
573 |               content: [{
574 |                 type: "text",
575 |                 text: JSON.stringify(response.data, null, 2),
576 |               }],
577 |             };
578 |           }
579 | 
580 |           case "search_records": {
581 |             const { base_id, table_name, field_name, value } = request.params.arguments as {
582 |               base_id: string;
583 |               table_name: string;
584 |               field_name: string;
585 |               value: string;
586 |             };
587 |             const response = await this.axiosInstance.get(`/${base_id}/${table_name}`, {
588 |               params: {
589 |                 filterByFormula: `{${field_name}} = "${value}"`,
590 |               },
591 |             });
592 |             return {
593 |               content: [{
594 |                 type: "text",
595 |                 text: JSON.stringify(response.data.records, null, 2),
596 |               }],
597 |             };
598 |           }
599 | 
600 |           case "get_record": {
601 |             const { base_id, table_name, record_id } = request.params.arguments as {
602 |               base_id: string;
603 |               table_name: string;
604 |               record_id: string;
605 |             };
606 |             const response = await this.axiosInstance.get(
607 |               `/${base_id}/${table_name}/${record_id}`
608 |             );
609 |             return {
610 |               content: [{
611 |                 type: "text",
612 |                 text: JSON.stringify(response.data, null, 2),
613 |               }],
614 |             };
615 |           }
616 | 
617 |           default:
618 |             throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}`);
619 |         }
620 |       } catch (error) {
621 |         if (axios.isAxiosError(error)) {
622 |           throw new McpError(
623 |             ErrorCode.InternalError,
624 |             `Airtable API error: ${error.response?.data?.error?.message ?? error.message}`
625 |           );
626 |         }
627 |         throw error;
628 |       }
629 |     });
630 |   }
631 | 
632 |   async run() {
633 |     const transport = new StdioServerTransport();
634 |     await this.server.connect(transport);
635 |     console.error("Airtable MCP server running on stdio");
636 |   }
637 | }
638 | 
639 | const server = new AirtableServer();
640 | server.run().catch((error) => {
641 |   console.error("Server error:", error);
642 |   process.exit(1);
643 | });
644 | 
```

--------------------------------------------------------------------------------
/docs/Airtable API field types and cell values.md:
--------------------------------------------------------------------------------

```markdown
   1 | # Field types and cell values
   2 | 
   3 | This documents all of the currently supported field types and their corresponding cell value formats, as well as their option formats.
   4 | 
   5 | **Note:** Webhooks have different cell payloads for some cell types (eg: [single select](https://airtable.com/developers/web/api/field-model#select)). This will be detailed below.
   6 | 
   7 | **Warning:** We may add more field types in the future and this will not be considered a [breaking change](https://support.airtable.com/docs/airtable-api-deprecation-guidelines). API consumers are expected to handle unknown field types gracefully. Further, object definitions are not meant to exhaustively describe the shape, new properties can be added and will not be considered a breaking change.
   8 | 
   9 | ## Field types
  10 | 
  11 | - [AI Text](https://airtable.com/developers/web/api/field-model#ai-text)
  12 | - [Attachment](https://airtable.com/developers/web/api/field-model#multiple-attachment)
  13 | - [Auto number](https://airtable.com/developers/web/api/field-model#auto-number)
  14 | - [Barcode](https://airtable.com/developers/web/api/field-model#barcode)
  15 | - [Button](https://airtable.com/developers/web/api/field-model#button)
  16 | - [Checkbox](https://airtable.com/developers/web/api/field-model#checkbox)
  17 | - [Collaborator](https://airtable.com/developers/web/api/field-model#collaborator)
  18 | - [Count](https://airtable.com/developers/web/api/field-model#count)
  19 | - [Created by](https://airtable.com/developers/web/api/field-model#created-by)
  20 | - [Created time](https://airtable.com/developers/web/api/field-model#created-time)
  21 | - [Currency](https://airtable.com/developers/web/api/field-model#currency-number)
  22 | - [Date](https://airtable.com/developers/web/api/field-model#date-only)
  23 | - [Date and time](https://airtable.com/developers/web/api/field-model#date-and-time)
  24 | - [Duration](https://airtable.com/developers/web/api/field-model#duration-number)
  25 | - [Email](https://airtable.com/developers/web/api/field-model#email-text)
  26 | - [Formula](https://airtable.com/developers/web/api/field-model#formula)
  27 | - [Last modified by](https://airtable.com/developers/web/api/field-model#last-modified-by)
  28 | - [Last modified time](https://airtable.com/developers/web/api/field-model#last-modified-time)
  29 | - [Link to another record](https://airtable.com/developers/web/api/field-model#foreign-key)
  30 | - [Long text](https://airtable.com/developers/web/api/field-model#multiline-text)
  31 | - [Lookup](https://airtable.com/developers/web/api/field-model#lookup)
  32 | - [Multiple collaborator](https://airtable.com/developers/web/api/field-model#multi-collaborator)
  33 | - [Multiple select](https://airtable.com/developers/web/api/field-model#multi-select)
  34 | - [Number](https://airtable.com/developers/web/api/field-model#decimal-or-integer-number)
  35 | - [Percent](https://airtable.com/developers/web/api/field-model#percent-number)
  36 | - [Phone](https://airtable.com/developers/web/api/field-model#phone)
  37 | - [Rating](https://airtable.com/developers/web/api/field-model#rating)
  38 | - [Rich text](https://airtable.com/developers/web/api/field-model#rich-text)
  39 | - [Rollup](https://airtable.com/developers/web/api/field-model#rollup)
  40 | - [Single line text](https://airtable.com/developers/web/api/field-model#simple-text)
  41 | - [Single select](https://airtable.com/developers/web/api/field-model#select)
  42 | - [Sync source](https://airtable.com/developers/web/api/field-model#sync-source)
  43 | - [Url](https://airtable.com/developers/web/api/field-model#url-text)
  44 | 
  45 | ## [§](https://airtable.com/developers/web/api/field-model\#aitext) AI Text
  46 | 
  47 | Long text (with AI output enabled)
  48 | 
  49 | AI generated text can depend on other cells in the same record and can be in a loading state.
  50 | 
  51 | Cell format (read only)
  52 | 
  53 | `any of the below objects`
  54 | 
  55 | * * *
  56 | 
  57 | ``
  58 | 
  59 | |     |     |
  60 | | --- | --- |
  61 | | [§](https://airtable.com/developers/web/api/field-model#aitext-cellformat-multiple-0-state)`state` | `"empty" | "loading" | "generated"` <br>The current state of the cell. |
  62 | | [§](https://airtable.com/developers/web/api/field-model#aitext-cellformat-multiple-0-isstale)`isStale` | `boolean` <br>If the cell should be recomputed due to a dependency change.<br>This can either be a dependent field or the field configuration. |
  63 | | [§](https://airtable.com/developers/web/api/field-model#aitext-cellformat-multiple-0-value)`value` | `string | null` <br>The value that is shown to the user inside of the cell |
  64 | 
  65 | * * *
  66 | 
  67 | ``
  68 | 
  69 | |     |     |
  70 | | --- | --- |
  71 | | [§](https://airtable.com/developers/web/api/field-model#aitext-cellformat-multiple-1-state)`state` | `"error"` <br>Whether the cell is currently in an error state. |
  72 | | [§](https://airtable.com/developers/web/api/field-model#aitext-cellformat-multiple-1-errortype)`errorType` | `string` <br>A short string that describes the error. |
  73 | | [§](https://airtable.com/developers/web/api/field-model#aitext-cellformat-multiple-1-isstale)`isStale` | `boolean` <br>If the cell should be recomputed due to a dependency change.<br>This can either be a dependent field or the field configuration. |
  74 | | [§](https://airtable.com/developers/web/api/field-model#aitext-cellformat-multiple-1-value)`value` | `string | null` <br>The value that is shown to the user inside of the cell |
  75 | 
  76 | Field type and options (read only)
  77 | 
  78 | ``
  79 | 
  80 | |     |     |
  81 | | --- | --- |
  82 | | [§](https://airtable.com/developers/web/api/field-model#aitext-fieldtype-type)`type` | `"aiText"` |
  83 | | [§](https://airtable.com/developers/web/api/field-model#aitext-fieldtype-options)`options` | `object`
  84 | 
  85 | |     |     |
  86 | | --- | --- |
  87 | | [§](https://airtable.com/developers/web/api/field-model#aitext-fieldtype-options-prompt)`prompt` | `optional<` `array of (strings | the below object)` `>`
  88 | 
  89 | The prompt that is used to generate the results in the AI field, additional object
  90 | types may be added in the future. Currently, this is an array of strings or objects that identify any fields interpolated into the prompt.
  91 | 
  92 | The prompt will not currently be provided if this field config is within another
  93 | fields configuration (like a lookup field)
  94 | 
  95 | ``
  96 | 
  97 | |     |     |
  98 | | --- | --- |
  99 | | [§](https://airtable.com/developers/web/api/field-model#aitext-fieldtype-options-prompt-field)`field` | `object`
 100 | 
 101 | |     |     |
 102 | | --- | --- |
 103 | | [§](https://airtable.com/developers/web/api/field-model#aitext-fieldtype-options-prompt-field-fieldid)`fieldId` | `string` | | |
 104 | | [§](https://airtable.com/developers/web/api/field-model#aitext-fieldtype-options-referencedfieldids)`referencedFieldIds` | `optional<` `array of strings` `>` <br>The other fields in the record that are used in the ai field<br>The referencedFieldIds will not currently be provided if this field config is within another<br>fields configuration (like a lookup field) | |
 105 | 
 106 | ## [§](https://airtable.com/developers/web/api/field-model\#multipleattachment) Attachment
 107 | 
 108 | Attachments allow you to add images, documents, or other files
 109 | which can then be viewed or downloaded.
 110 | 
 111 | URLs returned will expire 2 hours after being returned from our API.
 112 | If you want to persist the attachments, we recommend downloading them instead of saving the URL.
 113 | See our [support article](https://support.airtable.com/docs/changes-to-airtable-attachments) for
 114 | more information.
 115 | 
 116 | Cell format (read)
 117 | 
 118 | `array of the below object`  ``
 119 | 
 120 | |     |     |
 121 | | --- | --- |
 122 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-id)`id` | `string` <br>Unique attachment id |
 123 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-type)`type` | `string` <br>Content type, e.g. "image/jpeg" |
 124 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-filename)`filename` | `string` <br>Filename, e.g. "foo.jpg" |
 125 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-height)`height` | `number` <br>Height, in pixels (these may be available if the attachment is an image) |
 126 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-size)`size` | `number` <br>File size, in bytes |
 127 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-url)`url` | `string` <br>url, e.g. " [https://v5.airtableusercontent.com/foo](https://v5.airtableusercontent.com/foo)".<br>URLs returned will expire 2 hours after being returned from our API.<br>If you want to persist the attachments, we recommend downloading them instead of saving the URL.<br>See [our support article](https://support.airtable.com/docs/airtable-attachment-url-behavior)<br>for more information. |
 128 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-width)`width` | `number` <br>Width, in pixels (these may be available if the attachment is an image) |
 129 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails)`thumbnails` | `object`
 130 | 
 131 | These small, large, and full thumbnails may be available if attachment is an image or document
 132 | 
 133 | |     |     |
 134 | | --- | --- |
 135 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-full)`full` | `optional<` `object` `>`
 136 | 
 137 | |     |     |
 138 | | --- | --- |
 139 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-full-url)`url` | `string` <br>These may be available if the attachment is an image or document. See notes under `url` about the lifetime of these URLs. |
 140 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-full-height)`height` | `number` |
 141 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-full-width)`width` | `number` | |
 142 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-large)`large` | `optional<` `object` `>`
 143 | 
 144 | |     |     |
 145 | | --- | --- |
 146 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-large-url)`url` | `string` <br>These may be available if the attachment is an image or document. See notes under `url` about the lifetime of these URLs. |
 147 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-large-height)`height` | `number` |
 148 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-large-width)`width` | `number` | |
 149 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-small)`small` | `optional<` `object` `>`
 150 | 
 151 | |     |     |
 152 | | --- | --- |
 153 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-small-url)`url` | `string` <br>These may be available if the attachment is an image or document. See notes under `url` about the lifetime of these URLs. |
 154 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-small-height)`height` | `number` |
 155 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-small-width)`width` | `number` | | |
 156 | 
 157 | Cell format (write)
 158 | 
 159 | `array of any of the below objects`
 160 | 
 161 | * * *
 162 | 
 163 | ``
 164 | 
 165 | To create new attachments, provide the url and optionally filename.
 166 | 
 167 | You must also provide the id's for any existing attachment objects you wish to keep.
 168 | 
 169 | Note that in most cases the API does not currently return an error code for failed attachment object creation
 170 | given attachment uploading happens in an asynchronous manner, such cases will manifest with the
 171 | attachment object either being cleared from the cell or persisted with generated URLs that return
 172 | error responses when queried. If the same attachment URL fails to upload multiple times in a short time interval then
 173 | the API may return an ATTACHMENTS\_FAILED\_UPLOADING error code in the details field of the response and the attachment object will
 174 | be cleared from the cell synchronously.
 175 | 
 176 | We also require URLs used to upload have the https:// or http:// protocol (Note: http:// support will be removed in the
 177 | near future), have a limit of 3 max redirects, and a file size limit of 1GB. In addition,
 178 | URLs must be publicly accessible, in cases where cookie authentication or logging
 179 | in to access the file is required, the login page HTML will be downloaded instead of the file.
 180 | 
 181 | |     |     |
 182 | | --- | --- |
 183 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-write-multiple-0-url)`url` | `string` <br>url, e.g. " [https://v5.airtableusercontent.com/foo](https://v5.airtableusercontent.com/foo)".<br>URLs returned will expire 2 hours after being returned from our API.<br>If you want to persist the attachments, we recommend downloading them instead of saving the URL.<br>See [our support article](https://support.airtable.com/docs/airtable-attachment-url-behavior)<br>for more information. |
 184 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-write-multiple-0-filename)`filename` | `optional<` `string` `>` <br>Filename, e.g. "foo.jpg" |
 185 | 
 186 | * * *
 187 | 
 188 | ``
 189 | 
 190 | |     |     |
 191 | | --- | --- |
 192 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-write-multiple-1-id)`id` | `string` <br>When writing an attachment object, be sure to include all existing attachment objects<br>by providing an `id`. This can be retrieved using the [get record endpoint](https://airtable.com/developers/web/api/get-record).<br>To remove attachments, include the existing array of attachment objects,<br>excluding any that you wish to remove. |
 193 | 
 194 | Field type and options
 195 | 
 196 | ``
 197 | 
 198 | |     |     |
 199 | | --- | --- |
 200 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-fieldtype-type)`type` | `"multipleAttachments"` |
 201 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-fieldtype-options)`options` | `object`
 202 | 
 203 | |     |     |
 204 | | --- | --- |
 205 | | [§](https://airtable.com/developers/web/api/field-model#multipleattachment-fieldtype-options-isreversed)`isReversed` | `boolean` <br>Whether attachments are rendered in the reverse order from the cell value in the<br>Airtable UI (i.e. most recent first).<br>You generally do not need to rely on this option. | |
 206 | 
 207 | ## [§](https://airtable.com/developers/web/api/field-model\#autonumber) Auto number
 208 | 
 209 | Automatically incremented unique counter for each record.
 210 | 
 211 | Cell format (read only)
 212 | 
 213 | `number`
 214 | 
 215 | Field type and options (read only)
 216 | 
 217 | ``
 218 | 
 219 | |     |     |
 220 | | --- | --- |
 221 | | [§](https://airtable.com/developers/web/api/field-model#autonumber-fieldtype-type)`type` | `"autoNumber"` |
 222 | 
 223 | ## [§](https://airtable.com/developers/web/api/field-model\#barcode) Barcode
 224 | 
 225 | Use the Airtable iOS or Android app to scan barcodes.
 226 | 
 227 | Cell format
 228 | 
 229 | ``
 230 | 
 231 | The barcode object may contain the following two properties, both of which are optional.
 232 | 
 233 | |     |     |
 234 | | --- | --- |
 235 | | [§](https://airtable.com/developers/web/api/field-model#barcode-cellformat-type)`type` | `optional<` `string | null` `>` <br>Barcode symbology, e.g. "upce" or "code39" |
 236 | | [§](https://airtable.com/developers/web/api/field-model#barcode-cellformat-text)`text` | `string` <br>Barcode data |
 237 | 
 238 | Field type and options
 239 | 
 240 | ``
 241 | 
 242 | |     |     |
 243 | | --- | --- |
 244 | | [§](https://airtable.com/developers/web/api/field-model#barcode-fieldtype-type)`type` | `"barcode"` |
 245 | 
 246 | ## [§](https://airtable.com/developers/web/api/field-model\#button) Button
 247 | 
 248 | A button that can be clicked from the Airtable UI to open a URL or open an extension.
 249 | 
 250 | Cell format (read only)
 251 | 
 252 | ``
 253 | 
 254 | Object providing details about the button configuration.
 255 | 
 256 | |     |     |
 257 | | --- | --- |
 258 | | [§](https://airtable.com/developers/web/api/field-model#button-cellformat-label)`label` | `string` <br>Button label |
 259 | | [§](https://airtable.com/developers/web/api/field-model#button-cellformat-url)`url` | `string | null` <br>For "Open URL" actions, the computed url value |
 260 | 
 261 | Field type and options (read only)
 262 | 
 263 | ``
 264 | 
 265 | |     |     |
 266 | | --- | --- |
 267 | | [§](https://airtable.com/developers/web/api/field-model#button-fieldtype-type)`type` | `"button"` |
 268 | 
 269 | ## [§](https://airtable.com/developers/web/api/field-model\#checkbox) Checkbox
 270 | 
 271 | Cell format
 272 | 
 273 | `true`
 274 | 
 275 | This field is "true" when checked and otherwise empty.
 276 | 
 277 | You can write to the cell with "false", but the read value will be still be "empty" (unchecked).
 278 | 
 279 | Field type and options
 280 | 
 281 | ``
 282 | 
 283 | Bases on a free or plus plan are limited to using the `'check'` icon and `'greenBright'` color.
 284 | 
 285 | |     |     |
 286 | | --- | --- |
 287 | | [§](https://airtable.com/developers/web/api/field-model#checkbox-fieldtype-type)`type` | `"checkbox"` |
 288 | | [§](https://airtable.com/developers/web/api/field-model#checkbox-fieldtype-options)`options` | `object`
 289 | 
 290 | |     |     |
 291 | | --- | --- |
 292 | | [§](https://airtable.com/developers/web/api/field-model#checkbox-fieldtype-options-color)`color` | `"greenBright" | "tealBright" | "cyanBright" | "blueBright" | "purpleBright" | "pinkBright" | "redBright" | "orangeBright" | "yellowBright" | "grayBright"` <br>The color of the checkbox. |
 293 | | [§](https://airtable.com/developers/web/api/field-model#checkbox-fieldtype-options-icon)`icon` | `"check" | "xCheckbox" | "star" | "heart" | "thumbsUp" | "flag" | "dot"` <br>The icon name of the checkbox. | |
 294 | 
 295 | ## [§](https://airtable.com/developers/web/api/field-model\#collaborator) Collaborator
 296 | 
 297 | A collaborator field lets you add collaborators to your records.
 298 | Collaborators can optionally be notified when they're added (using the field settings in
 299 | the UI). A single collaborator field has been configured to only reference
 300 | one user collaborator.
 301 | 
 302 | Cell format (read)
 303 | 
 304 | ``
 305 | 
 306 | Object providing details about the user collaborator in this field.
 307 | 
 308 | |     |     |
 309 | | --- | --- |
 310 | | [§](https://airtable.com/developers/web/api/field-model#collaborator-cellformat-id)`id` | `string` <br>User id or group id |
 311 | | [§](https://airtable.com/developers/web/api/field-model#collaborator-cellformat-email)`email` | `optional<` `string` `>` <br>User's email address |
 312 | | [§](https://airtable.com/developers/web/api/field-model#collaborator-cellformat-name)`name` | `optional<` `string` `>` <br>User's display name (may be omitted if the user hasn't created an account) |
 313 | | [§](https://airtable.com/developers/web/api/field-model#collaborator-cellformat-permissionlevel)`permissionLevel` | `optional<``"none" | "read" | "comment" | "edit" | "create"` `>` <br>User's collaborator permission Level<br>This is only included if you're observing a webhooks response. |
 314 | | [§](https://airtable.com/developers/web/api/field-model#collaborator-cellformat-profilepicurl)`profilePicUrl` | `optional<` `string` `>` <br>User's profile picture<br>This is only included if it exists for the user **and** you're observing a webhooks response. |
 315 | 
 316 | Cell format (write)
 317 | 
 318 | `any of the below objects`
 319 | 
 320 | * * *
 321 | 
 322 | ``
 323 | 
 324 | |     |     |
 325 | | --- | --- |
 326 | | [§](https://airtable.com/developers/web/api/field-model#collaborator-cellformat-write-multiple-0-id)`id` | `string` <br>The user id, group id of the user |
 327 | 
 328 | * * *
 329 | 
 330 | ``
 331 | 
 332 | |     |     |
 333 | | --- | --- |
 334 | | [§](https://airtable.com/developers/web/api/field-model#collaborator-cellformat-write-multiple-1-email)`email` | `string` <br>The user's email address |
 335 | 
 336 | Field type and options
 337 | 
 338 | ``
 339 | 
 340 | |     |     |
 341 | | --- | --- |
 342 | | [§](https://airtable.com/developers/web/api/field-model#collaborator-fieldtype-type)`type` | `"singleCollaborator"` |
 343 | | [§](https://airtable.com/developers/web/api/field-model#collaborator-fieldtype-options)`options` | `optional<` `object` `>`
 344 | 
 345 | |
 346 | | |
 347 | 
 348 | ## [§](https://airtable.com/developers/web/api/field-model\#count) Count
 349 | 
 350 | Number of linked records, from a linked record field in the same table.
 351 | 
 352 | Cell format (read only)
 353 | 
 354 | `number`
 355 | 
 356 | Field type and options (read only)
 357 | 
 358 | ``
 359 | 
 360 | |     |     |
 361 | | --- | --- |
 362 | | [§](https://airtable.com/developers/web/api/field-model#count-fieldtype-type)`type` | `"count"` |
 363 | | [§](https://airtable.com/developers/web/api/field-model#count-fieldtype-options)`options` | `object`
 364 | 
 365 | |     |     |
 366 | | --- | --- |
 367 | | [§](https://airtable.com/developers/web/api/field-model#count-fieldtype-options-isvalid)`isValid` | `boolean` <br>`false` when recordLinkFieldId is null, e.g. the referenced column was deleted. |
 368 | | [§](https://airtable.com/developers/web/api/field-model#count-fieldtype-options-recordlinkfieldid)`recordLinkFieldId` | `optional<` `string | null` `>` | |
 369 | 
 370 | ## [§](https://airtable.com/developers/web/api/field-model\#createdby) Created by
 371 | 
 372 | The collaborator who created the record.
 373 | 
 374 | Cell format (read only)
 375 | 
 376 | ``
 377 | 
 378 | Object providing details about the user collaborator in this field.
 379 | 
 380 | |     |     |
 381 | | --- | --- |
 382 | | [§](https://airtable.com/developers/web/api/field-model#createdby-cellformat-id)`id` | `string` <br>User id or group id |
 383 | | [§](https://airtable.com/developers/web/api/field-model#createdby-cellformat-email)`email` | `optional<` `string` `>` <br>User's email address |
 384 | | [§](https://airtable.com/developers/web/api/field-model#createdby-cellformat-name)`name` | `optional<` `string` `>` <br>User's display name (may be omitted if the user hasn't created an account) |
 385 | | [§](https://airtable.com/developers/web/api/field-model#createdby-cellformat-permissionlevel)`permissionLevel` | `optional<``"none" | "read" | "comment" | "edit" | "create"` `>` <br>User's collaborator permission Level<br>This is only included if you're observing a webhooks response. |
 386 | | [§](https://airtable.com/developers/web/api/field-model#createdby-cellformat-profilepicurl)`profilePicUrl` | `optional<` `string` `>` <br>User's profile picture<br>This is only included if it exists for the user **and** you're observing a webhooks response. |
 387 | 
 388 | Field type and options (read only)
 389 | 
 390 | ``
 391 | 
 392 | |     |     |
 393 | | --- | --- |
 394 | | [§](https://airtable.com/developers/web/api/field-model#createdby-fieldtype-type)`type` | `"createdBy"` |
 395 | 
 396 | ## [§](https://airtable.com/developers/web/api/field-model\#createdtime) Created time
 397 | 
 398 | The time the record was created in UTC e.g. "2022-08-29T07:00:00.000Z" or "2022-08-29"
 399 | 
 400 | Cell format (read only)
 401 | 
 402 | `string`
 403 | 
 404 | Field type and options (read only)
 405 | 
 406 | ``
 407 | 
 408 | |     |     |
 409 | | --- | --- |
 410 | | [§](https://airtable.com/developers/web/api/field-model#createdtime-fieldtype-type)`type` | `"createdTime"` |
 411 | | [§](https://airtable.com/developers/web/api/field-model#createdtime-fieldtype-options)`options` | `object`
 412 | 
 413 | |     |     |
 414 | | --- | --- |
 415 | | [§](https://airtable.com/developers/web/api/field-model#createdtime-fieldtype-options-result)`result` | `optional<` `any of the below objects` `>` <br>This will always be a `date` or `dateTime` field config.<br>* * *<br>[`Date field config`](https://airtable.com/developers/web/api/field-model#dateonly)<br>* * *<br>[`Date-time field config`](https://airtable.com/developers/web/api/field-model#dateandtime) | |
 416 | 
 417 | ## [§](https://airtable.com/developers/web/api/field-model\#currencynumber) Currency
 418 | 
 419 | Currency value. Symbol set with the field config.
 420 | 
 421 | Cell format
 422 | 
 423 | `number`
 424 | 
 425 | Field type and options
 426 | 
 427 | ``
 428 | 
 429 | |     |     |
 430 | | --- | --- |
 431 | | [§](https://airtable.com/developers/web/api/field-model#currencynumber-fieldtype-type)`type` | `"currency"` |
 432 | | [§](https://airtable.com/developers/web/api/field-model#currencynumber-fieldtype-options)`options` | `object`
 433 | 
 434 | |     |     |
 435 | | --- | --- |
 436 | | [§](https://airtable.com/developers/web/api/field-model#currencynumber-fieldtype-options-precision)`precision` | `number` <br>Indicates the number of digits shown to the right of the decimal point for this field. (0-7 inclusive) |
 437 | | [§](https://airtable.com/developers/web/api/field-model#currencynumber-fieldtype-options-symbol)`symbol` | `string` <br>Currency symbol to use. | |
 438 | 
 439 | ## [§](https://airtable.com/developers/web/api/field-model\#dateonly) Date
 440 | 
 441 | String (ISO 8601 formatted date)
 442 | 
 443 | UTC date, e.g. "2022-09-05".
 444 | 
 445 | Cell format
 446 | 
 447 | `string`
 448 | 
 449 | A date.
 450 | 
 451 | When reading from and writing to a date field, the cell value will always be an
 452 | [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html)
 453 | formatted date. (Field options specify how it's formatted in the main Airtable UI - format
 454 | can be used with [moment.js](https://momentjs.com/) to match that.)
 455 | 
 456 | The date format string follows the moment.js structure documented
 457 | [here](https://momentjs.com/docs/#/parsing/string-format/).
 458 | 
 459 | When using the Airtable.js library you can also use a [Date object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date).
 460 | 
 461 | Field type and options (read)
 462 | 
 463 | ``
 464 | 
 465 | |     |     |
 466 | | --- | --- |
 467 | | [§](https://airtable.com/developers/web/api/field-model#dateonly-fieldtype-type)`type` | `"date"` |
 468 | | [§](https://airtable.com/developers/web/api/field-model#dateonly-fieldtype-options)`options` | `object`
 469 | 
 470 | |     |     |
 471 | | --- | --- |
 472 | | [§](https://airtable.com/developers/web/api/field-model#dateonly-fieldtype-options-dateformat)`dateFormat` | `object`
 473 | 
 474 | |     |     |
 475 | | --- | --- |
 476 | | [§](https://airtable.com/developers/web/api/field-model#dateonly-fieldtype-options-dateformat-format)`format` | `"l" | "LL" | "M/D/YYYY" | "D/M/YYYY" | "YYYY-MM-DD"` <br>`format` is always provided when reading.<br>( `l` for local, `LL` for friendly, `M/D/YYYY` for us, `D/M/YYYY` for european, `YYYY-MM-DD` for iso) |
 477 | | [§](https://airtable.com/developers/web/api/field-model#dateonly-fieldtype-options-dateformat-name)`name` | `"local" | "friendly" | "us" | "european" | "iso"` | | |
 478 | 
 479 | Field type and options (write)
 480 | 
 481 | ``
 482 | 
 483 | |     |     |
 484 | | --- | --- |
 485 | | [§](https://airtable.com/developers/web/api/field-model#dateonly-fieldtype-write-type)`type` | `"date"` |
 486 | | [§](https://airtable.com/developers/web/api/field-model#dateonly-fieldtype-write-options)`options` | `object`
 487 | 
 488 | |     |     |
 489 | | --- | --- |
 490 | | [§](https://airtable.com/developers/web/api/field-model#dateonly-fieldtype-write-options-dateformat)`dateFormat` | `object`
 491 | 
 492 | |     |     |
 493 | | --- | --- |
 494 | | [§](https://airtable.com/developers/web/api/field-model#dateonly-fieldtype-write-options-dateformat-format)`format` | `optional<``"l" | "LL" | "M/D/YYYY" | "D/M/YYYY" | "YYYY-MM-DD"` `>` <br>Format is optional when writing, but it must match<br>the corresponding name if provided.<br>( `l` for local, `LL` for friendly, `M/D/YYYY` for us, `D/M/YYYY` for european, `YYYY-MM-DD` for iso) |
 495 | | [§](https://airtable.com/developers/web/api/field-model#dateonly-fieldtype-write-options-dateformat-name)`name` | `"local" | "friendly" | "us" | "european" | "iso"` | | |
 496 | 
 497 | ## [§](https://airtable.com/developers/web/api/field-model\#dateandtime) Date and time
 498 | 
 499 | String (ISO 8601 formatted date)
 500 | 
 501 | UTC date and time, e.g. "2022-09-05T07:00:00.000Z".
 502 | 
 503 | Cell format
 504 | 
 505 | `string`
 506 | 
 507 | A date and time.
 508 | 
 509 | When reading from and writing to a date field, the cell value will always be an
 510 | [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html)
 511 | formatted date. (Field options specify how it's formatted in the main Airtable UI - format
 512 | can be used with [moment.js](https://momentjs.com/) to match that.)
 513 | 
 514 | When using the Airtable.js library you can also use a [Date object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date).
 515 | 
 516 | When writing to a `dateTime` field configured with a non `utc` or `client` time zone like `America/Los_Angeles`,
 517 | ambiguous string inputs like "2020-09-05T07:00:00" and "2020-09-08" will be interpreted according
 518 | to the `timeZone` of the field instead of `utc`, and nonambiguous string inputs with zone offset like "2020-09-05T07:00:00.000Z"
 519 | and "2020-09-08T00:00:00-07:00" will be interpreted correctly as the underlying timestamp.
 520 | 
 521 | Field type and options (read)
 522 | 
 523 | ``
 524 | 
 525 | |     |     |
 526 | | --- | --- |
 527 | | [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-type)`type` | `"dateTime"` |
 528 | | [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-options)`options` | `object`
 529 | 
 530 | |     |     |
 531 | | --- | --- |
 532 | | [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-options-timezone)`timeZone` | [`Timezone`](https://airtable.com/developers/web/api/model/timezone) |
 533 | | [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-options-dateformat)`dateFormat` | `object`
 534 | 
 535 | |     |     |
 536 | | --- | --- |
 537 | | [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-options-dateformat-format)`format` | `"l" | "LL" | "M/D/YYYY" | "D/M/YYYY" | "YYYY-MM-DD"` <br>`format` is always provided when reading.<br>( `l` for local, `LL` for friendly, `M/D/YYYY` for us, `D/M/YYYY` for european, `YYYY-MM-DD` for iso) |
 538 | | [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-options-dateformat-name)`name` | `"local" | "friendly" | "us" | "european" | "iso"` | |
 539 | | [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-options-timeformat)`timeFormat` | `object`
 540 | 
 541 | |     |     |
 542 | | --- | --- |
 543 | | [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-options-timeformat-format)`format` | `"h:mma" | "HH:mm"` |
 544 | | [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-options-timeformat-name)`name` | `"12hour" | "24hour"` | | |
 545 | 
 546 | Field type and options (write)
 547 | 
 548 | ``
 549 | 
 550 | |     |     |
 551 | | --- | --- |
 552 | | [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-write-type)`type` | `"dateTime"` |
 553 | | [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-write-options)`options` | `object`
 554 | 
 555 | |     |     |
 556 | | --- | --- |
 557 | | [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-write-options-timezone)`timeZone` | [`Timezone`](https://airtable.com/developers/web/api/model/timezone) |
 558 | | [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-write-options-dateformat)`dateFormat` | `object`
 559 | 
 560 | |     |     |
 561 | | --- | --- |
 562 | | [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-write-options-dateformat-format)`format` | `optional<``"l" | "LL" | "M/D/YYYY" | "D/M/YYYY" | "YYYY-MM-DD"` `>` <br>Format is optional when writing, but it must match<br>the corresponding name if provided.<br>( `l` for local, `LL` for friendly, `M/D/YYYY` for us, `D/M/YYYY` for european, `YYYY-MM-DD` for iso) |
 563 | | [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-write-options-dateformat-name)`name` | `"local" | "friendly" | "us" | "european" | "iso"` | |
 564 | | [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-write-options-timeformat)`timeFormat` | `object`
 565 | 
 566 | |     |     |
 567 | | --- | --- |
 568 | | [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-write-options-timeformat-name)`name` | `"12hour" | "24hour"` |
 569 | | [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-write-options-timeformat-format)`format` | `optional<``"h:mma" | "HH:mm"` `>` | | |
 570 | 
 571 | ## [§](https://airtable.com/developers/web/api/field-model\#durationnumber) Duration
 572 | 
 573 | An integer representing number of seconds.
 574 | 
 575 | Cell format
 576 | 
 577 | `number`
 578 | 
 579 | Field type and options
 580 | 
 581 | ``
 582 | 
 583 | |     |     |
 584 | | --- | --- |
 585 | | [§](https://airtable.com/developers/web/api/field-model#durationnumber-fieldtype-type)`type` | `"duration"` |
 586 | | [§](https://airtable.com/developers/web/api/field-model#durationnumber-fieldtype-options)`options` | `object`
 587 | 
 588 | |     |     |
 589 | | --- | --- |
 590 | | [§](https://airtable.com/developers/web/api/field-model#durationnumber-fieldtype-options-durationformat)`durationFormat` | `"h:mm" | "h:mm:ss" | "h:mm:ss.S" | "h:mm:ss.SS" | "h:mm:ss.SSS"` | |
 591 | 
 592 | ## [§](https://airtable.com/developers/web/api/field-model\#emailtext) Email
 593 | 
 594 | A valid email address.
 595 | 
 596 | Cell format
 597 | 
 598 | `string`
 599 | 
 600 | Field type and options
 601 | 
 602 | ``
 603 | 
 604 | |     |     |
 605 | | --- | --- |
 606 | | [§](https://airtable.com/developers/web/api/field-model#emailtext-fieldtype-type)`type` | `"email"` |
 607 | 
 608 | ## [§](https://airtable.com/developers/web/api/field-model\#formula) Formula
 609 | 
 610 | Compute a value in each record based on other fields in the same record.
 611 | 
 612 | Cell format (read only)
 613 | 
 614 | `string | number | true | array of (strings | numbers)`
 615 | 
 616 | Computed value - Check options.result to know the resulting field type.
 617 | 
 618 | Field type and options (read only)
 619 | 
 620 | ``
 621 | 
 622 | |     |     |
 623 | | --- | --- |
 624 | | [§](https://airtable.com/developers/web/api/field-model#formula-fieldtype-type)`type` | `"formula"` |
 625 | | [§](https://airtable.com/developers/web/api/field-model#formula-fieldtype-options)`options` | `object`
 626 | 
 627 | |     |     |
 628 | | --- | --- |
 629 | | [§](https://airtable.com/developers/web/api/field-model#formula-fieldtype-options-formula)`formula` | `string` <br>The formula including fields referenced by their IDs. For example, LEFT(4, {Birthday})<br>in the Airtable.com formula editor will be returned as LEFT(4, {fldXXX}) via API. |
 630 | | [§](https://airtable.com/developers/web/api/field-model#formula-fieldtype-options-isvalid)`isValid` | `boolean` <br>`false` if the formula contains an error. |
 631 | | [§](https://airtable.com/developers/web/api/field-model#formula-fieldtype-options-referencedfieldids)`referencedFieldIds` | `array of strings | null` <br>All fields in the record that are used in the formula. |
 632 | | [§](https://airtable.com/developers/web/api/field-model#formula-fieldtype-options-result)`result` | `Field type and options | null` <br>The resulting field type and options returned by the formula. See other field<br>type configs on this page for the possible values. Can be null if invalid. | |
 633 | 
 634 | ## [§](https://airtable.com/developers/web/api/field-model\#lastmodifiedby) Last modified by
 635 | 
 636 | Shows the collaborator who most recently modified any editable field or just in specific editable fields.
 637 | 
 638 | Cell format (read only)
 639 | 
 640 | ``
 641 | 
 642 | Object providing details about the user collaborator in this field.
 643 | 
 644 | |     |     |
 645 | | --- | --- |
 646 | | [§](https://airtable.com/developers/web/api/field-model#lastmodifiedby-cellformat-id)`id` | `string` <br>User id or group id |
 647 | | [§](https://airtable.com/developers/web/api/field-model#lastmodifiedby-cellformat-email)`email` | `optional<` `string` `>` <br>User's email address |
 648 | | [§](https://airtable.com/developers/web/api/field-model#lastmodifiedby-cellformat-name)`name` | `optional<` `string` `>` <br>User's display name (may be omitted if the user hasn't created an account) |
 649 | | [§](https://airtable.com/developers/web/api/field-model#lastmodifiedby-cellformat-permissionlevel)`permissionLevel` | `optional<``"none" | "read" | "comment" | "edit" | "create"` `>` <br>User's collaborator permission Level<br>This is only included if you're observing a webhooks response. |
 650 | | [§](https://airtable.com/developers/web/api/field-model#lastmodifiedby-cellformat-profilepicurl)`profilePicUrl` | `optional<` `string` `>` <br>User's profile picture<br>This is only included if it exists for the user **and** you're observing a webhooks response. |
 651 | 
 652 | Field type and options (read only)
 653 | 
 654 | ``
 655 | 
 656 | |     |     |
 657 | | --- | --- |
 658 | | [§](https://airtable.com/developers/web/api/field-model#lastmodifiedby-fieldtype-type)`type` | `"lastModifiedBy"` |
 659 | 
 660 | ## [§](https://airtable.com/developers/web/api/field-model\#lastmodifiedtime) Last modified time
 661 | 
 662 | The time the record was last modified in UTC e.g. "2022-08-29T07:00:00.000Z" or "2022-08-29"
 663 | 
 664 | Cell format (read only)
 665 | 
 666 | `string`
 667 | 
 668 | Field type and options (read only)
 669 | 
 670 | ``
 671 | 
 672 | |     |     |
 673 | | --- | --- |
 674 | | [§](https://airtable.com/developers/web/api/field-model#lastmodifiedtime-fieldtype-type)`type` | `"lastModifiedTime"` |
 675 | | [§](https://airtable.com/developers/web/api/field-model#lastmodifiedtime-fieldtype-options)`options` | `object`
 676 | 
 677 | |     |     |
 678 | | --- | --- |
 679 | | [§](https://airtable.com/developers/web/api/field-model#lastmodifiedtime-fieldtype-options-isvalid)`isValid` | `boolean` <br>False if this formula/field configuation has an error |
 680 | | [§](https://airtable.com/developers/web/api/field-model#lastmodifiedtime-fieldtype-options-referencedfieldids)`referencedFieldIds` | `array of strings | null` <br>The fields to check the last modified time of |
 681 | | [§](https://airtable.com/developers/web/api/field-model#lastmodifiedtime-fieldtype-options-result)`result` | `null | any of the below objects` <br>This will always be a `date` or `dateTime` field config.<br>* * *<br>[`Date field config`](https://airtable.com/developers/web/api/field-model#dateonly)<br>* * *<br>[`Date-time field config`](https://airtable.com/developers/web/api/field-model#dateandtime) | |
 682 | 
 683 | ## [§](https://airtable.com/developers/web/api/field-model\#foreignkey) Link to another record
 684 | 
 685 | Cell format V1
 686 | 
 687 | `array of strings`
 688 | 
 689 | Array of linked records IDs from the linked table.
 690 | 
 691 | Cell format V2 (webhooks)
 692 | 
 693 | `array of the below object`  ``
 694 | 
 695 | |     |     |
 696 | | --- | --- |
 697 | | [§](https://airtable.com/developers/web/api/field-model#foreignkey-cellformat-v-2-id)`id` | `string` <br>Record ID |
 698 | | [§](https://airtable.com/developers/web/api/field-model#foreignkey-cellformat-v-2-name)`name` | `string` |
 699 | 
 700 | Field type and options (read)
 701 | 
 702 | ``
 703 | 
 704 | |     |     |
 705 | | --- | --- |
 706 | | [§](https://airtable.com/developers/web/api/field-model#foreignkey-fieldtype-type)`type` | `"multipleRecordLinks"` |
 707 | | [§](https://airtable.com/developers/web/api/field-model#foreignkey-fieldtype-options)`options` | `object`
 708 | 
 709 | |     |     |
 710 | | --- | --- |
 711 | | [§](https://airtable.com/developers/web/api/field-model#foreignkey-fieldtype-options-isreversed)`isReversed` | `boolean` <br>Whether linked records are rendered in the reverse order from the cell value in the<br>Airtable UI (i.e. most recent first).<br>You generally do not need to rely on this option. |
 712 | | [§](https://airtable.com/developers/web/api/field-model#foreignkey-fieldtype-options-linkedtableid)`linkedTableId` | `string` <br>The ID of the table this field links to |
 713 | | [§](https://airtable.com/developers/web/api/field-model#foreignkey-fieldtype-options-preferssinglerecordlink)`prefersSingleRecordLink` | `boolean` <br>Whether this field prefers to only have a single linked record. While this preference<br>is enforced in the Airtable UI, it is possible for a field that prefers single linked<br>records to have multiple record links (for example, via copy-and-paste or programmatic<br>updates). |
 714 | | [§](https://airtable.com/developers/web/api/field-model#foreignkey-fieldtype-options-inverselinkfieldid)`inverseLinkFieldId` | `optional<` `string` `>` <br>The ID of the field in the linked table that links back<br>to this one |
 715 | | [§](https://airtable.com/developers/web/api/field-model#foreignkey-fieldtype-options-viewidforrecordselection)`viewIdForRecordSelection` | `optional<` `string` `>` <br>The ID of the view in the linked table to use when showing<br>a list of records to select from. | |
 716 | 
 717 | Field type and options (write)
 718 | 
 719 | ``
 720 | 
 721 | Creating "multipleRecordLinks" fields is supported but updating options for
 722 | existing "multipleRecordLinks" fields is not supported.
 723 | 
 724 | |     |     |
 725 | | --- | --- |
 726 | | [§](https://airtable.com/developers/web/api/field-model#foreignkey-fieldtype-write-type)`type` | `"multipleRecordLinks"` |
 727 | | [§](https://airtable.com/developers/web/api/field-model#foreignkey-fieldtype-write-options)`options` | `object`
 728 | 
 729 | |     |     |
 730 | | --- | --- |
 731 | | [§](https://airtable.com/developers/web/api/field-model#foreignkey-fieldtype-write-options-linkedtableid)`linkedTableId` | `string` <br>The ID of the table this field links to |
 732 | | [§](https://airtable.com/developers/web/api/field-model#foreignkey-fieldtype-write-options-viewidforrecordselection)`viewIdForRecordSelection` | `optional<` `string` `>` <br>The ID of the view in the linked table<br>to use when showing a list of records to select from | |
 733 | 
 734 | ## [§](https://airtable.com/developers/web/api/field-model\#multilinetext) Long text
 735 | 
 736 | Cell format
 737 | 
 738 | `string`
 739 | 
 740 | Multiple lines of text, which may contain "mention tokens", e.g.
 741 | `<airtable:mention id="menE1i9oBaGX3DseR">@Alex</airtable:mention>`
 742 | 
 743 | Field type and options
 744 | 
 745 | ``
 746 | 
 747 | |     |     |
 748 | | --- | --- |
 749 | | [§](https://airtable.com/developers/web/api/field-model#multilinetext-fieldtype-type)`type` | `"multilineText"` |
 750 | 
 751 | ## [§](https://airtable.com/developers/web/api/field-model\#lookup) Lookup
 752 | 
 753 | Lookup a field on linked records.
 754 | 
 755 | Cell format V1 (read only)
 756 | 
 757 | `array of (numbers | strings | booleans | any)`
 758 | 
 759 | Array of cell values from a field in the linked table.
 760 | 
 761 | Cell format V2 (webhooks)
 762 | 
 763 | ``
 764 | 
 765 | |     |     |
 766 | | --- | --- |
 767 | | [§](https://airtable.com/developers/web/api/field-model#lookup-cellformat-v-2-valuesbylinkedrecordid)`valuesByLinkedRecordId` | `object`
 768 | 
 769 | |     |     |
 770 | | --- | --- |
 771 | | `key: string` | `array of any` | |
 772 | | [§](https://airtable.com/developers/web/api/field-model#lookup-cellformat-v-2-linkedrecordids)`linkedRecordIds` | `array of strings` |
 773 | 
 774 | Field type and options (read only)
 775 | 
 776 | ``
 777 | 
 778 | |     |     |
 779 | | --- | --- |
 780 | | [§](https://airtable.com/developers/web/api/field-model#lookup-fieldtype-type)`type` | `"multipleLookupValues"` |
 781 | | [§](https://airtable.com/developers/web/api/field-model#lookup-fieldtype-options)`options` | `object`
 782 | 
 783 | |     |     |
 784 | | --- | --- |
 785 | | [§](https://airtable.com/developers/web/api/field-model#lookup-fieldtype-options-fieldidinlinkedtable)`fieldIdInLinkedTable` | `string | null` <br>The field in the linked table that this field is looking up. |
 786 | | [§](https://airtable.com/developers/web/api/field-model#lookup-fieldtype-options-isvalid)`isValid` | `boolean` <br>Is the field currently valid (e.g. false if the linked record field has<br>been deleted) |
 787 | | [§](https://airtable.com/developers/web/api/field-model#lookup-fieldtype-options-recordlinkfieldid)`recordLinkFieldId` | `string | null` <br>The linked record field in the current table. |
 788 | | [§](https://airtable.com/developers/web/api/field-model#lookup-fieldtype-options-result)`result` | `Field type and options | null` <br>The field type and options inside of the linked table. See other field<br>type configs on this page for the possible values. Can be null if invalid. | |
 789 | 
 790 | ## [§](https://airtable.com/developers/web/api/field-model\#multicollaborator) Multiple collaborator
 791 | 
 792 | Array of objects providing details about the user or [user group](https://support.airtable.com/docs/user-groups) collaborators in this field.
 793 | 
 794 | Note: Adding user groups to multiple collaborator fields is an enterprise feature.
 795 | 
 796 | Cell format (read)
 797 | 
 798 | `array of the below object`  ``
 799 | 
 800 | Object providing details about the user collaborator in this field.
 801 | 
 802 | |     |     |
 803 | | --- | --- |
 804 | | [§](https://airtable.com/developers/web/api/field-model#multicollaborator-cellformat-id)`id` | `string` <br>User id or group id |
 805 | | [§](https://airtable.com/developers/web/api/field-model#multicollaborator-cellformat-email)`email` | `optional<` `string` `>` <br>User's email address |
 806 | | [§](https://airtable.com/developers/web/api/field-model#multicollaborator-cellformat-name)`name` | `optional<` `string` `>` <br>User's display name (may be omitted if the user hasn't created an account) |
 807 | | [§](https://airtable.com/developers/web/api/field-model#multicollaborator-cellformat-permissionlevel)`permissionLevel` | `optional<``"none" | "read" | "comment" | "edit" | "create"` `>` <br>User's collaborator permission Level<br>This is only included if you're observing a webhooks response. |
 808 | | [§](https://airtable.com/developers/web/api/field-model#multicollaborator-cellformat-profilepicurl)`profilePicUrl` | `optional<` `string` `>` <br>User's profile picture<br>This is only included if it exists for the user **and** you're observing a webhooks response. |
 809 | 
 810 | Cell format (write)
 811 | 
 812 | `array of strings`
 813 | 
 814 | Array of user or group ids
 815 | 
 816 | Similar to [multipleAttachments](https://airtable.com/developers/web/api/field-model#multiple-attachment) and
 817 | [multipleSelects](https://airtable.com/developers/web/api/field-model#multi-select), this array-type field will override the current
 818 | cell value when being updated. Be sure to spread the current cell value if you want to keep
 819 | the currently selected collaborators.
 820 | 
 821 | Field type and options
 822 | 
 823 | ``
 824 | 
 825 | |     |     |
 826 | | --- | --- |
 827 | | [§](https://airtable.com/developers/web/api/field-model#multicollaborator-fieldtype-type)`type` | `"multipleCollaborators"` |
 828 | | [§](https://airtable.com/developers/web/api/field-model#multicollaborator-fieldtype-options)`options` | `object`
 829 | 
 830 | |
 831 | | |
 832 | 
 833 | ## [§](https://airtable.com/developers/web/api/field-model\#multiselect) Multiple select
 834 | 
 835 | Array of selected option names.
 836 | 
 837 | When creating or updating records, if a choice string does not exactly match an existing option,
 838 | the request will fail with an `INVALID_MULTIPLE_CHOICE_OPTIONS` error unless the `typecast`
 839 | parameter is enabled. If `typecast` is enabled, a new choice will be created if one does
 840 | not exactly match.
 841 | 
 842 | Similar to `multipleAttachments` and `multipleCollaborators`, this array-type field will override
 843 | the current cell value when being updated. Be sure to spread the current cell value if
 844 | you want to keep the currently selected choices.
 845 | 
 846 | Cell format V1
 847 | 
 848 | `array of strings`
 849 | 
 850 | Array of selected option names.
 851 | 
 852 | Cell format V2 (webhooks)
 853 | 
 854 | `array of the below object`  ``
 855 | 
 856 | |     |     |
 857 | | --- | --- |
 858 | | [§](https://airtable.com/developers/web/api/field-model#multiselect-cellformat-v-2-id)`id` | `string` |
 859 | | [§](https://airtable.com/developers/web/api/field-model#multiselect-cellformat-v-2-color)`color` | `optional<` `string` `>` <br>Optional when the select field is configured to not use colors.<br>Allowed values: "blueLight2", "cyanLight2", "tealLight2", "greenLight2", "yellowLight2", "orangeLight2", "redLight2", "pinkLight2", "purpleLight2", "grayLight2", "blueLight1", "cyanLight1", "tealLight1", "greenLight1", "yellowLight1", "orangeLight1", "redLight1", "pinkLight1", "purpleLight1", "grayLight1", "blueBright", "cyanBright", "tealBright", "greenBright", "yellowBright", "orangeBright", "redBright", "pinkBright", "purpleBright", "grayBright", "blueDark1", "cyanDark1", "tealDark1", "greenDark1", "yellowDark1", "orangeDark1", "redDark1", "pinkDark1", "purpleDark1", "grayDark1" |
 860 | | [§](https://airtable.com/developers/web/api/field-model#multiselect-cellformat-v-2-name)`name` | `string` |
 861 | 
 862 | Field type and options (read)
 863 | 
 864 | ``
 865 | 
 866 | |     |     |
 867 | | --- | --- |
 868 | | [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-type)`type` | `"multipleSelects"` |
 869 | | [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-options)`options` | `object`
 870 | 
 871 | |     |     |
 872 | | --- | --- |
 873 | | [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-options-choices)`choices` | `array of the below object`  ``
 874 | 
 875 | |     |     |
 876 | | --- | --- |
 877 | | [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-options-choices-id)`id` | `string` |
 878 | | [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-options-choices-color)`color` | `optional<` `string` `>` <br>Optional when the select field is configured to not use colors.<br>Allowed values: "blueLight2", "cyanLight2", "tealLight2", "greenLight2", "yellowLight2", "orangeLight2", "redLight2", "pinkLight2", "purpleLight2", "grayLight2", "blueLight1", "cyanLight1", "tealLight1", "greenLight1", "yellowLight1", "orangeLight1", "redLight1", "pinkLight1", "purpleLight1", "grayLight1", "blueBright", "cyanBright", "tealBright", "greenBright", "yellowBright", "orangeBright", "redBright", "pinkBright", "purpleBright", "grayBright", "blueDark1", "cyanDark1", "tealDark1", "greenDark1", "yellowDark1", "orangeDark1", "redDark1", "pinkDark1", "purpleDark1", "grayDark1" |
 879 | | [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-options-choices-name)`name` | `string` | | |
 880 | 
 881 | Field type and options (write)
 882 | 
 883 | ``
 884 | 
 885 | |     |     |
 886 | | --- | --- |
 887 | | [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-write-type)`type` | `"multipleSelects"` |
 888 | | [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-write-options)`options` | `object`
 889 | 
 890 | |     |     |
 891 | | --- | --- |
 892 | | [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-write-options-choices)`choices` | `array of the below object`  ``
 893 | 
 894 | |     |     |
 895 | | --- | --- |
 896 | | [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-write-options-choices-id)`id` | `optional<` `string` `>` <br>This is not specified when creating new options, useful when specifing existing<br>options (for example: reordering options, keeping old options and adding new ones, etc) |
 897 | | [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-write-options-choices-color)`color` | `optional<` `string` `>` <br>Optional when creating an option. |
 898 | | [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-write-options-choices-name)`name` | `string` | | |
 899 | 
 900 | ## [§](https://airtable.com/developers/web/api/field-model\#decimalorintegernumber) Number
 901 | 
 902 | A integer(whole number, e.g. 1, 32, 99) or decimal number showing decimal digits. Precision set with the field config.
 903 | 
 904 | Cell format
 905 | 
 906 | `number`
 907 | 
 908 | Field type and options
 909 | 
 910 | ``
 911 | 
 912 | |     |     |
 913 | | --- | --- |
 914 | | [§](https://airtable.com/developers/web/api/field-model#decimalorintegernumber-fieldtype-type)`type` | `"number"` |
 915 | | [§](https://airtable.com/developers/web/api/field-model#decimalorintegernumber-fieldtype-options)`options` | `object`
 916 | 
 917 | |     |     |
 918 | | --- | --- |
 919 | | [§](https://airtable.com/developers/web/api/field-model#decimalorintegernumber-fieldtype-options-precision)`precision` | `number` <br>Indicates the number of digits shown to the right of the decimal point for this field. (0-8 inclusive) | |
 920 | 
 921 | ## [§](https://airtable.com/developers/web/api/field-model\#percentnumber) Percent
 922 | 
 923 | Decimal number representing a percentage value. For example, the underlying cell value for 12.3% is 0.123.
 924 | 
 925 | Cell format
 926 | 
 927 | `number`
 928 | 
 929 | Field type and options
 930 | 
 931 | ``
 932 | 
 933 | |     |     |
 934 | | --- | --- |
 935 | | [§](https://airtable.com/developers/web/api/field-model#percentnumber-fieldtype-type)`type` | `"percent"` |
 936 | | [§](https://airtable.com/developers/web/api/field-model#percentnumber-fieldtype-options)`options` | `object`
 937 | 
 938 | |     |     |
 939 | | --- | --- |
 940 | | [§](https://airtable.com/developers/web/api/field-model#percentnumber-fieldtype-options-precision)`precision` | `number` <br>Indicates the number of digits shown to the right of the decimal point for this field. (0-8 inclusive) | |
 941 | 
 942 | ## [§](https://airtable.com/developers/web/api/field-model\#phone) Phone
 943 | 
 944 | A telephone number, e.g. "(415) 555-9876".
 945 | 
 946 | Cell format
 947 | 
 948 | `string`
 949 | 
 950 | Field type and options
 951 | 
 952 | ``
 953 | 
 954 | |     |     |
 955 | | --- | --- |
 956 | | [§](https://airtable.com/developers/web/api/field-model#phone-fieldtype-type)`type` | `"phoneNumber"` |
 957 | 
 958 | ## [§](https://airtable.com/developers/web/api/field-model\#rating) Rating
 959 | 
 960 | A positive integer (e.g. "3 stars" is 3). A rating cannot be 0.
 961 | 
 962 | Cell format
 963 | 
 964 | `number`
 965 | 
 966 | Field type and options
 967 | 
 968 | ``
 969 | 
 970 | Bases on a free or plus plan are limited to using the 'star' icon and 'yellowBright' color.
 971 | 
 972 | |     |     |
 973 | | --- | --- |
 974 | | [§](https://airtable.com/developers/web/api/field-model#rating-fieldtype-type)`type` | `"rating"` |
 975 | | [§](https://airtable.com/developers/web/api/field-model#rating-fieldtype-options)`options` | `object`
 976 | 
 977 | |     |     |
 978 | | --- | --- |
 979 | | [§](https://airtable.com/developers/web/api/field-model#rating-fieldtype-options-color)`color` | `"yellowBright" | "orangeBright" | "redBright" | "pinkBright" | "purpleBright" | "blueBright" | "cyanBright" | "tealBright" | "greenBright" | "grayBright"` <br>The color of selected icons. |
 980 | | [§](https://airtable.com/developers/web/api/field-model#rating-fieldtype-options-icon)`icon` | `"star" | "heart" | "thumbsUp" | "flag" | "dot"` <br>The icon name used to display the rating. |
 981 | | [§](https://airtable.com/developers/web/api/field-model#rating-fieldtype-options-max)`max` | `number` <br>The maximum value for the rating, from 1 to 10 inclusive. | |
 982 | 
 983 | ## [§](https://airtable.com/developers/web/api/field-model\#richtext) Rich text
 984 | 
 985 | Long text (with rich text formatting enabled)
 986 | 
 987 | A Markdown-inspired markup language.
 988 | [Learn more about using Markdown in long text's rich text formatting API.](https://support.airtable.com/docs/using-rich-text-with-airtable)
 989 | 
 990 | Cell format
 991 | 
 992 | `string`
 993 | 
 994 | Field type and options
 995 | 
 996 | ``
 997 | 
 998 | |     |     |
 999 | | --- | --- |
1000 | | [§](https://airtable.com/developers/web/api/field-model#richtext-fieldtype-type)`type` | `"richText"` |
1001 | 
1002 | ## [§](https://airtable.com/developers/web/api/field-model\#rollup) Rollup
1003 | 
1004 | A rollup allows you to summarize data from records that are linked to this table.
1005 | 
1006 | Cell format V1 (read only)
1007 | 
1008 | `string | number | true`
1009 | 
1010 | Cell format V2 (webhooks)
1011 | 
1012 | `any`
1013 | 
1014 | Field type and options (read only)
1015 | 
1016 | ``
1017 | 
1018 | |     |     |
1019 | | --- | --- |
1020 | | [§](https://airtable.com/developers/web/api/field-model#rollup-fieldtype-type)`type` | `"rollup"` |
1021 | | [§](https://airtable.com/developers/web/api/field-model#rollup-fieldtype-options)`options` | `object`
1022 | 
1023 | |     |     |
1024 | | --- | --- |
1025 | | [§](https://airtable.com/developers/web/api/field-model#rollup-fieldtype-options-fieldidinlinkedtable)`fieldIdInLinkedTable` | `optional<` `string` `>` <br>The id of the field in the linked table |
1026 | | [§](https://airtable.com/developers/web/api/field-model#rollup-fieldtype-options-recordlinkfieldid)`recordLinkFieldId` | `optional<` `string` `>` <br>The linked field id |
1027 | | [§](https://airtable.com/developers/web/api/field-model#rollup-fieldtype-options-result)`result` | `optional<` `Field type and options | null` `>` <br>The resulting field type and options for the rollup. See other field<br>type configs on this page for the possible values. Can be null if invalid. |
1028 | | [§](https://airtable.com/developers/web/api/field-model#rollup-fieldtype-options-isvalid)`isValid` | `optional<` `boolean` `>` |
1029 | | [§](https://airtable.com/developers/web/api/field-model#rollup-fieldtype-options-referencedfieldids)`referencedFieldIds` | `optional<` `array of strings` `>` <br>The ids of any fields referenced in the rollup formula | |
1030 | 
1031 | ## [§](https://airtable.com/developers/web/api/field-model\#simpletext) Single line text
1032 | 
1033 | A single line of text.
1034 | 
1035 | Cell format
1036 | 
1037 | `string`
1038 | 
1039 | Field type and options
1040 | 
1041 | ``
1042 | 
1043 | |     |     |
1044 | | --- | --- |
1045 | | [§](https://airtable.com/developers/web/api/field-model#simpletext-fieldtype-type)`type` | `"singleLineText"` |
1046 | 
1047 | ## [§](https://airtable.com/developers/web/api/field-model\#select) Single select
1048 | 
1049 | Selected option name.
1050 | 
1051 | When creating or updating records, if the choice string does not exactly match an existing option,
1052 | the request will fail with an `INVALID_MULTIPLE_CHOICE_OPTIONS` error unless the `typecast` parameter
1053 | is enabled. If `typecast` is enabled, a new choice will be created if one does not exactly match.
1054 | 
1055 | Cell format V1
1056 | 
1057 | `string`
1058 | 
1059 | Cell format V2 (webhooks)
1060 | 
1061 | ``
1062 | 
1063 | |     |     |
1064 | | --- | --- |
1065 | | [§](https://airtable.com/developers/web/api/field-model#select-cellformat-v-2-id)`id` | `string` |
1066 | | [§](https://airtable.com/developers/web/api/field-model#select-cellformat-v-2-color)`color` | `optional<` `string` `>` <br>Optional when the select field is configured to not use colors.<br>Allowed values: "blueLight2", "cyanLight2", "tealLight2", "greenLight2", "yellowLight2", "orangeLight2", "redLight2", "pinkLight2", "purpleLight2", "grayLight2", "blueLight1", "cyanLight1", "tealLight1", "greenLight1", "yellowLight1", "orangeLight1", "redLight1", "pinkLight1", "purpleLight1", "grayLight1", "blueBright", "cyanBright", "tealBright", "greenBright", "yellowBright", "orangeBright", "redBright", "pinkBright", "purpleBright", "grayBright", "blueDark1", "cyanDark1", "tealDark1", "greenDark1", "yellowDark1", "orangeDark1", "redDark1", "pinkDark1", "purpleDark1", "grayDark1" |
1067 | | [§](https://airtable.com/developers/web/api/field-model#select-cellformat-v-2-name)`name` | `string` |
1068 | 
1069 | Field type and options (read)
1070 | 
1071 | ``
1072 | 
1073 | |     |     |
1074 | | --- | --- |
1075 | | [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-type)`type` | `"singleSelect"` |
1076 | | [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-options)`options` | `object`
1077 | 
1078 | |     |     |
1079 | | --- | --- |
1080 | | [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-options-choices)`choices` | `array of the below object`  ``
1081 | 
1082 | |     |     |
1083 | | --- | --- |
1084 | | [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-options-choices-id)`id` | `string` |
1085 | | [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-options-choices-color)`color` | `optional<` `string` `>` <br>Optional when the select field is configured to not use colors.<br>Allowed values: "blueLight2", "cyanLight2", "tealLight2", "greenLight2", "yellowLight2", "orangeLight2", "redLight2", "pinkLight2", "purpleLight2", "grayLight2", "blueLight1", "cyanLight1", "tealLight1", "greenLight1", "yellowLight1", "orangeLight1", "redLight1", "pinkLight1", "purpleLight1", "grayLight1", "blueBright", "cyanBright", "tealBright", "greenBright", "yellowBright", "orangeBright", "redBright", "pinkBright", "purpleBright", "grayBright", "blueDark1", "cyanDark1", "tealDark1", "greenDark1", "yellowDark1", "orangeDark1", "redDark1", "pinkDark1", "purpleDark1", "grayDark1" |
1086 | | [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-options-choices-name)`name` | `string` | | |
1087 | 
1088 | Field type and options (write)
1089 | 
1090 | ``
1091 | 
1092 | |     |     |
1093 | | --- | --- |
1094 | | [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-write-type)`type` | `"singleSelect"` |
1095 | | [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-write-options)`options` | `object`
1096 | 
1097 | |     |     |
1098 | | --- | --- |
1099 | | [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-write-options-choices)`choices` | `array of the below object`  ``
1100 | 
1101 | |     |     |
1102 | | --- | --- |
1103 | | [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-write-options-choices-id)`id` | `optional<` `string` `>` <br>This is not specified when creating new options, useful when specifing existing<br>options (for example: reordering options, keeping old options and adding new ones, etc) |
1104 | | [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-write-options-choices-color)`color` | `optional<` `string` `>` <br>Optional when creating an option. |
1105 | | [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-write-options-choices-name)`name` | `string` | | |
1106 | 
1107 | ## [§](https://airtable.com/developers/web/api/field-model\#syncsource) Sync source
1108 | 
1109 | Shows the name of the source that a record is synced from. This field is only available on synced tables.
1110 | 
1111 | Cell format V1 (read only)
1112 | 
1113 | `string`
1114 | 
1115 | The sync source name.
1116 | 
1117 | Cell format V2 (webhooks)
1118 | 
1119 | ``
1120 | 
1121 | |     |     |
1122 | | --- | --- |
1123 | | [§](https://airtable.com/developers/web/api/field-model#syncsource-cellformat-v-2-id)`id` | `string` <br>The id unique for this source within this base. **Not** the baseId. |
1124 | | [§](https://airtable.com/developers/web/api/field-model#syncsource-cellformat-v-2-name)`name` | `string` <br>The sync source name. |
1125 | | [§](https://airtable.com/developers/web/api/field-model#syncsource-cellformat-v-2-color)`color` | `optional<` `string` `>` |
1126 | 
1127 | Field type and options
1128 | 
1129 | ``
1130 | 
1131 | |     |     |
1132 | | --- | --- |
1133 | | [§](https://airtable.com/developers/web/api/field-model#syncsource-fieldtype-type)`type` | `"externalSyncSource"` |
1134 | | [§](https://airtable.com/developers/web/api/field-model#syncsource-fieldtype-options)`options` | `object`
1135 | 
1136 | |     |     |
1137 | | --- | --- |
1138 | | [§](https://airtable.com/developers/web/api/field-model#syncsource-fieldtype-options-choices)`choices` | `array of the below object`  ``
1139 | 
1140 | |     |     |
1141 | | --- | --- |
1142 | | [§](https://airtable.com/developers/web/api/field-model#syncsource-fieldtype-options-choices-id)`id` | `string` |
1143 | | [§](https://airtable.com/developers/web/api/field-model#syncsource-fieldtype-options-choices-color)`color` | `optional<` `string` `>` <br>Optional when the select field is configured to not use colors.<br>Allowed values: "blueLight2", "cyanLight2", "tealLight2", "greenLight2", "yellowLight2", "orangeLight2", "redLight2", "pinkLight2", "purpleLight2", "grayLight2", "blueLight1", "cyanLight1", "tealLight1", "greenLight1", "yellowLight1", "orangeLight1", "redLight1", "pinkLight1", "purpleLight1", "grayLight1", "blueBright", "cyanBright", "tealBright", "greenBright", "yellowBright", "orangeBright", "redBright", "pinkBright", "purpleBright", "grayBright", "blueDark1", "cyanDark1", "tealDark1", "greenDark1", "yellowDark1", "orangeDark1", "redDark1", "pinkDark1", "purpleDark1", "grayDark1" |
1144 | | [§](https://airtable.com/developers/web/api/field-model#syncsource-fieldtype-options-choices-name)`name` | `string` | | |
1145 | 
1146 | ## [§](https://airtable.com/developers/web/api/field-model\#urltext) Url
1147 | 
1148 | A valid URL (e.g. airtable.com or [https://airtable.com/universe](https://airtable.com/universe)).
1149 | 
1150 | Cell format
1151 | 
1152 | `string`
1153 | 
1154 | Field type and options
1155 | 
1156 | ``
1157 | 
1158 | |     |     |
1159 | | --- | --- |
1160 | | [§](https://airtable.com/developers/web/api/field-model#urltext-fieldtype-type)`type` | `"url"` |
1161 | 
1162 | 
1163 | 
```
Page 1/3FirstPrevNextLast