Skip to main content
An agent decides what to do at runtime. To give it reliable capabilities, you attach actions as tools. Each action becomes a tool the model can call with a typed argument, and Keystroke validates the input, runs the action, and returns the result to the agent.

Attach an action as a tool

Pass action definitions in the tools array of defineAgent(). The same action you’d use as a workflow step works here, unchanged.
src/agents/support.ts
import { defineAgent } from "@keystrokehq/keystroke/agent";
import { triage } from "../actions/triage";

export default defineAgent({
  slug: "support",
  systemPrompt: "Help customers. Use the triage tool to classify incoming messages.",
  model: "anthropic/claude-sonnet-4.6",
  tools: [triage],
});
When the agent calls the tool, Keystroke parses the model’s arguments against the action’s input schema, runs run, and returns the output as the tool result.

How an action maps to a tool

The action’s metadata becomes the tool the model sees:
Tool fieldComes from
NameThe action slug
Labelname, falling back to slug
Descriptiondescription, falling back to name, then slug
ParametersThe action input Zod schema
Because the model reads description to decide when to call a tool, give tool actions a clear, action-oriented description. The output schema shapes what the agent gets back.

Design tool actions for the model

A tool action is read by the model, so write it for that audience:
  • Write a clear description. The model uses it to decide when to call the tool. Say what it does and when to reach for it, in plain language.
  • Describe each input field. Add .describe() to the fields in the input schema. The schema becomes the tool’s parameters, so the descriptions tell the model what each argument means.
  • Keep the output lean. The action’s output is serialized to JSON and returned to the model as the tool result, so it counts against the context window. Return the fields the agent needs to act on, not entire upstream payloads.
src/actions/lookup-customer.ts
export const lookupCustomer = defineAction({
  slug: "lookup-customer",
  description: "Look up a customer by email. Use before answering billing questions.",
  input: z.object({
    email: z.string().email().describe("The customer's email address"),
  }),
  output: z.object({
    plan: z.enum(["free", "pro", "enterprise"]),
    openInvoices: z.number(),
  }),
  run: async (input) => lookup(input.email),
});

Use integration actions as tools

Integration packages export actions you can attach directly; you don’t redefine them. Import only the ones the agent should have.
import { defineAgent } from "@keystrokehq/keystroke/agent";
import { slackSendMessage, listMessages } from "@keystrokehq/slack/actions";

export default defineAgent({
  slug: "support",
  systemPrompt: "Answer questions and post replies to Slack when asked.",
  model: "anthropic/claude-sonnet-4.6",
  tools: [listMessages, slackSendMessage],
});
Browse the full catalog of integrations for the actions each one provides.

Credentials for tool actions

When an action declares credentials, Keystroke resolves them before the tool runs; the agent never sees the secret. If an action can resolve credentials at more than one scope (organization, project, or user), pin the scope with .scope() when attaching it:
export default defineAgent({
  slug: "support",
  systemPrompt: "Post replies to Slack on behalf of the requesting user.",
  model: "anthropic/claude-sonnet-4.6",
  tools: [slackSendMessage.scope("user")],
});
Without an explicit scope, the resolver tries the project default, then the organization default. See credentials for how scopes and connections work.

Beyond actions

Actions are the usual way to give an agent reliable capabilities, but tools also accepts other tool types: MCP tools, subagents, and workflows — import them directly into tools (no wrappers). See build agents for subagents and workflows as tools.

Next steps

Actions as workflow steps

Run the same actions as durable steps in a workflow.

Build agents

Configure tools, models, skills, files, and more.

Credentials

Declare and scope the credentials a tool action needs.

Integrations

Browse built-in integration actions to attach as tools.