timeline-mcp
A deterministic MCP server that gives AI assistants a temporal memory layer by extracting events from conversation, normalizing time expressions, and maintaining structured timeline state to enable consistent multi-session conversations.
README
timeline-mcp
MCP Server for Timeline-Aware Conversational Memory
A lightweight, deterministic MCP (Model Context Protocol) server that gives AI assistants a temporal memory layer — extracting events from conversation, normalizing relative time expressions, and maintaining structured timeline state so LLMs can answer consistently across multi-session conversations.
Project Overview
Conversational AI systems today have no native sense of time. They treat every message as a fresh interaction, with no awareness of how many days have passed since a user last reported an event. timeline-mcp solves this by sitting between the LLM and the conversation history as a dedicated temporal reasoning tool.
The server exposes five MCP tools that any MCP-compatible client (Claude, Continue, Cursor, etc.) can call:
| # | Tool | Purpose |
|---|---|---|
| 1 | extract_timeline_events |
Scan messages for events and normalize dates |
| 2 | build_timeline_state |
Aggregate events into a coherent timeline |
| 3 | summarize_timeline_context |
Generate an LLM-ready natural-language summary |
| 4 | days_since_event |
Compute elapsed days since any tracked event |
| 5 | upsert_message_into_timeline |
Incrementally update the timeline with new messages |
Zero external dependencies beyond python-dateutil. Pure rule-based extraction — no ML, no randomness, fully deterministic.
Problem Statement
LLMs lose track of time across conversations.
This isn't a model quality issue — it's an architectural one. LLMs have no internal clock, no persistent state between sessions, and no mechanism to compute "how long ago" something happened relative to now. When a conversation spans days or weeks, the assistant's temporal reasoning collapses.
Concrete Failure Mode
Day 1 User: "I had appendicitis surgery two weeks ago." → surgery = May 8
Day 3 User: "Still have some pain, but it's improving."
Day 7 User: "Feeling much better today."
Day 14 User: "Should I remove my stitches now?"
Assistant: "You should remove them two weeks after surgery."
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
WRONG. Two weeks have ALREADY passed.
The correct answer accounts for elapsed time.
The assistant interpreted "two weeks" as a future interval from today, rather than understanding that two weeks have already elapsed since the original surgery date. This class of error is systematic — it happens whenever relative time anchors drift across session boundaries.
Why Timeline-Aware Memory Matters
This problem is acute in any domain where time-sensitive follow-up matters:
| Domain | Example Failure |
|---|---|
| Healthcare | Misjudging post-surgical recovery milestones, medication tapering schedules |
| Legal | Miscalculating filing deadlines relative to prior events |
| Project Management | Losing track of sprint days elapsed vs. original estimates |
| Habit Tracking | Recommending actions that don't account for days already passed |
| Customer Support | Failing to escalate based on how long an issue has been open |
timeline-mcp provides a reusable, protocol-compliant solution. Instead of every assistant developer building their own temporal logic (or ignoring the problem), they can point their MCP client at this server and get structured timeline state for free.
Installation
Prerequisites: Python 3.11+
Option 1: System package (Debian/Ubuntu)
sudo apt install python3-dateutil
git clone https://github.com/your-org/timeline-mcp.git
cd timeline-mcp
Option 2: Virtual environment
git clone https://github.com/your-org/timeline-mcp.git
cd timeline-mcp
python3 -m venv .venv
.venv/bin/pip install python-dateutil
The only runtime dependency is python-dateutil (for ISO-8601 date parsing). Everything else uses the Python standard library.
Quick Start
Run the included medical follow-up example to see the full scenario:
PYTHONPATH=src python3 examples/medical_followup.py
Run all tests:
PYTHONPATH=src python3 -m unittest discover tests -v
Expected: 33 tests pass.
Running as an MCP Server
The server communicates via JSON-RPC 2.0 over stdio — no network ports, no configuration files. The client launches timeline-mcp as a child process and communicates over its stdin/stdout pipes.
How the command works
python3 -m timeline_mcp.server
^
Runs the package as a Python module. The server loop
reads JSON-RPC requests from stdin, processes them,
and writes JSON-RPC responses to stdout.
The PYTHONPATH environment variable tells Python where to find the timeline_mcp package. If installed as a pip package, PYTHONPATH is not needed — the client can run timeline-mcp directly via the console script entry point.
Start the server manually (for testing)
cd timeline-mcp
PYTHONPATH=src python3 -m timeline_mcp.server
# Server is now waiting for JSON-RPC on stdin. Type a JSON-RPC
# request and press Enter, or pipe one in:
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | PYTHONPATH=src python3 -m timeline_mcp.server
MCP Client Configuration
All MCP clients that support stdio transport use the same pattern: a command, an args array, and optionally an env map. Pre-built config snippets are available in examples/configs/.
Common pattern (all clients)
{
"mcpServers": {
"timeline-mcp": {
"command": "python3",
"args": ["-m", "timeline_mcp.server"],
"env": {
"PYTHONPATH": "/absolute/path/to/timeline-mcp/src"
}
}
}
}
Replace /absolute/path/to/timeline-mcp/src with the actual path on your system. Use an absolute path — relative paths may resolve differently depending on how the client launches the process.
Virtual environment users: If you installed dependencies in a venv, point
commandto the venv's Python binary:"command": "/absolute/path/to/timeline-mcp/.venv/bin/python3"
Claude Desktop
File: claude_desktop_config.json (see Anthropic docs)
{
"mcpServers": {
"timeline-mcp": {
"command": "python3",
"args": ["-m", "timeline_mcp.server"],
"env": {
"PYTHONPATH": "/absolute/path/to/timeline-mcp/src"
}
}
}
}
After editing the config, restart Claude Desktop. The five timeline-mcp tools will appear in the tool list automatically.
Claude Code (CLI)
File: .claude/settings.json in your project, or ~/.claude/settings.json for all projects.
{
"mcpServers": {
"timeline-mcp": {
"type": "stdio",
"command": "python3",
"args": ["-m", "timeline_mcp.server"],
"env": {
"PYTHONPATH": "/absolute/path/to/timeline-mcp/src"
}
}
}
}
Claude Code requires the explicit "type": "stdio" field. Restart Claude Code or run /mcp reload to pick up the change.
Continue.dev (VS Code / JetBrains)
File: .continue/config.json (project) or ~/.continue/config.json (global)
{
"experimental": {
"mcpServers": {
"timeline-mcp": {
"command": "python3",
"args": ["-m", "timeline_mcp.server"],
"env": {
"PYTHONPATH": "/absolute/path/to/timeline-mcp/src"
}
}
}
}
}
Note: Continue wraps MCP servers under the experimental key. Restart Continue or reload the config from the extension menu.
Cursor IDE
File: .cursor/mcp.json (project) or ~/.cursor/mcp.json (global)
{
"mcpServers": {
"timeline-mcp": {
"command": "python3",
"args": ["-m", "timeline_mcp.server"],
"env": {
"PYTHONPATH": "/absolute/path/to/timeline-mcp/src"
}
}
}
}
Cursor discovers MCP servers on launch. Use the MCP panel (Ctrl+Shift+P → "MCP: Manage Servers") to verify.
Generic / Other Clients
Any MCP-compatible client that supports stdio transport uses the same structure. The three required fields are:
| Field | Purpose |
|---|---|
command |
The executable to launch (e.g., python3) |
args |
Arguments passed to the command (e.g., ["-m", "timeline_mcp.server"]) |
env |
Environment variables set for the child process (minimum: PYTHONPATH) |
The server implements the MCP 2024-11-05 protocol version and supports initialize, tools/list, and tools/call methods.
MCP Tools — Full Reference
1. extract_timeline_events
Parse a list of conversation messages and extract timeline-relevant events with normalized dates.
Input:
{
"messages": [
{
"id": "msg_1",
"text": "I had appendicitis surgery two weeks ago.",
"timestamp": "2026-05-22T10:00:00Z"
}
]
}
Output:
{
"events": [
{
"message_id": "msg_1",
"event_type": "surgery",
"time_expression": "two weeks ago",
"normalized_date": "2026-05-08",
"confidence": 0.89
}
]
}
Supported event types: surgery, stitch_removal, symptom_start, medication_start, medication_stop, followup_visit
Supported time expressions: today, yesterday, tomorrow, N days ago, N weeks ago, last week, next week, in N days, N days/weeks after <event>, word numbers (two weeks ago)
2. build_timeline_state
Aggregate extracted events into a normalized timeline with anchor dates, derived fields, and recovery phase.
Input: List of events + reference datetime
Output: TimelineState with anchor_events, event_log, derived (days_since_*), active_context (phase), conflicts
3. summarize_timeline_context
Generate a concise natural-language summary for injection into an LLM system prompt.
Output example: "The user had surgery 14 days ago. They are in the Post Op Recovery phase. No stitch removal event has been recorded yet."
4. days_since_event
Compute days since a named anchor event (e.g., surgery_date, stitch_removal_date).
Input: Timeline state + event name + reference time
Output: {"event_name": "surgery_date", "days_since": 14}
5. upsert_message_into_timeline
The primary runtime tool — feed in one new message and the existing timeline state; get back the updated state.
Key behavior:
- Detects new events in the message
- Resolves relative time expressions using existing anchor dates
- Merges new events with existing log (conflict resolution: prefers higher confidence, logs conflicts)
- Recomputes all derived fields against the new message timestamp
Example Usage: Medical Follow-Up
Message 1 (May 8): "I had appendicitis surgery today."
→ surgery_date: 2026-05-08, days_since: 0, phase: immediate_post_op
Message 2 (May 15): "I still have some pain."
→ symptom_start: 2026-05-15, days_since_surgery: 7, phase: early_recovery
Message 3 (May 22): "Should I remove my stitches now?"
→ days_since_surgery: 14, stitch_removal_date: null, phase: post_op_recovery
→ Summary: "The user had surgery 14 days ago. No stitch removal recorded."
Message 4 (May 23): "I removed my stitches yesterday."
→ stitch_removal_date: 2026-05-22, days_since_surgery: 15, phase: scar_care_early
The LLM receiving this context at Message 3 can correctly reason that the user is already at day 14 post-surgery and that stitch removal is appropriate now — rather than naively computing "two weeks from today."
Project Structure
timeline-mcp/
├── README.md
├── pyproject.toml
├── requirements.txt
├── src/
│ └── timeline_mcp/
│ ├── __init__.py
│ ├── server.py # MCP JSON-RPC 2.0 server (stdio transport)
│ ├── schemas.py # Dataclass models with dict serialization
│ ├── temporal.py # Time expression parser (10+ patterns)
│ ├── extractors.py # Event extraction via regex trigger phrases
│ ├── state.py # Timeline construction, upsert, conflict resolution
│ ├── summarizer.py # Template-based NL summary generation
│ └── constants.py # EventType enum, trigger phrases, recovery phases
├── tests/
│ ├── test_temporal.py # 13 tests — time expression parsing
│ ├── test_extractors.py # 7 tests — event detection
│ ├── test_state.py # 8 tests — state construction & updates
│ ├── test_summarizer.py # 4 tests — summary generation
│ └── test_integration.py # 1 test — full 15-day scenario
└── examples/
├── medical_followup.py # End-to-end demonstration script
└── configs/
├── generic-stdio.json # Generic MCP client config
├── claude-desktop.json # Claude Desktop config
├── claude-code.json # Claude Code (CLI) config
├── continue-dev.json # Continue.dev (VS Code) config
└── cursor.json # Cursor IDE config
Limitations
- Rule-based extraction only. Uses regex patterns and keyword matching — no ML. Covers common phrasings well but will miss implicit, idiomatic, or highly variable event mentions.
- English only. All trigger phrases, time expressions, and summaries target English text. Other languages would require separate pattern modules.
- Single conversation scope. Each timeline state is self-contained. No cross-conversation aggregation, no user identity layer (MVP scope).
- No persistence. State lives in memory only. Server restarts lose all timeline data. Persistent storage is a planned enhancement.
- Confidence scores are heuristic. Based on match length, not statistical calibration. Useful for relative ranking within a session, not as absolute probabilities.
- Recovery phases are illustrative. The phase labels (
post_op_recovery,scar_care_early) are example mappings for the medical domain. They are not clinical guidance.
Safety Disclaimer
timeline-mcp is NOT a medical device. It does not provide medical advice, diagnosis, prognosis, or treatment recommendations.
This tool:
- Tracks dates and computes elapsed time intervals
- Detects mentions of medical events in conversation text
- Labels recovery phases using a static day-range lookup table
This tool does not:
- Make clinical decisions or recommendations
- Replace professional medical judgment
- Store, transmit, or process Protected Health Information (PHI) in a HIPAA-compliant manner
- Validate the accuracy of user-reported medical events
Any medical-domain examples in this repository are for illustration only. The core capability is temporal reasoning — it applies equally to project management, legal workflows, habit tracking, customer support, and any other domain where elapsed time matters.
If you are building a healthcare application, consult with qualified medical and legal professionals.
Roadmap
v0.2 (next)
- [ ] Persistent timeline storage (SQLite)
- [ ] Multi-user / multi-session timeline isolation
- [ ] Confidence scoring based on explicit vs. implicit date resolution
- [ ] Additional event types:
lab_result,imaging,physical_therapy,diet_change
v0.3
- [ ] Persian (Farsi) language module — separate trigger phrase and time expression tables
- [ ] Calendar-aware date computation (skip weekends/holidays for business-day intervals)
- [ ] Timeline visualization as structured JSON for rendering
v1.0
- [ ] Conflict resolution strategies (user-prompted, majority-vote, source-weighted)
- [ ] Adapter examples for Claude Desktop, Continue.dev, Cursor, and OpenAI
- [ ] Comprehensive benchmark dataset for temporal extraction accuracy
- [ ] Full internationalization framework for trigger phrases
Sponsorship & Support
timeline-mcp is an open-source project built to solve a real problem in conversational AI. It is maintained by independent developers who believe LLMs should be able to track time reliably.
If this project is useful to you or your organization, please consider supporting it:
- GitHub Sponsors: github.com/sponsors/your-org
- Open Collective: opencollective.com/timeline-mcp
- Contribute: PRs, issues, and documentation improvements are always welcome
Commercial support and custom integrations are available. Contact timeline-mcp@example.com for inquiries about:
- Priority feature development
- Custom event type and domain modeling
- On-premises deployment support
- HIPAA-compliant configuration guidance
License
MIT — see LICENSE for details.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.