mcp-timely
Use this server as a read-only MCP interface to Timely for answering time-tracking questions through three query tools.
projects_overview: See projects with client, logged hours, budget burn, and unbilled amounts; optionally include inactive projects.time_spent: Get date-range rollups grouped by project, client, label, or day, including total, billable, and non-billable hours.work_log: Retrieve individual time entries with notes for a date range, including project, billable/billed status, and timer state.All supplied-schema tools are read-only and scoped to the authorized user; the schema does not include the write tools described in the README.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-timely What's on my plate?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-timely
An MCP server for Timely time tracking, built for asking questions rather than wrapping endpoints. It is for Timely users who want Claude, or any other MCP client, to answer "where did my time go?" reliably. Its three questions are each answered in a single upstream call with Timely doing the aggregation server-side, so the model never pages through raw entries to sum hours (and never gets the sum wrong). Four write tools log time, correct entries that were logged wrong, and mark invoiced hours billed.
Tool | The question it answers |
| What's on my plate? Projects with client, logged hours, budget burn, unbilled amounts |
| Where did my time go? Date-range rollups grouped by project, client, label or day, with billable split |
| What did I actually do? Individual entries (with their |
| Log time I already spent. One entry on a project and day; |
| Fix an entry. Move it to another project, or change its minutes, note, day, labels or billable flag; returns it before and after |
| Remove an entry, e.g. a duplicate. Does nothing unless |
| I've invoiced this. Marks my billable, unbilled entries on a project in a date range as billed; a dry run unless |
Everything is scoped to the authorized user; there are no user or team
parameters. update_entry and delete_entry refuse entries that are billed,
invoiced, locked, running a timer, or belong to someone else. When Timely
rejects a change, the error carries Timely's reason (for example labels the
target project does not allow).
Requirements
Python 3.12 or newer and uv
FastMCP 4 (
fastmcp>=4.0.10,<5.0.0, installed byuv sync)A Timely account and a Timely OAuth application
Docker, only for the containerized HTTP deployment
Related MCP server: time-tracker-mcp
Setup
Create a Timely OAuth app at
https://app.timelyapp.com/<account>/oauth_applicationswith callback URLurn:ietf:wg:oauth:2.0:oob.Configure
cp .env.example .env # fill in TIMELY_CLIENT_ID and TIMELY_CLIENT_SECRETAuthorize (once)
uv sync uv run mcp-timely authOpen the printed URL, authorize, paste the code. Tokens land in
TIMELY_TOKEN_FILE(defaulttimely_tokens.json) and refresh themselves from then on.Add to Claude Code (stdio)
claude mcp add timely -- uv run --directory /path/to/mcp-timely mcp-timely
Configuration
Settings come from environment variables (see .env.example).
Variable | Default | Purpose |
| empty | Timely OAuth application ID. |
| empty | Timely OAuth application secret. |
|
| Where the token pair is stored. Must be writable and persistent. |
|
| Timely API base URL. |
|
|
|
|
| Bind address for |
|
| Listen port for |
| empty | Bearer token for the MCP endpoint. Required when |
| unset | Version string reported by |
Authentication
There are two separate credentials:
Upstream (Timely): OAuth 2.0, bootstrapped once with
mcp-timely auth. Timely rotates refresh tokens on every refresh and its access tokens carry no expiry. The server uses the access token until a 401, then refreshes once, writes the new pair atomically before continuing, and retries the request once. The token file is the only state. Runningmcp-timely authagain rotates the token family, so any other running instance needs the new file. Otherwise re-authorization is only needed if the grant is revoked.Clients (HTTP only): with
TRANSPORT=http, every request needsAuthorization: Bearer <MCP_API_KEY>(constant-time compare). The server refuses to start over HTTP without a key.
HTTP deployment
TRANSPORT=http serves streamable HTTP on /mcp and liveness on /health
(also /healthz). The Dockerfile builds a non-root image with the token file
at /data/timely_tokens.json; compose.yaml runs the published image on host
port 8011 with a persistent timely-data volume. Run mcp-timely auth first
and place the resulting token file in that volume.
docker compose upUsage telemetry
A small middleware (src/mcp_timely/usage.py) writes one JSON line per tool
call to stderr: server name, tool name, duration, outcome and MCP protocol
version. It never records arguments or results. Tool failures raise
ToolError, so they are logged with outcome: error.
Development
uv sync
uv run pytest # in-memory MCP client, no network
uv run ruff check .CI (.github/workflows/ci.yml) runs ruff and the tests as the test check,
which is required before a pull request can merge into main.
Releases
Every push to main that touches non-doc files releases automatically: tests
and a security audit run, the next vX.Y.Z tag is pushed (no version-bump
commit), and a multi-arch image is published to ghcr.io/caseyro/mcp-timely
with that version baked in (reported by /health). Consequences:
The git tag is the version;
versioninpyproject.tomlis not bumped.Add
[skip ci]to a commit message to skip a release.Markdown-only and test-only changes don't trigger a release.
Support
If this server saves you time, you can buy me a coffee.
License
MIT, see LICENSE.
Available Tools
3 toolsprojects_overviewProjects overviewARead-onlyIdempotent
[timely] What's on my plate? Every project with client, logged hours, budget burn, and unbilled amounts, sorted by hours logged.
Inputs: include_inactive. Returns: count, summary, projects
time_spentTime spentARead-onlyIdempotent
[timely] Where did my time go? Server-side rollups for a date range (YYYY-MM-DD), grouped by project, client, label, or day, with billable split. Totals are computed by Timely, not client-side. Day buckets follow the Timely account's timezone (a day's bucket equals the sum of that day's entries).
Inputs: since (required), until (required), group_by. Returns: since, until, groups, summary, +5 more
work_logWork logARead-onlyIdempotent
[timely] What did I actually do? Individual entries with notes for a date range (YYYY-MM-DD) — standup, diary, and invoicing raw material.
Inputs: upto (required), since (required). Returns: upto, since, entries, summary, +1 more
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 3 tools
Each tool serves a clearly distinct purpose: projects_overview provides project-level summaries, time_spent aggregates time data, and work_log returns raw entries. No overlap or ambiguity.
All tool names follow a consistent pattern of [noun]_[descriptor] (e.g., projects_overview, time_spent, work_log), making them predictable and easy to understand.
Three tools are appropriate for a read-only time tracking reporting server, covering high-level overview, aggregated time, and detailed logs without unnecessary bloat.
The tools cover the main read operations for time tracking reporting, but lack write/update actions. For a reporting-focused server, this is acceptable, though a tool for client or user listing could enhance coverage.
Maintenance
Related MCP Connectors
timesheet.io MCP server - manage timers, projects, tasks and reports
Toggl 2.0 MCP server for tasks, projects, time entries, and workspace operations.
Manage Timequip projects, tasks, comments, members, and dashboards through MCP.
Read-only MCP server for ClassQuill, a tutoring-business-management platform.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceMCP server for Timely time tracking API. Connects Claude Code to your Timely account for reading and creating time entries, projects, tasks, and users.7MIT
- FlicenseNot gradedqualityDmaintenanceA local MCP server that reads logged hours from an internal time tracker, providing tools to list time entries, projects, and the active timer. It is read-only, enabling Claude Code to see time-tracking data without writing.-
- AlicenseNot gradedqualityCmaintenanceRead-only MCP server for Clockify time tracking, exposing 60 raw read tools and five workflows for status, workspace overview, and review of days/weeks.MIT
- FlicenseNot gradedqualityBmaintenanceRead-only MCP server for Hubstaff Time Tracking and Tasks APIs, providing tasks, comments, hours, and project data. Supports OAuth 2.1 for ChatGPT integration.-