This is page 1 of 3. Use http://codebase.md/felores/airtable-mcp?lines=false&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:
--------------------------------------------------------------------------------
```
node_modules/
build/
.env
*.log
```
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
```
# Source
src/
# Development files
.git/
.github/
.gitignore
.vscode/
.idea/
*.log
# Test files
test/
__tests__/
*.test.ts
*.spec.ts
# Configuration files
tsconfig.json
.eslintrc*
.prettierrc*
# Documentation
docs/
*.md
!README.md
# Build artifacts
*.tsbuildinfo
```
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
```markdown
# Airtable MCP Server
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.
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.
## Requirements: Node.js
1. Install Node.js (version 18 or higher) and npm from [nodejs.org](https://nodejs.org/)
2. Verify installation:
```bash
node --version
npm --version
```
⚠️ **Important**: Before running, make sure to setup your Airtable API key
## Obtaining an Airtable API Key
1. Log in to your Airtable account at [airtable.com](https://airtable.com)
2. Create a personal access token at [Airtable's Builder Hub](https://airtable.com/create/tokens)
3. In the Personal access token section select these scopes:
- data.records:read
- data.records:write
- schema.bases:read
- schema.bases:write
4. Select the workspace or bases you want to give access to the personal access token
5. Keep this key secure - you'll need it for configuration
## Installation
### Method 1: Using npx (Recommended)
1. Navigate to the Claude configuration directory:
- Windows: `C:\Users\NAME\AppData\Roaming\Claude`
- macOS: `~/Library/Application Support/Claude/`
You can also find these directories inside the Claude Desktop app: Claude Desktop > Settings > Developer > Edit Config
2. Create or edit `claude_desktop_config.json`:
```json
{
"mcpServers": {
"airtable": {
"command": "npx",
"args": ["@felores/airtable-mcp-server"],
"env": {
"AIRTABLE_API_KEY": "your_api_key_here"
}
}
}
}
```
Note: For Windows paths, use double backslashes (\\) or forward slashes (/).
### Method 2: Using mcp-installer:
mcp-installer is a MCP server to install other MCP servers.
1. Install [mcp-installer](https://github.com/anaisbetts/mcp-installer)
2. Install the Airtable MCP server by prompting Claude Desktop:
```bash
Install @felores/airtable-mcp-server set the environment variable AIRTABLE_API_KEY to 'your_api_key'
```
Claude will install the server, modify the configuration file and set the environment variable AIRTABLE_API_KEY to your Airtable API key.
### Method 3: Local Development Installation
If you want to contribute or modify the code run this in your terminal:
```bash
# Clone the repository
git clone https://github.com/felores/airtable-mcp.git
cd airtable-mcp
# Install dependencies
npm install
# Build the server
npm run build
# Run locally
node build/index.js
```
Then modify the Claude Desktop configuration file to use the local installation:
```json
{
"mcpServers": {
"airtable": {
"command": "node",
"args": ["path/to/airtable-mcp/build/index.js"],
"env": {
"AIRTABLE_API_KEY": "your_api_key_here"
}
}
}
}
```
### Verifying Installation
1. Start Claude Desktop
2. The Airtable MCP server should be listed in the "Connected MCP Servers" section
3. Test with a simple command:
```
List all bases
```
## Features
### Available Operations
#### Base Management
- `list_bases`: List all accessible Airtable bases
- `list_tables`: List all tables in a base
- `create_table`: Create a new table with fields
- `update_table`: Update a table's name or description
#### Field Management
- `create_field`: Add a new field to a table
- `update_field`: Modify an existing field
#### Record Operations
- `list_records`: Retrieve records from a table
- `create_record`: Add a new record
- `update_record`: Modify an existing record
- `delete_record`: Remove a record
- `search_records`: Find records matching criteria
- `get_record`: Get a single record by its ID
### Field Types
- `singleLineText`: Single line text field
- `multilineText`: Multi-line text area
- `email`: Email address field
- `phoneNumber`: Phone number field
- `number`: Numeric field with optional precision
- `currency`: Money field with currency symbol
- `date`: Date field with format options
- `singleSelect`: Single choice from options
- `multiSelect`: Multiple choices from options
### Field Colors
Available colors for select fields:
- `blueBright`, `redBright`, `greenBright`
- `yellowBright`, `purpleBright`, `pinkBright`
- `grayBright`, `cyanBright`, `orangeBright`
- `blueDark1`, `greenDark1`
## Contributing
We welcome contributions to improve the Airtable MCP server! Here's how you can contribute:
1. Fork the Repository
- Visit https://github.com/felores/airtable-mcp
- Click the "Fork" button in the top right
- Clone your fork locally:
```bash
git clone https://github.com/your-username/airtable-mcp.git
```
2. Create a Feature Branch
```bash
git checkout -b feature/your-feature-name
```
3. Make Your Changes
- Follow the existing code style
- Add tests if applicable
- Update documentation as needed
4. Commit Your Changes
```bash
git add .
git commit -m "feat: add your feature description"
```
5. Push to Your Fork
```bash
git push origin feature/your-feature-name
```
6. Create a Pull Request
- Go to your fork on GitHub
- Click "New Pull Request"
- Select your feature branch
- Describe your changes in detail
### Development Guidelines
- Use TypeScript for new code
- Follow semantic commit messages
- Update documentation for new features
- Add examples for new functionality
- Test your changes thoroughly
### Getting Help
- Open an issue for bugs or feature requests
- Join discussions in existing issues
- Ask questions in pull requests
Your contributions help make this tool better for everyone. Whether it's:
- Adding new features
- Fixing bugs
- Improving documentation
- Suggesting enhancements
We appreciate your help in making the Airtable MCP server more powerful and user-friendly!
## License
[MIT](LICENSE)
---
Made with ❤️ by the Airtable MCP community
```
--------------------------------------------------------------------------------
/scripts/post-build.js:
--------------------------------------------------------------------------------
```javascript
import { chmod } from 'fs/promises';
import { platform } from 'os';
if (platform() !== 'win32') {
await chmod('build/index.js', '755');
}
```
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
```json
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
```
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
```json
{
"name": "@felores/airtable-mcp-server",
"version": "0.3.0",
"description": "An Airtable Model Context Protocol Server",
"type": "module",
"bin": {
"airtable-server": "build/index.js"
},
"files": [
"build",
"scripts"
],
"scripts": {
"build": "tsc && node scripts/post-build.js",
"prepare": "npm run build",
"watch": "tsc --watch",
"inspector": "npx @modelcontextprotocol/inspector build/index.js"
},
"dependencies": {
"@modelcontextprotocol/sdk": "0.6.0",
"axios": "^1.7.9"
},
"devDependencies": {
"@types/node": "^20.11.24",
"typescript": "^5.3.3"
},
"author": "Felipe Restrepo",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/felores/airtable-mcp"
},
"keywords": [
"airtable",
"mcp",
"model-context-protocol",
"claude",
"api"
],
"engines": {
"node": ">=16.0.0"
}
}
```
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
```typescript
// Field type definitions for Airtable
export type FieldType =
| 'singleLineText'
| 'multilineText'
| 'number'
| 'singleSelect'
| 'multiSelect'
| 'date'
| 'checkbox'
| 'email'
| 'phoneNumber'
| 'currency';
export interface FieldOption {
name: string;
type: FieldType;
description?: string;
options?: Record<string, any>;
}
export const fieldRequiresOptions = (type: FieldType): boolean => {
switch (type) {
case 'number':
case 'singleSelect':
case 'multiSelect':
case 'date':
case 'currency':
return true;
default:
return false;
}
};
export const getDefaultOptions = (type: FieldType): Record<string, any> | undefined => {
switch (type) {
case 'number':
return { precision: 0 };
case 'date':
return { dateFormat: { name: 'local' } };
case 'currency':
return { precision: 2, symbol: '$' };
default:
return undefined;
}
};
```
--------------------------------------------------------------------------------
/prompts/system-prompt.md:
--------------------------------------------------------------------------------
```markdown
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:
## Core Principles
1. **Incremental Creation**
- Always create tables in stages, starting with basic fields
- Add one complex field at a time
- Verify each operation before proceeding
- Handle errors gracefully and provide clear feedback
2. **Field Type Categories**
Basic Fields (No Options Required):
- `singleLineText`: Single line of text
- `multilineText`: Multiple lines of text
- `email`: Valid email address
- `phoneNumber`: Phone number in any format
- `richText`: Text with formatting
- `url`: Valid URL
Complex Fields (Require Options):
- `number`: Requires precision (0-8)
- `currency`: Requires precision and symbol
- `percent`: Requires precision (0-8)
- `rating`: Requires max value (1-10) and icon/color
- `duration`: Requires format
- `date`: Requires dateFormat
- `dateTime`: Requires dateFormat and timeFormat
- `singleSelect`: Requires choices with names and colors
- `multipleSelects`: Requires choices with names and colors
- `checkbox`: Optional icon and color
- `barcode`: Supports various formats
- `button`: Configurable actions
- `count`: Automatic counter
- `autoNumber`: Automatic unique counter
- `formula`: Computed values
- `rollup`: Aggregated values from linked records
- `lookup`: Values from linked records
- `multipleRecordLinks`: Links to other records
- `attachment`: File attachments
3. **Creation Order**
1. Create table with basic text fields
2. Add numeric fields (number, currency, percent)
3. Add date/time fields
4. Add select/choice fields
5. Add computed fields (formula, rollup, lookup)
6. Add relationship fields (record links)
7. Verify each field after creation
## Field Configuration Reference
1. **Number Fields**
```json
{
"type": "number",
"options": {
"precision": 0 // 0 for integers, 1-8 for decimals
}
}
```
2. **Currency Fields**
```json
{
"type": "currency",
"options": {
"precision": 2,
"symbol": "$" // Currency symbol
}
}
```
3. **Date Fields**
```json
{
"type": "date",
"options": {
"dateFormat": {
"name": "local" // Options: local, friendly, us, european, iso
}
}
}
```
4. **DateTime Fields**
```json
{
"type": "dateTime",
"options": {
"dateFormat": {
"name": "local" // Options: local, friendly, us, european, iso
},
"timeFormat": {
"name": "12hour" // Options: 12hour, 24hour
}
}
}
```
5. **Select Fields**
```json
{
"type": "singleSelect",
"options": {
"choices": [
{
"name": "Option Name",
"color": "colorName" // Colors: blueBright, greenBright, redBright, yellowBright, pinkBright, purpleBright, cyanBright, grayBright
}
]
}
}
```
6. **Rating Fields**
```json
{
"type": "rating",
"options": {
"max": 5, // 1-10
"color": "yellowBright", // Standard color options
"icon": "star" // Options: star, heart, thumbsUp, flag, dot
}
}
```
## Implementation Steps
1. **Create Table with Basic Fields**
```json
{
"name": "create_table",
"arguments": {
"base_id": "your_base_id",
"table_name": "Your Table Name",
"description": "Table description",
"fields": [
{
"name": "Title",
"type": "singleLineText",
"description": "Title field"
},
{
"name": "Notes",
"type": "multilineText",
"description": "Notes field"
}
]
}
}
```
2. **Add Complex Fields (One at a Time)**
```json
{
"name": "create_field",
"arguments": {
"base_id": "your_base_id",
"table_id": "your_table_id",
"field": {
"name": "Field Name",
"type": "field_type",
"description": "Field description",
"options": {
// Field-specific options here
}
}
}
}
```
## Error Handling & Best Practices
1. **Validation**
- Verify each field after creation
- Test with sample data
- Check field options are correctly applied
- Validate field names and descriptions
- Ensure required options are provided
- Verify field type compatibility
2. **Error Recovery**
- If field creation fails, do not proceed to next field
- Verify field options match specifications exactly
- Retry failed field creation with corrected options
- Log errors for debugging
- Provide clear error messages
3. **Testing**
- Create test records after adding fields
- Update records to verify field behavior
- Test field constraints and validations
- Verify computed fields
- Test relationships between tables
4. **Security**
- Validate all inputs
- Sanitize field names and descriptions
- Use appropriate field types for sensitive data
- Implement proper access controls
- Follow rate limiting guidelines
## Response Format
When responding to table creation requests:
1. Acknowledge the request and outline the plan
2. Create the table with basic fields first
3. Add complex fields one at a time
4. Verify each step
5. Report success or handle errors
6. Provide guidance for next steps
Example response format:
```
I'll help you create the [table_name] table with the following steps:
1. Create table with basic fields:
- [field1]: [type]
- [field2]: [type]
2. Add complex fields:
- [field3]: [type] with [options]
- [field4]: [type] with [options]
I'll proceed with each step and verify completion before moving to the next one.
```
Remember to:
- Be explicit about each action
- Verify each step
- Handle errors gracefully
- Provide clear feedback
- Guide the user through the process
```
--------------------------------------------------------------------------------
/docs/mcp-llm-guide.md:
--------------------------------------------------------------------------------
```markdown
# MCP Development Guide for LLMs
This guide provides structured information for LLMs to assist in creating, modifying, and using Model Context Protocol (MCP) servers.
## 1. Core Concepts
### Protocol Overview
- MCP enables standardized communication between LLM applications and integrations
- Uses client-server architecture with JSON-RPC 2.0 message format
- Latest protocol version: 2024-11-05
- Supports stdio and SSE transports
### Key Components
1. **Hosts**: LLM applications that initiate connections (e.g., Claude Desktop)
2. **Clients**: Maintain 1:1 connections with servers
3. **Servers**: Provide context, tools, and prompts to clients
4. **Resources**: File-like data that can be read by clients
5. **Tools**: Functions that can be called by the LLM
6. **Prompts**: Pre-written templates for specific tasks
## 2. Server Implementation Guidelines
### Server Structure
1. Core Server Class:
```typescript
class Server extends Protocol<ServerRequest, ServerNotification, ServerResult> {
constructor(serverInfo: Implementation, options: ServerOptions)
// Must implement base protocol methods
}
```
2. Required Capabilities:
```typescript
interface ServerCapabilities {
experimental?: object;
logging?: object;
prompts?: { listChanged?: boolean };
resources?: {
subscribe?: boolean;
listChanged?: boolean
};
tools?: { listChanged?: boolean };
}
```
### Essential Implementation Steps
1. **Server Initialization**:
```typescript
const server = new Server(
{
name: "your-server-name",
version: "1.0.0"
},
{
capabilities: {
// Declare supported capabilities
resources: {},
tools: {},
prompts: {}
}
}
);
```
2. **Request Handlers**:
```typescript
// Example tool handler
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: "tool-name",
description: "Tool description",
inputSchema: {
type: "object",
properties: {
// Define parameters
}
}
}
]
}));
```
3. **Transport Setup**:
```typescript
const transport = new StdioServerTransport();
await server.connect(transport);
```
## 3. Core Features Implementation
### Resources
```typescript
interface Resource {
uri: string;
name: string;
description?: string;
mimeType?: string;
}
// Handler example
server.setRequestHandler(ListResourcesRequestSchema, async () => ({
resources: [
{
uri: "custom://resource",
name: "Resource Name",
description: "Resource description"
}
]
}));
```
### Tools
```typescript
interface Tool {
name: string;
description?: string;
inputSchema: {
type: "object";
properties?: object;
required?: string[];
};
}
// Handler example
server.setRequestHandler(CallToolRequestSchema, async (request) => ({
content: [
{
type: "text",
text: "Tool execution result"
}
]
}));
```
### Prompts
```typescript
interface Prompt {
name: string;
description?: string;
arguments?: PromptArgument[];
}
// Handler example
server.setRequestHandler(GetPromptRequestSchema, async (request) => ({
messages: [
{
role: "user",
content: {
type: "text",
text: "Prompt template"
}
}
]
}));
```
## 4. Best Practices
### Error Handling
1. Use appropriate error codes:
```typescript
enum ErrorCode {
ParseError = -32700,
InvalidRequest = -32600,
MethodNotFound = -32601,
InvalidParams = -32602,
InternalError = -32603
}
```
2. Tool errors should be in result:
```typescript
{
isError: true,
content: [{
type: "text",
text: "Error description"
}]
}
```
### Security Considerations
1. Input Validation:
- Validate all parameters against schemas
- Sanitize file paths and system commands
- Validate URLs and external identifiers
- Check parameter sizes and ranges
2. Access Control:
- Implement authentication where needed
- Use appropriate authorization checks
- Audit tool usage
- Rate limit requests
3. Resource Protection:
- Validate resource paths
- Monitor resource usage
- Implement access controls
- Rate limit requests
### Message Handling
1. Request Processing:
- Validate inputs thoroughly
- Use type-safe schemas
- Handle errors gracefully
- Implement timeouts
2. Progress Reporting:
- Use progress tokens for long operations
- Report progress incrementally
- Include total progress when known
## 5. Client Integration Guidelines
### Client Configuration
```json
{
"mcpServers": {
"server-name": {
"command": "command-to-run",
"args": ["arg1", "arg2"],
"env": {
"ENV_VAR": "value"
}
}
}
}
```
### Environment Variables
- Server inherits limited environment variables
- Custom variables must be specified in config
- Sensitive data should be in environment variables
## 6. Testing and Debugging
### MCP Inspector Usage
1. Start inspector with server:
```bash
npx mcp-inspector your-server-command
```
2. Features to test:
- Resource listing and reading
- Tool execution
- Prompt generation
- Error handling
- Progress reporting
### Common Issues
1. Connection Problems:
- Check transport configuration
- Verify server process is running
- Check for initialization errors
2. Message Handling:
- Validate message formats
- Check handler implementations
- Verify error responses
3. Resource Issues:
- Check file permissions
- Validate URI formats
- Verify content types
## 7. Performance and Scaling
### Best Practices
1. Resource Management:
- Cache when appropriate
- Implement cleanup
- Monitor memory usage
2. Request Handling:
- Use appropriate timeouts
- Implement rate limiting
- Handle concurrent requests
3. Error Recovery:
- Implement reconnection logic
- Handle partial failures
- Clean up resources
## 8. Documentation Requirements
### Server Documentation
1. Capabilities Documentation:
- List supported features
- Document configuration options
- Describe environment variables
2. API Documentation:
- Document all resources
- Document all tools
- Document all prompts
- Include example usage
3. Error Documentation:
- List possible error codes
- Describe error conditions
- Include recovery steps
### Integration Guide
1. Setup Instructions:
- Installation steps
- Configuration options
- Environment setup
2. Usage Examples:
- Basic usage patterns
- Common integrations
- Error handling examples
## 9. Versioning and Updates
### Version Management
1. Protocol Versioning:
- Support LATEST_PROTOCOL_VERSION
- Handle version negotiation
- Maintain compatibility
2. Server Versioning:
- Use semantic versioning
- Document breaking changes
- Provide migration guides
### Update Handling
1. Capability Updates:
- Notify clients of changes
- Handle capability negotiation
- Maintain backwards compatibility
2. Resource Updates:
- Handle resource changes
- Notify subscribed clients
- Maintain consistency
## 10. Specific Server Types
### Database Servers (like Airtable)
1. Required Capabilities:
- Resources for data access
- Tools for data manipulation
- Prompts for common operations
2. Implementation Focus:
- Connection management
- Query handling
- Data transformation
- Error handling
- Rate limiting
3. Security Considerations:
- API key management
- Access control
- Data validation
- Request sanitization
4. Tools to Implement:
- List databases/bases
- Create/modify tables
- Query data
- Update records
- Delete records
5. Resource Structure:
- Database schema
- Table contents
- Query results
6. Error Handling:
- Connection errors
- Query errors
- Rate limit errors
- Authorization errors
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.
```
--------------------------------------------------------------------------------
/prompts/project-knowledge.md:
--------------------------------------------------------------------------------
```markdown
# Airtable MCP Server Guide
## Table of Contents
1. [MCP Server Tools Overview](#mcp-server-tools-overview)
- Available Tools and Use Cases
- Tool Dependencies and Workflow
- Rate Limiting and Performance
- Tool Authorization Requirements
2. [Base Management](#base-management)
- Listing and Discovering Bases
- Table Operations
- Base Configuration
- Access Control
3. [Field Management](#field-management)
- Field Types and Options
- Field Creation and Updates
- Field Dependencies
- Data Validation
4. [Record Operations](#record-operations)
- Reading and Querying Records
- Creating and Updating Records
- Batch Operations
- Search and Filtering
## MCP Server Tools Overview
### Available Tools and Use Cases
1. **Base Management Tools**
a. **list_bases**
- **Purpose**: Lists all accessible Airtable bases
- **Key Considerations**:
- Requires valid API key
- Returns only bases with access permissions
- Useful for initial discovery
- **Best Practices**:
- Cache base IDs for frequent operations
- Verify base accessibility before operations
- Handle pagination if many bases
b. **list_tables**
- **Purpose**: Lists all tables in a specified base
- **Key Considerations**:
- Requires base_id
- Returns table metadata
- Useful for table discovery
- **Best Practices**:
- Cache table IDs for frequent operations
- Verify table existence before operations
- Handle pagination for large bases
c. **create_table**
- **Purpose**: Creates a new table in an Airtable base
- **Key Considerations**:
- Requires base_id and table name
- Can create multiple basic fields in one operation
- Should be used first in any table creation workflow
- Validate table name uniqueness in the base
- **Best Practices**:
- Start with essential basic fields only
- Use clear, descriptive table names
- Add proper table description
- Follow naming conventions
d. **update_table**
- **Purpose**: Updates a table's name or description
- **Key Considerations**:
- Requires base_id and table_id
- Can modify name and description
- Existing data remains unchanged
- **Best Practices**:
- Verify table existence before update
- Maintain naming consistency
- Update documentation accordingly
2. **Field Management Tools**
a. **create_field**
- **Purpose**: Adds a new field to an existing table
- **Key Considerations**:
- Requires both base_id and table_id
- Add one field at a time for complex types
- Field options must match type requirements
- **Best Practices**:
- Verify field creation before adding next
- Use descriptive field names
- Include field descriptions
- Configure appropriate field options
b. **update_field**
- **Purpose**: Modifies existing field configuration
- **Key Considerations**:
- Can update name, description, and options
- Some field types have immutable properties
- Changes may affect existing data
- **Best Practices**:
- Backup data before significant changes
- Test changes on sample records
- Update documentation accordingly
- Verify field behavior after changes
3. **Record Operation Tools**
a. **list_records**
- **Purpose**: Retrieves records from a table
- **Key Considerations**:
- Supports filtering and sorting
- Handles pagination
- Can specify fields to return
- **Best Practices**:
- Use field selection for performance
- Implement pagination for large datasets
- Cache results when appropriate
- Handle rate limits
b. **create_record**
- **Purpose**: Adds new records to a table
- **Key Considerations**:
- Validates field types
- Handles required fields
- Supports multiple records
- **Best Practices**:
- Validate data before submission
- Handle batch operations efficiently
- Verify record creation
- Implement error recovery
c. **update_record**
- **Purpose**: Modifies existing records
- **Key Considerations**:
- Requires record ID
- Partial updates supported
- Field validation applied
- **Best Practices**:
- Verify record existence
- Backup data before updates
- Handle field type constraints
- Log changes for audit
d. **delete_record**
- **Purpose**: Removes records from a table
- **Key Considerations**:
- Operation is irreversible
- Can affect linked records
- Supports batch deletion
- **Best Practices**:
- Verify record selection
- Backup before deletion
- Check dependencies
- Implement confirmation
e. **search_records**
- **Purpose**: Finds records matching criteria
- **Key Considerations**:
- Supports complex filters
- Can use multiple fields
- Returns paginated results
- **Best Practices**:
- Optimize search criteria
- Handle no results case
- Implement pagination
- Cache frequent searches
f. **get_record**
- **Purpose**: Retrieves a single record by ID
- **Key Considerations**:
- Direct record access
- Returns all or selected fields
- Efficient for single record ops
- **Best Practices**:
- Verify record existence
- Handle missing records
- Select needed fields only
- Cache when appropriate
### Tool Dependencies and Workflow
```mermaid
graph TD
A[list_bases] --> B[list_tables]
B --> C[create_table]
C --> D[create_field]
D --> E[update_field]
B --> F[list_records]
F --> G[create_record]
F --> H[update_record]
F --> I[delete_record]
F --> J[search_records]
F --> K[get_record]
C --> L[update_table]
```
### Rate Limiting and Performance
1. **API Constraints**
- Respect Airtable's rate limits
- Implement exponential backoff
- Handle throttling gracefully
- Monitor API usage
2. **Operation Timing**
- Allow time between operations
- Verify completion before next step
- Handle timeouts appropriately
- Log operation durations
3. **Resource Management**
- Monitor memory usage
- Clean up temporary resources
- Handle connection issues
- Implement proper error recovery
### Tool Authorization Requirements
1. **Authentication**
- Personal access token required
- OAuth integration support
- Proper scope configuration
- Token management best practices
2. **Permissions**
- Base creator role needed
- Verify write permissions
- Check field-level access
- Handle permission errors
## Base Management
## Table Management
### Available Table Tools
1. **list_tables**
- **Purpose**: Lists all tables in a specified base
- **Key Considerations**:
- Requires base_id
- Returns table metadata
- Useful for table discovery
- **Best Practices**:
- Cache table IDs for frequent operations
- Verify table existence before operations
- Handle pagination for large bases
2. **create_table**
- **Purpose**: Creates a new table in an Airtable base
- **Key Considerations**:
- Requires base_id and table name
- Can create multiple basic fields in one operation
- Should be used first in any table creation workflow
- Validate table name uniqueness in the base
- **Best Practices**:
- Start with essential basic fields only
- Use clear, descriptive table names
- Add proper table description
- Follow naming conventions
3. **update_table**
- **Purpose**: Updates a table's name or description
- **Key Considerations**:
- Requires base_id and table_id
- Can modify name and description
- Existing data remains unchanged
- **Best Practices**:
- Verify table existence before update
- Maintain naming consistency
- Update documentation accordingly
### Table Creation Workflow
1. **Initial Setup**
- Verify base access
- Check table name availability
- Plan table structure
- Define primary fields
2. **Field Planning**
- Start with basic fields
- Plan relationships with other tables
- Consider computed fields
- Define field dependencies
3. **Implementation Steps**
- Create table with basic fields
- Add complex fields incrementally
- Set up relationships
- Configure views and permissions
### Best Practices
1. **Table Design**
- Use clear, descriptive names
- Follow consistent naming conventions
- Include proper descriptions
- Plan for scalability
- Consider relationships early
2. **Data Organization**
- Group related fields logically
- Use appropriate field types
- Plan for future expansion
- Consider data validation needs
- Document table relationships
3. **Performance Considerations**
- Optimize field types for data size
- Plan indexes for frequent queries
- Consider record limits
- Monitor table size
- Handle large datasets efficiently
4. **Security and Access**
- Set appropriate permissions
- Document access requirements
- Plan sharing strategy
- Consider data sensitivity
- Implement proper controls
### Common Patterns
1. **Master-Detail Tables**
- Primary table contains main records
- Detail tables link to master
- Use lookup fields for data access
- Implement proper relationships
2. **Lookup Tables**
- Store reference data
- Use for standardization
- Minimize redundancy
- Easy maintenance
3. **Junction Tables**
- Handle many-to-many relationships
- Store relationship metadata
- Enable complex queries
- Maintain data integrity
### Error Handling
1. **Creation Errors**
- Handle name conflicts
- Validate field configurations
- Check permissions
- Provide clear error messages
2. **Update Errors**
- Verify table existence
- Check field dependencies
- Handle concurrent updates
- Maintain data integrity
3. **Deletion Considerations**
- Check for dependencies
- Backup important data
- Handle cascading deletes
- Verify permissions
```
--------------------------------------------------------------------------------
/docs/Airtable_MCP_server_guide_for_LLMs.md:
--------------------------------------------------------------------------------
```markdown
# Airtable MCP Server Guide
## Table of Contents
1. [MCP Server Tools Overview](#mcp-server-tools-overview)
- Available Tools and Use Cases
- Tool Dependencies and Workflow
- Rate Limiting and Performance
- Tool Authorization Requirements
2. [Base Management](#base-management)
- Listing and Discovering Bases
- Table Operations
- Base Configuration
- Access Control
3. [Field Management](#field-management)
- Field Types and Options
- Field Creation and Updates
- Field Dependencies
- Data Validation
4. [Record Operations](#record-operations)
- Reading and Querying Records
- Creating and Updating Records
- Batch Operations
- Search and Filtering
5. [System Prompt for Claude](#system-prompt-for-claude)
- Core Principles
- Implementation Guidelines
- Error Handling
- Response Formats
## MCP Server Tools Overview
### Available Tools and Use Cases
1. **Base Management Tools**
a. **list_bases**
- **Purpose**: Lists all accessible Airtable bases
- **Key Considerations**:
- Requires valid API key
- Returns only bases with access permissions
- Useful for initial discovery
- **Best Practices**:
- Cache base IDs for frequent operations
- Verify base accessibility before operations
- Handle pagination if many bases
b. **list_tables**
- **Purpose**: Lists all tables in a specified base
- **Key Considerations**:
- Requires base_id
- Returns table metadata
- Useful for table discovery
- **Best Practices**:
- Cache table IDs for frequent operations
- Verify table existence before operations
- Handle pagination for large bases
c. **create_table**
- **Purpose**: Creates a new table in an Airtable base
- **Key Considerations**:
- Requires base_id and table name
- Can create multiple basic fields in one operation
- Should be used first in any table creation workflow
- Validate table name uniqueness in the base
- **Best Practices**:
- Start with essential basic fields only
- Use clear, descriptive table names
- Add proper table description
- Follow naming conventions
d. **update_table**
- **Purpose**: Updates a table's name or description
- **Key Considerations**:
- Requires base_id and table_id
- Can modify name and description
- Existing data remains unchanged
- **Best Practices**:
- Verify table existence before update
- Maintain naming consistency
- Update documentation accordingly
2. **Field Management Tools**
a. **create_field**
- **Purpose**: Adds a new field to an existing table
- **Key Considerations**:
- Requires both base_id and table_id
- Add one field at a time for complex types
- Field options must match type requirements
- **Best Practices**:
- Verify field creation before adding next
- Use descriptive field names
- Include field descriptions
- Configure appropriate field options
b. **update_field**
- **Purpose**: Modifies existing field configuration
- **Key Considerations**:
- Can update name, description, and options
- Some field types have immutable properties
- Changes may affect existing data
- **Best Practices**:
- Backup data before significant changes
- Test changes on sample records
- Update documentation accordingly
- Verify field behavior after changes
3. **Record Operation Tools**
a. **list_records**
- **Purpose**: Retrieves records from a table
- **Key Considerations**:
- Supports filtering and sorting
- Handles pagination
- Can specify fields to return
- **Best Practices**:
- Use field selection for performance
- Implement pagination for large datasets
- Cache results when appropriate
- Handle rate limits
b. **create_record**
- **Purpose**: Adds new records to a table
- **Key Considerations**:
- Validates field types
- Handles required fields
- Supports multiple records
- **Best Practices**:
- Validate data before submission
- Handle batch operations efficiently
- Verify record creation
- Implement error recovery
c. **update_record**
- **Purpose**: Modifies existing records
- **Key Considerations**:
- Requires record ID
- Partial updates supported
- Field validation applied
- **Best Practices**:
- Verify record existence
- Backup data before updates
- Handle field type constraints
- Log changes for audit
d. **delete_record**
- **Purpose**: Removes records from a table
- **Key Considerations**:
- Operation is irreversible
- Can affect linked records
- Supports batch deletion
- **Best Practices**:
- Verify record selection
- Backup before deletion
- Check dependencies
- Implement confirmation
e. **search_records**
- **Purpose**: Finds records matching criteria
- **Key Considerations**:
- Supports complex filters
- Can use multiple fields
- Returns paginated results
- **Best Practices**:
- Optimize search criteria
- Handle no results case
- Implement pagination
- Cache frequent searches
f. **get_record**
- **Purpose**: Retrieves a single record by ID
- **Key Considerations**:
- Direct record access
- Returns all or selected fields
- Efficient for single record ops
- **Best Practices**:
- Verify record existence
- Handle missing records
- Select needed fields only
- Cache when appropriate
### Tool Dependencies and Workflow
```mermaid
graph TD
A[list_bases] --> B[list_tables]
B --> C[create_table]
C --> D[create_field]
D --> E[update_field]
B --> F[list_records]
F --> G[create_record]
F --> H[update_record]
F --> I[delete_record]
F --> J[search_records]
F --> K[get_record]
C --> L[update_table]
```
### Rate Limiting and Performance
1. **API Constraints**
- Respect Airtable's rate limits
- Implement exponential backoff
- Handle throttling gracefully
- Monitor API usage
2. **Operation Timing**
- Allow time between operations
- Verify completion before next step
- Handle timeouts appropriately
- Log operation durations
3. **Resource Management**
- Monitor memory usage
- Clean up temporary resources
- Handle connection issues
- Implement proper error recovery
### Tool Authorization Requirements
1. **Authentication**
- Personal access token required
- OAuth integration support
- Proper scope configuration
- Token management best practices
2. **Permissions**
- Base creator role needed
- Verify write permissions
- Check field-level access
- Handle permission errors
## System Prompt for Claude
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:
### Core Principles
1. **Incremental Creation**
- Always create tables in stages, starting with basic fields
- Add one complex field at a time
- Verify each operation before proceeding
- Handle errors gracefully and provide clear feedback
2. **Field Type Categories**
Basic Fields (No Options Required):
- `singleLineText`: Single line of text
- `multilineText`: Multiple lines of text
- `email`: Valid email address
- `phoneNumber`: Phone number in any format
- `richText`: Text with formatting
- `url`: Valid URL
Complex Fields (Require Options):
- `number`: Requires precision (0-8)
- `currency`: Requires precision and symbol
- `percent`: Requires precision (0-8)
- `rating`: Requires max value (1-10) and icon/color
- `duration`: Requires format
- `date`: Requires dateFormat
- `dateTime`: Requires dateFormat and timeFormat
- `singleSelect`: Requires choices with names and colors
- `multipleSelects`: Requires choices with names and colors
- `checkbox`: Optional icon and color
- `barcode`: Supports various formats
- `button`: Configurable actions
- `count`: Automatic counter
- `autoNumber`: Automatic unique counter
- `formula`: Computed values
- `rollup`: Aggregated values from linked records
- `lookup`: Values from linked records
- `multipleRecordLinks`: Links to other records
- `attachment`: File attachments
3. **Creation Order**
1. Create table with basic text fields
2. Add numeric fields (number, currency, percent)
3. Add date/time fields
4. Add select/choice fields
5. Add computed fields (formula, rollup, lookup)
6. Add relationship fields (record links)
7. Verify each field after creation
### Field Configuration Reference
1. **Number Fields**
```json
{
"type": "number",
"options": {
"precision": 0 // 0 for integers, 1-8 for decimals
}
}
```
2. **Currency Fields**
```json
{
"type": "currency",
"options": {
"precision": 2,
"symbol": "$" // Currency symbol
}
}
```
3. **Date Fields**
```json
{
"type": "date",
"options": {
"dateFormat": {
"name": "local" // Options: local, friendly, us, european, iso
}
}
}
```
4. **DateTime Fields**
```json
{
"type": "dateTime",
"options": {
"dateFormat": {
"name": "local" // Options: local, friendly, us, european, iso
},
"timeFormat": {
"name": "12hour" // Options: 12hour, 24hour
}
}
}
```
5. **Select Fields**
```json
{
"type": "singleSelect",
"options": {
"choices": [
{
"name": "Option Name",
"color": "colorName" // Colors: blueBright, greenBright, redBright, yellowBright, pinkBright, purpleBright, cyanBright, grayBright
}
]
}
}
```
6. **Rating Fields**
```json
{
"type": "rating",
"options": {
"max": 5, // 1-10
"color": "yellowBright", // Standard color options
"icon": "star" // Options: star, heart, thumbsUp, flag, dot
}
}
```
### Implementation Steps
1. **Create Table with Basic Fields**
```json
{
"name": "create_table",
"arguments": {
"base_id": "your_base_id",
"table_name": "Your Table Name",
"description": "Table description",
"fields": [
{
"name": "Title",
"type": "singleLineText",
"description": "Title field"
},
{
"name": "Notes",
"type": "multilineText",
"description": "Notes field"
}
]
}
}
```
2. **Add Complex Fields (One at a Time)**
```json
{
"name": "create_field",
"arguments": {
"base_id": "your_base_id",
"table_id": "your_table_id",
"field": {
"name": "Field Name",
"type": "field_type",
"description": "Field description",
"options": {
// Field-specific options here
}
}
}
}
```
### Error Handling & Best Practices
1. **Validation**
- Verify each field after creation
- Test with sample data
- Check field options are correctly applied
- Validate field names and descriptions
- Ensure required options are provided
- Verify field type compatibility
2. **Error Recovery**
- If field creation fails, do not proceed to next field
- Verify field options match specifications exactly
- Retry failed field creation with corrected options
- Log errors for debugging
- Provide clear error messages
3. **Testing**
- Create test records after adding fields
- Update records to verify field behavior
- Test field constraints and validations
- Verify computed fields
- Test relationships between tables
4. **Security**
- Validate all inputs
- Sanitize field names and descriptions
- Use appropriate field types for sensitive data
- Implement proper access controls
- Follow rate limiting guidelines
### Response Format
When responding to table creation requests:
1. Acknowledge the request and outline the plan
2. Create the table with basic fields first
3. Add complex fields one at a time
4. Verify each step
5. Report success or handle errors
6. Provide guidance for next steps
Example response format:
```
I'll help you create the [table_name] table with the following steps:
1. Create table with basic fields:
- [field1]: [type]
- [field2]: [type]
2. Add complex fields:
- [field3]: [type] with [options]
- [field4]: [type] with [options]
I'll proceed with each step and verify completion before moving to the next one.
```
Remember to:
- Be explicit about each action
- Verify each step
- Handle errors gracefully
- Provide clear feedback
- Guide the user through the process
```
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
```typescript
#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
ErrorCode,
McpError,
} from "@modelcontextprotocol/sdk/types.js";
import axios, { AxiosInstance } from "axios";
import { FieldOption, fieldRequiresOptions, getDefaultOptions, FieldType } from "./types.js";
const API_KEY = process.env.AIRTABLE_API_KEY;
if (!API_KEY) {
throw new Error("AIRTABLE_API_KEY environment variable is required");
}
class AirtableServer {
private server: Server;
private axiosInstance: AxiosInstance;
constructor() {
this.server = new Server(
{
name: "airtable-server",
version: "0.2.0",
},
{
capabilities: {
tools: {},
},
}
);
this.axiosInstance = axios.create({
baseURL: "https://api.airtable.com/v0",
headers: {
Authorization: `Bearer ${API_KEY}`,
},
});
this.setupToolHandlers();
// Error handling
this.server.onerror = (error) => console.error("[MCP Error]", error);
process.on("SIGINT", async () => {
await this.server.close();
process.exit(0);
});
}
private validateField(field: FieldOption): FieldOption {
const { type } = field;
// Remove options for fields that don't need them
if (!fieldRequiresOptions(type as FieldType)) {
const { options, ...rest } = field;
return rest;
}
// Add default options for fields that require them
if (!field.options) {
return {
...field,
options: getDefaultOptions(type as FieldType),
};
}
return field;
}
private setupToolHandlers() {
// Register available tools
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: "list_bases",
description: "List all accessible Airtable bases",
inputSchema: {
type: "object",
properties: {},
required: [],
},
},
{
name: "list_tables",
description: "List all tables in a base",
inputSchema: {
type: "object",
properties: {
base_id: {
type: "string",
description: "ID of the base",
},
},
required: ["base_id"],
},
},
{
name: "create_table",
description: "Create a new table in a base",
inputSchema: {
type: "object",
properties: {
base_id: {
type: "string",
description: "ID of the base",
},
table_name: {
type: "string",
description: "Name of the new table",
},
description: {
type: "string",
description: "Description of the table",
},
fields: {
type: "array",
description: "Initial fields for the table",
items: {
type: "object",
properties: {
name: {
type: "string",
description: "Name of the field",
},
type: {
type: "string",
description: "Type of the field (e.g., singleLineText, multilineText, number, etc.)",
},
description: {
type: "string",
description: "Description of the field",
},
options: {
type: "object",
description: "Field-specific options",
},
},
required: ["name", "type"],
},
},
},
required: ["base_id", "table_name"],
},
},
{
name: "update_table",
description: "Update a table's schema",
inputSchema: {
type: "object",
properties: {
base_id: {
type: "string",
description: "ID of the base",
},
table_id: {
type: "string",
description: "ID of the table to update",
},
name: {
type: "string",
description: "New name for the table",
},
description: {
type: "string",
description: "New description for the table",
},
},
required: ["base_id", "table_id"],
},
},
{
name: "create_field",
description: "Create a new field in a table",
inputSchema: {
type: "object",
properties: {
base_id: {
type: "string",
description: "ID of the base",
},
table_id: {
type: "string",
description: "ID of the table",
},
field: {
type: "object",
properties: {
name: {
type: "string",
description: "Name of the field",
},
type: {
type: "string",
description: "Type of the field",
},
description: {
type: "string",
description: "Description of the field",
},
options: {
type: "object",
description: "Field-specific options",
},
},
required: ["name", "type"],
},
},
required: ["base_id", "table_id", "field"],
},
},
{
name: "update_field",
description: "Update a field in a table",
inputSchema: {
type: "object",
properties: {
base_id: {
type: "string",
description: "ID of the base",
},
table_id: {
type: "string",
description: "ID of the table",
},
field_id: {
type: "string",
description: "ID of the field to update",
},
updates: {
type: "object",
properties: {
name: {
type: "string",
description: "New name for the field",
},
description: {
type: "string",
description: "New description for the field",
},
options: {
type: "object",
description: "New field-specific options",
},
},
},
},
required: ["base_id", "table_id", "field_id", "updates"],
},
},
{
name: "list_records",
description: "List records in a table",
inputSchema: {
type: "object",
properties: {
base_id: {
type: "string",
description: "ID of the base",
},
table_name: {
type: "string",
description: "Name of the table",
},
max_records: {
type: "number",
description: "Maximum number of records to return",
},
},
required: ["base_id", "table_name"],
},
},
{
name: "create_record",
description: "Create a new record in a table",
inputSchema: {
type: "object",
properties: {
base_id: {
type: "string",
description: "ID of the base",
},
table_name: {
type: "string",
description: "Name of the table",
},
fields: {
type: "object",
description: "Record fields as key-value pairs",
},
},
required: ["base_id", "table_name", "fields"],
},
},
{
name: "update_record",
description: "Update an existing record in a table",
inputSchema: {
type: "object",
properties: {
base_id: {
type: "string",
description: "ID of the base",
},
table_name: {
type: "string",
description: "Name of the table",
},
record_id: {
type: "string",
description: "ID of the record to update",
},
fields: {
type: "object",
description: "Record fields to update as key-value pairs",
},
},
required: ["base_id", "table_name", "record_id", "fields"],
},
},
{
name: "delete_record",
description: "Delete a record from a table",
inputSchema: {
type: "object",
properties: {
base_id: {
type: "string",
description: "ID of the base",
},
table_name: {
type: "string",
description: "Name of the table",
},
record_id: {
type: "string",
description: "ID of the record to delete",
},
},
required: ["base_id", "table_name", "record_id"],
},
},
{
name: "search_records",
description: "Search for records in a table",
inputSchema: {
type: "object",
properties: {
base_id: {
type: "string",
description: "ID of the base",
},
table_name: {
type: "string",
description: "Name of the table",
},
field_name: {
type: "string",
description: "Name of the field to search in",
},
value: {
type: "string",
description: "Value to search for",
},
},
required: ["base_id", "table_name", "field_name", "value"],
},
},
{
name: "get_record",
description: "Get a single record by its ID",
inputSchema: {
type: "object",
properties: {
base_id: {
type: "string",
description: "ID of the base",
},
table_name: {
type: "string",
description: "Name of the table",
},
record_id: {
type: "string",
description: "ID of the record to retrieve",
},
},
required: ["base_id", "table_name", "record_id"],
},
},
],
}));
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
try {
switch (request.params.name) {
case "list_bases": {
const response = await this.axiosInstance.get("/meta/bases");
return {
content: [{
type: "text",
text: JSON.stringify(response.data.bases, null, 2),
}],
};
}
case "list_tables": {
const { base_id } = request.params.arguments as { base_id: string };
const response = await this.axiosInstance.get(`/meta/bases/${base_id}/tables`);
return {
content: [{
type: "text",
text: JSON.stringify(response.data.tables, null, 2),
}],
};
}
case "create_table": {
const { base_id, table_name, description, fields } = request.params.arguments as {
base_id: string;
table_name: string;
description?: string;
fields?: FieldOption[];
};
// Validate and prepare fields
const validatedFields = fields?.map(field => this.validateField(field));
const response = await this.axiosInstance.post(`/meta/bases/${base_id}/tables`, {
name: table_name,
description,
fields: validatedFields,
});
return {
content: [{
type: "text",
text: JSON.stringify(response.data, null, 2),
}],
};
}
case "update_table": {
const { base_id, table_id, name, description } = request.params.arguments as {
base_id: string;
table_id: string;
name?: string;
description?: string;
};
const response = await this.axiosInstance.patch(`/meta/bases/${base_id}/tables/${table_id}`, {
name,
description,
});
return {
content: [{
type: "text",
text: JSON.stringify(response.data, null, 2),
}],
};
}
case "create_field": {
const { base_id, table_id, field } = request.params.arguments as {
base_id: string;
table_id: string;
field: FieldOption;
};
// Validate field before creation
const validatedField = this.validateField(field);
const response = await this.axiosInstance.post(
`/meta/bases/${base_id}/tables/${table_id}/fields`,
validatedField
);
return {
content: [{
type: "text",
text: JSON.stringify(response.data, null, 2),
}],
};
}
case "update_field": {
const { base_id, table_id, field_id, updates } = request.params.arguments as {
base_id: string;
table_id: string;
field_id: string;
updates: Partial<FieldOption>;
};
const response = await this.axiosInstance.patch(
`/meta/bases/${base_id}/tables/${table_id}/fields/${field_id}`,
updates
);
return {
content: [{
type: "text",
text: JSON.stringify(response.data, null, 2),
}],
};
}
case "list_records": {
const { base_id, table_name, max_records } = request.params.arguments as {
base_id: string;
table_name: string;
max_records?: number;
};
const response = await this.axiosInstance.get(`/${base_id}/${table_name}`, {
params: max_records ? { maxRecords: max_records } : undefined,
});
return {
content: [{
type: "text",
text: JSON.stringify(response.data.records, null, 2),
}],
};
}
case "create_record": {
const { base_id, table_name, fields } = request.params.arguments as {
base_id: string;
table_name: string;
fields: Record<string, any>;
};
const response = await this.axiosInstance.post(`/${base_id}/${table_name}`, {
fields,
});
return {
content: [{
type: "text",
text: JSON.stringify(response.data, null, 2),
}],
};
}
case "update_record": {
const { base_id, table_name, record_id, fields } = request.params.arguments as {
base_id: string;
table_name: string;
record_id: string;
fields: Record<string, any>;
};
const response = await this.axiosInstance.patch(
`/${base_id}/${table_name}/${record_id}`,
{ fields }
);
return {
content: [{
type: "text",
text: JSON.stringify(response.data, null, 2),
}],
};
}
case "delete_record": {
const { base_id, table_name, record_id } = request.params.arguments as {
base_id: string;
table_name: string;
record_id: string;
};
const response = await this.axiosInstance.delete(
`/${base_id}/${table_name}/${record_id}`
);
return {
content: [{
type: "text",
text: JSON.stringify(response.data, null, 2),
}],
};
}
case "search_records": {
const { base_id, table_name, field_name, value } = request.params.arguments as {
base_id: string;
table_name: string;
field_name: string;
value: string;
};
const response = await this.axiosInstance.get(`/${base_id}/${table_name}`, {
params: {
filterByFormula: `{${field_name}} = "${value}"`,
},
});
return {
content: [{
type: "text",
text: JSON.stringify(response.data.records, null, 2),
}],
};
}
case "get_record": {
const { base_id, table_name, record_id } = request.params.arguments as {
base_id: string;
table_name: string;
record_id: string;
};
const response = await this.axiosInstance.get(
`/${base_id}/${table_name}/${record_id}`
);
return {
content: [{
type: "text",
text: JSON.stringify(response.data, null, 2),
}],
};
}
default:
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}`);
}
} catch (error) {
if (axios.isAxiosError(error)) {
throw new McpError(
ErrorCode.InternalError,
`Airtable API error: ${error.response?.data?.error?.message ?? error.message}`
);
}
throw error;
}
});
}
async run() {
const transport = new StdioServerTransport();
await this.server.connect(transport);
console.error("Airtable MCP server running on stdio");
}
}
const server = new AirtableServer();
server.run().catch((error) => {
console.error("Server error:", error);
process.exit(1);
});
```
--------------------------------------------------------------------------------
/docs/Airtable API field types and cell values.md:
--------------------------------------------------------------------------------
```markdown
# Field types and cell values
This documents all of the currently supported field types and their corresponding cell value formats, as well as their option formats.
**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.
**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.
## Field types
- [AI Text](https://airtable.com/developers/web/api/field-model#ai-text)
- [Attachment](https://airtable.com/developers/web/api/field-model#multiple-attachment)
- [Auto number](https://airtable.com/developers/web/api/field-model#auto-number)
- [Barcode](https://airtable.com/developers/web/api/field-model#barcode)
- [Button](https://airtable.com/developers/web/api/field-model#button)
- [Checkbox](https://airtable.com/developers/web/api/field-model#checkbox)
- [Collaborator](https://airtable.com/developers/web/api/field-model#collaborator)
- [Count](https://airtable.com/developers/web/api/field-model#count)
- [Created by](https://airtable.com/developers/web/api/field-model#created-by)
- [Created time](https://airtable.com/developers/web/api/field-model#created-time)
- [Currency](https://airtable.com/developers/web/api/field-model#currency-number)
- [Date](https://airtable.com/developers/web/api/field-model#date-only)
- [Date and time](https://airtable.com/developers/web/api/field-model#date-and-time)
- [Duration](https://airtable.com/developers/web/api/field-model#duration-number)
- [Email](https://airtable.com/developers/web/api/field-model#email-text)
- [Formula](https://airtable.com/developers/web/api/field-model#formula)
- [Last modified by](https://airtable.com/developers/web/api/field-model#last-modified-by)
- [Last modified time](https://airtable.com/developers/web/api/field-model#last-modified-time)
- [Link to another record](https://airtable.com/developers/web/api/field-model#foreign-key)
- [Long text](https://airtable.com/developers/web/api/field-model#multiline-text)
- [Lookup](https://airtable.com/developers/web/api/field-model#lookup)
- [Multiple collaborator](https://airtable.com/developers/web/api/field-model#multi-collaborator)
- [Multiple select](https://airtable.com/developers/web/api/field-model#multi-select)
- [Number](https://airtable.com/developers/web/api/field-model#decimal-or-integer-number)
- [Percent](https://airtable.com/developers/web/api/field-model#percent-number)
- [Phone](https://airtable.com/developers/web/api/field-model#phone)
- [Rating](https://airtable.com/developers/web/api/field-model#rating)
- [Rich text](https://airtable.com/developers/web/api/field-model#rich-text)
- [Rollup](https://airtable.com/developers/web/api/field-model#rollup)
- [Single line text](https://airtable.com/developers/web/api/field-model#simple-text)
- [Single select](https://airtable.com/developers/web/api/field-model#select)
- [Sync source](https://airtable.com/developers/web/api/field-model#sync-source)
- [Url](https://airtable.com/developers/web/api/field-model#url-text)
## [§](https://airtable.com/developers/web/api/field-model\#aitext) AI Text
Long text (with AI output enabled)
AI generated text can depend on other cells in the same record and can be in a loading state.
Cell format (read only)
`any of the below objects`
* * *
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#aitext-cellformat-multiple-0-state)`state` | `"empty" | "loading" | "generated"` <br>The current state of the cell. |
| [§](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. |
| [§](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 |
* * *
``
| | |
| --- | --- |
| [§](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. |
| [§](https://airtable.com/developers/web/api/field-model#aitext-cellformat-multiple-1-errortype)`errorType` | `string` <br>A short string that describes the error. |
| [§](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. |
| [§](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 |
Field type and options (read only)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#aitext-fieldtype-type)`type` | `"aiText"` |
| [§](https://airtable.com/developers/web/api/field-model#aitext-fieldtype-options)`options` | `object`
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#aitext-fieldtype-options-prompt)`prompt` | `optional<` `array of (strings | the below object)` `>`
The prompt that is used to generate the results in the AI field, additional object
types may be added in the future. Currently, this is an array of strings or objects that identify any fields interpolated into the prompt.
The prompt will not currently be provided if this field config is within another
fields configuration (like a lookup field)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#aitext-fieldtype-options-prompt-field)`field` | `object`
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#aitext-fieldtype-options-prompt-field-fieldid)`fieldId` | `string` | | |
| [§](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) | |
## [§](https://airtable.com/developers/web/api/field-model\#multipleattachment) Attachment
Attachments allow you to add images, documents, or other files
which can then be viewed or downloaded.
URLs returned will expire 2 hours after being returned from our API.
If you want to persist the attachments, we recommend downloading them instead of saving the URL.
See our [support article](https://support.airtable.com/docs/changes-to-airtable-attachments) for
more information.
Cell format (read)
`array of the below object` ``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-id)`id` | `string` <br>Unique attachment id |
| [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-type)`type` | `string` <br>Content type, e.g. "image/jpeg" |
| [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-filename)`filename` | `string` <br>Filename, e.g. "foo.jpg" |
| [§](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) |
| [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-size)`size` | `number` <br>File size, in bytes |
| [§](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. |
| [§](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) |
| [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails)`thumbnails` | `object`
These small, large, and full thumbnails may be available if attachment is an image or document
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-full)`full` | `optional<` `object` `>`
| | |
| --- | --- |
| [§](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. |
| [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-full-height)`height` | `number` |
| [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-full-width)`width` | `number` | |
| [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-large)`large` | `optional<` `object` `>`
| | |
| --- | --- |
| [§](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. |
| [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-large-height)`height` | `number` |
| [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-large-width)`width` | `number` | |
| [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-small)`small` | `optional<` `object` `>`
| | |
| --- | --- |
| [§](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. |
| [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-small-height)`height` | `number` |
| [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-thumbnails-small-width)`width` | `number` | | |
Cell format (write)
`array of any of the below objects`
* * *
``
To create new attachments, provide the url and optionally filename.
You must also provide the id's for any existing attachment objects you wish to keep.
Note that in most cases the API does not currently return an error code for failed attachment object creation
given attachment uploading happens in an asynchronous manner, such cases will manifest with the
attachment object either being cleared from the cell or persisted with generated URLs that return
error responses when queried. If the same attachment URL fails to upload multiple times in a short time interval then
the API may return an ATTACHMENTS\_FAILED\_UPLOADING error code in the details field of the response and the attachment object will
be cleared from the cell synchronously.
We also require URLs used to upload have the https:// or http:// protocol (Note: http:// support will be removed in the
near future), have a limit of 3 max redirects, and a file size limit of 1GB. In addition,
URLs must be publicly accessible, in cases where cookie authentication or logging
in to access the file is required, the login page HTML will be downloaded instead of the file.
| | |
| --- | --- |
| [§](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. |
| [§](https://airtable.com/developers/web/api/field-model#multipleattachment-cellformat-write-multiple-0-filename)`filename` | `optional<` `string` `>` <br>Filename, e.g. "foo.jpg" |
* * *
``
| | |
| --- | --- |
| [§](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. |
Field type and options
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#multipleattachment-fieldtype-type)`type` | `"multipleAttachments"` |
| [§](https://airtable.com/developers/web/api/field-model#multipleattachment-fieldtype-options)`options` | `object`
| | |
| --- | --- |
| [§](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. | |
## [§](https://airtable.com/developers/web/api/field-model\#autonumber) Auto number
Automatically incremented unique counter for each record.
Cell format (read only)
`number`
Field type and options (read only)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#autonumber-fieldtype-type)`type` | `"autoNumber"` |
## [§](https://airtable.com/developers/web/api/field-model\#barcode) Barcode
Use the Airtable iOS or Android app to scan barcodes.
Cell format
``
The barcode object may contain the following two properties, both of which are optional.
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#barcode-cellformat-type)`type` | `optional<` `string | null` `>` <br>Barcode symbology, e.g. "upce" or "code39" |
| [§](https://airtable.com/developers/web/api/field-model#barcode-cellformat-text)`text` | `string` <br>Barcode data |
Field type and options
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#barcode-fieldtype-type)`type` | `"barcode"` |
## [§](https://airtable.com/developers/web/api/field-model\#button) Button
A button that can be clicked from the Airtable UI to open a URL or open an extension.
Cell format (read only)
``
Object providing details about the button configuration.
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#button-cellformat-label)`label` | `string` <br>Button label |
| [§](https://airtable.com/developers/web/api/field-model#button-cellformat-url)`url` | `string | null` <br>For "Open URL" actions, the computed url value |
Field type and options (read only)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#button-fieldtype-type)`type` | `"button"` |
## [§](https://airtable.com/developers/web/api/field-model\#checkbox) Checkbox
Cell format
`true`
This field is "true" when checked and otherwise empty.
You can write to the cell with "false", but the read value will be still be "empty" (unchecked).
Field type and options
``
Bases on a free or plus plan are limited to using the `'check'` icon and `'greenBright'` color.
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#checkbox-fieldtype-type)`type` | `"checkbox"` |
| [§](https://airtable.com/developers/web/api/field-model#checkbox-fieldtype-options)`options` | `object`
| | |
| --- | --- |
| [§](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. |
| [§](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. | |
## [§](https://airtable.com/developers/web/api/field-model\#collaborator) Collaborator
A collaborator field lets you add collaborators to your records.
Collaborators can optionally be notified when they're added (using the field settings in
the UI). A single collaborator field has been configured to only reference
one user collaborator.
Cell format (read)
``
Object providing details about the user collaborator in this field.
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#collaborator-cellformat-id)`id` | `string` <br>User id or group id |
| [§](https://airtable.com/developers/web/api/field-model#collaborator-cellformat-email)`email` | `optional<` `string` `>` <br>User's email address |
| [§](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) |
| [§](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. |
| [§](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. |
Cell format (write)
`any of the below objects`
* * *
``
| | |
| --- | --- |
| [§](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 |
* * *
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#collaborator-cellformat-write-multiple-1-email)`email` | `string` <br>The user's email address |
Field type and options
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#collaborator-fieldtype-type)`type` | `"singleCollaborator"` |
| [§](https://airtable.com/developers/web/api/field-model#collaborator-fieldtype-options)`options` | `optional<` `object` `>`
|
| |
## [§](https://airtable.com/developers/web/api/field-model\#count) Count
Number of linked records, from a linked record field in the same table.
Cell format (read only)
`number`
Field type and options (read only)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#count-fieldtype-type)`type` | `"count"` |
| [§](https://airtable.com/developers/web/api/field-model#count-fieldtype-options)`options` | `object`
| | |
| --- | --- |
| [§](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. |
| [§](https://airtable.com/developers/web/api/field-model#count-fieldtype-options-recordlinkfieldid)`recordLinkFieldId` | `optional<` `string | null` `>` | |
## [§](https://airtable.com/developers/web/api/field-model\#createdby) Created by
The collaborator who created the record.
Cell format (read only)
``
Object providing details about the user collaborator in this field.
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#createdby-cellformat-id)`id` | `string` <br>User id or group id |
| [§](https://airtable.com/developers/web/api/field-model#createdby-cellformat-email)`email` | `optional<` `string` `>` <br>User's email address |
| [§](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) |
| [§](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. |
| [§](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. |
Field type and options (read only)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#createdby-fieldtype-type)`type` | `"createdBy"` |
## [§](https://airtable.com/developers/web/api/field-model\#createdtime) Created time
The time the record was created in UTC e.g. "2022-08-29T07:00:00.000Z" or "2022-08-29"
Cell format (read only)
`string`
Field type and options (read only)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#createdtime-fieldtype-type)`type` | `"createdTime"` |
| [§](https://airtable.com/developers/web/api/field-model#createdtime-fieldtype-options)`options` | `object`
| | |
| --- | --- |
| [§](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) | |
## [§](https://airtable.com/developers/web/api/field-model\#currencynumber) Currency
Currency value. Symbol set with the field config.
Cell format
`number`
Field type and options
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#currencynumber-fieldtype-type)`type` | `"currency"` |
| [§](https://airtable.com/developers/web/api/field-model#currencynumber-fieldtype-options)`options` | `object`
| | |
| --- | --- |
| [§](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) |
| [§](https://airtable.com/developers/web/api/field-model#currencynumber-fieldtype-options-symbol)`symbol` | `string` <br>Currency symbol to use. | |
## [§](https://airtable.com/developers/web/api/field-model\#dateonly) Date
String (ISO 8601 formatted date)
UTC date, e.g. "2022-09-05".
Cell format
`string`
A date.
When reading from and writing to a date field, the cell value will always be an
[ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html)
formatted date. (Field options specify how it's formatted in the main Airtable UI - format
can be used with [moment.js](https://momentjs.com/) to match that.)
The date format string follows the moment.js structure documented
[here](https://momentjs.com/docs/#/parsing/string-format/).
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).
Field type and options (read)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#dateonly-fieldtype-type)`type` | `"date"` |
| [§](https://airtable.com/developers/web/api/field-model#dateonly-fieldtype-options)`options` | `object`
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#dateonly-fieldtype-options-dateformat)`dateFormat` | `object`
| | |
| --- | --- |
| [§](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) |
| [§](https://airtable.com/developers/web/api/field-model#dateonly-fieldtype-options-dateformat-name)`name` | `"local" | "friendly" | "us" | "european" | "iso"` | | |
Field type and options (write)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#dateonly-fieldtype-write-type)`type` | `"date"` |
| [§](https://airtable.com/developers/web/api/field-model#dateonly-fieldtype-write-options)`options` | `object`
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#dateonly-fieldtype-write-options-dateformat)`dateFormat` | `object`
| | |
| --- | --- |
| [§](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) |
| [§](https://airtable.com/developers/web/api/field-model#dateonly-fieldtype-write-options-dateformat-name)`name` | `"local" | "friendly" | "us" | "european" | "iso"` | | |
## [§](https://airtable.com/developers/web/api/field-model\#dateandtime) Date and time
String (ISO 8601 formatted date)
UTC date and time, e.g. "2022-09-05T07:00:00.000Z".
Cell format
`string`
A date and time.
When reading from and writing to a date field, the cell value will always be an
[ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html)
formatted date. (Field options specify how it's formatted in the main Airtable UI - format
can be used with [moment.js](https://momentjs.com/) to match that.)
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).
When writing to a `dateTime` field configured with a non `utc` or `client` time zone like `America/Los_Angeles`,
ambiguous string inputs like "2020-09-05T07:00:00" and "2020-09-08" will be interpreted according
to the `timeZone` of the field instead of `utc`, and nonambiguous string inputs with zone offset like "2020-09-05T07:00:00.000Z"
and "2020-09-08T00:00:00-07:00" will be interpreted correctly as the underlying timestamp.
Field type and options (read)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-type)`type` | `"dateTime"` |
| [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-options)`options` | `object`
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-options-timezone)`timeZone` | [`Timezone`](https://airtable.com/developers/web/api/model/timezone) |
| [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-options-dateformat)`dateFormat` | `object`
| | |
| --- | --- |
| [§](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) |
| [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-options-dateformat-name)`name` | `"local" | "friendly" | "us" | "european" | "iso"` | |
| [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-options-timeformat)`timeFormat` | `object`
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-options-timeformat-format)`format` | `"h:mma" | "HH:mm"` |
| [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-options-timeformat-name)`name` | `"12hour" | "24hour"` | | |
Field type and options (write)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-write-type)`type` | `"dateTime"` |
| [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-write-options)`options` | `object`
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-write-options-timezone)`timeZone` | [`Timezone`](https://airtable.com/developers/web/api/model/timezone) |
| [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-write-options-dateformat)`dateFormat` | `object`
| | |
| --- | --- |
| [§](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) |
| [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-write-options-dateformat-name)`name` | `"local" | "friendly" | "us" | "european" | "iso"` | |
| [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-write-options-timeformat)`timeFormat` | `object`
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-write-options-timeformat-name)`name` | `"12hour" | "24hour"` |
| [§](https://airtable.com/developers/web/api/field-model#dateandtime-fieldtype-write-options-timeformat-format)`format` | `optional<``"h:mma" | "HH:mm"` `>` | | |
## [§](https://airtable.com/developers/web/api/field-model\#durationnumber) Duration
An integer representing number of seconds.
Cell format
`number`
Field type and options
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#durationnumber-fieldtype-type)`type` | `"duration"` |
| [§](https://airtable.com/developers/web/api/field-model#durationnumber-fieldtype-options)`options` | `object`
| | |
| --- | --- |
| [§](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"` | |
## [§](https://airtable.com/developers/web/api/field-model\#emailtext) Email
A valid email address.
Cell format
`string`
Field type and options
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#emailtext-fieldtype-type)`type` | `"email"` |
## [§](https://airtable.com/developers/web/api/field-model\#formula) Formula
Compute a value in each record based on other fields in the same record.
Cell format (read only)
`string | number | true | array of (strings | numbers)`
Computed value - Check options.result to know the resulting field type.
Field type and options (read only)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#formula-fieldtype-type)`type` | `"formula"` |
| [§](https://airtable.com/developers/web/api/field-model#formula-fieldtype-options)`options` | `object`
| | |
| --- | --- |
| [§](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. |
| [§](https://airtable.com/developers/web/api/field-model#formula-fieldtype-options-isvalid)`isValid` | `boolean` <br>`false` if the formula contains an error. |
| [§](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. |
| [§](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. | |
## [§](https://airtable.com/developers/web/api/field-model\#lastmodifiedby) Last modified by
Shows the collaborator who most recently modified any editable field or just in specific editable fields.
Cell format (read only)
``
Object providing details about the user collaborator in this field.
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#lastmodifiedby-cellformat-id)`id` | `string` <br>User id or group id |
| [§](https://airtable.com/developers/web/api/field-model#lastmodifiedby-cellformat-email)`email` | `optional<` `string` `>` <br>User's email address |
| [§](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) |
| [§](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. |
| [§](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. |
Field type and options (read only)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#lastmodifiedby-fieldtype-type)`type` | `"lastModifiedBy"` |
## [§](https://airtable.com/developers/web/api/field-model\#lastmodifiedtime) Last modified time
The time the record was last modified in UTC e.g. "2022-08-29T07:00:00.000Z" or "2022-08-29"
Cell format (read only)
`string`
Field type and options (read only)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#lastmodifiedtime-fieldtype-type)`type` | `"lastModifiedTime"` |
| [§](https://airtable.com/developers/web/api/field-model#lastmodifiedtime-fieldtype-options)`options` | `object`
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#lastmodifiedtime-fieldtype-options-isvalid)`isValid` | `boolean` <br>False if this formula/field configuation has an error |
| [§](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 |
| [§](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) | |
## [§](https://airtable.com/developers/web/api/field-model\#foreignkey) Link to another record
Cell format V1
`array of strings`
Array of linked records IDs from the linked table.
Cell format V2 (webhooks)
`array of the below object` ``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#foreignkey-cellformat-v-2-id)`id` | `string` <br>Record ID |
| [§](https://airtable.com/developers/web/api/field-model#foreignkey-cellformat-v-2-name)`name` | `string` |
Field type and options (read)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#foreignkey-fieldtype-type)`type` | `"multipleRecordLinks"` |
| [§](https://airtable.com/developers/web/api/field-model#foreignkey-fieldtype-options)`options` | `object`
| | |
| --- | --- |
| [§](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. |
| [§](https://airtable.com/developers/web/api/field-model#foreignkey-fieldtype-options-linkedtableid)`linkedTableId` | `string` <br>The ID of the table this field links to |
| [§](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). |
| [§](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 |
| [§](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. | |
Field type and options (write)
``
Creating "multipleRecordLinks" fields is supported but updating options for
existing "multipleRecordLinks" fields is not supported.
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#foreignkey-fieldtype-write-type)`type` | `"multipleRecordLinks"` |
| [§](https://airtable.com/developers/web/api/field-model#foreignkey-fieldtype-write-options)`options` | `object`
| | |
| --- | --- |
| [§](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 |
| [§](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 | |
## [§](https://airtable.com/developers/web/api/field-model\#multilinetext) Long text
Cell format
`string`
Multiple lines of text, which may contain "mention tokens", e.g.
`<airtable:mention id="menE1i9oBaGX3DseR">@Alex</airtable:mention>`
Field type and options
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#multilinetext-fieldtype-type)`type` | `"multilineText"` |
## [§](https://airtable.com/developers/web/api/field-model\#lookup) Lookup
Lookup a field on linked records.
Cell format V1 (read only)
`array of (numbers | strings | booleans | any)`
Array of cell values from a field in the linked table.
Cell format V2 (webhooks)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#lookup-cellformat-v-2-valuesbylinkedrecordid)`valuesByLinkedRecordId` | `object`
| | |
| --- | --- |
| `key: string` | `array of any` | |
| [§](https://airtable.com/developers/web/api/field-model#lookup-cellformat-v-2-linkedrecordids)`linkedRecordIds` | `array of strings` |
Field type and options (read only)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#lookup-fieldtype-type)`type` | `"multipleLookupValues"` |
| [§](https://airtable.com/developers/web/api/field-model#lookup-fieldtype-options)`options` | `object`
| | |
| --- | --- |
| [§](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. |
| [§](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) |
| [§](https://airtable.com/developers/web/api/field-model#lookup-fieldtype-options-recordlinkfieldid)`recordLinkFieldId` | `string | null` <br>The linked record field in the current table. |
| [§](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. | |
## [§](https://airtable.com/developers/web/api/field-model\#multicollaborator) Multiple collaborator
Array of objects providing details about the user or [user group](https://support.airtable.com/docs/user-groups) collaborators in this field.
Note: Adding user groups to multiple collaborator fields is an enterprise feature.
Cell format (read)
`array of the below object` ``
Object providing details about the user collaborator in this field.
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#multicollaborator-cellformat-id)`id` | `string` <br>User id or group id |
| [§](https://airtable.com/developers/web/api/field-model#multicollaborator-cellformat-email)`email` | `optional<` `string` `>` <br>User's email address |
| [§](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) |
| [§](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. |
| [§](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. |
Cell format (write)
`array of strings`
Array of user or group ids
Similar to [multipleAttachments](https://airtable.com/developers/web/api/field-model#multiple-attachment) and
[multipleSelects](https://airtable.com/developers/web/api/field-model#multi-select), this array-type field will override the current
cell value when being updated. Be sure to spread the current cell value if you want to keep
the currently selected collaborators.
Field type and options
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#multicollaborator-fieldtype-type)`type` | `"multipleCollaborators"` |
| [§](https://airtable.com/developers/web/api/field-model#multicollaborator-fieldtype-options)`options` | `object`
|
| |
## [§](https://airtable.com/developers/web/api/field-model\#multiselect) Multiple select
Array of selected option names.
When creating or updating records, if a choice string does not exactly match an existing option,
the request will fail with an `INVALID_MULTIPLE_CHOICE_OPTIONS` error unless the `typecast`
parameter is enabled. If `typecast` is enabled, a new choice will be created if one does
not exactly match.
Similar to `multipleAttachments` and `multipleCollaborators`, this array-type field will override
the current cell value when being updated. Be sure to spread the current cell value if
you want to keep the currently selected choices.
Cell format V1
`array of strings`
Array of selected option names.
Cell format V2 (webhooks)
`array of the below object` ``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#multiselect-cellformat-v-2-id)`id` | `string` |
| [§](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" |
| [§](https://airtable.com/developers/web/api/field-model#multiselect-cellformat-v-2-name)`name` | `string` |
Field type and options (read)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-type)`type` | `"multipleSelects"` |
| [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-options)`options` | `object`
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-options-choices)`choices` | `array of the below object` ``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-options-choices-id)`id` | `string` |
| [§](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" |
| [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-options-choices-name)`name` | `string` | | |
Field type and options (write)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-write-type)`type` | `"multipleSelects"` |
| [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-write-options)`options` | `object`
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-write-options-choices)`choices` | `array of the below object` ``
| | |
| --- | --- |
| [§](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) |
| [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-write-options-choices-color)`color` | `optional<` `string` `>` <br>Optional when creating an option. |
| [§](https://airtable.com/developers/web/api/field-model#multiselect-fieldtype-write-options-choices-name)`name` | `string` | | |
## [§](https://airtable.com/developers/web/api/field-model\#decimalorintegernumber) Number
A integer(whole number, e.g. 1, 32, 99) or decimal number showing decimal digits. Precision set with the field config.
Cell format
`number`
Field type and options
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#decimalorintegernumber-fieldtype-type)`type` | `"number"` |
| [§](https://airtable.com/developers/web/api/field-model#decimalorintegernumber-fieldtype-options)`options` | `object`
| | |
| --- | --- |
| [§](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) | |
## [§](https://airtable.com/developers/web/api/field-model\#percentnumber) Percent
Decimal number representing a percentage value. For example, the underlying cell value for 12.3% is 0.123.
Cell format
`number`
Field type and options
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#percentnumber-fieldtype-type)`type` | `"percent"` |
| [§](https://airtable.com/developers/web/api/field-model#percentnumber-fieldtype-options)`options` | `object`
| | |
| --- | --- |
| [§](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) | |
## [§](https://airtable.com/developers/web/api/field-model\#phone) Phone
A telephone number, e.g. "(415) 555-9876".
Cell format
`string`
Field type and options
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#phone-fieldtype-type)`type` | `"phoneNumber"` |
## [§](https://airtable.com/developers/web/api/field-model\#rating) Rating
A positive integer (e.g. "3 stars" is 3). A rating cannot be 0.
Cell format
`number`
Field type and options
``
Bases on a free or plus plan are limited to using the 'star' icon and 'yellowBright' color.
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#rating-fieldtype-type)`type` | `"rating"` |
| [§](https://airtable.com/developers/web/api/field-model#rating-fieldtype-options)`options` | `object`
| | |
| --- | --- |
| [§](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. |
| [§](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. |
| [§](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. | |
## [§](https://airtable.com/developers/web/api/field-model\#richtext) Rich text
Long text (with rich text formatting enabled)
A Markdown-inspired markup language.
[Learn more about using Markdown in long text's rich text formatting API.](https://support.airtable.com/docs/using-rich-text-with-airtable)
Cell format
`string`
Field type and options
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#richtext-fieldtype-type)`type` | `"richText"` |
## [§](https://airtable.com/developers/web/api/field-model\#rollup) Rollup
A rollup allows you to summarize data from records that are linked to this table.
Cell format V1 (read only)
`string | number | true`
Cell format V2 (webhooks)
`any`
Field type and options (read only)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#rollup-fieldtype-type)`type` | `"rollup"` |
| [§](https://airtable.com/developers/web/api/field-model#rollup-fieldtype-options)`options` | `object`
| | |
| --- | --- |
| [§](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 |
| [§](https://airtable.com/developers/web/api/field-model#rollup-fieldtype-options-recordlinkfieldid)`recordLinkFieldId` | `optional<` `string` `>` <br>The linked field id |
| [§](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. |
| [§](https://airtable.com/developers/web/api/field-model#rollup-fieldtype-options-isvalid)`isValid` | `optional<` `boolean` `>` |
| [§](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 | |
## [§](https://airtable.com/developers/web/api/field-model\#simpletext) Single line text
A single line of text.
Cell format
`string`
Field type and options
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#simpletext-fieldtype-type)`type` | `"singleLineText"` |
## [§](https://airtable.com/developers/web/api/field-model\#select) Single select
Selected option name.
When creating or updating records, if the choice string does not exactly match an existing option,
the request will fail with an `INVALID_MULTIPLE_CHOICE_OPTIONS` error unless the `typecast` parameter
is enabled. If `typecast` is enabled, a new choice will be created if one does not exactly match.
Cell format V1
`string`
Cell format V2 (webhooks)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#select-cellformat-v-2-id)`id` | `string` |
| [§](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" |
| [§](https://airtable.com/developers/web/api/field-model#select-cellformat-v-2-name)`name` | `string` |
Field type and options (read)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-type)`type` | `"singleSelect"` |
| [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-options)`options` | `object`
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-options-choices)`choices` | `array of the below object` ``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-options-choices-id)`id` | `string` |
| [§](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" |
| [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-options-choices-name)`name` | `string` | | |
Field type and options (write)
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-write-type)`type` | `"singleSelect"` |
| [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-write-options)`options` | `object`
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-write-options-choices)`choices` | `array of the below object` ``
| | |
| --- | --- |
| [§](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) |
| [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-write-options-choices-color)`color` | `optional<` `string` `>` <br>Optional when creating an option. |
| [§](https://airtable.com/developers/web/api/field-model#select-fieldtype-write-options-choices-name)`name` | `string` | | |
## [§](https://airtable.com/developers/web/api/field-model\#syncsource) Sync source
Shows the name of the source that a record is synced from. This field is only available on synced tables.
Cell format V1 (read only)
`string`
The sync source name.
Cell format V2 (webhooks)
``
| | |
| --- | --- |
| [§](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. |
| [§](https://airtable.com/developers/web/api/field-model#syncsource-cellformat-v-2-name)`name` | `string` <br>The sync source name. |
| [§](https://airtable.com/developers/web/api/field-model#syncsource-cellformat-v-2-color)`color` | `optional<` `string` `>` |
Field type and options
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#syncsource-fieldtype-type)`type` | `"externalSyncSource"` |
| [§](https://airtable.com/developers/web/api/field-model#syncsource-fieldtype-options)`options` | `object`
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#syncsource-fieldtype-options-choices)`choices` | `array of the below object` ``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#syncsource-fieldtype-options-choices-id)`id` | `string` |
| [§](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" |
| [§](https://airtable.com/developers/web/api/field-model#syncsource-fieldtype-options-choices-name)`name` | `string` | | |
## [§](https://airtable.com/developers/web/api/field-model\#urltext) Url
A valid URL (e.g. airtable.com or [https://airtable.com/universe](https://airtable.com/universe)).
Cell format
`string`
Field type and options
``
| | |
| --- | --- |
| [§](https://airtable.com/developers/web/api/field-model#urltext-fieldtype-type)`type` | `"url"` |
```