Early MCP
An MCP server that gives AI assistants full access to EARLY (Timeular v4) time tracking — managing activities, timers, time entries, reports, and raw API calls.
Activity management: list, create, update (name/color), and archive activities.
Timers: view the currently running tracker, start tracking an activity with an optional note, and stop it to produce a time entry.
Time entries: query entries in a date range, create manual entries, and delete entries.
Reports: aggregate hours by activity for a period (today/week/month/etc.), run efficiency reports that detect untracked gaps, and compute billable hours/cost from an hourly rate.
API explorer: send raw authenticated requests (GET, POST, PATCH, PUT, DELETE) to any EARLY endpoint.
The README also documents further tools not shown in this schema (e.g. edit/cancel tracking, edit time entry, get_time_entry, timesheet, get_me, tag listing, unarchive).
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., "@Early MCP Start a timer for my 'Development' activity"
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.
EARLY MCP Server
An MCP (Model Context Protocol) server that integrates with the EARLY (Timeular v4) time tracking API. Gives AI assistants like Claude full access to time tracking, activity management, and analytics.
Features
Activity Management - Create, update, list, and delete activities
Time Tracking - Start/stop timers, view current tracking status
Time Entries - Query, create, and delete manual time entries
Analytics - Time summaries, efficiency reports with gap detection, and billing reports
API Explorer - Raw authenticated access to any EARLY API endpoint
Related MCP server: TrackingTime MCP Server
Tools
Tool | Description |
| Show the authenticated user's profile |
| List tags and mentions (IDs used in notes) |
| List active, inactive and archived activities |
| Create a new activity in a folder (folder ID required) |
| Update an existing activity's name or color |
| Archive an activity (entries are kept) |
| Restore an archived activity |
| Get the currently running timer |
| Start tracking time for an activity |
| Change the running timer's activity, start time or note |
| Stop the current tracker, creating a time entry; |
| Discard the running timer without creating an entry |
| Query time entries within a date range |
| Get one time entry by ID |
| Create a manual time entry |
| Change an entry's activity, times or note |
| Delete a time entry |
| Aggregate hours by activity for a period |
| Analyze time distribution and detect untracked gaps |
| Calculate billable hours and cost by activity |
| Roll entries into "Activity: note" rows with rounded hours per local day, optionally for one folder |
| Make raw authenticated GET requests to any EARLY API endpoint (writes opt-in) |
Setup
Prerequisites
Python 3.12+
uv package manager
An EARLY developer API key and secret
Install
git clone git@github.com:sakebomb/early_mcp.git
cd early_mcp
uv syncConfiguration
Create a .env file with your EARLY API credentials:
EARLY_API_KEY=your_api_key
EARLY_API_SECRET=your_api_secretOptional settings:
Variable | Default | Effect |
| system timezone | IANA zone (e.g. |
| unset | Set to |
Tool hints
Every tool declares MCP annotations so clients can decide what to confirm. Tools that can lose tracked time are marked destructive: deleting or editing an entry, cancelling a timer, and also creating an entry or stopping a timer, because EARLY splits or removes existing entries that a new one overlaps. explore_api is advertised read-only unless writes are enabled.
Dates and timezones
The EARLY API stores timestamps in UTC without an offset. Tools take dates (YYYY-MM-DD) and naive timestamps as local time in EARLY_TIMEZONE and convert them to UTC, so a "day" means your local day. Timestamps with an explicit offset (+01:00, Z) are converted from that offset. Raw entries returned by list_time_entries keep EARLY's UTC timestamps; report tools group by local day.
Stopping a timer
EARLY rejects a stop less than one minute after the start and discards the timer along with it, so stop_tracking checks the timer's age first and leaves a younger one running. With round_minutes, both ends of the entry are snapped to the nearest step (on the UTC grid) after the stop. A neighbouring entry off that grid, for example one made in the app, would then overlap and EARLY would split or remove it, so the rounded span is clamped to its neighbours, and it keeps its exact times if under a minute would remain.
Command line
early_cli.py runs the same tools from a hook or timer, printing JSON:
uv run python early_cli.py stop --round 15 --folder <folder_id> # only stops a timer in that folder
uv run python early_cli.py timesheet 2026-10-17 2026-10-30 --folder <folder_id>Claude Code
Add this to your Claude Code MCP settings (~/.claude/settings.json):
{
"mcpServers": {
"early": {
"command": "uv",
"args": ["run", "--directory", "/path/to/early_mcp", "python", "early.py"],
"env": {
"EARLY_API_KEY": "your_api_key",
"EARLY_API_SECRET": "your_api_secret"
}
}
}
}Project Structure
early.py # MCP server with tool definitions
early_client.py # API client, auth, and utility functions
early_cli.py # Command-line entry for hooks and timers
tests/ # pytest suite (mocked HTTP; run with `uv run pytest`)
pyproject.toml # Project config and dependenciesAuthentication
The server uses EARLY's developer sign-in flow. It exchanges your API key/secret for a bearer token, caches it in memory, and automatically refreshes on expiry.
Available Tools
14 toolsbilling_reportB
Calculate billable hours and cost by activity.
Args:
start_date: Start date in YYYY-MM-DD format
end_date: End date in YYYY-MM-DD format
hourly_rate: Rate per hour in your currency
Inputs: end_date (required), start_date (required), hourly_rate (required). Returns: object
create_activityB
Create a new activity in EARLY.
Args:
name: Name of the activity (e.g. "Deep Work", "Meetings")
color: Hex color code for the activity (default: green)
Inputs: name (required), color. Returns: object
create_time_entryA
Create a manual time entry.
Args:
activity_id: ID of the activity
started_at: Start time in ISO format (e.g. "2026-02-16T09:00:00.000")
stopped_at: Stop time in ISO format (e.g. "2026-02-16T10:30:00.000")
note: Optional note/description for this entry
Inputs: started_at (required), stopped_at (required), activity_id (required), note. Returns: object
current_trackingA
Get the currently running tracking entry, if any.
Returns the active timer with activity info and start time, or an error with "does not exist" if nothing is tracking.
Inputs: no named parameters. Returns: object
delete_activityB
Archive/delete an activity in EARLY.
Args:
activity_id: ID of the activity to archive
Inputs: activity_id (required). Returns: object
delete_time_entryC
Delete a time entry.
Args:
entry_id: ID of the time entry to delete
Inputs: entry_id (required). Returns: object
efficiency_reportA
Analyze time distribution and detect gaps between entries.
Shows how time was spent, identifies untracked gaps, and provides
daily breakdowns. Useful for finding productivity patterns.
Args:
start_date: Start date in YYYY-MM-DD format
end_date: End date in YYYY-MM-DD format
Inputs: end_date (required), start_date (required). Returns: object
explore_apiA
Make a raw authenticated request to any EARLY API endpoint.
Use this to probe undocumented or newly discovered endpoints.
The base URL is already set — just provide the path.
Args:
method: HTTP method (GET, POST, PATCH, DELETE, PUT)
path: API path (e.g. "/tracking", "/time-entries/2024-01-01/2024-01-31")
body: JSON request body (optional)
params: Query parameters (optional)
Inputs: path (required), method (required), body, params. Returns: object
list_activitiesB
List all activities in EARLY.
Returns the full list of activities with their IDs, names, colors, etc.
Inputs: no named parameters. Returns: object
list_time_entriesB
Query time entries within a date range.
Args:
start_date: Start date in YYYY-MM-DD format (e.g. "2026-02-01")
end_date: End date in YYYY-MM-DD format (e.g. "2026-02-16")
Inputs: end_date (required), start_date (required). Returns: object
start_trackingA
Start tracking time for an activity.
Args:
activity_id: ID of the activity to track (use list_activities to find IDs)
note: Optional note/description for this tracking session
Inputs: activity_id (required), note. Returns: object
stop_trackingA
Stop the currently running tracker.
Returns the completed time entry with start/stop times and duration.
Inputs: no named parameters. Returns: object
time_summaryA
Aggregate hours by activity for a time period.
Args:
period: One of "today", "yesterday", "week", "last_week", "month", "last_month"
Inputs: period. Returns: object
update_activityC
Update an existing activity in EARLY.
Args:
activity_id: ID of the activity to update
name: New name for the activity (optional)
color: New hex color code (optional)
Inputs: activity_id (required), name, color. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 14 tools
Each tool targets a distinct resource or action: activities, time entries, tracking state, reports, and raw API access. No functional overlap; descriptions clearly differentiate them.
All tool names follow a consistent verb_noun pattern in snake_case (e.g., create_activity, list_time_entries, stop_tracking). No mixed conventions or ambiguous verbs.
14 tools cover the full scope of a time-tracking server: CRUD for activities and entries, tracking controls, multiple reports, and an API explorer. Well-balanced, not excessive or sparse.
Core lifecycle is covered: create/read/update/delete activities, create/delete/list time entries, start/stop/current tracking. Minor gaps: no update_time_entry or get_single_time_entry, but workflows are still functional.
Maintenance
Related MCP Connectors
Connects AI assistants to TrackingTime for querying time entries, projects, tasks, customers, and team data using natural language.
Read your tracked time and projects, pause tracking or add a note, from Claude or ChatGPT.
Time tracking you talk to: log, check and fix your work hours from your AI assistant.
Read tracked time and projects; create projects and start or stop timers in DeskTime.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables AI assistants to interact with the Clockify API for managing time entries, timers, and team management tasks. It provides tools for searching time records, tracking project hours, and performing high-level analysis like overtime detection and weekly summaries.9MIT
- AlicenseNot gradedqualityDmaintenanceConnects AI assistants to the TrackingTime API v4 for managing projects, tasks, and team assignments. Users can start or stop timers, log manual time entries, and organize project workflows using natural language.16 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables AI assistants to interact with Kimai time-tracking API for managing timesheets, projects, activities, customers, users, and more.146 PyPI49MIT
- AlicenseAqualityDmaintenanceEnables AI assistants to manage Toggl Track time entries, projects, and workspaces through natural language, supporting CRUD operations and past date time slots.1318 npm2MIT