Skip to content
Scalekit Docs
Talk to an Engineer Dashboard

Connect AI agents to the Harvest MCP server

Vendor MCP
Open markdown

The Harvest MCP connector routes your AI agent's tool calls to Harvest's own MCP server through Scalekit. Each user signs in to Harvest once, and Scalekit stores and refreshes their tokens, so your agent never handles credentials. It comes with 37 tools.

Tools
37
What they doRead · write · destructive
16 · 18 · 316 read18 write3 destructive
Users sign in with
OAuth app
Scalekit's or your own

Setup

  1. Install the SDK

    Terminal window
    npm install @scalekit-sdk/node dotenv
  2. Set your credentials

    Add your Scalekit credentials to your .env file. Find values in app.scalekit.com > Developers > API Credentials.

    .env
    SCALEKIT_ENVIRONMENT_URL=<your-environment-url>
    SCALEKIT_CLIENT_ID=<your-client-id>
    SCALEKIT_CLIENT_SECRET=<your-client-secret>
  3. Create the Harvest MCP connection

    In AgentKit > Connections, create a Harvest MCP connection. The name you give it is the connection_name your code passes. See Configure connections.

    Scalekit credentials are available for Harvest MCP server, so you don't need to register an OAuth app.

  4. Authorize a user and make your first call

    quickstart.mts
    import { ScalekitClient } from '@scalekit-sdk/node'
    import 'dotenv/config'
    import { createInterface } from 'node:readline/promises'
    const scalekit = new ScalekitClient(
    process.env.SCALEKIT_ENVIRONMENT_URL,
    process.env.SCALEKIT_CLIENT_ID,
    process.env.SCALEKIT_CLIENT_SECRET,
    )
    const actions = scalekit.actions
    const connector = 'harvestmcp'
    const identifier = 'user_123'
    // Generate an authorization link for the user
    const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
    console.log('Authorize Harvest MCP:', link)
    const rl = createInterface({ input: process.stdin, output: process.stdout })
    await rl.question('Press Enter after authorizing...')
    rl.close()
    // Make your first call
    const result = await actions.executeTool({
    connector,
    identifier,
    toolName: 'harvestmcp_get_account_settings',
    toolInput: {},
    })
    console.log(result)
    Terminal window
    npx tsx quickstart.mts

    Each user signs in once. See Authorize a user for the full flow and statuses.

Tools

Pass the exact name to execute_tool
Try in PlaygroundRequest a tool
  • harvestmcp_get_account_settingsReturn account-level settings: company name, plan, timezone, week start day, hour rounding configuration, and other preferences.Read-only

    GetAccountSettings

    Return account-level settings: company name, plan, timezone, week start day, hour rounding configuration, and other preferences.

    Inputs

    This tool takes no inputs.

  • harvestmcp_get_expenseReturn a single expense by id, including category, project, and receipt info.Read-only

    GetExpense

    Return a single expense by id, including category, project, and receipt info.

    Inputs

    idintegerrequired
    Expense id.
  • harvestmcp_get_invoiceReturn a single invoice with its header and full line_items.Read-only

    GetInvoice

    Return a single invoice with its header and full line_items. Use list_invoices first to find the id.

    Inputs

    idintegerrequired
    Invoice id.
  • harvestmcp_get_project_budgetReturn the budget status for a project: total budget, hours/amount spent, and remaining.Read-only

    GetProjectBudget

    Return the budget status for a project: total budget, hours/amount spent, and remaining. project_id is required.

    Inputs

    project_idintegerrequired
    Project id.
  • harvestmcp_get_running_timerReturn the currently running timer for the authenticated user, or null if no timer is running.Read-only

    GetRunningTimer

    Return the currently running timer for the authenticated user, or null if no timer is running.

    Inputs

    user_idinteger
    Positive integer id of a user whose running timer to check. Requires manager/admin permission for that user; defaults to the authenticated user.
  • harvestmcp_get_time_reportAggregate time entries over a date range, grouped by project, client, or user.Read-only

    GetTimeReport

    Aggregate time entries over a date range, grouped by project, client, or user. Returns billable/non-billable hours, invoiced/uninvoiced hours per group. from and to are required.

    Inputs

    fromstringrequired
    Inclusive start date (YYYY-MM-DD, e.g. 2026-06-01).
    tostringrequired
    Inclusive end date (YYYY-MM-DD, e.g. 2026-06-30).
    group_bystring
    Grouping dimension. Defaults to project.one of projectclientuser
    include_zero_hour_usersboolean
    Only with group_by=user. When true, also returns zero-hour rows for visible team members who logged nothing.
  • harvestmcp_list_clientsList clients in the user's Harvest account, ordered by name.Read-only

    ListClients

    List clients in the user's Harvest account, ordered by name. Returns up to 100 clients per page; `total_count` is how many clients match the filter in full, so when `truncated` is true you can tell how many are missing — refine `search` or `is_active` to narrow the result.

    Inputs

    is_activeboolean
    Filter to active (true) or archived (false) clients. Omit for all.
    searchstring
    Case-insensitive prefix match on client name.
  • harvestmcp_list_expense_categoriesList expense categories in the account, ordered by name.Read-only

    ListExpenseCategories

    List expense categories in the account, ordered by name. Used to look up expense_category_id before creating an expense.

    Inputs

    is_activeboolean
    Filter to active (true) or archived (false) categories. Omit for active categories only — pass false explicitly to see archived ones.