First-party app
Gusto Gusto

Gusto

Read and update a Gusto payroll account — employees, contractors, compensation, payrolls, pay schedules, time off and departments.

stable Human ResourcesFinance & AccountingProductivity

About

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.

App id
io.w6w.gusto
Version
0.1.2
Author
w6w
Licence
MIT
Categories
Human Resources · Finance & Accounting · Productivity

Overview

Gusto 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.

Build with Gusto

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.

List company admins

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.

Get company

company-get

The company record — including whether it is approved to run payroll at all, and the version any update has to carry.

List company locations

company-location-list

The company's work locations — which decide state taxes, minimum wage and registrations, not just where the post goes.

List contractors

contractor-list

A company's contractors — a separate collection from employees, with their own tax treatment and their own payment route.

List contractor payments

contractor-payment-list

Contractor payments in a date window — individual transactions rather than a run, and entirely separate from payrolls when totting up spend.

Create department

department-create

Create a department. Titles are not unique in Gusto, so running this twice makes two departments with the same name.

List departments

department-list

Departments with their members — flat, with no nesting and no manager field, which is the whole of Gusto's org model.

Add people to a department

department-people-add

Add employees or contractors to a department. They are separate lists, because they are separate collections everywhere in Gusto.

Create employee

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.

Get employee

employee-get

One employee, with the `version` any update has to carry. Read this immediately before writing — Gusto rejects a stale version.

List an employee's home addresses

employee-home-address-list

Home addresses with their effective dates — a history, because a mid-year move changes which state's tax applied when.

List employees

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.

Terminate employee

employee-terminate

End an employment. Stops pay, starts the final-paycheck clock, and is visible to the employee. Requires an explicit confirmation.

Update employee

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.

List events

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.

List an employee's garnishments

garnishment-list

Court-ordered and voluntary deductions on an employee. Read-only here on purpose: these are legal instruments, not settings.

List a job's compensations

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.

List pay periods

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.

List pay schedules

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.

Get payroll

payroll-get

One payroll broken down per employee — hours, earnings, taxes, deductions. Unprocessed numbers are a projection, not actuals.

List payrolls

payroll-list

A company's payroll runs. `processed` is the field that matters — an unprocessed payroll is a draft whose totals still move.

List time off requests

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.

Get token info

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>"
      }
    }
  ]
}

Here are some of the things you can do

  • List contractor payments

    read
    contractor-payment-list
  • List company admins

    read
    company-admin-list
  • Get company

    read
    company-get
  • List company locations

    read
    company-location-list
  • List contractors

    read
    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.

Install
npm install @w6w/sdk
yarn add @w6w/sdk
pnpm add @w6w/sdk
deno add npm:@w6w/sdk
Code
import { 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);
Install the CLI
npm install -g @w6w/cli
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.

What the agent gets

Credentials it can't read

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.

A tool surface scoped to the caller

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.

A durable workflow in one call

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.

Health-aware discovery

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).

Request MCP access

Health checks

Gusto declares its own checks, so its health is a property of the app rather than something the host guesses at.

service

Gusto platform status

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.

dependency

Pinned API version

Whether the API version this app pins is still supported, read from the `deprecation` response header Gusto sends and nobody reads.