Files
grist-mcp-server/CHANGELOG.md

7.2 KiB

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[1.5.0] - 2026-01-26

Added

Column Label Support

  • add_column: New optional label parameter for setting display name
  • modify_column: New optional label parameter for updating display name

Labels are human-readable names shown in Grist column headers, separate from the column_id used in formulas and API calls. If not provided, Grist defaults the label to the column ID.

Usage

# Create column with display label
add_column(document="crm", table="Contacts", column_id="first_name", column_type="Text", label="First Name")

# Update existing column's label
modify_column(document="crm", table="Contacts", column_id="first_name", label="Given Name")

[1.4.1] - 2026-01-14

Added

Reference Column Filter Support

  • Filter normalization: get_records now automatically normalizes filter values to array format
  • Fixes 400 errors when filtering on Ref:* (reference/foreign key) columns
  • Single values are wrapped in arrays before sending to Grist API

Usage

# Before: Failed with 400 Bad Request
get_records(document="accounting", table="TransactionLines", filter={"Transaction": 44})

# After: Works - filter normalized to {"Transaction": [44]}
get_records(document="accounting", table="TransactionLines", filter={"Transaction": 44})

# Multiple values also supported
get_records(document="accounting", table="TransactionLines", filter={"Transaction": [44, 45, 46]})

Fixed

  • Shell script shebangs updated to #!/usr/bin/env bash for portability across environments

[1.4.0] - 2026-01-12

Added

Attachment Download via Proxy

  • GET /api/v1/attachments/{id}: New HTTP endpoint for downloading attachments
  • Returns binary content with appropriate Content-Type and Content-Disposition headers
  • Requires read permission in session token
  • Complements the existing upload endpoint for complete attachment workflows

Usage

# Get session token with read permission
TOKEN=$(curl -s ... | jq -r '.token')

# Download attachment
curl -H "Authorization: Bearer $TOKEN" \
  https://example.com/api/v1/attachments/42 \
  -o downloaded.pdf
# Python example
import requests

response = requests.get(
    f'{base_url}/api/v1/attachments/42',
    headers={'Authorization': f'Bearer {token}'}
)
with open('downloaded.pdf', 'wb') as f:
    f.write(response.content)

[1.3.0] - 2026-01-03

Added

Attachment Upload via Proxy

  • POST /api/v1/attachments: New HTTP endpoint for file uploads
  • Uses multipart/form-data for efficient binary transfer (no base64 overhead)
  • Automatic MIME type detection from filename
  • Returns attachment ID for linking to records via update_records
  • Requires write permission in session token

Usage

# Get session token with write permission
TOKEN=$(curl -s ... | jq -r '.token')

# Upload file
curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@invoice.pdf" \
  https://example.com/api/v1/attachments

# Returns: {"success": true, "data": {"attachment_id": 42, "filename": "invoice.pdf", "size_bytes": 31395}}
# Python example
import requests

response = requests.post(
    f'{proxy_url.replace("/proxy", "/attachments")}',
    headers={'Authorization': f'Bearer {token}'},
    files={'file': open('invoice.pdf', 'rb')}
)
attachment_id = response.json()['data']['attachment_id']

# Link to record via proxy
requests.post(proxy_url, headers={'Authorization': f'Bearer {token}'}, json={
    'method': 'update_records',
    'table': 'Bills',
    'records': [{'id': 1, 'fields': {'Attachment': [attachment_id]}}]
})

[1.2.0] - 2026-01-02

Added

Session Token Proxy

  • Session token proxy: Agents can request short-lived tokens for bulk operations
  • get_proxy_documentation MCP tool: returns complete proxy API spec
  • request_session_token MCP tool: creates scoped session tokens with TTL (max 1 hour)
  • POST /api/v1/proxy HTTP endpoint: accepts session tokens for direct API access
  • Supports all 11 Grist operations (read, write, schema) via HTTP

[1.1.0] - 2026-01-02

Added

Logging

  • Tool Call Logging: Human-readable logs for every MCP tool call with agent identity, document, stats, and duration
  • Token Truncation: Secure token display in logs (first/last 3 chars only)
  • Stats Extraction: Meaningful operation stats per tool (e.g., "42 records", "3 tables")
  • LOG_LEVEL Support: Configure logging verbosity via environment variable (DEBUG, INFO, WARNING, ERROR)
  • Health Check Suppression: /health requests logged at DEBUG level to reduce noise

Log Format

2026-01-02 10:15:23 | agent-name (abc...xyz) | get_records | sales | 42 records | success | 125ms
  • Pipe-delimited format for easy parsing
  • Multi-line error details with indentation
  • Duration tracking in milliseconds

[1.0.0] - 2026-01-01

Initial release of grist-mcp, an MCP server for AI agents to interact with Grist spreadsheets.

Added

Core Features

  • MCP Server: Full Model Context Protocol implementation with SSE transport
  • Token-based Authentication: Secure agent authentication via GRIST_MCP_TOKEN
  • Granular Permissions: Per-document access control with read, write, and schema scopes
  • Multi-tenant Support: Configure multiple Grist instances and documents

Discovery Tools

  • list_documents: List accessible documents with their permissions

Read Tools

  • list_tables: List all tables in a document
  • describe_table: Get column metadata (id, type, formula)
  • get_records: Fetch records with optional filter, sort, and limit
  • sql_query: Execute read-only SELECT queries

Write Tools

  • add_records: Insert new records into a table
  • update_records: Modify existing records by ID
  • delete_records: Remove records by ID

Schema Tools

  • create_table: Create new tables with column definitions
  • add_column: Add columns to existing tables
  • modify_column: Change column type or formula
  • delete_column: Remove columns from tables

Infrastructure

  • Docker Support: Multi-stage Dockerfile with non-root user
  • Docker Compose: Ready-to-deploy configuration with environment variables
  • Health Endpoint: /health for container orchestration readiness checks
  • SSE Transport: Server-Sent Events for MCP client communication
  • Environment Variable Substitution: ${VAR} syntax in config files

Testing

  • Unit Tests: Comprehensive coverage with pytest-httpx mocking
  • Integration Tests: Docker-based tests with ephemeral containers
  • Rich Test Runner: Progress display for test execution
  • Test Isolation: Dynamic port discovery for parallel test runs

Developer Experience

  • Makefile: Commands for testing, building, and deployment
  • Dev Environment: Docker Compose setup for local development
  • MCP Config Display: Startup message with client configuration snippet

Security

  • SQL injection prevention with SELECT-only query validation
  • API key isolation per document
  • Token validation at startup (no runtime exposure)
  • Non-root container execution