Add SessionTokenManager class that creates short-lived session tokens
for HTTP proxy access. Each token includes agent identity, document
scope, permissions, and expiration time.
Enables agents to delegate bulk data operations to scripts,
bypassing LLM generation time for data-intensive operations.
Scripts authenticate via short-lived session tokens requested
through MCP, then call a simplified HTTP proxy endpoint.
When Grist validates the Host header (common with reverse proxy setups),
internal Docker networking fails because requests arrive with
Host: container-name instead of the external domain.
The new host_header config option allows overriding the Host header
sent to Grist while still connecting via internal Docker hostnames.
- Add .gitea/workflows/release.yml for Gitea builds
- Uses plain docker commands (no action dependencies)
- Pushes to git.prettyhefty.com registry
- Simplify .github/workflows/build.yaml for GitHub only
- Remove Gitea detection logic
- Only push latest tag for non-prerelease versions
The workflow was checking vars.GITEA_ACTIONS (repository variable)
but Gitea sets GITEA_ACTIONS as an environment variable. This caused
Gitea builds to incorrectly try using ghcr.io.
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.
The MCP config was using the internal container port (3000) instead of
the external mapped port. Added EXTERNAL_PORT env var support so clients
get the correct connection URL when running behind Docker port mapping.
- Add deploy/dev/config.yaml for dev environment testing
- Mount config from ./config.yaml instead of project root
- Create template config if missing and exit gracefully
- Update .gitignore to only ignore root config.yaml
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
- Add scripts/test-runner.py with rich progress bars and fail-fast behavior
- Add rich>=13.0.0 as dev dependency
- Update Makefile: `make test` now runs all tests (unit + integration)
- Test runner shows live progress, current test, and summary
Now `make test` runs both unit and integration tests with docker
containers, matching the docker-service-architecture skill guidelines.
- 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
Reorganize Docker configuration into environment-specific directories:
- deploy/dev/: Development with hot reload and source mounting
- deploy/test/: Ephemeral testing with branch isolation and dynamic ports
- deploy/prod/: Production with resource limits, logging, and restart policy
Key improvements in test compose:
- Dynamic ports (no fixed 3000/8484) for parallel test runs
- Branch-isolated container/network names via TEST_INSTANCE_ID
- service_healthy condition instead of service_started
- Increased retry counts for stability
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.
- 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)