Harvest MCP

Live

OAUTH 2.1

TIME TRACKING

Productivity

Harvest MCP gives agents authenticated access to your time tracking: log hours, run billable reports, watch budgets, and turn tracked time into invoices.

  • Per-user credentials: each call uses the actual user's token, never a shared bot.
  • Encrypted per-tenant vault: AES-256, resolved at request time, never in LLM context.
  • Scoped before every call: pre-call scope check, 90-day SIEM-exportable audit chain.
Harvest MCP
agent · Acme Q3
Run
How many billable hours did the team log this week, and is the Acme redesign on budget?
S
harvestmcp_get_time_report
88ms
Harvest agent
142.5 billable hours this week across 4 projects. Acme redesign: 96 of 120 budgeted hours used, 24 remain. 31.5 hours are still uninvoiced.
Sources: 4 projects, 6 users, Jul 20 to Jul 26
harvestmcp
4 projects
18:29
Message Claude...

Tools your time agent reaches for on Harvest, scoped per user.

CALL ANY TOOL
Run time tracking end to end: start timers, log hours, report billable time, watch project budgets, and invoice tracked work.
harvestmcp_add_task_to_project
Add task to project
Add an existing task to a project. project_id and task_id are required.
Parameters
Name
Type
Required
Description
project_id
integer
Required
Project id to add the task to.
task_id
integer
Required
Task id to add.
billable
boolean
Optional
Whether the task is billable on this project. Defaults to the task's billable_by_default.
hourly_rate
number
Optional
Hourly rate for this task on this project.
harvestmcp_assign_user_to_project
Assign user to project
harvestmcp_create_client
Create client
harvestmcp_create_expense
Create expense
harvestmcp_create_invoice
Create invoice
harvestmcp_create_invoice_from_tracked_time
Create invoice from tracked time
harvestmcp_create_project
Create project
harvestmcp_delete_time_entry
Delete time entry
harvestmcp_get_account_settings
Get account settings
harvestmcp_get_expense
Get expense
harvestmcp_get_invoice
Get invoice
harvestmcp_get_project_budget
Get project budget
harvestmcp_get_running_timer
Get running timer
harvestmcp_list_clients
List clients
harvestmcp_list_expense_categories
List expense categories
harvestmcp_list_expenses
List expenses
harvestmcp_list_invoices
List invoices
harvestmcp_list_projects
List projects
harvestmcp_list_tasks
List tasks
harvestmcp_list_time_entries
List time entries
harvestmcp_log_time
Log time
harvestmcp_remove_task_from_project
Remove task from project
harvestmcp_start_timer
Start timer
harvestmcp_stop_timer
Stop timer
harvestmcp_submit_feedback
Submit feedback
harvestmcp_submit_timesheet
Submit timesheet
harvestmcp_update_client
Update client
harvestmcp_update_expense
Update expense
harvestmcp_update_project
Update project
harvestmcp_update_task
Update task

For more tools, view docs.

Build your Agent
Same auth pattern across LangChain, OpenAI, Anthropic, and Google ADK.
Python · LlamaIndex
import { ScalekitClient } from "@scalekit-sdk/node";
import { createReactAgent } from "@langchain/langgraph/prebuilt";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);

// Harvest tools scoped to this user
const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["harvestmcp"], toolNames: [
    "harvestmcp_list_time_entries",
    "harvestmcp_get_time_report",
    "harvestmcp_get_project_budget"] },
  pageSize: 100,
});

const agent = createReactAgent({ llm, tools });
await agent.invoke({ messages: [{ role: "user", content: "How many billable hours did the team log this week?" }] });
import OpenAI from "openai";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);
const openai = new OpenAI();

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["harvestmcp"] }, pageSize: 100,
});

const res = await openai.chat.completions.create({
  model: "gpt-5",
  messages: [{ role: "user", content: "Which projects are close to their budget?" }],
  tools,
});

// Execute the tool call with the user's vaulted Harvest credential
await sk.tools.executeTool(res.choices[0].message.tool_calls[0], "user_123");
import Anthropic from "@anthropic-ai/sdk";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);
const anthropic = new Anthropic();

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["harvestmcp"] }, pageSize: 100,
});

const msg = await anthropic.messages.create({
  model: "claude-sonnet-5",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Draft an invoice from Acme's uninvoiced June time." }],
  tools,
});

// Tool call runs with the user's vaulted Harvest credential
await sk.tools.executeTool(msg.content, "user_123");
import { Agent } from "@google/adk/agents";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["harvestmcp"] }, pageSize: 100,
});

const agent = new Agent({
  name: "harvest_time_agent",
  model: "gemini-2.5-pro",
  instruction: "Track time and manage Harvest projects for the signed-in user.",
  tools,
});

