Traggo MCP Server
Everything you need to use traggo with your favorite LLM.
Documentation
Traggo MCP Server
An MCP server that lets AI assistants track time in Traggo. It proxies MCP tool calls to a Traggo instance's GraphQL API, and ships a small web UI for obtaining the access token you authenticate with.
How it works
The server has two surfaces:
- Web login (
/login) — you sign in with your Traggo username and password and get back a Traggo device token. This is a thin wrapper over Traggo'sloginGraphQL mutation; the token is shown on screen for you to copy. - MCP endpoint (
/mcp) — your MCP client connects here and sends the token as aAuthorization: Bearer <token>header. Each tool call is translated into a Traggo GraphQL request (sent upstream asAuthorization: traggo <token>, the scheme Traggo expects).
The server is stateless — it stores nothing. The Traggo token is the entire auth state.
┌─────────────┐ Bearer <token> ┌──────────────┐ traggo <token> ┌────────────┐
MCP client │ POST /mcp │ ─────────────────► │ traggo-mcp │ ─────────────────► │ Traggo │
└─────────────┘ │ (this server)│ GraphQL │ instance │
└──────────────┘ └────────────┘
browser ── GET/POST /login ──────────────► returns a device token to copy
Tools
| Tool | Description |
|---|---|
start_timer | Start a running timer (open timespan) with tags and a note. Start defaults to now. |
stop_timer | Stop a running timer by id. End defaults to now. |
add_timespan | Record a completed timespan with explicit start/end, tags and a note. |
update_timespan | Edit a timespan's start, end, tags and note by id. |
remove_timespan | Delete a timespan by id. |
list_timers | List currently running timers (to find an id to stop). |
list_timespans | List recorded timespans, optionally within an RFC3339 time range (to find an id to edit). |
list_tags | List all tag definitions (key, color, usage count). |
create_tag | Create a tag definition (key + hex color). |
update_tag | Change a tag's color and optionally rename it. |
remove_tag | Delete a tag definition by key. |
ping_auth | Diagnostic — echoes the token to verify auth wiring. |
Tags are key/value pairs (e.g. {"key": "project", "value": "traggo"}). Times are RFC3339
(e.g. 2026-06-28T09:00:00Z).
Running
The server needs one environment variable: TRAGGO_URL, the base URL of your Traggo instance
(no trailing slash).
export TRAGGO_URL=https://traggo.example.com
go run ./cmd/server
It listens on :8080. Open http://localhost:8080/login to get a token, then point your MCP
client at http://localhost:8080/mcp.
Connecting an MCP client
Use a streamable-HTTP MCP transport pointed at /mcp, with the token as a bearer credential. For
example, in a client that supports HTTP MCP servers:
{
"mcpServers": {
"traggo": {
"url": "http://localhost:8080/mcp",
"headers": { "Authorization": "Bearer <your-traggo-token>" }
}
}
}
Development
Prerequisites
- Go 1.26+
- templ —
go install github.com/a-h/templ/cmd/templ@latest(HTML templating) - Bun — runs the Tailwind CLI via
bunx - air —
go install github.com/air-verse/air@latest(hot reload, optional) - Dagger — only needed to build/publish the container image
Hot-reload dev loop
export TRAGGO_URL=https://traggo.example.com
air
air (configured in .air.toml) regenerates templates and CSS, rebuilds, and serves with live
reload on http://localhost:8090 (proxying the app on :8080).
Building assets manually
If you're not using air:
templ generate # .templ → _templ.go
bunx @tailwindcss/cli -i ./app.css -o assets/output.css # build CSS
go run ./cmd/server
Project layout
cmd/server/ Entry point: route wiring, starts the HTTP server
internal/
auth/ Web login flow → Traggo device token
mcp/ MCP server: tool registration + bearer-token middleware
traggo/ GraphQL client for the Traggo API (all timer/timespan/tag ops)
views/ templ components and pages for the web UI
assets/ Static files (generated CSS, images)
.dagger/ Dagger module for building & publishing the container image
Building & publishing the image
The container image is built with Dagger — a multi-stage build (Go compile
on golang:1.26, runtime on wolfi-base) that publishes to a container registry. Registry,
credentials and image name are all parameters:
dagger call build \
--source . \
--registry registry.example.com \
--username [email protected] \
--registry-password env:REGISTRY_PASSWORD \
--image traggo-mcp:latest
--source defaults to . and --image defaults to traggo-mcp:latest. The function returns the
published image reference.
Contributing
Contributions are welcome. To get started:
- Fork and clone the repo.
- Install the prerequisites above and run
air(or the manual build steps) against a Traggo instance you control. - Make your change. If you touch a
.templfile, runtempl generate. If you add or change a dependency, rungo mod tidy. - Make sure
go build ./...andgo vet ./...pass. - Open a pull request describing the change.
When adding a new tool, the pattern is:
- Define the input/output types in
internal/traggo/types.go(usejsonschemastruct tags so the MCP schema is descriptive). - Add the operation method to
internal/traggo/service.go(it goes through the sharedexecutehelper for auth and error handling). - Register the tool in
internal/mcp/server.go.
The Traggo GraphQL schema is the source of truth for available operations and field names.