Commit Graph

46 Commits

Author SHA1 Message Date
renovate-bot a12ac6aa56 chore(deps): update python:3.14-slim docker digest to 44dd044 2026-06-14 04:04:30 +00:00
renovate-bot 6521078b6a chore(deps): pin dependencies 2026-03-26 22:12:00 +00:00
Bill 33bb464102 feat: add label parameter to add_column and modify_column tools
Allow setting a human-readable display label for columns, separate from
the column_id used in formulas and API calls. The label defaults to the
column_id if not provided.
2026-01-26 15:18:11 -05:00
Bill a97930848b feat: normalize filter values to array format for Grist API
The Grist API requires all filter values to be arrays. This change adds
automatic normalization of filter values in get_records, wrapping single
values in lists before sending to the API.

This fixes 400 errors when filtering on Ref columns with single integer IDs.

Changes:
- Add filters.py module with normalize_filter function
- Update get_records to normalize filters before API call
- Add Orders table with Ref column to mock Grist server
- Add filter validation to mock server (rejects non-array values)
- Fix shell script shebangs for portability (#!/usr/bin/env bash)
2026-01-14 17:56:18 -05:00
Bill 734cc0a525 feat: add attachment download via proxy endpoint
Add GET /api/v1/attachments/{id} endpoint for downloading attachments
through the MCP proxy. This complements the existing upload endpoint and
enables complete attachment workflows via the proxy API.
2026-01-12 12:13:23 -05:00
Bill a7c87128ef feat: replace MCP attachment tool with proxy endpoint
Build and Push Docker Image / build (push) Successful in 8s
The MCP tool approach was impractical because it required the LLM to
generate large base64 strings token-by-token, causing timeouts.

Changes:
- Remove upload_attachment MCP tool
- Add POST /api/v1/attachments endpoint for multipart/form-data uploads
- Update proxy documentation to show both endpoints
- Uses existing GristClient.upload_attachment() method
- Requires write permission in session token
2026-01-03 20:26:36 -05:00
Bill 848cfd684f feat: add upload_attachment MCP tool
Build and Push Docker Image / build (push) Successful in 24s
Add support for uploading file attachments to Grist documents:

- GristClient.upload_attachment() method using multipart/form-data
- upload_attachment tool function with base64 decoding and MIME detection
- Tool registration in server.py
- Comprehensive unit tests (7 new tests)

Returns attachment ID for linking to records via update_records.

Bumps version to 1.3.0.
2026-01-03 19:59:47 -05:00
Bill 50c5cfbab1 Merge master into feature/session-proxy 2026-01-02 14:40:37 -05:00
Bill 8484536aae fix(integration): add auth headers and fix mock server routes 2026-01-02 14:36:25 -05:00
Bill b3bfdf97c2 fix(test): increase sleep duration for flaky expiry test 2026-01-02 14:24:10 -05:00
Bill 3d1ac1fe60 test(integration): add session proxy integration test 2026-01-02 14:17:59 -05:00
Bill 80e93ab3d9 test(proxy): add permission denial test 2026-01-02 14:08:58 -05:00
Bill 7073182f9e feat(proxy): add method dispatch 2026-01-02 14:07:47 -05:00
Bill caa435d972 feat(proxy): add request parsing 2026-01-02 13:57:38 -05:00
Bill ba88ba01f3 feat(server): register session token tools
Add get_proxy_documentation and request_session_token tools to the MCP
server. The create_server function now accepts an optional token_manager
parameter (SessionTokenManager | None) to maintain backward compatibility.

When token_manager is None, request_session_token returns an error
message instead of creating tokens.
2026-01-02 13:51:47 -05:00
Bill fb6d4af973 feat(tools): add request_session_token tool
Add MCP tool for agents to request short-lived session tokens for HTTP
proxy access. The tool validates that agents can only request permissions
they already have (no privilege escalation).

- Validates document access and each requested permission
- Creates session token via SessionTokenManager
- Returns token metadata including proxy URL and expiration
- Includes tests for success case and permission denial scenarios
2026-01-02 13:45:07 -05:00
Bill a7bb11d765 feat(tools): add get_proxy_documentation tool
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.
2026-01-02 13:39:02 -05:00
Bill c65ec0489c test(session): add tests for invalid and expired tokens 2026-01-02 13:34:52 -05:00
Bill 681cb0f67c feat(session): add token validation 2026-01-02 13:31:18 -05:00
Bill 3c97ad407c feat(session): cap TTL at 1 hour maximum 2026-01-02 13:27:30 -05:00
Bill b310ee10a9 feat(session): add SessionTokenManager with token creation
Add SessionTokenManager class that creates short-lived session tokens
for HTTP proxy access. Each token includes agent identity, document
scope, permissions, and expiration time.
2026-01-02 13:22:53 -05:00
Bill d6fb3f4ef0 feat(logging): add get_logger helper 2026-01-02 12:45:17 -05:00
Bill 163b48f1f4 feat(logging): add setup_logging with LOG_LEVEL support 2026-01-02 12:41:40 -05:00
Bill a668baa4d0 feat(logging): add log line formatter 2026-01-02 12:37:19 -05:00
Bill 69a65a68a6 feat(logging): add stats extraction for all tools 2026-01-02 12:35:18 -05:00
Bill ff7dff7571 feat(logging): add token truncation helper 2026-01-02 12:30:09 -05:00
Bill 49c5043661 fix: use correct Grist API endpoint for modify_column
The Grist API uses PATCH /tables/{table}/columns with a columns array
in the body, not PATCH /tables/{table}/columns/{column_id}. Updated
the endpoint to match the API spec.
2026-01-01 10:10:49 -05:00
Bill 8809095549 refactor: per-connection auth via Authorization header
Replace startup token authentication with per-SSE-connection auth.
Each client now passes Bearer token in Authorization header when
connecting. Server validates against config.yaml tokens and creates
isolated Server instance per connection.

- server.py: accept (auth, agent) instead of (config_path, token)
- main.py: extract Bearer token, authenticate, create server per connection
- Remove GRIST_MCP_TOKEN from docker-compose environments
2026-01-01 08:49:58 -05:00
Bill f921412f01 feat: add test isolation scripts with dynamic port discovery
- Add get-test-instance-id.sh for branch-based container isolation
- Add run-integration-tests.sh for full test lifecycle management
- Update integration tests to read service URLs from environment
  variables (GRIST_MCP_URL, MOCK_GRIST_URL) with fallback defaults
2025-12-30 19:11:04 -05:00
Bill e235e998e4 refactor: organize tests into unit/ and integration/ directories
Move unit tests from tests/ to tests/unit/ for clearer separation
from integration tests. Update pyproject.toml testpaths and Makefile
test target to reflect the new structure.
2025-12-30 17:38:46 -05:00
Bill c57e71b92a fix: use pure ASGI app for SSE transport compatibility
- Replace Starlette routing with direct ASGI dispatcher to avoid
  double-response issues with SSE transport
- Simplify integration test fixtures by removing async client fixture
- Consolidate integration tests into single test functions per file
  to prevent SSE connection cleanup issues between tests
- Fix add_records assertion to expect 'inserted_ids' (actual API response)
2025-12-30 15:05:32 -05:00
Bill e6f737e2a3 feat: add tool integration tests with Grist API validation 2025-12-30 11:46:34 -05:00
Bill 5607946441 feat: add MCP protocol compliance tests 2025-12-30 11:44:18 -05:00
Bill 3ecd3303ce feat: add integration test fixtures with MCP client 2025-12-30 11:43:23 -05:00
Bill ee385d82ad feat: add integration test configuration 2025-12-30 11:38:29 -05:00
Bill 7acd602ffd feat: add mock Grist server for integration testing 2025-12-30 11:37:36 -05:00
Bill ed612694fe fix: add security hardening and documentation for deployment
- Add document validation to prevent NoneType crash when document not configured
- Add SQL query validation (SELECT only, no multi-statement)
- Add 30-second HTTP request timeout
- Fix filter parameter JSON encoding for get_records
- Add return type annotation to get_document
- Add tests for document lookup and SQL validation
- Add comprehensive README with usage instructions
2025-12-29 18:42:36 -05:00
Bill f716e5d37e fix: implement token-based authentication at server startup
- Server now authenticates from GRIST_MCP_TOKEN env var or token parameter
- Removed unused code (_set_agent, nonlocal check)
- Added AuthError handling in main.py
- Updated test to pass token explicitly
2025-12-03 15:07:06 -05:00
Bill 1ed5554944 feat: add MCP server with all tools registered 2025-12-03 15:00:48 -05:00
Bill 9b759cfe76 feat: add schema tools (create_table, add_column, modify_column, delete_column) 2025-12-03 14:53:17 -05:00
Bill eb0bf3eaf6 feat: add write tools (add_records, update_records, delete_records) 2025-12-03 14:49:32 -05:00
Bill 0a6f699d30 feat: add read tools (list_tables, describe_table, get_records, sql_query) 2025-12-03 14:45:55 -05:00
Bill a3167bec63 feat: add list_documents discovery tool 2025-12-03 14:42:45 -05:00
Bill c4ddc3b1b0 feat: add Grist API client 2025-12-03 14:34:37 -05:00
Bill 716de523d8 feat: add authentication and authorization 2025-12-03 14:30:32 -05:00
Bill 43fbd2dced feat: add config loading with env var substitution 2025-12-03 14:26:53 -05:00