# Agents API

The Agents API provides methods to interact with Mastra AI agents, including generating responses, streaming interactions, and managing agent tools.

## Getting all agents

Retrieve a list of all available agents:

```typescript
const agents = await mastraClient.listAgents()
```

Returns a record of agent IDs to their serialized agent configurations.

## Working with a specific agent

Get an instance of a specific agent by its ID:

```typescript
export const myAgent = new Agent({
  id: 'my-agent',
})
```

```typescript
const agent = mastraClient.getAgent('my-agent')
```

## Agent methods

### `details()`

Retrieve detailed information about an agent:

```typescript
const details = await agent.details()
```

### `generate()`

Generate a response from the agent:

```typescript
const response = await agent.generate(
  [
    {
      role: 'user',
      content: 'Hello, how are you?',
    },
  ],
  {
    memory: {
      thread: 'thread-abc', // Optional: Thread ID for conversation context
      resource: 'user-123', // Optional: Resource ID
    },
    structuredOutput: {}, // Optional: Structured Output configuration
  },
)
```

You can also use the simplified string format with memory options:

```typescript
const response = await agent.generate('Hello, how are you?', {
  memory: {
    thread: 'thread-1',
    resource: 'resource-1',
  },
})
```

### `stream()`

Stream responses from the agent for real-time interactions:

```typescript
const response = await agent.stream('Tell me a story')

// Process data stream with the processDataStream util
response.processDataStream({
  onChunk: async chunk => {
    console.log(chunk)
  },
})
```

You can also use the simplified string format with memory options:

```typescript
const response = await agent.stream('Tell me a story', {
  memory: {
    thread: 'thread-1',
    resource: 'resource-1',
  },
  clientTools: { colorChangeTool },
})

response.processDataStream({
  onChunk: async chunk => {
    if (chunk.type === 'text-delta') {
      console.log(chunk.payload.text)
    }
  },
})
```

You can also read from response body directly:

```typescript
const reader = response.body.getReader()
while (true) {
  const { done, value } = await reader.read()
  if (done) break
  console.log(new TextDecoder().decode(value))
}
```

#### AI SDK compatible format

To stream AI SDK-formatted parts on the client from an `agent.stream(...)` response, wrap `response.processDataStream` into a `ReadableStream<ChunkType>` and use `toAISdkStream`:

```typescript
import { createUIMessageStream } from 'ai'
import { toAISdkStream } from '@mastra/ai-sdk'
import type { ChunkType, MastraModelOutput } from '@mastra/core/stream'

const response = await agent.stream('Tell me a story')

const chunkStream: ReadableStream<ChunkType> = new ReadableStream<ChunkType>({
  start(controller) {
    response
      .processDataStream({
        onChunk: async chunk => controller.enqueue(chunk as ChunkType),
      })
      .finally(() => controller.close())
  },
})

const uiMessageStream = createUIMessageStream({
  execute: async ({ writer }) => {
    for await (const part of toAISdkStream(chunkStream as unknown as MastraModelOutput, {
      from: 'agent',
    })) {
      writer.write(part)
    }
  },
})

for await (const part of uiMessageStream) {
  console.log(part)
}
```

### `getTool()`

Retrieve information about a specific tool available to the agent:

```typescript
const tool = await agent.getTool('tool-id')
```

### `executeTool()`

Execute a specific tool for the agent:

```typescript
const result = await agent.executeTool('tool-id', {
  data: { input: 'value' },
})
```

### `network()`

Stream responses from an agent network for multi-agent interactions:

```typescript
const response = await agent.network('Research this topic and write a summary')

response.processDataStream({
  onChunk: async chunk => {
    console.log(chunk)
  },
})
```

### `approveToolCall()`

Approve a pending tool call that requires human confirmation:

```typescript
const response = await agent.approveToolCall({
  runId: 'run-123',
  toolCallId: 'tool-call-456',
})

response.processDataStream({
  onChunk: async chunk => {
    console.log(chunk)
  },
})
```

### `declineToolCall()`

Decline a pending tool call that requires human confirmation:

```typescript
const response = await agent.declineToolCall({
  runId: 'run-123',
  toolCallId: 'tool-call-456',
})

response.processDataStream({
  onChunk: async chunk => {
    console.log(chunk)
  },
})
```

### `approveToolCallGenerate()`

Approve a pending tool call when using `generate()` (non-streaming). Returns the complete response:

```typescript
const output = await agent.generate('Find user John', {
  requireToolApproval: true,
})

if (output.finishReason === 'suspended') {
  const result = await agent.approveToolCallGenerate({
    runId: output.runId,
    toolCallId: output.suspendPayload.toolCallId,
  })

  console.log(result.text)
}
```

### `declineToolCallGenerate()`

Decline a pending tool call when using `generate()` (non-streaming). Returns the complete response:

```typescript
const output = await agent.generate('Find user John', {
  requireToolApproval: true,
})

if (output.finishReason === 'suspended') {
  const result = await agent.declineToolCallGenerate({
    runId: output.runId,
    toolCallId: output.suspendPayload.toolCallId,
  })

  console.log(result.text)
}
```

## Client tools

Client-side tools allow you to execute custom functions on the client side when the agent requests them.

```typescript
import { createTool } from '@mastra/client-js'
import { z } from 'zod'

const colorChangeTool = createTool({
  id: 'changeColor',
  description: 'Changes the background color',
  inputSchema: z.object({
    color: z.string(),
  }),
  execute: async inputData => {
    document.body.style.backgroundColor = inputData.color
    return { success: true }
  },
})

// Use with generate
const response = await agent.generate('Change the background to blue', {
  clientTools: { colorChangeTool },
})

// Use with stream
const response = await agent.stream('Tell me a story', {
  memory: {
    thread: 'thread-1',
    resource: 'resource-1',
  },
  clientTools: { colorChangeTool },
})

response.processDataStream({
  onChunk: async chunk => {
    if (chunk.type === 'text-delta') {
      console.log(chunk.payload.text)
    } else if (chunk.type === 'tool-call') {
      console.log(
        `calling tool ${chunk.payload.toolName} with args ${JSON.stringify(
          chunk.payload.args,
          null,
          2,
        )}`,
      )
    }
  },
})
```

## Stored agents

Stored agents are agent configurations stored in a database that can be created, updated, and deleted at runtime. They reference primitives (tools, workflows, other agents, scorers) by key, which are resolved from the Mastra registry when the agent is instantiated. Memory is configured inline as a `SerializedMemoryConfig` object with options such as `lastMessages` and `semanticRecall`.

### `listStoredAgents()`

Retrieve a paginated list of all stored agents:

```typescript
const result = await mastraClient.listStoredAgents()
console.log(result.agents) // Array of stored agents
console.log(result.total) // Total count
```

With pagination and ordering:

```typescript
const result = await mastraClient.listStoredAgents({
  page: 0,
  perPage: 20,
  orderBy: {
    field: 'createdAt',
    direction: 'DESC',
  },
})
```

### `createStoredAgent()`

Create a new stored agent:

```typescript
const agent = await mastraClient.createStoredAgent({
  id: 'my-agent',
  name: 'My Assistant',
  instructions: 'You are a helpful assistant.',
  model: {
    provider: 'openai',
    name: 'gpt-5.4',
  },
})
```

With all options:

```typescript
const agent = await mastraClient.createStoredAgent({
  id: 'full-agent',
  name: 'Full Agent',
  description: 'A fully configured agent',
  instructions: 'You are a helpful assistant.',
  model: {
    provider: 'openai',
    name: 'gpt-5.4',
  },
  tools: { calculator: {}, weather: {} },
  workflows: { 'data-processing': {} },
  agents: { 'subagent-1': {} },
  memory: {
    options: {
      lastMessages: 20,
      semanticRecall: false,
    },
  },
  scorers: {
    'quality-scorer': {
      sampling: { type: 'ratio', rate: 0.1 },
    },
  },
  defaultOptions: {
    maxSteps: 10,
  },
  metadata: {
    version: '1.0',
    team: 'engineering',
  },
})
```

### `getStoredAgent()`

Get an instance of a specific stored agent:

```typescript
const storedAgent = mastraClient.getStoredAgent('my-agent')
```

## Stored agent methods

### `details()`

Retrieve the stored agent configuration:

```typescript
const details = await storedAgent.details()
console.log(details.name)
console.log(details.instructions)
console.log(details.model)
```

### `update()`

Update specific fields of a stored agent. All fields are optional:

```typescript
const updated = await storedAgent.update({
  name: 'Updated Agent Name',
  instructions: 'New instructions for the agent.',
})
```

```typescript
// Update just the tools
await storedAgent.update({
  tools: { 'new-tool-1': {}, 'new-tool-2': {} },
})

// Update metadata
await storedAgent.update({
  metadata: {
    version: '2.0',
    lastModifiedBy: 'admin',
  },
})
```

### `delete()`

Delete a stored agent:

```typescript
const result = await storedAgent.delete()
console.log(result.success) // true
```

## Version management

Both `Agent` (code-defined) and `StoredAgent` instances have methods for managing configuration versions. See the [Editor overview](https://mastra.ai/docs/editor/overview) for an introduction to version management.

### Getting an agent with a specific version

Pass a version identifier when getting an agent:

```typescript
// Load the published version (default)
const agent = mastraClient.getAgent('support-agent')

// Load the latest draft
const draftAgent = mastraClient.getAgent('support-agent', { status: 'draft' })

// Load a specific version
const versionedAgent = mastraClient.getAgent('support-agent', { versionId: 'abc-123' })
```

For stored agents, pass a status option to `details()`:

```typescript
const storedAgent = mastraClient.getStoredAgent('my-agent')
const draft = await storedAgent.details(undefined, { status: 'draft' })
```

### `listVersions()`

List all versions for an agent:

```typescript
const versions = await agent.listVersions()
console.log(versions.items) // Array of version snapshots
console.log(versions.total)
```

With pagination and sorting:

```typescript
const versions = await agent.listVersions({
  page: 0,
  perPage: 10,
  orderBy: {
    field: 'createdAt',
    direction: 'DESC',
  },
})
```

### `createVersion()`

Create a new version snapshot:

```typescript
const version = await agent.createVersion({
  changeMessage: 'Updated tone to be more friendly',
})
```

### `getVersion()`

Get a specific version by ID:

```typescript
const version = await agent.getVersion('version-123')
console.log(version.versionNumber)
console.log(version.changedFields)
console.log(version.createdAt)
```

### `activateVersion()`

Set a version as the active published version:

```typescript
await agent.activateVersion('version-123')
```

### `restoreVersion()`

Restore a previous version by creating a new version with the same configuration:

```typescript
await agent.restoreVersion('version-456')
```

### `deleteVersion()`

Delete a version:

```typescript
await agent.deleteVersion('version-789')
```

### `compareVersions()`

Compare two versions and return their differences:

```typescript
const diff = await agent.compareVersions('version-123', 'version-456')
console.log(diff.changes) // Fields that changed between versions
```

### React SDK

In the React SDK, pass an `agentVersionId` through `requestContext` when using the `useChat` hook:

```typescript
import { useChat } from '@mastra/react'

function Chat() {
  const { messages, input, handleInputChange, handleSubmit } = useChat({
    agentId: 'support-agent',
    requestContext: {
      agentVersionId: 'abc-123',
    },
  })

  // ... render chat UI
}
```