await agent.run("Is the website redesign project over budget?");
Try these prompts
Copy any prompt into your agent. Each maps directly to a Harvest tool. Click to copy, paste into your agent, done.
Track time
Copy the prompt
Copied
Start a timer on the Acme redesign, design task.
Copy the prompt
Copied
Log 1.5 hours to internal meetings for today.
Copy the prompt
Copied
Is a timer running right now? Stop it if so.
Copy the prompt
Copied
Submit my timesheet for this week.
Reports and budgets
Copy the prompt
Copied
How many billable hours did the team log this week?
Copy the prompt
Copied
Which projects have used more than 80 percent of their budget?
Copy the prompt
Copied
Show uninvoiced hours by client for June.
Invoices and clients
Copy the prompt
Copied
Draft an invoice from Acme's uninvoiced June time.
Copy the prompt
Copied
List open invoices due this month.
Copy the prompt
Copied
Which invoices are late, and for how much?
SEE HOW AUTH WORKS
Your users connect once. Their Harvest credentials stay vaulted, every call is scope-checked, and every action is logged.
1
Authorize
Your user connects
Harvest MCP
once. We tie it to their identity and the meetings they approved — no shared bot account, no org-wide access
Who:
user ‘A’
when:
Once per user
access:
Limited to user
2
Store
Their
Harvest MCP
token lives in a vault scoped to them. User A's meetings are never reachable by an agent acting for user B, even on the same connection
vault:
encrypted
scope:
per-user
tokens:
auto-refreshed
3
Resolve
When your agent calls a
Harvest MCP
tool, we fetch the right token server-side. It never touches your agent, never appears in the LLM context, never shows up in your logs
speed:
~40ms
check:
before every call
seen by:
nobody
4
Audit
Every
Harvest MCP
tool call is logged — who triggered it, which meeting was fetched, what came back. 90 days of history, tied to the user who authorized it
history:
90 days
export:
SIEM-ready
logged:
every call
Test other agents
See the same per-user auth pattern across other productivity connectors.
Engineering Teams
Engineering standup agent
Pulls commits from GitHub and GitLab, tracks issue movement in Jira, and posts a per-engineer standup brief to Slack. Each engineer's activity is read on their own delegated OAuth.
Engineering Teams
DevOps assistant agent
Polls GitHub for failing checks and stale PRs, opens Linear issues for the ones that need work, and posts a daily digest to Slack. It acts as the engineer, not a shared service account.
Engineering Teams
Slack triage
Polls Slack for new messages, classifies bugs and support requests with a LangGraph router, files GitHub issues or Zendesk tickets, and confirms in the thread.
People Ops and HR teams
Performance review collector
Collects review feedback from Airtable and Google Forms scoped to each manager's direct reports, writes per-employee summaries to Notion, and DMs the manager a Slack digest.
Test other agents
See the same per-user auth pattern across other productivity connectors.
ENGINEERING
Engineering standup agent
Pull commits from GitHub and GitLab, track Jira issue movement, and post a per-engineer standup brief to Slack.
ENGINEERING
DevOps assistant agent
Poll GitHub for failing checks and stale pull requests, open Linear issues for the ones that need work, and digest to Slack.
ENGINEERING
Slack triage agent
Classify new Slack messages as bugs or support requests, file the GitHub issue or Zendesk ticket, and reply in the thread.
PEOPLE OPS
Performance review collector agent
Collect review feedback from Airtable and Google Forms per manager, summarise each report in Notion, and DM the digest in Slack.
Why Scalekit
Secure your agent's access. Connectors ship in minutes
01.
Shared tokens break per-user analytics
A shared Harvest token looks fine in a demo. In production every logged hour, timer, and invoice looks like one service account, and you cannot tell who tracked the time or drafted the bill. Scalekit resolves the credential of the actual user who triggered the agent, never a shared bot.
// shared token
audit → bot_service_account

// scalekit
audit → user_abc ✓
02.
Authentication is not authorization
03.
Multi-tenancy is architectural
04.
Harvest today. Ten connectors tomorrow.
“Our agents act across Salesforce, Gong, Google Drive, and more, on behalf of every customer. Scalekit behind the scenes meant we can keep adding tools without ever rebuilding how credentials or tool calling work.”
Venu Madhav Kattagoni
Head of Engineering / Von
FAQs
Frequently Asked Questions
Does the agent access Harvest as the user or through a shared key?
As the user. Scalekit resolves the credential of the person who triggered the agent at request time, so every timer, logged hour, and invoice in your audit trail is attributed to a real user, not a shared service account.
Where is the Harvest token stored?
In an AES-256 encrypted vault with per-tenant namespacing. Tokens are resolved at request time, never enter LLM context, refresh automatically, and can be revoked from one dashboard.
Can I limit what the agent does in Harvest?
Yes. Filter by tool name in listScopedTools to expose only what you want, for example time reports and budget reads without create_invoice or delete_time_entry. Scalekit also enforces scope checks before every API call.
What happens when a user revokes access?
The credential is invalidated at the next tool call. The call fails closed, other users' connections are unaffected, and the revocation is logged in the audit chain.
Can the agent delete time entries or send invoices on its own?
Only if you allow it. delete_time_entry is permanent in Harvest, so most teams exclude it via the toolNames filter, and invoices the agent creates land as drafts for a human to review and send. Every write is scope-checked and logged either way.
Start in your coding agent
Up and running in one command
Install the Scalekit skill in your editor of choice. Connector, auth, tools, prompt, all wired up
Claude Code REPL
/plugin marketplace add scalekit-inc/claude-code-authstack
/plugin install agentkit@scalekit-auth-stack
Cursor Code REPL
# ~/.cursor/mcp.json
{
""mcpServers"": {
""harvestmcp"": {
""url"": ""https://mcp.scalekit.com/harvestmcp"",
""headers"": { ""Authorization"": ""Bearer $SCALEKIT_TOKEN"" }
}
}
}
Codex Code REPL
# ~/.codex/config.toml
[mcp_servers.harvestmcp]
url = ""https://mcp.scalekit.com/harvestmcp""
auth_env = ""SCALEKIT_TOKEN""
Copilot Code REPL
# .vscode/mcp.json
{
""servers"": {
""harvestmcp"": {
""url"": ""https://mcp.scalekit.com/harvestmcp"",
""type"": ""http""
}
}
}