StackOne is now a Pydantic AI capability StackOne, the integration gateway for AI agents, is now a capability in Pydantic AI Harness, allowing agents to access actions on linked accounts such as Workday, BambooHR, Salesforce, and Zendesk with a single line of code. The capability, added via the capabilities array, leverages StackOne's Search & Execute to avoid serializing its catalog of thousands of actions into prompts. Developers can get started by installing the harness with the stackone extra and configuring a StackOne connector, linked account, and API key. StackOne https://www.stackone.com/?utm source=pydantic&utm medium=referral&utm campaign=pydantic-harness-launch&utm content=pydantic-homepage , the integration gateway for AI agents, is now a capability in Pydantic AI Harness https://pydantic.dev/docs/ai/harness/overview/ . Add StackOne account id=... to an agent's capabilities list and it can work with the actions on a linked account: Workday, BambooHR, Salesforce, Zendesk, and the rest of the StackOne connector catalog. This post covers the problem this new capability solves, how it works, and what to configure before an agent starts writing to a system of record. The AI integration problem with SaaS tools An agent that answers questions about your company's data needs to reach the systems that hold it. In practice, there are two usual ways to do that, and each has a cost. The first is to hand-write a tool per endpoint: a list employees wrapper here, a create ticket wrapper there, each with its own auth handling, its own pagination quirks, and its own schema to keep in sync when the vendor changes something. Do that across three or four providers and the integration code outgrows the agent. The second is the obvious shortcut, and it backfires too: dump every action you might need into the tool list and you spend your context window on schemas the model will never call, while tool selection gets worse as the list grows. StackOne handles both. It is one gateway in front of hundreds of SaaS systems, with thousands of executable actions behind it, and Search & Execute https://docs.stackone.com/optimize/search-and-execute?utm source=pydantic&utm medium=referral&utm campaign=pydantic-harness-launch&utm content=pydantic-docs-search-execute running on the gateway so a catalog that size never has to be serialized into a prompt. The capability in Pydantic AI Harness is the front door to it from an agent, and it is one line. What a capability is Pydantic AI Harness is the official capability library for Pydantic AI. A capability is a self-contained battery: tools, hooks, instructions, and settings bundled together, added to an agent through the capabilities= ... array, and composable with the other capabilities in the library. StackOne is one of those, alongside code execution, memory, planning, and guardrails. An agent can work across as many accounts as it needs. Each StackOne instance is scoped to a StackOne linked account https://docs.stackone.com/gateway/concepts/linked-accounts?utm source=pydantic&utm medium=referral&utm campaign=pydantic-harness-launch&utm content=pydantic-docs-linked-accounts , meaning one end user's authenticated connection to one underlying system, whether that is their Workday, their Salesforce, or their Zendesk. Getting started Install the harness with the stackone extra, plus the model provider you want. The spec extra covers the YAML agent example further down and logfire covers the tracing calls in every snippet: uv add "pydantic-ai-harness stackone " "pydantic-ai-slim openai,spec,logfire " Before the first run you need to configure a connector in StackOne, link an account, copy the linked account ID from the dashboard, and create an API key that can execute actions. For a first test, enable only the read actions you need. export STACKONE API KEY='your-stackone-api-key' export STACKONE ACCOUNT ID='your-linked-account-id' export OPENAI API KEY='your-openai-api-key' StackOne reads STACKONE API KEY on its own. The account ID is read explicitly in the example below so it stays out of the source: python import os import logfire from pydantic ai import Agent from pydantic ai harness.stackone import StackOne logfire.configure logfire.instrument pydantic ai agent = Agent 'openai:gpt-5', capabilities= StackOne account id=os.environ 'STACKONE ACCOUNT ID' , , result = agent.run sync 'List the first 5 employees' print result.output That is the whole setup. The model receives two tools by default: one to search for an action matching the request, one to execute the action it found by ID. Two ways to expose actions The search-then-execute pair is the interesting design decision, so it is worth understanding both modes before you pick one. | Mode | What the model receives | Use it when | |---|---|---| search execute | Two tools: search for an action, then execute it by ID | The account has many enabled actions. This is the default. | individual | One tool and schema per enabled action | You need exact action selection or per-tool behavior. | search execute keeps the context cost flat no matter how many actions the account has enabled, because the catalog is queried at runtime instead of being serialized into the prompt. Action IDs come back from the search tool and should not be guessed. individual mode sends every selected schema to the model, which is what you want when the set is small and you care about exactly which actions are reachable. Filter it with actions , using fnmatch https://docs.python.org/3/library/fnmatch.html patterns that ignore case and match the full {connector} {action} {entity} tool name: python from pydantic ai harness.stackone import StackOne StackOne account id='your-linked-account-id', actions= ' list ' All matching list tools StackOne account id='your-linked-account-id', actions= 'workday get worker' One exact tool Passing actions selects individual mode for you. Combining it with an explicit tool mode='search execute' raises an error, because that mode only ever registers the search and execute tools. One thing to be clear about: actions is a context-management tool, not an access control. StackOne controls which actions are enabled for the linked account, and that configuration is the real boundary. Treat the pattern list as a way to shape what the model sees, and the StackOne dashboard as the place where permissions live. If you want the tools kept out of context entirely until the agent needs them, defer the load: python from pydantic ai harness.stackone import StackOne StackOne account id='your-linked-account-id', defer loading=True The capability uses id='stackone' by default so it can be loaded on demand. Give each instance a distinct id when one agent manages more than one linked account. Before you let it write Two settings matter as soon as the agent does more than read. Provider actions can return large exports, and a full employee list will happily eat a context window. ToolOutputLimits bounds oversized returns agent-wide, and composes with StackOne like any other capability: python import logfire from pydantic ai import Agent from pydantic ai harness.stackone import StackOne from pydantic ai harness.tool output limits import ToolOutputLimits logfire.configure logfire.instrument pydantic ai agent = Agent 'openai:gpt-5', capabilities= StackOne account id='your-linked-account-id' , ToolOutputLimits , , Approval is not enabled automatically, and it should be your default for anything that mutates a system of record. Use the public StackOneToolset with Pydantic AI's tool approval https://pydantic.dev/docs/ai/tools-toolsets/toolsets/ requiring-tool-approval : python import os import logfire from pydantic ai import Agent from pydantic ai harness.stackone import StackOneToolset logfire.configure logfire.instrument pydantic ai stackone tools = StackOneToolset account id=os.environ 'STACKONE ACCOUNT ID' , actions= 'workday create employee' , .approval required agent = Agent 'openai:gpt-5', toolsets= stackone tools That returns deferred approval requests for your application to resolve, so a human sits between the model and the write. StackOneToolset is the lower-level entry point in general: reach for it when you need Agent toolsets= ... or another toolset wrapper rather than the capability's defaults. Defining it in YAML The capability works with Pydantic AI's agent spec https://pydantic.dev/docs/ai/core-concepts/agent-spec/ format, so the configuration can live outside the code. Keep the key in STACKONE API KEY rather than in the file: agent.yaml model: openai:gpt-5 capabilities: - StackOne: account id: 'your-linked-account-id' actions: ' list ' python import logfire from pydantic ai import Agent from pydantic ai harness.stackone import StackOne logfire.configure logfire.instrument pydantic ai agent = Agent.from file 'agent.yaml', custom capability types= StackOne Pass custom capability types so the spec loader knows how to instantiate StackOne . Why this pairing works Pydantic AI brings the parts that make an agent debuggable: typed tool definitions, validated outputs, and tracing through Pydantic Logfire https://pydantic.dev/logfire . StackOne brings the connector surface, so the agent's business logic is not buried in HTTP plumbing per vendor. The combination matters most in the failure cases. When an agent picks the wrong action, or a provider returns a payload shaped differently than last week, a trace shows you which action ID was searched, what was executed, and what came back. A few caveats worth reading before you ship: - Harness uses 0.x versioning, so the API may change between releases. Breaking changes ship with a deprecation warning where that is practical. - Custom base url and URL-valued client values must use HTTPS. - For URL values, the toolset appends the tool-mode query parameter when it is absent for the search execute path. It raises an error when a URL's tool-mode conflicts with the configured mode, because rewriting it would invalidate a signed URL. If you use search execute with a signed URL, include tool-mode=search execute before signing. - Prebuilt clients are used as-is, so configure their transport, auth, account selection, and tool mode yourself. Try it Link an account in StackOne https://docs.stackone.com/guides/introduction?utm source=pydantic&utm medium=referral&utm campaign=pydantic-harness-launch&utm content=pydantic-docs-get-started , export the two environment variables, and add StackOne account id=... to an agent's capabilities. Then: - The StackOne capability docs https://pydantic.dev/docs/ai/harness/stackone/ carry the full API reference for StackOne and StackOneToolset . - The Harness overview https://pydantic.dev/docs/ai/harness/overview/ lists the other capabilities you can compose with it, including memory, planning, and guardrails. - All examples call logfire.configure . That is Pydantic Logfire https://pydantic.dev/logfire , and it turns each run into a trace you can open: tool searches, action calls, retries, and token costs, queryable with SQL. Try Logfire /logfire 's MCP Server https://pydantic.dev/docs/logfire/guides/mcp-server/ for debugging. - The Pydantic AI integration docs https://pydantic.dev/docs/logfire/integrations/llms/pydanticai/ cover the setup for other parts of your application. Pydantic Evals https://pydantic.dev/docs/ai/evals/evals/ is what you want once the agent is choosing between actions on its own, so a prompt change that improves one workflow does not quietly break another. Together, these are pieces of the Pydantic Stack https://pydantic.dev/ .