Skip to content

feat(toggl): add self-hostable HTTP transport - #36

Open
jack-arturo wants to merge 3 commits into
mainfrom
feat/self-host-streamable-http
Open

feat(toggl): add self-hostable HTTP transport#36
jack-arturo wants to merge 3 commits into
mainfrom
feat/self-host-streamable-http

Conversation

@jack-arturo

@jack-arturo jack-arturo commented May 2, 2026

Copy link
Copy Markdown
Member

Summary

  • enforce 50% Vitest coverage gates and include all src/**/*.ts in coverage
  • add shared MCP server setup with stdio default plus Streamable HTTP at POST /mcp and GET /health
  • make timeline title privacy default-safe with title_mode support and deprecated redact_titles compatibility
  • add sanitized MCP error payloads, focused MCP tests, Dockerfile, and GHCR release workflow
  • document self-hosting, server-side TOGGL_API_TOKEN auth, Docker, PaaS deployment notes, and MCP HTTP bearer auth

Breaking Changes

  • Timeline event titles are now redacted by default. Existing callers that relied on raw window titles must pass title_mode: "raw" or redact_titles: false.
  • Streamable HTTP deployments require MCP_HTTP_AUTH_TOKEN unless explicitly running unauthenticated loopback-only development mode. stdio remains the default transport.

Test Plan

  • npm run lint
  • npm run build
  • npm test
  • npm run test:coverage
  • npm audit --audit-level=high
  • ../mcp-ecosystem/scripts/audit-server.sh ../mcp-toggl
  • docker build -t mcp-toggl:self-host-test .
  • Docker HTTP smoke: /health and MCP listTools with TOGGL_API_TOKEN=dummy and MCP_HTTP_AUTH_TOKEN set

Related Issues

Copilot AI review requested due to automatic review settings May 2, 2026 15:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a self-hostable HTTP transport alongside the existing stdio MCP server, hardens some error handling/privacy defaults, and expands tests/docs to cover the new deployment mode. In the broader codebase, it extends the existing Toggl MCP server from a local CLI-focused tool into a deployable HTTP service while also changing timeline privacy behavior.

Changes:

  • Add Streamable HTTP serving with /mcp and /health, plus Docker and GHCR build workflow support for self-hosting.
  • Sanitize MCP/Toggl error payloads and add broader MCP/HTTP smoke tests.
  • Change timeline title handling to redact by default, introduce title_mode, and document self-hosting/privacy behavior.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
vitest.config.ts Expands coverage collection to all src/**/*.ts and adds minimum thresholds.
tests/toggl-api.test.ts Adds regression coverage for sanitized auth error handling.
tests/timeline.test.ts Verifies new default-redaction and title_mode timeline behavior.
tests/stdio-smoke.test.ts Updates stdio smoke expectations for the new timeline schema defaults.
tests/mcp-server.test.ts Adds in-memory MCP server tests for schema, error payloads, cache tools, and timeline privacy.
tests/http-smoke.test.ts Adds end-to-end smoke coverage for the new HTTP transport and /health endpoint.
tests/cache-manager.test.ts Minor formatting-only test change.
src/toggl-api.ts Reworks 4xx/Timeline errors into structured sanitized TogglAPIErrors.
src/timeline.ts Introduces title_mode and flips timeline title redaction to default-on.
src/index.ts Refactors server creation, adds HTTP transport, error sanitization, and updated tool schema/help text.
README.md Documents new privacy defaults, self-hosting, Docker/PaaS usage, and config variables.
Dockerfile Adds container image for HTTP deployment.
.github/workflows/docker-build.yml Adds Docker build/publish workflow for GHCR releases.
.dockerignore Excludes build, git, and local artifacts from Docker context.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/timeline.ts
Comment thread src/index.ts
Comment thread src/index.ts
Comment thread src/index.ts Outdated
Comment thread src/index.ts Outdated
Comment thread README.md Outdated
@jack-arturo
jack-arturo force-pushed the feat/self-host-streamable-http branch from f6df1b6 to b631c46 Compare June 4, 2026 00:16
@jack-arturo

Copy link
Copy Markdown
Member Author

Refreshed this branch onto current main (fd1debf) with a clean rebase and force-with-lease push.

Local verification from the rebased branch:

  • npm run build — pass
  • npm test — 43/43 pass
  • npm run test:coverage — pass; coverage summary stays above the 50% gates
  • npm run lint — 0 errors; existing no-explicit-any warnings remain
  • npm audit --audit-level=high — 0 high/critical; existing moderate brace-expansion advisory only

I could not run the local Docker smoke because Docker is not running on this machine (missing ~/.docker/run/docker.sock), but the refreshed GitHub Docker Build check is passing, along with CI, Security/CodeQL, and PR-title checks.

I also compared #50 while refreshing this: the important pieces from that review path are already covered here (per-request server/transport, structured JSON-RPC errors, auth, CORS opt-in, and cache warm-up memoization). I did not add the literal --http CLI flag because this PR’s env-based TRANSPORT=http contract is the documented self-host path and keeps the public interface narrower.

* feat(toggl): add workspace user reporting

Refreshes PR #46 on top of feat/self-host-streamable-http.

Adds privacy-safe workspace user lookup and optional uid report filtering through Toggl Reports API v3.

Co-authored-by: Vincent Ardern <vincent@charityaccounts.co.nz>

* fix: address review feedback for workspace users and header casing

---------

Co-authored-by: Vincent Ardern <vincent@charityaccounts.co.nz>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants