MCP Server

harvest

io.usefulapi/harvest
Business & Operations Productivity Public & reachable MCP 2026-07-28

What this MCP does

Manages Harvest time tracking, projects, clients, tasks, expenses, estimates, and invoices.

harvest_create_time_entry
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.
Destructive
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['project_id', 'task_id', 'spent_date'], 'properties': {'hours': {'type': 'number', 'minimum': 0, 'description': 'Duration in decimal hours, e.g. 1.5. Omit to start a running timer.'}, 'notes': {'type': 'string', 'description': 'Notes for the time entry.'}, 'task_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'The task id within the project (required).', 'exclusiveMinimum': 0}, 'user_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'Log on behalf of another user (defaults to the authenticated user; requires permission).', 'exclusiveMinimum': 0}, 'ended_time': {'type': 'string', 'description': "End time for a timestamped entry, e.g. '9:30am'."}, 'project_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'The project id to log time against (required).', 'exclusiveMinimum': 0}, 'spent_date': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'The date the time was spent, yyyy-mm-dd (required).'}, 'started_time': {'type': 'string', 'description': "Start time for a timestamped entry, e.g. '8:00am'."}}}
harvest_delete_time_entry
Delete time entry
Permanently delete a time entry by id. This cannot be undone. Harvest REST: DELETE /time_entries/{id}. WRITE — destroys data.
Destructive
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['time_entry_id'], 'properties': {'time_entry_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'The time entry id to delete (required).', 'exclusiveMinimum': 0}}}
harvest_get_client
Get client
Retrieve a single client by id. Harvest REST: GET /clients/{id}.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['client_id'], 'properties': {'client_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'The client id (required).', 'exclusiveMinimum': 0}}}
harvest_get_company
Get company
Retrieve the company/account settings for the authenticated account (name, currency, time/date formats, week start, feature flags). Harvest REST: GET /company.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {}}
harvest_get_current_user
Get current user
Retrieve the currently authenticated user (whom the access token belongs to). Harvest REST: GET /users/me.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {}}
harvest_get_invoice
Get invoice
Retrieve a single invoice by id, including its line items. Harvest REST: GET /invoices/{id}.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['invoice_id'], 'properties': {'invoice_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'The invoice id (required).', 'exclusiveMinimum': 0}}}
harvest_get_project
Get project
Retrieve a single project by id. Harvest REST: GET /projects/{id}.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['project_id'], 'properties': {'project_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'The project id (required).', 'exclusiveMinimum': 0}}}
harvest_get_time_entry
Get time entry
Retrieve a single time entry by id. Harvest REST: GET /time_entries/{id}.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['time_entry_id'], 'properties': {'time_entry_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'The time entry id (required).', 'exclusiveMinimum': 0}}}
harvest_list_clients
List clients
List clients, optionally filtered by active status or updated-since. Paginated. Harvest REST: GET /clients.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'page': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 1, 'description': 'Page number (1-based) for pagination.'}, 'per_page': {'type': 'integer', 'maximum': 2000, 'minimum': 1, 'description': 'Results per page (1–2000, Harvest default 2000).'}, 'is_active': {'type': 'boolean', 'description': 'Only active (true) or archived (false) clients.'}, 'updated_since': {'type': 'string', 'description': 'Only clients updated since this ISO-8601 datetime.'}}}
harvest_list_estimates
List estimates
List estimates, optionally filtered by client, state, date range, or updated-since. Paginated. Harvest REST: GET /estimates.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'to': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'Only estimates issued on/before this date, yyyy-mm-dd.'}, 'from': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'Only estimates issued on/after this date, yyyy-mm-dd.'}, 'page': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 1, 'description': 'Page number (1-based) for pagination.'}, 'state': {'enum': ['draft', 'sent', 'accepted', 'declined'], 'type': 'string', 'description': 'Filter by estimate state: draft, sent, accepted or declined.'}, 'per_page': {'type': 'integer', 'maximum': 2000, 'minimum': 1, 'description': 'Results per page (1–2000, Harvest default 2000).'}, 'client_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'Filter to a single client id.', 'exclusiveMinimum': 0}, 'updated_since': {'type': 'string', 'description': 'Only estimates updated since this ISO-8601 datetime.'}}}
harvest_list_expenses
List expenses
List expenses, optionally filtered by user, client, project, date range, billed status, or updated-since. Paginated. Harvest REST: GET /expenses.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'to': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'Only expenses on/before this date, yyyy-mm-dd.'}, 'from': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'Only expenses on/after this date, yyyy-mm-dd.'}, 'page': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 1, 'description': 'Page number (1-based) for pagination.'}, 'user_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'Filter to a single user id.', 'exclusiveMinimum': 0}, 'per_page': {'type': 'integer', 'maximum': 2000, 'minimum': 1, 'description': 'Results per page (1–2000, Harvest default 2000).'}, 'client_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'Filter to a single client id.', 'exclusiveMinimum': 0}, 'is_billed': {'type': 'boolean', 'description': 'Only billed (true) or unbilled (false) expenses.'}, 'project_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'Filter to a single project id.', 'exclusiveMinimum': 0}, 'updated_since': {'type': 'string', 'description': 'Only expenses updated since this ISO-8601 datetime.'}}}
harvest_list_invoices
List invoices
List invoices, optionally filtered by client, project, state, date range, or updated-since. Paginated. Harvest REST: GET /invoices.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'to': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'Only invoices issued on/before this date, yyyy-mm-dd.'}, 'from': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'Only invoices issued on/after this date, yyyy-mm-dd.'}, 'page': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 1, 'description': 'Page number (1-based) for pagination.'}, 'state': {'enum': ['draft', 'open', 'paid', 'closed'], 'type': 'string', 'description': 'Filter by invoice state: draft, open, paid or closed.'}, 'per_page': {'type': 'integer', 'maximum': 2000, 'minimum': 1, 'description': 'Results per page (1–2000, Harvest default 2000).'}, 'client_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'Filter to a single client id.', 'exclusiveMinimum': 0}, 'project_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'Filter to a single project id.', 'exclusiveMinimum': 0}, 'updated_since': {'type': 'string', 'description': 'Only invoices updated since this ISO-8601 datetime.'}}}
harvest_list_project_assignments
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.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'page': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 1, 'description': 'Page number (1-based) for pagination.'}, 'per_page': {'type': 'integer', 'maximum': 2000, 'minimum': 1, 'description': 'Results per page (1–2000, Harvest default 2000).'}}}
harvest_list_projects
List projects
List projects, optionally filtered by active status or client, or updated-since. Paginated. Harvest REST: GET /projects.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'page': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 1, 'description': 'Page number (1-based) for pagination.'}, 'per_page': {'type': 'integer', 'maximum': 2000, 'minimum': 1, 'description': 'Results per page (1–2000, Harvest default 2000).'}, 'client_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'Filter to a single client id.', 'exclusiveMinimum': 0}, 'is_active': {'type': 'boolean', 'description': 'Only active (true) or archived (false) projects.'}, 'updated_since': {'type': 'string', 'description': 'Only projects updated since this ISO-8601 datetime.'}}}
harvest_list_tasks
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.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'page': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 1, 'description': 'Page number (1-based) for pagination.'}, 'per_page': {'type': 'integer', 'maximum': 2000, 'minimum': 1, 'description': 'Results per page (1–2000, Harvest default 2000).'}, 'is_active': {'type': 'boolean', 'description': 'Only active (true) or archived (false) tasks.'}, 'updated_since': {'type': 'string', 'description': 'Only tasks updated since this ISO-8601 datetime.'}}}
harvest_list_time_entries
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.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'to': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'Only entries on/before this date, yyyy-mm-dd.'}, 'from': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'Only entries on/after this date, yyyy-mm-dd.'}, 'page': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 1, 'description': 'Page number (1-based) for pagination.'}, 'task_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'Filter to a single task id.', 'exclusiveMinimum': 0}, 'user_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'Filter to a single user id.', 'exclusiveMinimum': 0}, 'per_page': {'type': 'integer', 'maximum': 2000, 'minimum': 1, 'description': 'Results per page (1–2000, Harvest default 2000).'}, 'client_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'Filter to a single client id.', 'exclusiveMinimum': 0}, 'is_billed': {'type': 'boolean', 'description': 'Only billed (true) or unbilled (false) entries.'}, 'is_running': {'type': 'boolean', 'description': 'Only running (true) or only stopped (false) entries.'}, 'project_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'Filter to a single project id.', 'exclusiveMinimum': 0}, 'updated_since': {'type': 'string', 'description': 'Only entries updated since this ISO-8601 datetime.'}}}
harvest_list_users
List users
List users in the account, optionally filtered by active status or updated-since. Paginated. Harvest REST: GET /users.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'page': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 1, 'description': 'Page number (1-based) for pagination.'}, 'per_page': {'type': 'integer', 'maximum': 2000, 'minimum': 1, 'description': 'Results per page (1–2000, Harvest default 2000).'}, 'is_active': {'type': 'boolean', 'description': 'Only active (true) or archived (false) users.'}, 'updated_since': {'type': 'string', 'description': 'Only users updated since this ISO-8601 datetime.'}}}
harvest_restart_time_entry
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.
Destructive
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['time_entry_id'], 'properties': {'time_entry_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'The stopped time entry id to restart (required).', 'exclusiveMinimum': 0}}}
harvest_stop_time_entry
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.
Destructive
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['time_entry_id'], 'properties': {'time_entry_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'The running time entry id to stop (required).', 'exclusiveMinimum': 0}}}
harvest_update_time_entry
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.
Destructive
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['time_entry_id'], 'properties': {'hours': {'type': 'number', 'minimum': 0, 'description': 'Change the duration in decimal hours, e.g. 2.25.'}, 'notes': {'type': 'string', 'description': 'Change the notes.'}, 'task_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'Reassign to a different task id.', 'exclusiveMinimum': 0}, 'ended_time': {'type': 'string', 'description': "Change the end time, e.g. '9:30am'."}, 'project_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'Reassign to a different project id.', 'exclusiveMinimum': 0}, 'spent_date': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'Change the date, yyyy-mm-dd.'}, 'started_time': {'type': 'string', 'description': "Change the start time, e.g. '8:00am'."}, 'time_entry_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'The time entry id to update (required).', 'exclusiveMinimum': 0}}}
Changed
harvest_delete_time_entry
Oct. 1, 2026, 2:43 a.m.
Changed
harvest_restart_time_entry
Oct. 1, 2026, 2:43 a.m.
Changed
harvest_stop_time_entry
Oct. 1, 2026, 2:43 a.m.
Changed
harvest_update_time_entry
Oct. 1, 2026, 2:43 a.m.
Changed
harvest_create_time_entry
Oct. 1, 2026, 2:43 a.m.
Changed
harvest_get_company
Oct. 1, 2026, 2:43 a.m.
Changed
harvest_list_expenses
Oct. 1, 2026, 2:43 a.m.
Changed
harvest_list_estimates
Oct. 1, 2026, 2:43 a.m.
Changed
harvest_get_invoice
Oct. 1, 2026, 2:43 a.m.
Changed
harvest_list_invoices
Oct. 1, 2026, 2:43 a.m.
Changed
harvest_list_project_assignments
Oct. 1, 2026, 2:43 a.m.
Changed
harvest_get_current_user
Oct. 1, 2026, 2:43 a.m.
Changed
harvest_list_users
Oct. 1, 2026, 2:43 a.m.
Changed
harvest_list_tasks
Oct. 1, 2026, 2:43 a.m.
Changed
harvest_get_client
Oct. 1, 2026, 2:43 a.m.
Changed
harvest_list_clients
Oct. 1, 2026, 2:43 a.m.
Changed
harvest_get_project
Oct. 1, 2026, 2:43 a.m.
Changed
harvest_list_projects
Oct. 1, 2026, 2:43 a.m.
Changed
harvest_get_time_entry
Oct. 1, 2026, 2:43 a.m.
Changed
harvest_list_time_entries
Oct. 1, 2026, 2:43 a.m.
Added
harvest_delete_time_entry
Sept. 21, 2026, 2:44 a.m.
Added
harvest_restart_time_entry
Sept. 21, 2026, 2:44 a.m.
Added
harvest_stop_time_entry
Sept. 21, 2026, 2:44 a.m.
Added
harvest_update_time_entry
Sept. 21, 2026, 2:44 a.m.
Added
harvest_create_time_entry
Sept. 21, 2026, 2:44 a.m.
Added
harvest_get_company
Sept. 21, 2026, 2:44 a.m.
Added
harvest_list_expenses
Sept. 21, 2026, 2:44 a.m.
Added
harvest_list_estimates
Sept. 21, 2026, 2:44 a.m.
Added
harvest_get_invoice
Sept. 21, 2026, 2:44 a.m.
Added
harvest_list_invoices
Sept. 21, 2026, 2:44 a.m.