> ## Documentation Index
> Fetch the complete documentation index at: https://smithers.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrations

> Three patterns for connecting Smithers to external services.

Smithers ships first-party event sources for GitHub, Linear, and Telegram (`@smthrs/integrations`) that turn provider webhooks into durable workflow signals. For other services (Notion, Slack, etc.), your app owns the integration: pick tools on an SDK agent, skills/plugins/MCP on a CLI agent, or an external CLI run inside a task. If the service already exposes an MCP server and you're using an SDK agent, [MCP Toolset](/integrations/mcp-toolset) turns that server into AI SDK tools.

## Pattern 1: Pass tools to an SDK agent

Use this when the agent needs judgment but the external calls should stay explicit and reviewable.

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { ToolLoopAgent as Agent, tool, zodSchema } from "ai";
import { anthropic } from "@ai-sdk/anthropic";
import { z } from "zod";

const linearGetIssue = tool({
  description: "Fetch a Linear issue",
  inputSchema: zodSchema(z.object({ id: z.string() })),
  execute: async ({ id }) => linearClient.getIssue(id),
});

const opsAgent = new Agent({
  model: anthropic("claude-fable-5"),
  tools: { linearGetIssue },
});
```

## Pattern 2: Pass a skill / plugin / MCP config to a CLI agent

Use this when your CLI agent already supports external integrations and Smithers should only orchestrate the task.

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { PiAgent } from "smthrs";

const pi = new PiAgent({
  provider: "openai",
  model: "gpt-5.6-sol",
  skill: ["./skills/linear", "./skills/notion"],
});
```

```tsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
<Task id="ticket-review" output={outputs.review} agent={pi}>
  {`Use the Linear skill to inspect ${ctx.input.issueId}, then summarize next actions.`}
</Task>
```

## Pattern 3: Run an external CLI in a task

Use this when the step is deterministic and you do not need the model involved.

```tsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
<Task id="load-linear" output={outputs.linearIssue}>
  {async () => {
    const proc = Bun.spawn(["linear", "issue", "view", ctx.input.issueId, "--json"], {
      stdout: "pipe",
      stderr: "pipe",
    });
    const stdout = await new Response(proc.stdout).text();
    const stderr = await new Response(proc.stderr).text();
    if (await proc.exited !== 0) throw new Error(stderr || stdout);
    return JSON.parse(stdout);
  }}
</Task>
```

## Choosing between them

| If you need                                           | Prefer                                  |
| ----------------------------------------------------- | --------------------------------------- |
| AI judgment over a small integration surface          | Pattern 1 (SDK agent with narrow tools) |
| Existing CLI ecosystem support (skills, plugins, MCP) | Pattern 2 (CLI agent)                   |
| Deterministic sync or publish steps                   | Pattern 3 (compute task)                |

## See also

React hook patterns: [/recipes#custom-hooks-over-ctx](/recipes#custom-hooks-over-ctx). Agent-class details: [SDK agents](/integrations/sdk-agents), [MCP Toolset](/integrations/mcp-toolset), [CLI agents](/integrations/cli-agents). To wire Smithers *into* your coding agent so it can drive workflows, see [Agent Support](/agents/overview).
