Skip to main content

Tracking MCP

PyPI version Python Version License Downloads GitHub stars

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 analytics
  • Local-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

Installation

From PyPI (when published)

pip install tracking-mcp

From Source

git clone https://github.com/mariomosca/tracking-mcp.git
cd tracking-mcp
pip install -e .

Initialize Database

# Database will be auto-created in data/tracking.db
# Or manually initialize:
cd data
sqlite3 tracking.db < schema.sql

Quick Start

Claude Desktop Configuration

Add to your Claude Desktop MCP settings (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "tracking": {
      "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 today
Show me my weight trend for the last 30 days
Log workout: HYROX for 45 minutes today

MCP 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 format
  • data (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 type
  • entity_id (string, optional): Filter by entity ID
  • start_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
id INTEGER PRIMARY KEY Auto-increment ID
entity_type TEXT Entity type ('weight', 'scorecard', etc.)
entity_id TEXT Optional unique ID for entity instances
date DATE Event date (YYYY-MM-DD)
data JSON Schema-free JSON data
created_at TIMESTAMP Auto-generated creation timestamp
updated_at TIMESTAMP Auto-updated modification timestamp

Indexes: entity_type, date, entity_id

entity_types Table

Column Type Description
entity_type TEXT PRIMARY KEY Entity type name
description TEXT Human-readable description
schema_example JSON Example JSON schema
created_at TIMESTAMP Registration timestamp
updated_at 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.md

Architecture 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

pytest

Code Quality

# Format code
black mcp_server/

# Lint
ruff check mcp_server/

Install Development Dependencies

pip install -e ".[dev]"

Version History

See CHANGELOG.md for version history.

Current version: 1.0.0 (Initial public release)

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

Metadata

Release files for tracking-mcp 1.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tracking-mcp 1.0.1
File Size Uploaded
tracking_mcp-1.0.1.tar.gz 13.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tracking-mcp 1.0.1
File Interpreter ABI Platform
tracking_mcp-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 24.6 kB

Release files / tracking_mcp-1.0.1.tar.gz

Download URL tracking_mcp-1.0.1.tar.gz
Size 13.8 kB
Tags Source
SHA-256 checksum
How to use checksums
cc61cdb3a5461f888d7505d25313d4ae06e81162b52e85a65f8abff85728095f
BLAKE2b-256 checksum
How to use checksums
4d59f93578a1d41f21143a8437add76c01199b4cba67edb0840988d873f78e8b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.8

Release files / tracking_mcp-1.0.1-py3-none-any.whl

Download URL tracking_mcp-1.0.1-py3-none-any.whl
Size 10.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d5b27d05868c0b620c5620559f12bbc1ea2215ce92ce10dd312752d4be57dc1f
BLAKE2b-256 checksum
How to use checksums
9ec6bbe039c46d2621febe3fa115b1e755c028a6010f3a4f356edc03fbd9baef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.8

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page