Onboarding built for the agent, not the buyer
If the person integrating your product is a coding agent, then your onboarding is a tool schema, your error messages are enum values, and your documentation is something returned by a function call. Most B2B products are still built as though a human will read a pricing page and book a demo.
The integrator changed
For a developer tool in 2026, the entity that reads your documentation, evaluates your pricing and writes your integration is frequently not a person. It is a coding agent, working from a one-line instruction like "add cross-promotion to this app."
That agent has a specific set of capabilities and a specific set of frustrations. It can read a JSON schema perfectly and a marketing page badly. It can follow a tool sequence reliably and a "contact sales" link not at all. It will parse your error message with a regular expression and get it wrong when you improve the wording.
Most B2B onboarding is still built for a buyer who will read a pricing page, book a demo, receive a sandbox key and forward it to an engineer. That flow takes a week. The agent flow takes four minutes, and the products that support it will be integrated in situations where the products that do not never get evaluated.
What building for it actually involves
Ship the tool before the screen. If a capability exists only as a dashboard form, an agent cannot use it, and adding an API later means two implementations that disagree. Building the tool first and letting the dashboard call the same thing costs nothing extra and avoids the divergence entirely.
Publish prices as a function. get_rate_card {} returning structured data, unauthenticated, is worth more than any pricing page. An agent evaluating three vendors will silently drop the two that require a conversation.
Return your documentation from a tool. get_integration_guide {} returns the current guide as markdown. The agent gets the authoritative version at the moment of use instead of scraping a page that may be cached, may be stale, and may be for a different major version.
Make rejections machine-actionable. gate_domain_too_young with an eligibility date is something an agent can schedule around. "Unfortunately your domain does not meet our requirements at this time" is something it can only give up on.
Leave a diff, not instructions. npx @ghan/sdk init writes the wiring and leaves a reviewable change. It does not commit, because the human still has to look.
The two moments that should stay human
Full automation is available and is the wrong target. Two decisions should require a person, and naming them explicitly is what makes automating everything else defensible:
Shipping the release. Third-party code entering a binary you sign is a decision about what your signature means. An agent can prepare it; a person should approve it.
Authorising money. Not each payment — a ceiling, set once, inside which an agent spends freely. The ceiling is the human decision and the spending is not.
Every other step — registration, scoring, integration, campaign creation, budget changes, ledger reads, payout requests — is better done by an agent, and in GHAN it is.
What this costs
Building MCP-first means the dashboard arrives late and looks sparse, because it is a mirror rather than the product. Publishing prices as a function means losing the negotiation. Returning reason codes means your rejections are legible to competitors as well as to partners.
Those are real costs. They are smaller than the cost of being the vendor an agent could not evaluate.
Questions people ask about this
What does MCP-first mean?
That every write capability ships as an MCP tool before, or instead of, a dashboard screen. The dashboard becomes a read-only mirror plus billing rather than the primary interface. In practice it changes what you build first - a tool schema rather than a form, an enum of rejection reasons rather than a support article, and a function that returns the integration guide rather than a documentation site an agent has to scrape.
Should everything be automated?
No, and picking the exceptions deliberately matters more than the automation. Two moments should stay human - shipping a release that contains third-party code, which is a decision about what you put your signature on, and authorising money, which is a decision about risk. Automating either one would be technically straightforward and would remove the accountability that makes the rest safe.
Why return error codes instead of messages?
Because an agent acting on a rejection needs to branch, and branching on English is unreliable and silently version-dependent. A stable code with an unstable human-readable string beside it gives both audiences what they need. The code is the contract; the sentence is a courtesy.
Machine-readable versions of this page: markdown · llms.txt · llms-full.txt · OpenAPI · AI catalog