Harvest MCP server. Read time entries, projects, clients, tasks and invoices; log and update tracked time.
Add to your MCP config, then reload & authorize:
{
"mcpServers": {
"harvest": {
"url": "https://harvest.usefulapi.io/mcp"
}
}
}| Tool | Type | What it does |
|---|---|---|
harvest_list_time_entries | read | List time entries List time entries, optionally filtered by user, project, client, task, date range, running/billed status, or updated-since. Paginated. Harvest REST: GET /time_entries. |
harvest_get_time_entry | read | Get time entry Retrieve a single time entry by id. Harvest REST: GET /time_entries/{id}. |
harvest_list_projects | read | List projects List projects, optionally filtered by active status or client, or updated-since. Paginated. Harvest REST: GET /projects. |
harvest_get_project | read | Get project Retrieve a single project by id. Harvest REST: GET /projects/{id}. |
harvest_list_clients | read | List clients List clients, optionally filtered by active status or updated-since. Paginated. Harvest REST: GET /clients. |
harvest_get_client | read | Get client Retrieve a single client by id. Harvest REST: GET /clients/{id}. |
harvest_list_tasks | read | List tasks List tasks (the billable/non-billable work categories that can be assigned to projects), optionally filtered by active status or updated-since. Paginated. Harvest REST: GET /tasks. |
harvest_list_users | read | List users List users in the account, optionally filtered by active status or updated-since. Paginated. Harvest REST: GET /users. |
harvest_get_current_user | read | Get current user Retrieve the currently authenticated user (whom the access token belongs to). Harvest REST: GET /users/me. |
harvest_list_project_assignments | read | List my project assignments List the authenticated user's active project assignments — the projects and their assignable tasks the current user can log time against (use this to find the project_id + task_id for harvest_create_time_entry). Paginated. Harvest REST: GET /users/me/project_assignments. |
harvest_list_invoices | read | List invoices List invoices, optionally filtered by client, project, state, date range, or updated-since. Paginated. Harvest REST: GET /invoices. |
harvest_get_invoice | read | Get invoice Retrieve a single invoice by id, including its line items. Harvest REST: GET /invoices/{id}. |
harvest_list_estimates | read | List estimates List estimates, optionally filtered by client, state, date range, or updated-since. Paginated. Harvest REST: GET /estimates. |
harvest_list_expenses | read | List expenses List expenses, optionally filtered by user, client, project, date range, billed status, or updated-since. Paginated. Harvest REST: GET /expenses. |
harvest_get_company | read | Get company Retrieve the company/account settings for the authenticated account (name, currency, time/date formats, week start, feature flags). Harvest REST: GET /company. |
harvest_create_time_entry | write | Create time entry Create a time entry. Requires project_id, task_id and spent_date. Provide `hours` to log a specific duration; OR provide `started_time` (+ optional `ended_time`) for a timestamped entry; OR omit both to start a running timer (on a timestamp-tracking account). Use harvest_list_project_assignments to find valid project_id + task_id. Harvest REST: POST /time_entries. WRITE — creates data. |
harvest_update_time_entry | write | Update time entry Update an existing time entry's hours, notes, spent date, or project/task. Only the fields you provide are changed. Harvest REST: PATCH /time_entries/{id}. WRITE — modifies data. |
harvest_stop_time_entry | write | Stop running time entry Stop a currently running time entry (no-op error if it is already stopped). Harvest REST: PATCH /time_entries/{id}/stop. WRITE — modifies data. |
harvest_restart_time_entry | write | Restart stopped time entry Restart a previously stopped time entry, resuming its timer (error if it is already running). Harvest REST: PATCH /time_entries/{id}/restart. WRITE — modifies data. |
harvest_delete_time_entry | write | Delete time entry Permanently delete a time entry by id. This cannot be undone. Harvest REST: DELETE /time_entries/{id}. WRITE — destroys data. |
harvest_usage_status | Usage status (free-tier meter) Report the caller's current free-tier usage this month: calls used, monthly limit, remaining, and whether the cap is reached. | |
harvest_upgrade | Upgrade to Pro (unlimited) Subscribe to Pro for unlimited tool calls, monthly ($9) or yearly ($90). Returns a Stripe Checkout link. |
| Plan | Price | Limit |
|---|---|---|
| Free | $0 | 100 tool calls / month |
| Pro | $9/mo · $90/yr | Unlimited |
This is a Model Context Protocol endpoint — meant to be connected from an AI client, not opened in a browser. An invalid_token response at the URL is the auth gate working as designed; clients authenticate automatically.