Tracking MCP
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., "@Tracking MCPTrack my weight: 72.5kg today"
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.
Tracking MCP
Generic MCP server for tracking any entity type with schema-less JSON Hybrid storage.
Track body weight, daily scorecards, fitness sessions, books, or any custom entity without defining rigid schemas. Auto-discovery, self-documenting, and SQL-queryable.
Features
Schema-less Design: Track any entity type (weight, scorecard, fitness, books, custom) without ALTER TABLE
Auto-Discovery: Entity types automatically registered on first use
Self-Documenting: MCP Resources expose schema examples and usage guides
SQL-Queryable: Use
json_extract()for advanced analyticsLocal-First: Privacy-friendly, zero external dependencies
Hybrid Storage: SQLite with JSON columns for flexibility + performance
CRUD Operations: Insert, update, query, delete via MCP Tools
Built-in Prompts: Pre-configured templates for common tracking scenarios
Related MCP server: nutrition-mcp
Installation
Using uvx (Recommended)
# Run directly without installation
uvx tracking-mcp
# Or install globally
pip install tracking-mcpFrom Source
git clone https://github.com/mindfullabai/tracking-mcp.git
cd tracking-mcp
pip install -e .Initialize Database
Database is auto-created on first use at the path specified in DB_PATH environment variable (defaults to ~/tracking.db).
Quick Start
Claude Desktop Configuration
Add to your Claude Desktop MCP settings (.mcp.json or ~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"tracking-mcp": {
"type": "stdio",
"command": "uvx",
"args": ["tracking-mcp"],
"env": {
"DB_PATH": "/path/to/your/data/tracking.db"
}
}
}
}Alternative (with pip install):
{
"mcpServers": {
"tracking-mcp": {
"type": "stdio",
"command": "tracking-mcp",
"env": {
"DB_PATH": "/path/to/your/data/tracking.db"
}
}
}
}Basic Usage
From Claude Desktop, you can now:
Track my weight: 72.5kg todayShow me my weight trend for the last 30 daysLog workout: HYROX for 45 minutes todayMCP Server Specification
Tools (4)
1. track_event
Insert or update tracking event for any entity type.
Parameters:
entity_type(string, required): Entity type (e.g., 'weight', 'scorecard', 'fitness', 'book', or custom)date(string, required): Event date in YYYY-MM-DD formatdata(object, required): Entity-specific data (schema-free JSON)entity_id(string, optional): Unique ID for entity instance (e.g., 'book_atomic_habits')
Example:
track_event(
entity_type="weight",
date="2026-01-14",
data={"weight_kg": 72.8, "day_type": "MAR", "source": "manual"}
)2. query_events
Query tracking events with filters.
Parameters:
entity_type(string, optional): Filter by entity typeentity_id(string, optional): Filter by entity IDstart_date(string, optional): Start date (inclusive)end_date(string, optional): End date (inclusive)limit(integer, optional): Maximum results (default: 100)
Example:
query_events(
entity_type="weight",
start_date="2025-12-15",
end_date="2026-01-14",
limit=30
)3. delete_event
Delete tracking event by ID.
Parameters:
event_id(integer, required): Event ID to delete
4. list_entity_types
Get all registered entity types with schema examples.
Returns: JSON array of entity types with descriptions and schema examples.
Resources (3)
1. tracking://schema/entity_types
List of all registered entity types with schema examples (JSON).
2. tracking://docs/usage
Usage guide for tracking new entity types dynamically (Markdown).
3. tracking://stats/summary
Current statistics: total events, entity types, date range, events by type (JSON).
Prompts (3)
1. track-weight
Template for tracking body weight.
Arguments: weight_kg, date
2. track-workout
Template for logging workout session.
Arguments: workout_type, duration_min, date
3. query-trend
Get trend data for entity type over date range.
Arguments: entity_type, days (default: 30)
Database Schema
tracking_events Table
Column | Type | Description |
| INTEGER PRIMARY KEY | Auto-increment ID |
| TEXT | Entity type ('weight', 'scorecard', etc.) |
| TEXT | Optional unique ID for entity instances |
| DATE | Event date (YYYY-MM-DD) |
| JSON | Schema-free JSON data |
| TIMESTAMP | Auto-generated creation timestamp |
| TIMESTAMP | Auto-updated modification timestamp |
Indexes: entity_type, date, entity_id
entity_types Table
Column | Type | Description |
| TEXT PRIMARY KEY | Entity type name |
| TEXT | Human-readable description |
| JSON | Example JSON schema |
| TIMESTAMP | Registration timestamp |
| TIMESTAMP | Last update timestamp |
Pre-seeded entity types: weight, scorecard, fitness, book
Advanced Usage Examples
Track Custom Entity Type
# Sleep quality tracking (auto-registered)
track_event(
entity_type="sleep_quality",
date="2026-01-14",
data={
"hours": 7.5,
"quality_score": 8,
"dreams": True,
"interruptions": 2,
"notes": "Felt refreshed"
}
)Track Entity with Unique ID
# Reading progress for specific book
track_event(
entity_type="book",
entity_id="book_atomic_habits",
date="2026-01-14",
data={
"title": "Atomic Habits",
"author": "James Clear",
"current_page": 150,
"total_pages": 320,
"rating": 5
}
)Query with Filters
# Get all weight entries for January 2026
query_events(
entity_type="weight",
start_date="2026-01-01",
end_date="2026-01-31"
)
# Get all entries for specific book
query_events(
entity_type="book",
entity_id="book_atomic_habits"
)Update Existing Event
To update an event, call track_event() with the same entity_type + date (+ entity_id if used). The tool will automatically UPDATE instead of INSERT.
SQL Analytics
Since data is stored in SQLite with JSON columns, you can run advanced analytics:
Weight Trend (Last 30 Days)
SELECT
date,
json_extract(data, '$.weight_kg') as weight,
json_extract(data, '$.delta_kg') as delta
FROM tracking_events
WHERE entity_type = 'weight'
AND date >= date('now', '-30 days')
ORDER BY date DESC;Scorecard Weekly Average
SELECT
strftime('%Y-W%W', date) as week,
AVG(CAST(json_extract(data, '$.total_score') AS INTEGER)) as avg_score,
COUNT(*) as days
FROM tracking_events
WHERE entity_type = 'scorecard'
AND date >= date('now', 'weekday 0', '-7 days')
GROUP BY week;Fitness Volume by Workout Type (This Month)
SELECT
json_extract(data, '$.workout_type') as type,
COUNT(*) as sessions,
SUM(CAST(json_extract(data, '$.duration_min') AS INTEGER)) as total_minutes,
AVG(CAST(json_extract(data, '$.duration_min') AS INTEGER)) as avg_minutes
FROM tracking_events
WHERE entity_type = 'fitness'
AND date >= date('now', 'start of month')
GROUP BY type;Project Structure
tracking-mcp/
├── data/
│ ├── tracking.db # SQLite database
│ └── schema.sql # Database schema
├── tracking_mcp/
│ ├── tracking_server.py # MCP server implementation
│ └── __init__.py
├── tests/
│ └── test_server.py
├── pyproject.toml
├── LICENSE
├── CHANGELOG.md
└── README.mdArchitecture Decisions
Why JSON Hybrid (SQLite + JSON)?
✅ Flexibility: Add new entity types without schema migrations
✅ Performance: SQLite indexes +
json_extract()for fast queries✅ SQL-queryable: Standard SQL for analytics
❌ EAV alternative: Too many JOINs, poor performance for analytics
Why Custom MCP vs Official SQLite MCP?
✅ Auto-discovery: New entity types registered automatically
✅ Self-documenting: Resources expose schemas and usage
✅ Dynamic: No rigid schema required
❌ Official SQLite MCP: Requires predefined schema
Why SQLite vs PostgreSQL?
✅ Zero setup: File-based, no server required
✅ Local-first: Privacy-friendly for personal tracking
✅ Sufficient: Perfect for single-user personal use
❌ PostgreSQL: Unnecessary overhead for personal tracking
Development
Run Tests
pytestCode Quality
# Format code
black mcp_server/
# Lint
ruff check mcp_server/Install Development Dependencies
pip install -e ".[dev]"Troubleshooting
RuntimeWarning: coroutine 'main' was never awaited
If you see this error when running the server:
<coroutine object main at 0x...>
RuntimeWarning: coroutine 'main' was never awaitedThis was fixed in version 1.0.1. Update to the latest version:
pip install --upgrade tracking-mcp
# or with uvx
uvx --refresh tracking-mcpRoot cause: Python CLI entry points from setuptools expect synchronous main() functions. Version 1.0.1+ includes a sync wrapper that properly handles the async MCP server.
Version History
See CHANGELOG.md for version history.
Current version: 1.0.1 (Async entry point fix)
Related Projects
viz-mcp: Companion MCP server for auto-generating data visualizations from tracking data
work-hub: Personal productivity system using tracking-mcp for daily scorecard and habit tracking
License
MIT License - see LICENSE file for details.
Author
Mario Mosca - GitHub
Contributing
Contributions welcome! Please open an issue or pull request.
Support
For issues, questions, or feature requests, please open an issue on GitHub: https://github.com/mariomosca/tracking-mcp/issues
Available Tools
4 toolsdelete_eventB
Delete tracking event by ID
| Name | Required | Description | Default |
|---|---|---|---|
| event_id | Yes | Event ID to delete |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description bears full responsibility for disclosing behavior. It states the tool is destructive ('delete') but omits details such as irreversibility, authorization requirements, cascading effects, or outcome (e.g., success indication).
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 a single, front-loaded sentence with no superfluous words. It efficiently conveys the core purpose but sacrifices helpful detail for brevity.
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?
For a simple tool with one required parameter and no output schema, the description is minimally adequate. It fails to mention success/failure indicators or error conditions, which would be useful for an agent.
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%: the required param event_id is described with type and description. The description adds no additional semantics beyond what the schema already provides, earning a baseline score of 3.
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 'Delete tracking event by ID' clearly states the verb (delete), resource (tracking event), and scope (by ID). It distinguishes from sibling tools like list_entity_types, query_events, and track_event which do not perform deletion.
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 implies that the tool should be used when you have an event ID and want to delete that specific event, but it does not provide explicit guidance on when to use vs alternatives, nor any prerequisites or caveats.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_entity_typesA
Get all registered entity types with schema examples
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It indicates a read operation and adds 'with schema examples', but does not disclose other behavioral aspects like authentication requirements or if the list is complete.
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 a single concise sentence that is front-loaded with the core action and resource, containing no unnecessary words.
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?
For a simple list tool with no parameters and no output schema, the description is complete enough. It clearly defines what the tool returns and the scope.
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?
There are no parameters, and schema coverage is trivially 100%. The description naturally does not add parameter information, and baseline for 0 params is 4.
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 clearly states the verb 'Get' and the resource 'all registered entity types', and further specifies 'with schema examples', which distinguishes it from sibling tools that operate on events.
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?
No explicit guidance is provided on when to use this tool vs. alternatives. However, the context of 'entity types' and sibling tools focused on events implies usage, but it is not clearly stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
query_eventsB
Query tracking events with filters
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results (default: 100) | |
| end_date | No | End date (inclusive, optional) | |
| entity_id | No | Filter by entity ID (optional) | |
| start_date | No | Start date (inclusive, optional) | |
| entity_type | No | Filter by entity type (optional) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description must disclose behavior. It mentions 'with filters' but doesn't describe pagination, ordering, side effects, or whether it's read-only. Minimal behavioral context.
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?
Very short and front-loaded. Every word earns its place, though it could be slightly more informative without losing conciseness.
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?
Despite 5 parameters and no output schema, the description is too brief. It doesn't explain how filters combine, response format, or pagination behavior, leaving the agent underinformed.
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 baseline is 3. Description adds 'with filters' but adds no additional meaning beyond what's in the schema's parameter descriptions.
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 clearly states 'Query tracking events with filters', providing a specific verb (query), resource (tracking events), and qualifier (with filters). It distinguishes from siblings like delete_event, list_entity_types, and track_event.
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?
No guidance on when to use this tool versus alternatives. Doesn't mention prerequisites, when not to use, or relationship to sibling tools like delete_event or track_event.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
track_eventB
Insert or update tracking event for any entity type
| Name | Required | Description | Default |
|---|---|---|---|
| data | Yes | Entity-specific data (schema-free JSON) | |
| date | Yes | Event date in YYYY-MM-DD format | |
| entity_id | No | Optional: unique ID for entity instance (e.g., 'book_atomic_habits') | |
| entity_type | Yes | Entity type (e.g., 'weight', 'scorecard', 'fitness', 'book', or custom) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It states 'insert or update', suggesting upsert behavior, but fails to explain details like idempotency, concurrency, or side effects. The optional entity_id implies update logic, but this is not clarified.
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 very concise (one sentence). However, it lacks structure and could benefit from a second sentence clarifying when to use or behavioral notes. It is not verbose but under-specified for the tool's complexity.
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 4 parameters, no output schema, and no annotations, the description is incomplete. It omits explanation of upsert behavior, entity_id's role, and the 'data' object's expectations. Sibling tools exist but are not differentiated.
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 schema already documents each parameter. The description adds no additional meaning beyond 'insert or update for any entity type', which is already implied by the name. Baseline 3 is appropriate.
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 clearly states the verb (insert/update) and resource (tracking event) and specifies 'for any entity type', which distinguishes it from sibling tools like delete_event and list_entity_types. The purpose is unambiguous.
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 implies usage for recording tracking events but provides no guidance on when to use this tool versus alternatives. There are no exclusions or conditions provided.
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.
4 tool updates
v1.0.1- First observed
delete_event - First observed
list_entity_types - First observed
query_events - First observed
track_event
TDQS
Scored across 4 tools
Each tool targets a distinct action: deleting, tracking, querying events, or listing entity types. No overlap.
All tool names follow a consistent verb_noun pattern in snake_case (e.g., delete_event, track_event).
4 tools is well-scoped for a tracking server, covering essential operations without bloat.
Core CRUD is present (create/update via track_event, read via query_events, delete via delete_event), plus entity type discovery. Minor gap: no explicit get single event, but query_events with filters can serve that purpose.
Maintenance
Related MCP Connectors
MCP server for Withings health data — sleep, activity, heart, and body metrics.
MCP server exposing supplements database used by iNutriPlan.com
Hosted MCP server for AI-driven data ops. Create apps, manage schemas, and CRUD structured data.
Related MCP Servers
- FlicenseBqualityDmaintenanceA personal fitness tracking server that enables logging and querying workouts, nutrition, and body metrics through a local SQLite database. Integrates with OpenNutrition MCP for food logging and supports exercise history tracking for workout progression.17-
- FlicenseNot gradedqualityBmaintenanceLocal-first nutrition tracker MCP server for Hermes, enabling food, alias, recipe, and meal log management with SQLite persistence.-
- FlicenseNot gradedqualityCmaintenanceA personal health and fitness MCP server that provides tools for managing profile data, goals, body measurements, nutrition, workouts, sleep, check-ins, life events, analytics, and coach memories via Supabase Postgres.1-
- FlicenseNot gradedqualityBmaintenanceA FastMCP server for journaling, habit tracking, and task management with SQLite storage.-