harvest

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Harvest

Harvest

<!-- BEGIN:skill-intro -->
Independent, unofficial connector for Harvest. Not affiliated with, endorsed by, or sponsored by Harvest. "Harvest" is a trademark of its owner, used only to identify the service this connector works with.
Agent-callable tools for Harvest, the time-tracking and project-billing service. Track time (log hours by duration or by start/end time, start and stop timers), and manage the projects, clients, contacts, and tasks that time is logged against. Also covers read access to invoices and the account-context reads (current user, company settings) that determine how time is tracked. Wraps the Harvest API v2 (
https://api.harvestapp.com/v2/
).
<!-- legal:disclaimer -->
Independent, unofficial connector for Harvest. Not affiliated with, endorsed by, or sponsored by Harvest. "Harvest" is a trademark of its owner, used only to identify the service this connector works with.
<!-- /legal:disclaimer --> <!-- END:skill-intro -->
<!-- BEGIN:skill-intro -->
这是一款独立的非官方Harvest连接器,与Harvest无关联、未获其认可或赞助。“Harvest”是其所有者的商标,仅用于标识本连接器适配的服务。
面向Harvest(时间追踪与项目计费服务)的Agent可调用工具。支持追踪时间(按时长或起止时间记录工时、启动和停止计时器),管理用于记录时间的项目、客户、联系人和任务。还支持读取发票,以及决定时间追踪方式的账户上下文信息(当前用户、公司设置)。封装了Harvest API v2(
https://api.harvestapp.com/v2/
)。
<!-- legal:disclaimer -->
这是一款独立的非官方Harvest连接器,与Harvest无关联、未获其认可或赞助。“Harvest”是其所有者的商标,仅用于标识本连接器适配的服务。
<!-- /legal:disclaimer --> <!-- END:skill-intro -->

When to use this

适用场景

<!-- BEGIN:skill-use-cases -->
  • Logging and editing time — create, update, or delete time entries; start, stop, and restart timers. Harvest tracks time in one of two mutually exclusive modes (by duration or by start/end timestamps); read
    getCompany
    first when the mode is unknown (see
    references/harvest-api-gotchas.md
    ).
  • Setting up what time is logged against — create and manage projects, clients, contacts, and tasks, and assign tasks to projects (a project references a task through a project task assignment, which governs how that task bills on the project).
  • Reading time, projects, and billing — list and get time entries, projects, clients, contacts, tasks, and invoices; answer "what did we log / bill for this client or project".
  • Account context — read the current user (the default owner of a time entry) and company settings (time-tracking mode, feature flags).
Not for: creating or sending invoices/estimates, logging expenses, running the aggregate Reports API, or user administration — those are out of scope for this connector.
<!-- END:skill-use-cases -->
<!-- BEGIN:skill-use-cases -->
  • 记录与编辑时间 — 创建、更新或删除时间条目;启动、停止和重启计时器。Harvest支持两种互斥的时间追踪模式(按时长或按起止时间戳);若未知模式,先调用
    getCompany
    接口(详见
    references/harvest-api-gotchas.md
    )。
  • 配置时间记录关联对象 — 创建并管理项目、客户、联系人和任务,将任务分配给项目(项目通过项目任务关联引用任务,该关联控制任务在项目中的计费方式)。
  • 读取时间、项目与计费信息 — 列出并获取时间条目、项目、客户、联系人、任务和发票;解答“我们为该客户或项目记录/计费了哪些内容”这类问题。
  • 账户上下文 — 读取当前用户(时间条目的默认所有者)和公司设置(时间追踪模式、功能开关)。
不支持的操作: 创建或发送发票/预估单、记录费用、运行聚合报表API,以及用户管理——这些超出了本连接器的范围。
<!-- END:skill-use-cases -->

Setup

安装配置

This is an agentskills.io skill.
If the connector has not been installed as a skill yet, install it first with
npx skills add zapier/connectors --skill harvest
(or your harness's own skill-install mechanism), then continue here. Installing the skill copies these files, not dependencies. Before running the CLI, a local MCP server, or
zapier-sdk
auth commands, run
npm install --omit=dev
here once. Importing the published package as a dependency in your own project instead? That
npm install
already resolves everything — see
references/use-as-sdk.md
.
The connector runs on Node.js 22.18+. Pick the reference that matches how you're running it, and load it before doing anything else:
You have...Load
An MCP-aware client — tools may already be loaded (e.g.
mcp__harvest__<tool>
), or you can register a local server yourself (or guide the user to)
references/use-as-mcp.md
Terminal / subprocess access (you can run
node
)
references/use-as-cli.md
Only your own code, importing this package as a dependency
references/use-as-sdk.md
No tool access, no terminal, no ability to import this package — you write your own code that calls the Harvest API directly (e.g. a code-execution sandbox)
references/use-as-recipe.md
这是一款agentskills.io技能工具。
若尚未将该连接器作为技能工具安装,请先执行
npx skills add zapier/connectors --skill harvest
进行安装(或使用你的工具链自带的技能安装机制),再继续后续操作。安装技能工具仅会复制这些文件,不会安装依赖项。运行CLI、本地MCP服务器或
zapier-sdk
认证命令前,先在此处执行一次
npm install --omit=dev
。若要在你自己的项目中导入已发布的包作为依赖?此时
npm install
已经处理了所有依赖——详见
references/use-as-sdk.md
该连接器运行于**Node.js 22.18+**环境。请根据你的运行方式选择对应的参考文档,并在操作前加载:
你的环境...加载文档
支持MCP的客户端——工具可能已加载(例如
mcp__harvest__<tool>
),你也可以自行注册本地服务器(或引导用户注册)
references/use-as-mcp.md
可访问终端/子进程(能运行
node
命令)
references/use-as-cli.md
仅使用自有代码,将本包作为依赖导入
references/use-as-sdk.md
无工具访问权限、无终端、无法导入本包——需自行编写调用Harvest API的代码(例如代码执行沙箱)
references/use-as-recipe.md

Scripts

脚本

<!-- BEGIN:skill-connections-note -->
All scripts use the single
harvest
connection. Ids (
id
,
project_id
,
task_id
,
client_id
,
user_id
) are integers; resolve them from the matching
list*
tool.
<!-- END:skill-connections-note --> <!-- BEGIN:skill-scripts-table -->
ScriptScript nameConnectionsDescription
scripts/createTimeEntry.ts
createTimeEntryharvestLog time by duration (hours) against a project + task. Omit
hours
to start a running timer. Duration-mode accounts only.
scripts/createTimeEntryForTimestamps.ts
createTimeEntryForTimestampsharvestLog time by start/end time against a project + task. Omit
ended_time
to leave it running. Timestamps-mode accounts only.
scripts/updateTimeEntry.ts
updateTimeEntryharvestUpdate a time entry (notes, hours, times, task, or day). Only the fields you pass change.
scripts/deleteTimeEntry.ts
deleteTimeEntryharvestDelete a time entry. Locked/invoiced entries cannot be deleted.
scripts/restartTimer.ts
restartTimerharvestRestart the timer on a stopped time entry.
scripts/stopTimer.ts
stopTimerharvestStop the timer on a running time entry.
scripts/listTimeEntries.ts
listTimeEntriesharvestList time entries, filtered by user, project, client, task, date range, or running/billed/approval state.
scripts/getTimeEntry.ts
getTimeEntryharvestRetrieve a single time entry by id.
scripts/createProject.ts
createProjectharvestCreate a project for a client.
scripts/updateProject.ts
updateProjectharvestUpdate a project (rename, re-budget, archive via
is_active: false
).
scripts/listProjects.ts
listProjectsharvestList projects, optionally filtered by client or active state. Source of
project_id
.
scripts/getProject.ts
getProjectharvestRetrieve a single project by id.
scripts/createClient.ts
createClientharvestCreate a client.
scripts/updateClient.ts
updateClientharvestUpdate a client (rename, change currency, archive via
is_active: false
).
scripts/listClients.ts
listClientsharvestList clients, optionally filtered by active state. Source of
client_id
.
scripts/getClient.ts
getClientharvestRetrieve a single client by id.
scripts/createContact.ts
createContactharvestCreate a contact for a client.
scripts/updateContact.ts
updateContactharvestUpdate a contact.
scripts/listContacts.ts
listContactsharvestList client contacts, optionally filtered by client.
scripts/deleteContact.ts
deleteContactharvestDelete a contact (hard delete).
scripts/createTask.ts
createTaskharvestCreate an account-wide task. A project references it through a project task assignment (createProjectTaskAssignment).
scripts/listTasks.ts
listTasksharvestList the account's tasks. For tasks valid on a specific project, use listProjectTaskAssignments.
scripts/listProjectTaskAssignments.ts
listProjectTaskAssignmentsharvestList the tasks assigned to a project — the valid
task_id
s for logging time on it.
scripts/createProjectTaskAssignment.ts
createProjectTaskAssignmentharvestAssign a task to a project so time can be logged against it.
scripts/listInvoices.ts
listInvoicesharvestList invoices, optionally filtered by client, date range, or state. Read-only.
scripts/getInvoice.ts
getInvoiceharvestRetrieve a single invoice by id, including line items. Read-only.
scripts/getCurrentUser.ts
getCurrentUserharvestRetrieve the authenticated user (the default owner of a time entry; timezone, roles).
scripts/listUsers.ts
listUsersharvestList users in the account (to log or read time for a specific teammate).
scripts/getCompany.ts
getCompanyharvestRetrieve company settings — most importantly
wants_timestamp_timers
(which time-entry create tool is valid) and feature flags.
<!-- END:skill-scripts-table --> <!-- BEGIN:disambiguation-and-refusals? -->
<!-- BEGIN:skill-connections-note -->
所有脚本均使用单一的
harvest
连接。各类ID(
id
project_id
task_id
client_id
user_id
)均为整数;需通过对应的
list*
工具获取。
<!-- END:skill-connections-note --> <!-- BEGIN:skill-scripts-table -->
脚本文件脚本名称连接配置描述
scripts/createTimeEntry.ts
createTimeEntryharvest针对指定项目和任务,按时长(小时)记录时间。省略
hours
参数可启动运行中的计时器。仅适用于时长模式的账户。
scripts/createTimeEntryForTimestamps.ts
createTimeEntryForTimestampsharvest针对指定项目和任务,按起止时间记录时间。省略
ended_time
参数可让计时器持续运行。仅适用于时间戳模式的账户。
scripts/updateTimeEntry.ts
updateTimeEntryharvest更新时间条目(备注、工时、时间、任务或日期)。仅修改你传入的字段。
scripts/deleteTimeEntry.ts
deleteTimeEntryharvest删除时间条目。已锁定/已计费的条目无法删除。
scripts/restartTimer.ts
restartTimerharvest重启已停止的时间条目计时器。
scripts/stopTimer.ts
stopTimerharvest停止正在运行的时间条目计时器。
scripts/listTimeEntries.ts
listTimeEntriesharvest列出时间条目,可按用户、项目、客户、任务、日期范围或运行/已计费/审批状态筛选。
scripts/getTimeEntry.ts
getTimeEntryharvest通过ID获取单个时间条目。
scripts/createProject.ts
createProjectharvest为客户创建项目。
scripts/updateProject.ts
updateProjectharvest更新项目(重命名、重新设置预算、通过
is_active: false
归档)。
scripts/listProjects.ts
listProjectsharvest列出项目,可按客户或活跃状态筛选。是获取
project_id
的来源。
scripts/getProject.ts
getProjectharvest通过ID获取单个项目。
scripts/createClient.ts
createClientharvest创建客户。
scripts/updateClient.ts
updateClientharvest更新客户(重命名、更改货币、通过
is_active: false
归档)。
scripts/listClients.ts
listClientsharvest列出客户,可按活跃状态筛选。是获取
client_id
的来源。
scripts/getClient.ts
getClientharvest通过ID获取单个客户。
scripts/createContact.ts
createContactharvest为客户创建联系人。
scripts/updateContact.ts
updateContactharvest更新联系人信息。
scripts/listContacts.ts
listContactsharvest列出客户联系人,可按客户筛选。
scripts/deleteContact.ts
deleteContactharvest删除联系人(硬删除)。
scripts/createTask.ts
createTaskharvest创建账户级任务。项目需通过项目任务关联引用该任务(调用createProjectTaskAssignment)。
scripts/listTasks.ts
listTasksharvest列出账户下的任务。若要获取特定项目可用的任务,请使用listProjectTaskAssignments。
scripts/listProjectTaskAssignments.ts
listProjectTaskAssignmentsharvest列出分配给项目的任务——即该项目可用于记录时间的有效
task_id
scripts/createProjectTaskAssignment.ts
createProjectTaskAssignmentharvest将任务分配给项目,以便针对该项目记录时间。
scripts/listInvoices.ts
listInvoicesharvest列出发票,可按客户、日期范围或状态筛选。仅支持读取操作。
scripts/getInvoice.ts
getInvoiceharvest通过ID获取单个发票,包含明细项。仅支持读取操作。
scripts/getCurrentUser.ts
getCurrentUserharvest获取已认证用户信息(时间条目的默认所有者;时区、角色)。
scripts/listUsers.ts
listUsersharvest列出账户中的用户(以便为特定团队成员记录或读取时间)。
scripts/getCompany.ts
getCompanyharvest获取公司设置——最重要的是
wants_timestamp_timers
(决定应使用哪个时间条目创建工具)和功能开关。
<!-- END:skill-scripts-table --> <!-- BEGIN:disambiguation-and-refusals? -->

Disambiguation & refusals

歧义处理与操作拒绝

  • Resolving a project, client, task, or contact by name before writing. Names collide — two projects can share a name, two clients can too, and a contact name can repeat across clients. Before creating or updating a record against a name-matched id, count the exact (case-insensitive) matches from
    listProjects
    /
    listClients
    /
    listTasks
    /
    listContacts
    : exactly one → act on it, don't over-ask. Two or more that tie → stop, list the candidates with a distinguishing field (client name, code, or id) and ask which one. Never silently pick the first.
  • Picking the right time-entry create tool.
    createTimeEntry
    (duration) and
    createTimeEntryForTimestamps
    (start/end) are mutually exclusive by account mode. If you don't know the account's mode, read
    getCompany
    (
    wants_timestamp_timers
    ) before logging time rather than guessing — calling the wrong one returns a recoverable error naming its sibling.
  • Unsupported operations — decline, don't fake. This connector does not create or send invoices or estimates, log expenses, run the aggregate Reports API, or create/archive users. If asked to do one of these, say it's not supported and stop — do not substitute a different tool (e.g. do not "log an expense" as a time entry) and report success for an action you didn't perform. There is no hard delete for clients, projects, or tasks — they are archived via
    is_active: false
    ; don't claim a delete you can only archive.
<!-- END:disambiguation-and-refusals -->
  • 通过名称解析项目、客户、任务或联系人后再执行写入操作。 名称可能重复——两个项目、两个客户可能同名,同一联系人姓名也可能在不同客户下重复。根据
    listProjects
    /
    listClients
    /
    listTasks
    /
    listContacts
    的精确(不区分大小写)匹配结果计数:若恰好匹配一个→执行操作,无需额外询问;若匹配两个或更多→停止操作,列出候选对象及区分字段(客户名称、编码或ID),询问用户选择哪一个。切勿默认选择第一个结果。
  • 选择正确的时间条目创建工具。
    createTimeEntry
    (时长模式)和
    createTimeEntryForTimestamps
    (起止时间模式)因账户模式互斥。若未知账户模式,请先调用
    getCompany
    接口(
    wants_timestamp_timers
    字段),再记录时间,切勿猜测——调用错误工具会返回可恢复的错误,并提示应使用的对应工具。
  • 不支持的操作——直接拒绝,切勿伪造。 本连接器不支持创建或发送发票/预估单、记录费用、运行聚合报表API,或创建/归档用户。若用户要求执行此类操作,请告知不支持并停止操作——切勿替代使用其他工具(例如不要将“记录费用”伪装为时间条目)并谎称操作成功。客户、项目或任务不支持硬删除——只能通过
    is_active: false
    归档;切勿声称已执行删除操作。
<!-- END:disambiguation-and-refusals -->

Auth

身份验证

Every shape passes auth as one connection selector, not the secret — a
[<resolver>:]<value>
string. Every connector accepts
zapier:<connection-id>
(Zapier-managed auth — routes through Zapier's auth, retries, and governance layer); some also accept one or more direct-token resolvers (naming and count vary per connector) — check this connector's own resolvers rather than assuming. The
<resolver>:
prefix is optional; a bare value goes to the first resolver that claims it — a UUID-shaped bare value always claims
zapier:
. Each script declares the connections it needs and the resolvers each accepts. The exact syntax for passing a connection (and how to see this connector's resolver list) differs by shape — see the reference you loaded above.
Checking what's already configured first? Don't dump environment values to do it —
env
or
env | grep <name>
prints the value along with the name, leaking a live credential into the transcript if one is set. Check names only (
env | cut -d= -f1 | grep -i <name>
) or test a known name directly (
[ -n "$VAR_NAME" ]
).
<!-- BEGIN:skill-auth-notes? operational behavior that differs by WHICH resolver is used — a safety gate only one path enforces, scopes/permissions that differ between resolvers, a billing/plan difference tied to the auth path, or a feature only available (or unavailable) on one resolver. Not for describing how to obtain or pass a credential — that's references/use-without-zapier.md's job. Leave this region empty (unfilled) if every resolver behaves identically. --> <!-- END:skill-auth-notes -->
No connection yet? Pick one — and follow the reference's own flow to obtain it; never just ask the user for a connection id or token as if they already have one memorized:
Load
Pass the credential directly
references/use-without-zapier.md
Route it through a Zapier connection
references/use-with-zapier.md
所有操作均通过单个连接选择器传递身份验证信息,而非密钥——格式为
[<resolver>:]<value>
字符串。所有连接器均接受
zapier:<connection-id>
(由Zapier管理的身份验证——通过Zapier的认证、重试和治理层路由);部分连接器还接受一种或多种直接令牌解析器(名称和数量因连接器而异)——请查看本连接器的解析器列表,切勿假设。
<resolver>:
前缀是可选的;无前缀的值会交给第一个匹配的解析器处理——UUID格式的无前缀值默认使用
zapier:
解析器。每个脚本都会声明所需的连接及支持的解析器。传递连接的具体语法(以及查看本连接器解析器列表的方式)因运行环境而异——请查看你之前加载的参考文档。
想要检查已配置的内容?切勿直接打印环境变量——
env
env | grep <name>
会同时打印变量名和值,如果存在有效凭证,会将其泄露到输出中。仅检查变量名(
env | cut -d= -f1 | grep -i <name>
)或直接测试已知变量(
[ -n "$VAR_NAME" ]
)。
<!-- BEGIN:skill-auth-notes? operational behavior that differs by WHICH resolver is used — a safety gate only one path enforces, scopes/permissions that differ between resolvers, a billing/plan difference tied to the auth path, or a feature only available (or unavailable) on one resolver. Not for describing how to obtain or pass a credential — that's references/use-without-zapier.md's job. Leave this region empty (unfilled) if every resolver behaves identically. --> <!-- END:skill-auth-notes -->
还没有连接?请选择一种方式,并按照对应参考文档的流程获取连接信息;切勿直接向用户索要连接ID或令牌,假设他们已经记住这些信息:
加载文档
直接传递凭证
references/use-without-zapier.md
通过Zapier连接路由凭证
references/use-with-zapier.md

Output format

输出格式

Every script returns a
{ data, meta }
envelope:
  • data
    — the script's result (the shape its
    outputSchema
    declares; see the reference you loaded above for how to inspect a script's exact schema in your shape).
  • meta.outputDataValidation
    — what validating
    data
    did:
    • { skipped: false, droppedPaths: null }
      — validated, nothing removed.
    • { skipped: false, droppedPaths: [...], instruction }
      — validated, but those paths were stripped from
      data
      : fields the script returned from the API that the
      outputSchema
      doesn't declare. If you need them, re-run with output validation skipped.
    • { skipped: true }
      — validation was bypassed;
      data
      is the raw, unchecked script output.
Reading dropped fields /
skipOutputDataValidation
.
To receive the raw, unvalidated result, opt out of output validation (the exact syntax differs by shape — see the reference you loaded above). Input validation is never skipped.
Trimming the result /
filterOutputData
.
To shrink a large result down to the fields you need, pass a jq expression that post-processes
data
(again, exact syntax per shape). The jq runs against
data
only, NOT the
{ data, meta }
envelope, so write it rooted at
data
(run the script's
--help
— or your shape's equivalent — to see its output schema). The transformed value replaces
data
,
meta
is preserved, and the result is NOT re-validated against the output schema.
<!-- BEGIN:skill-references-table -->
所有脚本均返回
{ data, meta }
格式的结果包:
  • data
    — 脚本的执行结果(符合其
    outputSchema
    声明的结构;请查看你加载的参考文档,了解如何在你的环境中查看脚本的确切输出结构)。
  • meta.outputDataValidation
    — 对
    data
    的验证结果:
    • { skipped: false, droppedPaths: null }
      — 已验证,未移除任何内容。
    • { skipped: false, droppedPaths: [...], instruction }
      — 已验证,但这些路径已从
      data
      中移除:脚本从API返回的字段未在
      outputSchema
      中声明。若需要这些字段,请跳过输出验证重新运行。
    • { skipped: true }
      — 已跳过验证;
      data
      为原始的未检查脚本输出。
读取被移除的字段 /
skipOutputDataValidation
若要接收原始的未验证结果,请选择跳过输出验证(具体语法因环境而异——请查看你加载的参考文档)。输入验证永远不会被跳过。
精简结果 /
filterOutputData
若要将大型结果精简为你需要的字段,请传入一个jq表达式对
data
进行后处理(同样,具体语法因环境而异)。jq仅针对
data
运行,而非
{ data, meta }
结果包,因此表达式需以
data
为根节点(运行脚本的
--help
命令——或你的环境中的等效命令——查看其输出结构)。转换后的值会替换
data
meta
会被保留,且结果不会再次根据输出结构进行验证。
<!-- BEGIN:skill-references-table -->

References

参考文档

Load the matching reference file before working in that area:
ReferenceCoversLoad it when
references/harvest-api-gotchas.mdThe duration-vs-timestamps account mode and which time-entry create tool each allows (
wants_timestamp_timers
), running-timer creation and the state-guarded stop/restart, server-side hours rounding, delete-vs-archive constraints on clients/projects/time entries, required create fields, task/project task-assignment resolution,
is_active
/
updated_since
list filters, cursor pagination (follow
links.next
,
per_page
max 2000), auth headers, and the error envelope + rate limits (100 req / 15s)
a call is rejected unexpectedly, you're choosing between the two time-entry tools, a delete/archive behaves unexpectedly, or you're paginating a large list
<!-- END:skill-references-table -->
在对应场景下工作前,请加载匹配的参考文档:
参考文档涵盖内容加载时机
references/harvest-api-gotchas.md时长模式与时间戳模式的区别及对应的时间条目创建工具(
wants_timestamp_timers
)、运行中计时器的创建及状态控制的启停/重启、服务器端工时四舍五入规则、客户/项目/时间条目的删除与归档限制、创建操作的必填字段、任务/项目任务关联的解析、
is_active
/
updated_since
列表筛选、游标分页(跟随
links.next
per_page
最大值为2000)、认证头、错误结果包及速率限制(15秒内最多100次请求)
当调用被意外拒绝、需要在两个时间条目工具间选择、删除/归档操作不符合预期,或需要对大型列表进行分页时
<!-- END:skill-references-table -->