harvest
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseHarvest
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 ().
<!-- legal:disclaimer -->
https://api.harvestapp.com/v2/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()。
<!-- legal:disclaimer -->
https://api.harvestapp.com/v2/这是一款独立的非官方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 first when the mode is unknown (see
getCompany).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 (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 auth commands, run here once. Importing the published package as a dependency in your own project instead? That already resolves everything — see .
npx skills add zapier/connectors --skill harvestzapier-sdknpm install --omit=devnpm installreferences/use-as-sdk.mdThe 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. | |
Terminal / subprocess access (you can run | |
| Only your own code, importing this package as a dependency | |
| 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) | |
这是一款agentskills.io技能工具。
若尚未将该连接器作为技能工具安装,请先执行进行安装(或使用你的工具链自带的技能安装机制),再继续后续操作。安装技能工具仅会复制这些文件,不会安装依赖项。运行CLI、本地MCP服务器或认证命令前,先在此处执行一次。若要在你自己的项目中导入已发布的包作为依赖?此时已经处理了所有依赖——详见。
npx skills add zapier/connectors --skill harvestzapier-sdknpm install --omit=devnpm installreferences/use-as-sdk.md该连接器运行于**Node.js 22.18+**环境。请根据你的运行方式选择对应的参考文档,并在操作前加载:
| 你的环境... | 加载文档 |
|---|---|
支持MCP的客户端——工具可能已加载(例如 | |
可访问终端/子进程(能运行 | |
| 仅使用自有代码,将本包作为依赖导入 | |
| 无工具访问权限、无终端、无法导入本包——需自行编写调用Harvest API的代码(例如代码执行沙箱) | |
Scripts
脚本
<!-- BEGIN:skill-connections-note -->
<!-- END:skill-scripts-table -->
<!-- BEGIN:disambiguation-and-refusals? -->
All scripts use the single connection. Ids (, , , , ) are integers; resolve them from the matching tool.
<!-- END:skill-connections-note -->
<!-- BEGIN:skill-scripts-table -->
harvestidproject_idtask_idclient_iduser_idlist*| Script | Script name | Connections | Description |
|---|---|---|---|
| createTimeEntry | harvest | Log time by duration (hours) against a project + task. Omit |
| createTimeEntryForTimestamps | harvest | Log time by start/end time against a project + task. Omit |
| updateTimeEntry | harvest | Update a time entry (notes, hours, times, task, or day). Only the fields you pass change. |
| deleteTimeEntry | harvest | Delete a time entry. Locked/invoiced entries cannot be deleted. |
| restartTimer | harvest | Restart the timer on a stopped time entry. |
| stopTimer | harvest | Stop the timer on a running time entry. |
| listTimeEntries | harvest | List time entries, filtered by user, project, client, task, date range, or running/billed/approval state. |
| getTimeEntry | harvest | Retrieve a single time entry by id. |
| createProject | harvest | Create a project for a client. |
| updateProject | harvest | Update a project (rename, re-budget, archive via |
| listProjects | harvest | List projects, optionally filtered by client or active state. Source of |
| getProject | harvest | Retrieve a single project by id. |
| createClient | harvest | Create a client. |
| updateClient | harvest | Update a client (rename, change currency, archive via |
| listClients | harvest | List clients, optionally filtered by active state. Source of |
| getClient | harvest | Retrieve a single client by id. |
| createContact | harvest | Create a contact for a client. |
| updateContact | harvest | Update a contact. |
| listContacts | harvest | List client contacts, optionally filtered by client. |
| deleteContact | harvest | Delete a contact (hard delete). |
| createTask | harvest | Create an account-wide task. A project references it through a project task assignment (createProjectTaskAssignment). |
| listTasks | harvest | List the account's tasks. For tasks valid on a specific project, use listProjectTaskAssignments. |
| listProjectTaskAssignments | harvest | List the tasks assigned to a project — the valid |
| createProjectTaskAssignment | harvest | Assign a task to a project so time can be logged against it. |
| listInvoices | harvest | List invoices, optionally filtered by client, date range, or state. Read-only. |
| getInvoice | harvest | Retrieve a single invoice by id, including line items. Read-only. |
| getCurrentUser | harvest | Retrieve the authenticated user (the default owner of a time entry; timezone, roles). |
| listUsers | harvest | List users in the account (to log or read time for a specific teammate). |
| getCompany | harvest | Retrieve company settings — most importantly |
<!-- BEGIN:skill-connections-note -->
<!-- END:skill-scripts-table -->
<!-- BEGIN:disambiguation-and-refusals? -->
所有脚本均使用单一的连接。各类ID(、、、、)均为整数;需通过对应的工具获取。
<!-- END:skill-connections-note -->
<!-- BEGIN:skill-scripts-table -->
harvestidproject_idtask_idclient_iduser_idlist*| 脚本文件 | 脚本名称 | 连接配置 | 描述 |
|---|---|---|---|
| createTimeEntry | harvest | 针对指定项目和任务,按时长(小时)记录时间。省略 |
| createTimeEntryForTimestamps | harvest | 针对指定项目和任务,按起止时间记录时间。省略 |
| updateTimeEntry | harvest | 更新时间条目(备注、工时、时间、任务或日期)。仅修改你传入的字段。 |
| deleteTimeEntry | harvest | 删除时间条目。已锁定/已计费的条目无法删除。 |
| restartTimer | harvest | 重启已停止的时间条目计时器。 |
| stopTimer | harvest | 停止正在运行的时间条目计时器。 |
| listTimeEntries | harvest | 列出时间条目,可按用户、项目、客户、任务、日期范围或运行/已计费/审批状态筛选。 |
| getTimeEntry | harvest | 通过ID获取单个时间条目。 |
| createProject | harvest | 为客户创建项目。 |
| updateProject | harvest | 更新项目(重命名、重新设置预算、通过 |
| listProjects | harvest | 列出项目,可按客户或活跃状态筛选。是获取 |
| getProject | harvest | 通过ID获取单个项目。 |
| createClient | harvest | 创建客户。 |
| updateClient | harvest | 更新客户(重命名、更改货币、通过 |
| listClients | harvest | 列出客户,可按活跃状态筛选。是获取 |
| getClient | harvest | 通过ID获取单个客户。 |
| createContact | harvest | 为客户创建联系人。 |
| updateContact | harvest | 更新联系人信息。 |
| listContacts | harvest | 列出客户联系人,可按客户筛选。 |
| deleteContact | harvest | 删除联系人(硬删除)。 |
| createTask | harvest | 创建账户级任务。项目需通过项目任务关联引用该任务(调用createProjectTaskAssignment)。 |
| listTasks | harvest | 列出账户下的任务。若要获取特定项目可用的任务,请使用listProjectTaskAssignments。 |
| listProjectTaskAssignments | harvest | 列出分配给项目的任务——即该项目可用于记录时间的有效 |
| createProjectTaskAssignment | harvest | 将任务分配给项目,以便针对该项目记录时间。 |
| listInvoices | harvest | 列出发票,可按客户、日期范围或状态筛选。仅支持读取操作。 |
| getInvoice | harvest | 通过ID获取单个发票,包含明细项。仅支持读取操作。 |
| getCurrentUser | harvest | 获取已认证用户信息(时间条目的默认所有者;时区、角色)。 |
| listUsers | harvest | 列出账户中的用户(以便为特定团队成员记录或读取时间)。 |
| getCompany | harvest | 获取公司设置——最重要的是 |
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: 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.listContacts - Picking the right time-entry create tool. (duration) and
createTimeEntry(start/end) are mutually exclusive by account mode. If you don't know the account's mode, readcreateTimeEntryForTimestamps(getCompany) before logging time rather than guessing — calling the wrong one returns a recoverable error naming its sibling.wants_timestamp_timers - 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 ; don't claim a delete you can only archive.
is_active: false
- 通过名称解析项目、客户、任务或联系人后再执行写入操作。 名称可能重复——两个项目、两个客户可能同名,同一联系人姓名也可能在不同客户下重复。根据/
listProjects/listClients/listTasks的精确(不区分大小写)匹配结果计数:若恰好匹配一个→执行操作,无需额外询问;若匹配两个或更多→停止操作,列出候选对象及区分字段(客户名称、编码或ID),询问用户选择哪一个。切勿默认选择第一个结果。listContacts - 选择正确的时间条目创建工具。 (时长模式)和
createTimeEntry(起止时间模式)因账户模式互斥。若未知账户模式,请先调用createTimeEntryForTimestamps接口(getCompany字段),再记录时间,切勿猜测——调用错误工具会返回可恢复的错误,并提示应使用的对应工具。wants_timestamp_timers - 不支持的操作——直接拒绝,切勿伪造。 本连接器不支持创建或发送发票/预估单、记录费用、运行聚合报表API,或创建/归档用户。若用户要求执行此类操作,请告知不支持并停止操作——切勿替代使用其他工具(例如不要将“记录费用”伪装为时间条目)并谎称操作成功。客户、项目或任务不支持硬删除——只能通过归档;切勿声称已执行删除操作。
is_active: false
Auth
身份验证
Every shape passes auth as one connection selector, not the secret — a string. Every connector accepts (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 prefix is optional; a bare value goes to the first resolver that claims it — a UUID-shaped bare value always claims . 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.
[<resolver>:]<value>zapier:<connection-id><resolver>:zapier:Checking what's already configured first? Don't dump environment values to do it — or prints the value along with the name, leaking a live credential into the transcript if one is set. Check names only () or test a known name directly ().
<!-- 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 -->
envenv | grep <name>env | cut -d= -f1 | grep -i <name>[ -n "$VAR_NAME" ]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 | |
| Route it through a Zapier connection | |
所有操作均通过单个连接选择器传递身份验证信息,而非密钥——格式为字符串。所有连接器均接受(由Zapier管理的身份验证——通过Zapier的认证、重试和治理层路由);部分连接器还接受一种或多种直接令牌解析器(名称和数量因连接器而异)——请查看本连接器的解析器列表,切勿假设。前缀是可选的;无前缀的值会交给第一个匹配的解析器处理——UUID格式的无前缀值默认使用解析器。每个脚本都会声明所需的连接及支持的解析器。传递连接的具体语法(以及查看本连接器解析器列表的方式)因运行环境而异——请查看你之前加载的参考文档。
[<resolver>:]<value>zapier:<connection-id><resolver>:zapier:想要检查已配置的内容?切勿直接打印环境变量——或会同时打印变量名和值,如果存在有效凭证,会将其泄露到输出中。仅检查变量名()或直接测试已知变量()。
<!-- 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 -->
envenv | grep <name>env | cut -d= -f1 | grep -i <name>[ -n "$VAR_NAME" ]还没有连接?请选择一种方式,并按照对应参考文档的流程获取连接信息;切勿直接向用户索要连接ID或令牌,假设他们已经记住这些信息:
| 加载文档 | |
|---|---|
| 直接传递凭证 | |
| 通过Zapier连接路由凭证 | |
Output format
输出格式
Every script returns a envelope:
{ data, meta }- — the script's result (the shape its
datadeclares; see the reference you loaded above for how to inspect a script's exact schema in your shape).outputSchema - — what validating
meta.outputDataValidationdid:data- — validated, nothing removed.
{ skipped: false, droppedPaths: null } - — validated, but those paths were stripped from
{ skipped: false, droppedPaths: [...], instruction }: fields the script returned from the API that thedatadoesn't declare. If you need them, re-run with output validation skipped.outputSchema - — validation was bypassed;
{ skipped: true }is the raw, unchecked script output.data
Reading dropped fields / . 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.
skipOutputDataValidationTrimming the result / . To shrink a large result down to the fields you need, pass a jq expression that post-processes (again, exact syntax per shape). The jq runs against only, NOT the envelope, so write it rooted at (run the script's — or your shape's equivalent — to see its output schema). The transformed value replaces , is preserved, and the result is NOT re-validated against the output schema.
<!-- BEGIN:skill-references-table -->filterOutputDatadatadata{ data, meta }data--helpdatameta所有脚本均返回格式的结果包:
{ data, meta }- — 脚本的执行结果(符合其
data声明的结构;请查看你加载的参考文档,了解如何在你的环境中查看脚本的确切输出结构)。outputSchema - — 对
meta.outputDataValidation的验证结果:data- — 已验证,未移除任何内容。
{ skipped: false, droppedPaths: null } - — 已验证,但这些路径已从
{ skipped: false, droppedPaths: [...], instruction }中移除:脚本从API返回的字段未在data中声明。若需要这些字段,请跳过输出验证重新运行。outputSchema - — 已跳过验证;
{ skipped: true }为原始的未检查脚本输出。data
读取被移除的字段 / 。 若要接收原始的未验证结果,请选择跳过输出验证(具体语法因环境而异——请查看你加载的参考文档)。输入验证永远不会被跳过。
skipOutputDataValidation精简结果 / 。 若要将大型结果精简为你需要的字段,请传入一个jq表达式对进行后处理(同样,具体语法因环境而异)。jq仅针对运行,而非结果包,因此表达式需以为根节点(运行脚本的命令——或你的环境中的等效命令——查看其输出结构)。转换后的值会替换,会被保留,且结果不会再次根据输出结构进行验证。
<!-- BEGIN:skill-references-table -->filterOutputDatadatadata{ data, meta }data--helpdatametaReferences
参考文档
Load the matching reference file before working in that area:
| Reference | Covers | Load it when |
|---|---|---|
| references/harvest-api-gotchas.md | The duration-vs-timestamps account mode and which time-entry create tool each allows ( | 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 |
在对应场景下工作前,请加载匹配的参考文档:
| 参考文档 | 涵盖内容 | 加载时机 |
|---|---|---|
| references/harvest-api-gotchas.md | 时长模式与时间戳模式的区别及对应的时间条目创建工具( | 当调用被意外拒绝、需要在两个时间条目工具间选择、删除/归档操作不符合预期,或需要对大型列表进行分页时 |