Skip to main content

Cross-agent time-calibration corpus served over MCP

Project description

TimeCal

A cross-agent time-calibration corpus, served over MCP. It counters the systematic over-estimation that LLM agents inherit from ~30 years of human software-engineering timelines.

Problem

When an agent reads "build a Reddit→Claude pipeline," its training prior maps that to engineer-weeks. A capable agent driving Claude Code can ship the same thing in an afternoon. That bad prior cascades: things get called "infeasible solo," scope gets cut that didn't need cutting, multi-phase rollouts get proposed where one session would do.

Asserting "you're powerful" doesn't override the prior — examples do.

Solution

A small MCP server backed by a local SQLite corpus of real "human-estimated → actually-took" rows. Any MCP-aware agent (Claude Code, Codex, Cursor, Cline) can:

  • Call calibrate_task(task_description) to retrieve similar past rows before scoping.
  • Call log_completion(...) to append new rows as work finishes, so the corpus grows.
  • Load the timecal://preamble resource to reset the prior at conversation start.

The corpus separates two clocks (wall-clock days vs. active hours — different units, never compared raw) and tags every row with a regime so the reading agent can tell whether a human "months" estimate was a fake prior or a real external constraint.

Quickstart

Zero-install, with uv:

uvx timecal          # runs the MCP server over stdio

Or install it:

pip install timecal
python -m timecal.server

The corpus DB is created and seeded automatically on first run (10-row example corpus), at ~/.timecal/timecal.db. No setup step. Point TIMECAL_DB at any path to use your own corpus instead — the server, scripts, and tests all read it at call time.

From source (for development):

git clone https://github.com/Conalh/timecal && cd timecal
pip install -e ".[dev]"
pytest -q            # 25 passing

Use it from an agent

Claude Code:

claude mcp add timecal -- uvx timecal

Generic MCP client (mcp.json / client config):

{
  "mcpServers": {
    "timecal": {
      "command": "uvx",
      "args": ["timecal"],
      "env": { "TIMECAL_DB": "/path/to/your/corpus.db" }
    }
  }
}

(env is optional — drop it to use the auto-seeded default.) Once connected, the agent gets two tools (calibrate_task, log_completion) and one resource (timecal://preamble).

What it changes — before / after

Same task, same model, the difference is one calibrate_task call:

User: Can we build a Slack bot that summarizes standup messages?

Without TimeCal: "That's a solid 2–3 week project — you'll need to design the webhook integration, build the summarization pipeline, handle Slack's API rate limits, and test across channels. I'd suggest phasing it: week 1 plumbing, week 2 the LLM layer, week 3 hardening."

With TimeCal (after calibrate_task("slack bot that summarizes standup messages") returns the standup-summary-bot row — human bucket: weeks, actual: ~5h active, agent_executed): "A close match in the corpus shipped in about 5 active hours, agent-executed — the webhook plumbing dominated, not the LLM call. This is an afternoon, not a sprint. Want me to start on the webhook handler?"

Layout

timecal/
  README.md             this file
  LICENSE               MIT
  pyproject.toml        packaging + pytest/ruff config
  src/timecal/
    server.py           MCP server entrypoint (FastMCP, stdio)
    calibrate.py        retrieval / ranking + agent-facing formatting
    log.py              validation + insert (mcp-free, unit-tested)
    db.py               DB path + auto-init/seed (honors TIMECAL_DB)
    data/
      schema.sql        SQLite schema (shipped in the wheel)
      example.csv       10-row synthetic corpus, auto-seeded on first run
  scripts/
    bootstrap.py        pre-create + seed the DB without starting the server
    init_db.py          create an empty DB from schema
    import_seed.py      import a reviewed CSV (validates enums)
  tests/                pytest suite (db, calibrate, log, import_seed)

Data model

Every row in projects carries:

  • regime — what kind of work it was; drives whether a human estimate was a fake prior or a real constraint:
    • agent_executed — agent does the work end-to-end; human-week estimates are usually agent-hour.
    • review_bound — agent produces code in minutes, but human review / re-prompting dominates wall-clock.
    • external_bound — gated by people, data accrual, or training runs; "months" is months, not a prior.
  • two clockswall_clock_days (includes idle gaps) and active_hours (real work time). Different units; the corpus never compares them raw.
  • estimate_bucket — ordinal of what a human team would have estimated (hoursyear_plus), plus estimate_raw for nuance.
  • data_quality — how the row was measured: dates_only, timed_session, or self_reported.
  • source — provenance. Rows with an empty source are filtered out of the default calibrate_task response, so synthetic exploration data can't pollute the agent's view.

Bring your own corpus

The auto-seeded example rows (marked source=example) are synthetic — enough to make the demo runnable, not enough to be your real prior. Build your own:

  • point TIMECAL_DB at a fresh path, then log tasks as you finish them via the log_completion tool, or
  • import a reviewed CSV into your TIMECAL_DB: python scripts/import_seed.py path/to/your.csv (rejects, rather than silently drops, rows with bad enums or empty what_shipped).

To keep your corpus free of the example rows, delete them with DELETE FROM projects WHERE source = 'example'; or start from an empty DB via python scripts/init_db.py.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

timecal-0.1.0.tar.gz (17.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

timecal-0.1.0-py3-none-any.whl (15.5 kB view details)

Uploaded Python 3

File details

Details for the file timecal-0.1.0.tar.gz.

File metadata

  • Download URL: timecal-0.1.0.tar.gz
  • Upload date:
  • Size: 17.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for timecal-0.1.0.tar.gz
Algorithm Hash digest
SHA256 fd8c5c890cbfac2c79b421d3d4f929cea26d7d4b8731de65bd62442f8ee2409c
MD5 cd3f30cf9a52adf29c2210a24a1c610d
BLAKE2b-256 b8b01bb34a04fb907ee125e9737de1df4e6354e36946cda8cf565b893828a470

See more details on using hashes here.

File details

Details for the file timecal-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: timecal-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 15.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for timecal-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 da9256d7c7ed6fe229841e8b0448fa1a313e01be72a9f6b886536c55175d56aa
MD5 5d56a936a2bebb356cc9a55b3f0f58e3
BLAKE2b-256 d80a075c6d8e59ccf623803cf57d784a45ae0d36fcf721d0604833cb5aa00622

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page