# How to Use the SAM AI Agent for SEO Tasks in Open SEO

> Unlock powerful SEO with the SAM AI agent in Open SEO. Research keywords, analyze SERPs, audit backlinks, and maintain project memory for efficient SEO task management.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: how-to-guide
- Published: 2026-08-17

---

**The SAM AI agent in Open SEO is a stateful, credit-metered LLM that runs inside a Cloudflare Durable Object, streams responses through a Think-based chat loop, and can research keywords, analyze SERPs, audit backlinks, and persist project memory across sessions.**

The SAM (Search-Assistant Machine) agent is the built-in SEO assistant inside the `every-app/open-seo` repository, and this guide covers how to use the SAM AI agent for SEO tasks ranging from keyword research to backlink audits. It combines an LLM hosted in a `SamChatAgent` Durable Object with a Think-based chat loop, MCP tool integrations, and project-scoped memory blocks to automate complex workflows. By connecting to the agent through TanStack server functions and the Think client, developers can stream conversational responses while SAM automatically invokes paid data-provider tools and tracks usage against your credit balance.

## Architecture and Key Components

SAM is not a simple chat wrapper. It is a tightly integrated agent defined in [`src/server/features/sam/SamChatAgent.ts`](https://github.com/every-app/open-seo/blob/main/src/server/features/sam/SamChatAgent.ts) that wires together model selection, billing, tool calling, and durable memory.

### SamChatAgent Durable Object

The `SamChatAgent` class is a Cloudflare Durable Object that hosts a single chat session. It implements the Think-based chat loop, streams responses back to the client, and isolates state per project. The class definition lives in [`src/server/features/sam/SamChatAgent.ts`](https://github.com/every-app/open-seo/blob/main/src/server/features/sam/SamChatAgent.ts) at lines 84-90.

### System Prompt and Identity

SAM’s personality, tone, and tool-use policy are defined by a read-only “soul” block generated by `buildSamSystemPrompt` in [`src/server/features/sam/samSystemPrompt.ts`](https://github.com/every-app/open-seo/blob/main/src/server/features/sam/samSystemPrompt.ts). This system prompt governs how SAM interprets requests and selects SEO tools.

### Project Memory Blocks

SAM persists knowledge across sessions through two writable context blocks managed by `projectBlockProvider`:

- **`memory`** – durable project facts that accumulate over time.
- **`research_log`** – dated one-line logs that track what has been researched.

These blocks are stored in `sam_project_memory` rows via `SamProjectMemoryRepository`, referenced in [`SamChatAgent.ts`](https://github.com/every-app/open-seo/blob/main/SamChatAgent.ts) at lines 95-118. Because they are project-scoped, all sessions for the same project share the same memory.

### MCP Toolset and Credit Metering

Before each turn, `beforeTurn` loads the session and checks the organization’s credit balance using `checkUsageCreditsDepleted` (lines 41-60 in [`SamChatAgent.ts`](https://github.com/every-app/open-seo/blob/main/SamChatAgent.ts)). If credits are depleted, SAM returns a refusal turn. When credits are available, SAM builds its toolset through `buildSamMcpTools` (lines 75-82) and exposes data-provider utilities such as keyword research, site reading, and backlink analysis. The underlying LLM is retrieved via `getModel()`, which reads the `OPENROUTER_API_KEY` environment variable and delegates to `buildChatAgentModel` in [`src/server/lib/openrouter.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/openrouter.ts). Token costs are recorded on each step via `onStepFinish` and `openRouterCostUsd` (lines 90-92).

## Session Lifecycle

A complete SAM interaction follows six discrete steps:

1. **Create** – The client calls `createSamSession`, which inserts a row into the `sam_sessions` table (defined in [`src/db/sam.schema.ts`](https://github.com/every-app/open-seo/blob/main/src/db/sam.schema.ts)) and returns a UUID that becomes the Durable Object name.
2. **Connect** – The front-end uses `useAgent({ name: sessionId })` from the Think client to open a WebSocket to the Durable Object.
3. **First turn** – `beforeTurn` loads the session, verifies credits, builds the MCP toolset, and injects the system prompt via `buildSoulPrompt`.
4. **User message** – SAM receives the message and may autonomously call tools such as `read_pages` or `keyword_research`. Each tool call is metered against your balance.
5. **Response** – SAM streams the response. `onChatResponse` logs turn cost, derives the session title from the first user message, and refreshes the system prompt so other sessions see updated memory.
6. **Archive** – Calling `archiveSamSession` marks the row archived in `sam_sessions`. The Durable Object retains the transcript, but the UI hides the session.

## Practical Implementation Examples

### Create a Session and Connect via the Think Client

In a TanStack React Start application, you create a session with the server function and connect using the Think client:

```tsx
import { createServerFn } from '@tanstack/react-start'
import { useAgent } from 'agents/chat'

// Create a new chat session
const createSamSession = createServerFn({
  method: 'POST',
  url: '/api/create-sam-session',
})

// Call it from your UI
async function startChat(projectId: string) {
  const { id } = await createSamSession({ projectId })
  // Connect the Think client to the Durable Object
  const agent = useAgent({ name: id })
  return agent
}

// Send a message
async function askKeywords(agent, question: string) {
  const { messages } = await agent.sendMessage({ role: 'user', content: question })
  console.log(messages) // streamed response from SAM
}

```

### Invoke SEO Tools Through Natural Language

You do not call tools manually. SAM decides when to invoke them based on its system prompt and the user’s request. For example, asking SAM to read pages triggers the built-in `read_pages` tool automatically:

```ts
const userPrompt = `Read the homepage and pricing page of the site and tell me what the main product is.`

```

The tool definition lives inside `buildSamMcpTools` in [`src/server/features/sam/samChatTools.ts`](https://github.com/every-app/open-seo/blob/main/src/server/features/sam/samChatTools.ts). The Think client routes the call to the back-end and returns the synthesized answer.

### Access Persistent Project Memory

After SAM has gathered facts, you can retrieve the `memory` block programmatically via `SamProjectMemoryRepository`:

```ts
import { SamProjectMemoryRepository } from '@/server/features/sam/SamProjectMemoryRepository'

async function getMemory(projectId: string) {
  const mem = await SamProjectMemoryRepository.getBlock(projectId, 'memory')
  console.log('Current project memory:', mem)
}

```

### Archive a Chat Session

To clean up the UI without destroying the Durable Object transcript, call the archive server function:

```ts
import { archiveSamSession } from '@/serverFunctions/sam'

async function archive(sessionId: string) {
  await archiveSamSession({ sessionId })
}

```

## Core Source Files

The following files contain the full implementation details for extending or debugging the agent:

- **[`src/server/features/sam/SamChatAgent.ts`](https://github.com/every-app/open-seo/blob/main/src/server/features/sam/SamChatAgent.ts)** – Durable Object that implements the chat loop, model selection, billing, and memory handling.
- **[`src/server/features/sam/samSystemPrompt.ts`](https://github.com/every-app/open-seo/blob/main/src/server/features/sam/samSystemPrompt.ts)** – Generates the read-only “soul” system prompt that defines SAM’s identity, tone, and tool-use policy.
- **[`src/serverFunctions/sam.ts`](https://github.com/every-app/open-seo/blob/main/src/serverFunctions/sam.ts)** – TanStack server-function endpoints for creating, listing (`listSamSessions`), and archiving SAM chat sessions.
- **[`src/server/lib/openrouter.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/openrouter.ts)** – Helper that builds the OpenRouter model used by SAM (`buildChatAgentModel`).
- **[`src/db/sam.schema.ts`](https://github.com/every-app/open-seo/blob/main/src/db/sam.schema.ts)** – Database schema defining the `sam_sessions` table and `sam_project_memory` rows.
- **[`src/server/features/sam/samChatTools.ts`](https://github.com/every-app/open-seo/blob/main/src/server/features/sam/samChatTools.ts)** – Constructs the full MCP toolset that SAM can invoke.

## Summary

- SAM is a Durable Object-backed LLM agent inside `every-app/open-seo` designed specifically for SEO workflows.
- It uses `SamChatAgent` to manage stateful chat sessions with project-scoped memory (`memory` and `research_log`).
- SEO tools are exposed through an MCP toolset in `buildSamMcpTools` and invoked autonomously by SAM based on natural language prompts.
- Every turn is gated by a credit check (`checkUsageCreditsDepleted`) and costs are recorded via `openRouterCostUsd`.
- Client code creates sessions with `createSamSession`, connects via `useAgent`, and archives with `archiveSamSession`.

## Frequently Asked Questions

### What SEO tasks can the SAM AI agent perform?

SAM can research keywords, analyze domains and competitors, inspect SERPs, review backlink profiles, read rank-tracking data, and query Google Search Console. It runs these operations through integrated data-provider tools that are automatically metered against your account credits.

### How does SAM remember context across multiple chat sessions?

SAM persists project-wide memory through two durable blocks managed by `SamProjectMemoryRepository`: a `memory` block for accumulated facts and a `research_log` block for dated activity lines. These are stored in `sam_project_memory` and shared across all sessions for the same project.

### How are tool usage and credits managed?

Before each turn, `beforeTurn` in [`SamChatAgent.ts`](https://github.com/every-app/open-seo/blob/main/SamChatAgent.ts) calls `checkUsageCreditsDepleted`. If your organization has insufficient credits, SAM returns a refusal. Otherwise, each tool invocation and model step is billed via `onStepFinish` using `openRouterCostUsd` to track spend against your balance.

### Can I extend SAM with custom SEO tools?

Yes. The MCP toolset is built in [`src/server/features/sam/samChatTools.ts`](https://github.com/every-app/open-seo/blob/main/src/server/features/sam/samChatTools.ts) by `buildSamMcpTools` and injected into the agent in [`SamChatAgent.ts`](https://github.com/every-app/open-seo/blob/main/SamChatAgent.ts). You can modify the tool definitions and the system prompt in [`samSystemPrompt.ts`](https://github.com/every-app/open-seo/blob/main/samSystemPrompt.ts) to teach SAM new capabilities or change how it uses existing ones.