pysince
MCP server for coding agents: detects stale file reads before your agent acts on outdated content. Zero dependencies.
pip install pysince
What it does
pysince is a local MCP server that stamps every file your agent reads with its mtime and SHA-256 hash. On any subsequent tool call, it compares stored fingerprints against the current file and surfaces all tracked files that have changed, unprompted. The agent does not need to remember to check anything.
Files changed since last read:
config.json (content changed, mtime changed) read 4m ago (+2 lines)
alerts.py (content changed, mtime changed) read 3m ago
How it works
Every file the agent reads gets stamped with its current mtime and content hash. On any later MCP call, pysince checks all tracked files: mtime first (fast os.stat), full hash only if mtime moved. No daemon, no polling, no background process. Just a comparison against disk at the next turn.
Setup
Add to your MCP client config:
VS Code (.vscode/mcp.json):
{
"servers": {
"pysince": {
"type": "stdio",
"command": "pysince-mcp"
}
}
}
Antigravity (mcp_config.json):
{
"mcpServers": {
"pysince": {
"command": "python",
"args": ["-m", "since.mcp"]
}
}
}
Then add this line to your agent's system instructions:
On the first read of any file, call
stamp_file_read. Before editing a file, callcheck_staleness. When the response lists changed files, re-read them before acting on their contents.
Tools
| Tool | When to call it | Returns |
|---|---|---|
stamp_file_read |
After reading any file | Source ID confirmation |
check_staleness |
Before editing a stamped file | Stale status, change reasons (content vs mtime), line delta, read timestamp. Also lists all other tracked files that changed. |
session_duration |
Anytime | Session age and message count |
invalidate_source |
Manual override | Number of invalidated events |
check_staleness never answers only about the one file asked. It reports the full set of tracked files that have drifted, so the agent cannot stay blind to a change it did not think to check.
When to use
Strongest when files change outside the agent's view: another process, a teammate on the same repo, a formatter, a pre-commit hook, a parallel agent, or context that drifted over a long session.
Less useful for quick single-file edits an agent already re-reads on its own. Skip it for throwaway scripts. Reach for it when agents share files, sessions run long, or more than one actor touches the tree.
Chat apps
pysince also provides a @since_time decorator for wrapping LLM chat functions with temporal context: timestamps, session duration tracking, gap detection, and stale context surfacing.
from since import Store, since_time
from openai import OpenAI
store = Store("~/.since/chat.db")
client = OpenAI()
@since_time(store=store, timezone="Asia/Kolkata")
def chat(messages):
return client.chat.completions.create(model="gpt-4o-mini", messages=messages)
resp = chat(messages=[{"role": "user", "content": "hello"}])
print(resp.choices[0].message.content)
The model receives a time block before each turn:
Now: Wed Jul 01, 02:36 AM (night)
Session: 9h 2m total, 4m active across 3 sittings, 8 messages
Gap: 6h since the last message
Works with OpenAI, Anthropic, and Gemini response shapes automatically. Pass extract_reply= for other providers.
CLI
pysince enrich <session_id> # Enrich a session with temporal context
pysince search <session_id> # Search messages by time range
pysince stats <session_id> # Show session statistics
Requirements
- Python 3.10+
- Zero dependencies
The PyPI name is pysince because since was already taken. The import name and repo name are since.
Links
Metadata
Release files for pysince 0.2.9
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pysince-0.2.9.tar.gz | 23.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pysince-0.2.9-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 42.7 kB
Release files / pysince-0.2.9.tar.gz
| Download URL | pysince-0.2.9.tar.gz |
|---|---|
| Size | 23.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
844d42ff27fb68f53f2f59ef39fd354264fbb5d6c68cee474ba9512037b2f40e
|
|
BLAKE2b-256 checksum How to use checksums |
7e712be05a2deb6969e4b7ad254f2a193e588ee2d592cd97b15283f2db28076f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.9
|
Release files / pysince-0.2.9-py3-none-any.whl
| Download URL | pysince-0.2.9-py3-none-any.whl |
|---|---|
| Size | 19.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d422039b2e02b6970dddbf5b8f56e97cd930773ba1222222cc55b75528a63c38
|
|
BLAKE2b-256 checksum How to use checksums |
1976695934a9893e0dad3be20e06bfdb7a9c96ae392c311bb1cd9f740294bc0c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.9
|
Security for pysince 0.2.9
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.