Add a new MCP tool that returns complete documentation for the HTTP proxy API. This enables agents to get all the information they need to construct valid proxy requests when writing scripts. The tool is stateless and returns a static documentation dict describing endpoints, methods, authentication, and example usage.
grist-mcp
MCP server for AI agents to interact with Grist documents.
Overview
grist-mcp is a Model Context Protocol (MCP) server that enables AI agents to read, write, and modify Grist spreadsheets. It provides secure, token-based access control with granular permissions per document.
Features
- Discovery: List accessible documents with permissions
- Read Operations: List tables, describe columns, fetch records, run SQL queries
- Write Operations: Add, update, and delete records
- Schema Operations: Create tables, add/modify/delete columns
- Security: Token-based authentication with per-document permission scopes (read, write, schema)
- Multi-tenant: Support multiple Grist instances and documents
Quick Start (Docker)
Prerequisites
- Docker and Docker Compose
- Access to one or more Grist documents with API keys
1. Create configuration directory
mkdir grist-mcp && cd grist-mcp
2. Download configuration files
# Download docker-compose.yml
curl -O https://raw.githubusercontent.com/Xe138/grist-mcp-server/master/deploy/prod/docker-compose.yml
# Download example config
curl -O https://raw.githubusercontent.com/Xe138/grist-mcp-server/master/config.yaml.example
cp config.yaml.example config.yaml
3. Generate tokens
Generate a secure token for your agent:
python -c "import secrets; print(secrets.token_urlsafe(32))"
# or
openssl rand -base64 32
4. Configure config.yaml
Edit config.yaml to define your Grist documents and agent tokens:
# Document definitions
documents:
my-document: # Friendly name (used in token scopes)
url: https://docs.getgrist.com # Your Grist instance URL
doc_id: abcd1234efgh5678 # Document ID from the URL
api_key: your-grist-api-key # Grist API key (or use ${ENV_VAR} syntax)
# Agent tokens with access scopes
tokens:
- token: your-generated-token-here # The token you generated in step 3
name: my-agent # Human-readable name
scope:
- document: my-document # Must match a document name above
permissions: [read, write] # Allowed: read, write, schema
Finding your Grist document ID: Open your Grist document in a browser. The URL will look like:
https://docs.getgrist.com/abcd1234efgh5678/My-Document - the document ID is abcd1234efgh5678.
Getting a Grist API key: In Grist, go to Profile Settings → API → Create API Key.
5. Create .env file
Create a .env file with your agent token:
# .env
GRIST_MCP_TOKEN=your-generated-token-here
PORT=3000
The GRIST_MCP_TOKEN must match one of the tokens defined in config.yaml.
6. Start the server
docker compose up -d
The server will be available at http://localhost:3000.
7. Configure your MCP client
Add to your MCP client configuration (e.g., Claude Desktop):
{
"mcpServers": {
"grist": {
"type": "sse",
"url": "http://localhost:3000/sse"
}
}
}
Available Tools
Discovery
| Tool | Description |
|---|---|
list_documents |
List documents accessible to this agent with their permissions |
Read Operations (requires read permission)
| Tool | Description |
|---|---|
list_tables |
List all tables in a document |
describe_table |
Get column information (id, type, formula) for a table |
get_records |
Fetch records with optional filter, sort, and limit |
sql_query |
Run a read-only SELECT query against a document |
Write Operations (requires write permission)
| Tool | Description |
|---|---|
add_records |
Add new records to a table |
update_records |
Update existing records by ID |
delete_records |
Delete records by ID |
Schema Operations (requires schema permission)
| Tool | Description |
|---|---|
create_table |
Create a new table with specified columns |
add_column |
Add a column to an existing table |
modify_column |
Change a column's type or formula |
delete_column |
Remove a column from a table |
Configuration Reference
Environment Variables
| Variable | Description | Default |
|---|---|---|
PORT |
Server port | 3000 |
GRIST_MCP_TOKEN |
Agent authentication token (required) | - |
CONFIG_PATH |
Path to config file inside container | /app/config.yaml |
config.yaml Structure
# Document definitions (each is self-contained)
documents:
budget-2024:
url: https://work.getgrist.com
doc_id: mK7xB2pQ9mN4v
api_key: ${GRIST_WORK_API_KEY} # Supports environment variable substitution
personal-tracker:
url: https://docs.getgrist.com
doc_id: pN0zE5sT2qP7x
api_key: ${GRIST_PERSONAL_API_KEY}
# Agent tokens with access scopes
tokens:
- token: your-secure-token-here
name: finance-agent
scope:
- document: budget-2024
permissions: [read, write] # Can read and write
- token: another-token-here
name: readonly-agent
scope:
- document: budget-2024
permissions: [read] # Read only
- document: personal-tracker
permissions: [read, write, schema] # Full access
Permission Levels
read: Query tables and records, run SQL querieswrite: Add, update, delete recordsschema: Create tables, add/modify/delete columns
Security
- Token-based auth: Each agent has a unique token with specific document access
- Permission scopes: Granular control with
read,write, andschemapermissions - SQL validation: Only SELECT queries allowed, no multi-statement queries
- API key isolation: Each document can use a different Grist API key
- No token exposure: Tokens are validated at startup, not stored in responses
Development
Requirements
- Python 3.14+
- uv package manager
Local Setup
# Clone the repository
git clone https://github.com/Xe138/grist-mcp-server.git
cd grist-mcp-server
# Install dependencies
uv sync --dev
# Run tests
make test-unit
Running Locally
export GRIST_MCP_TOKEN="your-agent-token"
CONFIG_PATH=./config.yaml uv run python -m grist_mcp.main
Project Structure
grist-mcp/
├── src/grist_mcp/
│ ├── main.py # Entry point
│ ├── server.py # MCP server setup and tool registration
│ ├── config.py # Configuration loading
│ ├── auth.py # Authentication and authorization
│ ├── grist_client.py # Grist API client
│ └── tools/
│ ├── discovery.py # list_documents
│ ├── read.py # Read operations
│ ├── write.py # Write operations
│ └── schema.py # Schema operations
├── tests/
│ ├── unit/ # Unit tests
│ └── integration/ # Integration tests
├── deploy/
│ ├── dev/ # Development docker-compose
│ ├── test/ # Test docker-compose
│ └── prod/ # Production docker-compose
└── config.yaml.example
License
MIT