Skip to main content
Glama
iiinigence

@iiinigence/harvest-mcp

by iiinigence
README.md
# @iiinigence/harvest-mcp

**Track time, run timers, and read time reports — by just asking your AI.**

An open-source [MCP](https://modelcontextprotocol.io) server for [Harvest](https://www.getharvest.com), developed by [IIInigence](https://iiinigence.com). Works with Claude Desktop, Claude Code, and any MCP-compatible client.

> 🎥 Setup tutorial video: coming soon — [subscribe](https://www.youtube.com/@iiinigence)

## Easiest install — one file, no terminal (Claude Desktop)

1. Download **`iiinigence-harvest.mcpb`** from the [latest release](https://github.com/iiinigence/harvest-mcp/releases/latest)
2. In Claude Desktop: **Settings → Extensions → Advanced settings → Install Extension** → pick the downloaded file. Claude shows what you're getting; click **Install**.
3. Paste your Harvest **Personal Access Token** and **Account ID** (both from [id.getharvest.com/developers](https://id.getharvest.com/developers)) into the settings form, then click the **Disabled** button so it reads **Enabled**. Done.

No Node, no config files — Claude Desktop runs the bundle with its built-in runtime. Nervous about giving an AI write access to your timesheet? Flip on **Read-only mode** in the same form: Claude can read projects, entries, and reports but can't log or change a thing until you turn it off.

## Quick start (manual / npx route)

**1. Get your credentials** — [id.getharvest.com/developers](https://id.getharvest.com/developers) → Create new personal access token. Note the token **and** the numeric Account ID shown with it.

**2. Add to Claude Desktop** — Settings → Developer → Edit Config:

```json
{
  "mcpServers": {
    "harvest": {
      "command": "npx",
      "args": ["-y", "@iiinigence/harvest-mcp"],
      "env": {
        "HARVEST_ACCESS_TOKEN": "your_token_here",
        "HARVEST_ACCOUNT_ID": "1234567",
        "READ_ONLY": "false"
      }
    }
  }
}
```

Restart Claude Desktop, then try: *"How many hours did I log this week?"*

## What it's like to use

- *"Start a timer on the Acme website project — task: development, note: fixing the checkout bug."*
- *"Stop my timer."*
- *"Log 2 hours yesterday on Acme — client meeting."*
- *"How many hours did we spend per client this month, and how much of it was billable?"*
- *"Who on the team logged the most hours last week?"*
- *"Find my unbilled overtime — compare this month's hours to the project budgets."*

## Tools

| Tool | What it does |
|------|--------------|
| `get_me` | Verify the connection; your user id, roles, timezone |
| `list_clients` | Clients in the account |
| `list_projects` | Projects with client, code, and budget info |
| `list_project_tasks` | Tasks available on a project (needed to log time) |
| `list_time_entries` | Entries with filters: date range, project, person, running |
| `get_time_report` | Aggregated hours by client / project / task / team member |
| `log_time` | Create a completed time entry |
| `start_timer` | Start a running timer (auto-stops any other running timer) |
| `stop_timer` | Stop the running timer |
| `update_time_entry` | Edit hours, notes, date, project, or task |
| `list_users` | Team members (admin/manager) |

## Configuration

| Env var | Required | Description |
|---------|----------|-------------|
| `HARVEST_ACCESS_TOKEN` | ✅ | Personal Access Token from id.getharvest.com/developers |
| `HARVEST_ACCOUNT_ID` | ✅ | Numeric account id shown next to the token |
| `READ_ONLY` | — | `true` = reports and entries readable, all writing blocked (default `false`) |

## Safety notes

- **No delete tool — by design.** This server can log and edit time, but it can never delete an entry. If something truly needs deleting, do it in Harvest.
- **Read-only mode** is a hard block enforced by the server, not a suggestion to the model.
- Your Personal Access Token carries your Harvest permissions. Treat it like a password; revoke it at id.getharvest.com/developers if unsure.
- Keep yourself as the approval step for edits: ask your assistant to show entries before changing them.

## Privacy

This connector runs locally, collects **no data**, has no telemetry, and talks only to Harvest's API. Your token is stored on your device by Claude Desktop and sent only to Harvest. Full policy: [PRIVACY.md](./PRIVACY.md).

## Who built this

[**IIInigence**](https://iiinigence.com) — a software development agency: custom software, AI automations, full platforms. This connector is part of our [video series](https://www.youtube.com/@iiinigence) on connecting Claude to your business tools, one at a time. See also our [SendGrid connector](https://github.com/iiinigence/sendgrid-mcp).

Want something like this built for your business? [Tell us what you'd build](https://get.iiinigence.io/contact).

## Development

```bash
git clone https://github.com/iiinigence/harvest-mcp.git
cd harvest-mcp
npm install
npm run build
HARVEST_ACCESS_TOKEN=xxx HARVEST_ACCOUNT_ID=1234567 node dist/index.js
```

MIT licensed. PRs welcome.

---

*This is an independent project by IIInigence. It is not affiliated with, endorsed, or sponsored by Harvest. "Harvest" is a trademark of Iridesco, LLC, used here only to describe compatibility.*

TDQS

A4.1/5.0

Scored across 11 tools

Disambiguation5/5

Each tool targets a distinct resource or action. The only potential overlap is between log_time and start_timer, but descriptions clearly separate completed entries from running timers. list_time_entries and get_time_report serve different purposes (raw vs aggregated).

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern using snake_case. Read operations use list_ for collections and get_ for single entities (get_me, get_time_report), which is a predictable and logical variation. No mixed naming conventions are present.

Tool Count5/5

11 tools is well within the ideal 3-15 range. Each tool addresses a core time-tracking workflow: listing entities, logging/editing entries, managing timers, and generating reports. No tool seems redundant or unnecessary.

Completeness4/5

The surface covers the essential lifecycle of time entries: create (log_time, start_timer), read (list_time_entries, get_time_report), and update (update_time_entry). Delete is intentionally omitted with a clear rationale, making it a minor gap. Project/client/task management is limited to listing, but that is suitable for a time-tracking integration.

Maintenance

ActivitySlowing
ResponsivenessNo issues