DepTime
DepTime is a local MCP server for Python-library API history that helps agents diagnose version-related errors and check compatibility.
Explain errors: Analyze tracebacks for
ImportError,ModuleNotFoundError,AttributeError, and signatureTypeErrors, returning what changed, release versions, deprecation messages, replacement candidates, confidence, and pins to restore old APIs.Trace symbol history: Look up a package symbol’s version history, including first/last seen, signature changes, deprecations, removals, and replacements.
Preflight code: Batch-check symbols and intended keyword arguments against a specific installed version, reporting missing symbols, rejected kwargs, deprecation notes, and hints.
Diff versions: Find breaking changes and deprecations between two versions or since a date, optionally restricted to symbols your code uses.
Check coverage: List indexed packages/version ranges and identify packages DepTime cannot answer for, avoiding guesses.
Stay local: Answers are computed from a prebuilt SQLite index on your machine; library code is not imported or executed.
Indexes PyPI package releases and their public APIs to provide version history, breaking-change and deprecation diffs, symbol compatibility checks, and traceback-based error explanations for Python libraries.
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., "@DepTimewhat changed in httpx between 0.27.2 and 0.28.1?"
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.
When an agent hits ImportError, AttributeError or "unexpected keyword argument" in a fast-moving library, one call to DepTime says what changed, in which release, and what to use instead. Answers are computed from static diffs of every indexed release, not from docs or model memory.
Free, open source (MIT), and local: your code and errors never leave your machine.
Every night, GitHub Actions reads each new release's public API with griffe, which parses the source without running it, diffs it against the previous release, and publishes the result as one file, index.sqlite.gz, on this repo's Releases. On your machine, deptime mcp checks that file's sha256 and schema before swapping it in, then answers every question locally in milliseconds. The full design is in docs/04-architecture.md, and the decisions are in docs/adr/.
TypeError: Client.__init__() got an unexpected keyword argument 'proxies'{
"symbol": "httpx.Client.__init__(proxies)",
"issue": "param_removed",
"installed_version": "0.28.1",
"last_version_with": "0.27.2",
"first_version_without": "0.28.0",
"deprecated_in": "0.26.0",
"replacements": [
{"target": "proxy", "confidence": 0.8, "source": "deprecation_message"},
{"target": "mounts", "confidence": 0.79, "source": "deprecation_message"}
],
"pin_to_restore": "httpx<=0.27.2",
"confidence": "high"
}That's the real explain_error answer from the published index, trimmed. The full answer also quotes the deprecation message DepTime found in httpx's own source, and adds a one-sentence explanation for your agent to pass on.
Status: alpha. The prebuilt index is rebuilt nightly. Known gaps are tracked in BACKLOG.md.
Install
Requires uv.
# Claude Code. Cursor, Codex, VS Code and Claude Desktop take the same
# command (uvx deptime mcp) in their MCP config.
claude mcp add deptime -- uvx deptime mcpOn first launch DepTime downloads its prebuilt index (one file from this repo's GitHub Releases) in the background, then checks for a newer one at most once a day. Set DEPTIME_OFFLINE=1 to never touch the network.
Claude Code users can also install the plugin in integrations/claude-code with /plugin marketplace add cschmertz/deptime, then /plugin install deptime@deptime. It adds a skill and a local hook that suggests DepTime when a Python version-change error appears in a command's output.
Related MCP server: driftwatch-mcp
Tools
Tool | Use it when |
| An import or call into a library just failed |
| Before trusting an API you remember |
| Pre-flight check of the symbols and kwargs you're about to use |
| Upgrading, or "what changed since my training cutoff?" |
| What's indexed (52 fast-moving packages: AI/agent stack + libraries with known breaking changes) |
Every answer carries evidence and a confidence level. If a package isn't covered, DepTime says so instead of guessing. The contracts are in docs/03-product-spec.md.
CLI
uvx deptime explain --installed httpx==0.28.1 < traceback.txt
uvx deptime history httpx Client.__init__
uvx deptime check httpx 0.28.1 'httpx.Client:proxies,proxy'
uvx deptime diff httpx 0.27.2 0.28.1
uvx deptime diff pydantic 2024-06-01 # everything since a date
uvx deptime index status | pullHosting (optional)
Local mode covers coding agents. For web clients that only accept a URL, run deptime serve (MCP at /mcp, JSON at /v1/*) on any container host. The repo includes a Dockerfile and fly.toml, and the server applies anonymous rate limits. See docs/05-self-hosting.md.
Prior art and credits
griffe does the static analysis.
since-cutoff diffs your pinned dependencies against a model's training cutoff, locally and on demand. DepTime differs by shipping a prebuilt cross-version index and starting from a traceback.
Context7 and Ref serve version-specific docs. DepTime answers symbol-level "when and what replaced it" questions.
Contributing
The most useful contributions are wrong-answer reports, which become benchmark cases. See CONTRIBUTING.md. Development setup:
uv sync && uv run pytest
# build a small local index from real PyPI wheels
uv run deptime ingest httpx --versions 0.27.2 0.28.1Docs
Product spec · Architecture · Self-hosting · Risks & spikes · Privacy & security
License
Available Tools
5 toolscheck_symbolsCheck symbols and kwargs against an installed versionARead-onlyIdempotent
Batch-check that symbols, and the keyword arguments you plan to pass, exist in a specific version of a package. Returns present/missing per symbol, rejected kwargs, deprecation notes, and hints. Use it to preflight code against the version you have installed; for one symbol across all releases use symbol_history, and after an exception use explain_error.
| Name | Required | Description | Default |
|---|---|---|---|
| package | Yes | PyPI distribution name, e.g. 'langchain-core'. | |
| symbols | Yes | Up to 100 symbols, each a public dotted path plus the keyword arguments you plan to pass. | |
| version | Yes | Installed version, e.g. '0.28.1'. |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| exact | Yes | |
| package | Yes | |
| results | Yes | |
| resolved_version | Yes | Nearest indexed version <= requested_version. |
| requested_version | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent and closed-world, so the safety profile is covered; the description adds useful context by enumerating what the response contains (present/missing per symbol, rejected kwargs, deprecation notes, hints) and pinning the check to the installed version. It stops short of stating limits or edge behavior for invalid dotted paths, so not a full 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences: capability first, return contents second, routing third. No filler, and the most decision-relevant information (what it checks, what it returns) is front-loaded before the sibling routing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a full output schema, complete parameter descriptions and annotations covering safety, the description only needs to fix scope and routing — which it does. It makes clear the target is the installed version and that results are per-symbol, leaving nothing an agent needs ambiguous before calling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and all three parameters are documented inline, including the 100-symbol cap and dotted-path examples, so the baseline is 3. The description only restates that kwargs are the ones you 'plan to pass' and that checking is batched — no additional syntax, format or constraint guidance beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and scope: 'Batch-check that symbols, and the keyword arguments you plan to pass, exist in a specific version of a package.' That is a precise verb (batch-check) plus two resources (symbols, kwargs) qualified by version, which an agent can immediately distinguish from diff_versions or coverage.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It names the canonical use case ('preflight code against the version you have installed') and routes to two named alternatives with the conditions that select them: symbol_history for one symbol across all releases, explain_error after an exception. This is explicit when-to-use plus alternatives, exactly the top of the scale.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
coverageWhat DepTime indexesARead-onlyIdempotent
Lists indexed packages and version ranges. If a package is missing, DepTime cannot answer about it. Takes no arguments; call it first when unsure whether a package is covered.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| policy | Yes | |
| packages | Yes | |
| index_built_at | Yes | |
| configured_but_not_indexed | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and openWorldHint=false, so the safety profile is covered. The description adds genuinely new behavior: it takes no arguments and absence from the list means DepTime cannot answer about that package — a useful precondition an agent couldn't infer from annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, each earning its place: purpose first, then the failure implication, then the calling guidance. Nothing is padded or redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return shape needn't be described, annotations carry the safety profile, and there are no parameters. The description supplies exactly the missing pieces — scope and the consequence of a package being absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so the baseline of 4 applies; the description confirms 'takes no arguments,' matching the empty schema. No additional parameter meaning is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Lists indexed packages and version ranges,' which is a distinct object from what siblings like symbol_history or diff_versions operate on. It's clear, but it never names a sibling to explicitly differentiate itself, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Takes no arguments; call it first when unsure whether a package is covered' gives a concrete usage trigger, and the missing-package warning explains the consequence of skipping it. There's no explicit when-not-to-use or named alternative, so it stops at 4.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diff_versionsBreaking changes between versionsARead-onlyIdempotent
Breaking changes and deprecations of a package between two versions, or since a date such as your training cutoff ('YYYY-MM-DD'). Optionally restrict to the symbols your code uses. Most severe first. Use it when upgrading, or for code written against an older release; for a single symbol use symbol_history.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum events to return (1-500), most severe first; `truncated` is true when more exist. | |
| package | Yes | PyPI distribution name, e.g. 'langchain-core'. | |
| to_version | No | Defaults to the latest indexed release. | |
| from_version | Yes | Version, or a date 'YYYY-MM-DD' (nearest release on/before). | |
| used_symbols | No | Public dotted paths your code uses (up to 500); only changes on these paths or their members are returned. | |
| include_added | No | Also list symbols added in the range. Off by default: breaking changes and deprecations only. |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| events | Yes | |
| package | Yes | |
| truncated | No | |
| to_version | Yes | |
| from_version | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnly, idempotent, closed-world), so the description's job is to add behavior: it does, with result ordering ('most severe first') and the default that added symbols are excluded. It stops short of discussing permissions or result volume, but that is minor for a read-only query.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences, front-loaded with purpose and scope, followed by the sibling routing. Every clause (date form, symbol restriction, ordering) carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values needn't be described, and the description covers purpose, scope, ordering, and sibling routing. Only minor gaps remain around the limit/truncation interaction, which the schema already handles.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so all six parameters are already documented. The description's mention of date-based from_version and the 'symbols your code uses' filter largely restates the schema, adding only the training-cutoff framing; include_added and limit are not touched.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb+resource (diffing a package's versions) with explicit scope: breaking changes and deprecations between two versions or since a date. It also names the sibling it is not for (symbol_history) so an agent can discriminate without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete usage contexts ('when upgrading, or for code written against an older release') and names the alternative for the single-symbol case. It lacks an explicit when-not/exclusion, but the routing cue is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
explain_errorExplain a Python import/attribute/signature errorARead-onlyIdempotent
Call this when a third-party Python library raises ImportError ('cannot import name'), ModuleNotFoundError, AttributeError ('has no attribute'), or TypeError ('unexpected keyword argument' / 'missing required argument'). Returns what changed, in which release, the deprecation message, replacement candidates with evidence, and the version pin that restores the old API. Pass installed versions for an exact answer. An error DepTime can't explain returns empty findings rather than a guess; check note and not_covered.
| Name | Required | Description | Default |
|---|---|---|---|
| traceback | Yes | Traceback text, or at least the final 'SomeError: message' line. Long logs are fine: only the last 20,000 characters are analysed. | |
| pip_freeze | No | Output of `pip freeze` / `uv pip freeze` / `pip list`. | |
| installed_versions | No | Installed versions, e.g. {"httpx": "0.28.1"}. |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| signal | Yes | |
| findings | Yes | |
| not_covered | No | Packages involved in the error that DepTime does not index. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint=true, openWorldHint=false, and idempotentHint=true. Beyond that, the description adds important behavior: it explains what evidence is returned, that passing installed versions yields an exact answer, that unexplained errors return empty findings 'rather than a guess', and that callers should inspect `note` and `not_covered`.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the trigger conditions, then the return value, then the exact-answer guidance, and finally the limitation. Every sentence contributes useful routing or behavioral information, with no wasted text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema, the description does not need to fully document return values, but it still summarizes the key findings and explicitly covers the empty-result and not_covered behavior. Together with the fully described input schema, this makes the definition complete for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds meaning beyond the schema by explaining that passing installed versions produces 'an exact answer', which tells the agent why and when to supply that optional parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific diagnostic action, 'explain' a Python error, and enumerates the exact exception classes it covers: ImportError, ModuleNotFoundError, AttributeError, and TypeError. It also states the concrete result ('what changed, in which release, the deprecation message, replacement candidates with evidence, and the version pin'), which clearly separates it from the sibling tools like symbol_history and diff_versions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit call conditions: 'Call this when a third-party Python library raises...' followed by the exact exception types. It does not explicitly name alternatives such as check_symbols or diff_versions or state when not to use this tool, so it falls short of a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
symbol_historyVersion history of one symbolARead-onlyIdempotent
Version history of one public symbol, e.g. package='httpx', path='httpx.Client.init': first and last release it exists in, signature changes, deprecations, removals, and replacement candidates. Use before writing code against an API you remember from training data. A path no indexed release has is not an error: it returns ever_seen=false. For many symbols at one installed version, use check_symbols.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Public dotted path; the package prefix may be omitted. | |
| package | Yes | PyPI distribution name, e.g. 'langchain-core'. |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| path | Yes | |
| events | No | |
| indexed | Yes | False when the package is not in DepTime's coverage; see the `coverage` tool. |
| package | Yes | |
| ever_seen | No | False means no indexed version ever exposed this public path. |
| last_seen | No | |
| first_seen | No | |
| replacements | No | |
| present_in_latest | No | |
| latest_indexed_version | No | |
| signature_at_last_seen | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses what the history includes: first and last release, signature changes, deprecations, removals, and replacement candidates. It also clarifies an important edge case: an unindexed path is not an error and returns ever_seen=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with purpose, then usage guidance, edge-case behavior, and the alternative tool. Every clause carries useful information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, annotations, and existing output schema, the description is complete enough to support correct selection and invocation. It covers purpose, usage, non-error behavior, and sibling-tool routing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already well documented. The description adds concrete examples like package='httpx' and path='httpx.Client.__init__', but does not meaningfully expand parameter semantics beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: version history of one public symbol. It gives concrete examples and explicitly distinguishes the single-symbol use case from the sibling check_symbols tool for many symbols.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says when to use it: before writing code against an API remembered from training data. It also names the alternative check_symbols and the condition that selects it: many symbols at one installed version.
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.
2 tool updates
v0.1.3- Changed
check_symbols2 fields changed- added
Input schema / properties / package / descriptionAdded value: +"PyPI distribution name, e.g. 'langchain-core'." - added
Input schema / properties / symbols / descriptionAdded value: +"Up to 100 symbols, each a public dotted path plus the keyword arguments you plan to pass."
- Changed
diff_versions4 fields changed- added
Input schema / properties / include_added / descriptionAdded value: +"Also list symbols added in the range. Off by default: breaking changes and deprecations only." - added
Input schema / properties / limit / descriptionAdded value: +"Maximum events to return (1-500), most severe first; `truncated` is true when more exist." - added
Input schema / properties / package / descriptionAdded value: +"PyPI distribution name, e.g. 'langchain-core'." - added
Input schema / properties / used_symbols / descriptionAdded value: +"Public dotted paths your code uses (up to 500); only changes on these paths or their members are returned."
5 tool updates
v0.1.0- First observed
check_symbols - First observed
coverage - First observed
diff_versions - First observed
explain_error - First observed
symbol_history
TDQS
Scored across 5 tools
Each tool has a distinct role, and the descriptions explicitly route between close cases such as symbol_history vs check_symbols vs diff_versions. There is still some conceptual overlap around symbol/version inspection, so an agent could initially hesitate between history and batch checking.
All names use snake_case, but the action convention is mixed: explain_error, check_symbols, and diff_versions are verb_noun, while symbol_history and coverage are noun phrases. Readable, but not a predictable verb_noun pattern throughout.
Five focused tools cover the workflow without redundant entries, and each has a clear job. This is well within the appropriate range for a focused dependency/API compatibility server.
The surface covers coverage discovery, error explanation, single-symbol history, batch preflight, and version diffing, which are the core workflows for dependency/API compatibility. Minor gaps might include broader symbol/package discovery or manifest-level dependency resolution, but agents can work around them.
Maintenance
Related MCP Connectors
Dated, verified API breakages for coding agents, plus a local scan for them in your existing code.
Check exact npm/PyPI upgrades for evidence-backed breaking changes; query APIs and components.
Search indexed code, trace dependencies, assess change impact, and recall repository memory.
Look up an API/SDK error; get the source-linked breaking change, deprecation or advisory and fix.
Related MCP Servers
- AlicenseBqualityBmaintenanceEnables AI agents to index local Python repositories and retrieve code intelligence through semantic search, caller lookups, hybrid context expansion, and visualization.5MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI coding agents to identify exactly what broke between two dependency versions, with citations for every claim, and to verify package existence to catch typosquatting, all without requiring an API key.MIT
- AlicenseAqualityCmaintenanceEnables AI coding agents to inspect project dependency versions, resolve version constraints, and audit Python code for deprecated or incompatible APIs using authoritative evidence and local AST analysis.316 npmMIT
- AlicenseAqualityBmaintenanceProvides a local, version-exact API index for installed Python and TypeScript packages, enabling accurate lookups and static code checking that catches hallucinated or misused APIs without executing the code.9MIT