Skip to main content
Glama

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). Three write tools log time and correct entries that were logged wrong.

Tool

The question it answers

projects_overview

What's on my plate? Projects with client, logged hours, budget burn, unbilled amounts

time_spent

Where did my time go? Date-range rollups grouped by project, client, label or day, with billable split

work_log

What did I actually do? Individual entries (with their id) and notes for a range; standup, diary or invoicing material

create_entry

Log time I already spent. One entry on a project and day; external_id makes a repeat call a no-op

update_entry

Fix an entry. Move it to another project, or change its minutes, note, day, labels or billable flag; returns it before and after

delete_entry

Remove an entry, e.g. a duplicate. Does nothing unless confirm is true

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 by uv sync)

  • A Timely account and a Timely OAuth application

  • Docker, only for the containerized HTTP deployment

Related MCP server: time-tracker-mcp

Setup

  1. Create a Timely OAuth app at https://app.timelyapp.com/<account>/oauth_applications with callback URL urn:ietf:wg:oauth:2.0:oob.

  2. Configure

    cp .env.example .env   # fill in TIMELY_CLIENT_ID and TIMELY_CLIENT_SECRET
  3. Authorize (once)

    uv sync
    uv run mcp-timely auth

    Open the printed URL, authorize, paste the code. Tokens land in TIMELY_TOKEN_FILE (default timely_tokens.json) and refresh themselves from then on.

  4. 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

TIMELY_CLIENT_ID

empty

Timely OAuth application ID.

TIMELY_CLIENT_SECRET

empty

Timely OAuth application secret.

TIMELY_TOKEN_FILE

timely_tokens.json

Where the token pair is stored. Must be writable and persistent.

TIMELY_API_BASE

https://api.timelyapp.com

Timely API base URL.

TRANSPORT

stdio

stdio or http (streamable HTTP on /mcp).

HOST

127.0.0.1

Bind address for http.

PORT

8000

Listen port for http.

MCP_API_KEY

empty

Bearer token for the MCP endpoint. Required when TRANSPORT=http.

APP_VERSION

unset

Version string reported by /health; set by the release image build.

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. Running mcp-timely auth again 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 needs Authorization: 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 up

Usage 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; version in pyproject.toml is 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 tools
projects_overviewProjects overviewA
Read-onlyIdempotent

[timely] What's on my plate? Every project with client, logged hours, budget burn, and unbilled amounts, sorted by hours logged.

ParametersJSON Schema
NameRequiredDescriptionDefault
include_inactiveNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYes
summaryYes
projectsYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, openWorld, and idempotent hints. The description adds behavioral details such as sorting by hours logged and specifying output fields (client, budget burn, unbilled amounts), providing additional context beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence that front-loads the purpose with '[timely] What's on my plate?' followed by a clear list of outputs. Every word is informative, with no wasted content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has one optional parameter and an output schema, the description covers the main purpose and output fields. However, it omits guidance on the include_inactive parameter, leaving a minor completeness gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, meaning the parameter include_inactive has no description in the schema. The tool description does not mention this parameter or explain when to set it to true, failing to compensate for the low schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool returns every project with client, logged hours, budget burn, and unbilled amounts, sorted by hours logged. It specifies the resource (projects overview) and the action (list/retrieve), making it distinct from sibling tools like time_spent and work_log.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage through '[timely] What's on my plate?' suggesting a quick overview, but it does not explicitly provide when to use this tool versus alternatives or conditions when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

time_spentTime spentA
Read-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).

ParametersJSON Schema
NameRequiredDescriptionDefault
sinceYes
untilYes
group_byNoproject

Output Schema

ParametersJSON Schema
NameRequiredDescription
sinceYes
untilYes
groupsYes
summaryYes
group_byYes
total_hoursYes
billable_hoursYes
total_formattedYes
non_billable_hoursYes

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate read-only, idempotent behavior. The description adds value by disclosing that totals are computed server-side by Timely and that day buckets follow the account's timezone. This provides clarity beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise, containing a few clear sentences. It front-loads the purpose and critical details without unnecessary words. The informal lead phrase 'Where did my time go?' adds personality but is still efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (3 params, output schema present), the description covers the main aspects: date range, grouping, timezone behavior, and server-side computation. It provides sufficient context for an agent to use the tool effectively.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description should compensate. It mentions the date range format (YYYY-MM-DD) and the group_by options, but does not elaborate on the meaning of 'since' and 'until' beyond the schema. Some value added but incomplete.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool computes server-side rollups for time spent, grouped by project/client/label/day, with billable split. It distinguishes from siblings by focusing on aggregated rollups rather than detailed logs or overviews.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for aggregated time data, mentioning server-side rollups and grouping options. However, it does not explicitly state when to use this tool over siblings like work_log or projects_overview, leaving the agent to infer based on the 'rollup' nature.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

work_logWork logA
Read-onlyIdempotent

[timely] What did I actually do? Individual entries with notes for a date range (YYYY-MM-DD) — standup, diary, and invoicing raw material.

ParametersJSON Schema
NameRequiredDescriptionDefault
uptoYes
sinceYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
uptoYes
sinceYes
entriesYes
summaryYes
total_hoursYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint, openWorldHint, idempotentHint; description adds date range format (YYYY-MM-DD) and notes about entries, but does not mention pagination, size limits, or other behavioral traits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Compact single sentence with a clarifying bracketed prefix, though the '[timely]' may be ambiguous; front-loaded with purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Description covers key output (entries with notes), references use cases (standup, diary, invoicing), and pairs well with existing annotations and output schema, making it mostly complete for a data retrieval tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema has 0% parameter description coverage. Description only indicates date range format but does not explain the 'since' and 'upto' parameters individually or their constraints.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states the tool retrieves individual work log entries with notes for a date range, explicitly distinguishing from sibling tools like projects_overview and time_spent by calling it 'raw material' for standup, diary, and invoicing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implies usage for raw activity entries, but no explicit guidance on when to use this versus siblings, nor when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.1.2
    • First observedprojects_overview
    • First observedtime_spent
    • First observedwork_log

TDQS

A4/5.0

Scored across 3 tools

Disambiguation5/5

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.

Naming Consistency5/5

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.

Tool Count5/5

Three tools are appropriate for a read-only time tracking reporting server, covering high-level overview, aggregated time, and detailed logs without unnecessary bloat.

Completeness4/5

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

ActivityActive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers