Read and update a Gusto payroll account — employees, contractors, compensation, payrolls, pay schedules, time off and departments.
Gusto ships in the w6w first-party pack. It declares 23 actions, 2 health checks, and the host runs its code in a sandbox that never sees the credential.
io.w6w.gustoGusto runs payroll, benefits and HR for a company, and this app reads and updates the operational side of that account: the employee and contractor roster, compensation history, payroll runs and pay schedules, time-off requests, and departments.
New employees are added into Gusto’s onboarding flow rather than hired outright — no job, compensation or tax withholding is set here — which lets self-onboarding collect the sensitive details directly from the employee instead of routing them through a workflow. Compensation, payroll and pay-period data are all read-only, giving a workflow visibility into who earns what, which payrolls have actually been processed, and when the next deadline lands, without the ability to submit a payroll run itself.
Deliberately excluded: submitting or approving payroll, anything touching Social Security numbers or bank details, and edits to garnishments or home addresses, since those carry legal and compliance weight this app leaves to Gusto’s own interface. What’s here is the everyday read-and-light-write loop — who earns what, whether they took time off, and what department they sit in.
Three routes to the same 23 actions. The Workflow tab is generated from Gusto's own manifest and carries its real ids, so it is copy-pasteable; the Code and CLI examples are the same call for any action on any app, so every app-specific value in them is a blank you fill in.
company-admin-list The administrators of the company — the people a workflow escalates to when a payroll decision is not an automation's to make.
company-get The company record — including whether it is approved to run payroll at all, and the version any update has to carry.
company-location-list The company's work locations — which decide state taxes, minimum wage and registrations, not just where the post goes.
contractor-list A company's contractors — a separate collection from employees, with their own tax treatment and their own payment route.
contractor-payment-list Contractor payments in a date window — individual transactions rather than a run, and entirely separate from payrolls when totting up spend.
department-create Create a department. Titles are not unique in Gusto, so running this twice makes two departments with the same name.
department-list Departments with their members — flat, with no nesting and no manager field, which is the whole of Gusto's org model.
department-people-add Add employees or contractors to a department. They are separate lists, because they are separate collections everywhere in Gusto.
employee-create Create an employee record in ONBOARDING — no job, no compensation, no tax details, so they cannot yet be paid. Self-onboarding lets Gusto collect the rest.
employee-get One employee, with the `version` any update has to carry. Read this immediately before writing — Gusto rejects a stale version.
employee-home-address-list Home addresses with their effective dates — a history, because a mid-year move changes which state's tax applied when.
employee-list A company's employees. Terminated people are EXCLUDED by default, which is why a sync that only reads this never learns that somebody left.
employee-terminate End an employment. Stops pay, starts the final-paycheck clock, and is visible to the employee. Requires an explicit confirmation.
employee-update Change an employee's name, emails or date of birth. Requires the version you just read — Gusto rejects a stale one rather than overwriting somebody else's change.
event-list What changed and when — the feed a sync reads instead of re-reading the whole company. It also carries the terminations that make people vanish from the employee list.
garnishment-list Court-ordered and voluntary deductions on an employee. Read-only here on purpose: these are legal instruments, not settings.
job-compensation-list A job's pay history — a raise is a new compensation with an effective date, not an edit. Read `payment_unit` before annualising anything.
pay-period-list The pay calendar, with each period's payroll deadline — the date a workflow has to beat for hours, bonuses and reimbursements to land in that run.
pay-schedule-list A company's pay schedules and their frequencies — several can run at once, which is what makes 'annualise this rate' ambiguous without them.
payroll-get One payroll broken down per employee — hours, earnings, taxes, deductions. Unprocessed numbers are a projection, not actuals.
payroll-list A company's payroll runs. `processed` is the field that matters — an unprocessed payroll is a draft whose totals still move.
time-off-request-list Time off requests with their approval status — pending is a plan, approved is a fact, and treating them alike books cover for leave nobody takes.
token-info What this token is scoped to, and which companies it reaches — the call that answers 'which company id do I use', and the only one needing no permission.
A workflow step names the app and the action, and the editor fills in the
connection when you pick one. This is the Step shape from the
workflow spec, carrying Gusto's real ids.
{
"manifestVersion": "2",
"name": "gusto-example",
"steps": [
{
"id": "contractor-payment-list",
"uses": {
"app": "io.w6w.gusto",
"action": "contractor-payment-list",
"connection": "conn_YOUR_CONNECTION_ID"
},
"with": {
"startDate": "<startDate>",
"endDate": "<endDate>"
}
}
]
}contractor-payment-list company-admin-list company-get company-location-list contractor-list +18 more actions available
Every app-specific value here is a blank you have to fill in. An
app action is reached through the connection that authenticates it, so the
address is a connection id, not the app id — and connections belong to your account,
so a public page cannot know yours. Create one for Gusto, then fill in
the three blanks: conn_YOUR_CONNECTION_ID, the action key, and the
parameters that action declares. The call itself is real — the shape is transcribed
from the studio's own snippet builder, which prints the same kind of blanks — but
nothing in it is specific to Gusto. The Workflow tab is where this app's
real ids are.
npm install @w6w/sdkyarn add @w6w/sdkpnpm add @w6w/sdkdeno add npm:@w6w/sdkimport { W6wClient, isActionRun } from "@w6w/sdk";
// Reads W6W_BASE_URL and W6W_TOKEN from the environment when omitted.
const client = new W6wClient();
const envelope = await client.run({
urn: "conn_YOUR_CONNECTION_ID",
action: "contractor-payment-list",
payload: {
// companyId: "<value>",
startDate: "<value>",
endDate: "<value>",
},
});
if (isActionRun(envelope)) console.log(envelope.value); npm install -g @w6w/cli w6w run conn_YOUR_CONNECTION_ID --action contractor-payment-list --payload '{"startDate":"<value>","endDate":"<value>"}' Give an AI agent Gusto — without giving it Gusto's credentials. One MCP endpoint exposes every app, function and workflow the caller is entitled to, as tools it can discover and run. Access is granted per team while we onboard.
One tool call{
"name": "w6w_invoke",
"arguments": {
"ref": "app:io.w6w.gusto#contractor-payment-list",
"input": {
"startDate": "<startDate>",
"endDate": "<endDate>"
}
}
}
Every tool names its target with a single ref. The
app: form above doesn't name a connection at all — the
host resolves which of the caller's Gusto connections to sign
with, and refuses rather than guesses when the answer is ambiguous.
The token is attached host-side, at the moment of the call. It is never a tool argument, never in the model's context, and never in a transcript — so a prompt injection has nothing to exfiltrate.
Tools are derived per end user from what that person has actually connected and is entitled to — not one shared bot identity carrying the union of everyone's access.
Multi-step work runs on the workflow engine and returns a run handle the agent can poll — retries, branching and state survive the conversation that started them.
Gusto's declared health checks are on the surface too, so an agent can tell "the vendor is down" from "your credential expired" before it burns a retry on either.
The MCP surface is part of the hosted platform. Gusto itself is MIT, and the runtime that executes it is source-available (FSL).
Gusto declares its own checks, so its health is a property of the app rather than something the host guesses at.
The API and payroll components decide the verdict. Gusto's infrastructure vendors are reported for context but capped at degraded, and its support channels are ignored.
Whether the API version this app pins is still supported, read from the `deprecation` response header Gusto sends and nobody reads.