# Amp TypeScript SDK

Use the Amp SDK to programmatically deploy the Amp agent anywhere you run TypeScript. Execute Amp CLI commands programmatically with full type safety, streaming responses, and complete control over your AI coding agent workflows.

## Why use the Amp SDK?

The Amp TypeScript SDK brings the Amp agent directly into your applications with simple, reliable functionality:

- **Stream Inputs**: Send prompts and messages incrementally to the Amp agent
- **Stream Outputs**: Receive structured JSON responses (system, assistant, result) as the agent executes tasks
- **Multi-turn Conversations**: Maintain back-and-forth interactions across multiple executions
- **Thread Continuity**: Continue an existing thread (latest or by ID) to build stateful agent workflows
- **Programmatic Settings**: Configure working directories, settings, and tools without user prompts — ideal for automation
- **MCP Integration**: Extend Amp with custom Model Context Protocol servers and tools
- **Custom Skills**: Define and use custom agent skills to extend Amp's functionality

## What can you build?

The Amp SDK enables a wide range of AI-powered applications:

### Development Tools

- **Code Review Agent**: Automated pull request analysis and feedback
- **Documentation Generator**: Create and maintain project documentation
- **Test Automation**: Generate and execute test suites
- **Migration Assistant**: Help upgrade codebases and refactor legacy code

### Workflow Automation

- **CI/CD Integration**: Smart build and deployment pipelines
- **Issue Triage**: Automatically categorize and prioritize bug reports
- **Code Quality Monitoring**: Continuous analysis of code health metrics
- **Release Management**: Automated changelog generation and version bumping

## Quick Start

### Installation

```bash
# Install the Amp SDK using npm
npm install @ampcode/sdk

# or yarn
yarn add @ampcode/sdk

# Optional: manually install the Amp CLI, already a dependency
npx -y @ampcode/sdk install
```

If you need to use Amp before Amp Neo, install the legacy SDK release
[`@ampcode/sdk@0.1.0-20260528044221-ge0e19fa`](https://www.npmjs.com/package/@ampcode/sdk/v/0.1.0-20260528044221-ge0e19fa):

```bash
npm install @ampcode/sdk@0.1.0-20260528044221-ge0e19fa
```

The SDK requires an Amp CLI version that is at least the version pinned by your SDK release. If your
organization installs Amp CLI through Homebrew, Artifactory, or another internal distribution channel,
you can keep using that installation as long as its version is new enough.

Once installed, add your API key to the environment. You can access your API key in
[Security Settings](https://ampcode.com/settings/security#access-token).

```bash
export AMP_API_KEY=sgamp_your_api_key_here
```

### Your First Amp Command

Now that you have the SDK installed and your API key set up, you can start using Amp with the `execute()` function:

```typescript
import { execute } from '@ampcode/sdk'

// Simple execution - get the final result
for await (const message of execute({ prompt: 'What files are in this directory?' })) {
	if (message.type === 'result' && !message.is_error) {
		console.log('Result:', message.result)
		break
	}
}
```

The `execute()` function only requires that you provide a `prompt` to get started. The SDK streams messages as the agent works, letting you handle responses and integrate them directly into your application.

## Core Concepts

### Message Streaming

The SDK streams different types of messages as your agent executes:

```typescript
for await (const message of execute({ prompt: 'Run tests' })) {
	if (message.type === 'system') {
		// Session info, available tools, MCP servers
		console.log('Available tools:', message.tools)
	} else if (message.type === 'assistant') {
		// AI responses and tool usage
		console.log('Assistant is working...')
	} else if (message.type === 'result') {
		// Final result (success or error)
		console.log('Done:', message.result)
	}
}
```

### Simple Result Extraction

When you just need the final result without handling streaming:

```typescript
async function getResult(prompt: string): Promise<string> {
	for await (const message of execute({ prompt, options: { dangerouslyAllowAll: true } })) {
		if (message.type === 'result') {
			if (message.is_error) {
				throw new Error(message.error)
			}
			return message.result
		}
	}
	throw new Error('No result received')
}

// Usage
try {
	const result = await getResult('List all TypeScript files in this project')
	console.log('Found files:', result)
} catch (error) {
	console.error('Failed:', error.message)
}
```

### Thread Continuity

Continue conversations across multiple interactions:

```typescript
// Continue the most recent conversation
for await (const message of execute({
	prompt: 'What was the last error you found?',
	options: { continue: true },
})) {
	if (message.type === 'result') {
		console.log(message.result)
	}
}

// Continue a specific thread by ID
for await (const message of execute({
	prompt: 'Can you update that code we discussed?',
	options: { continue: 'T-abc123-def456' },
})) {
	if (message.type === 'result') {
		console.log(message.result)
	}
}
```

## Common Configuration

### Working Directory

Specify where Amp should run:

```typescript
for await (const message of execute({
	prompt: 'Refactor the auth module',
	options: { cwd: './my-project' },
})) {
	// Process messages...
}
```

### Enable Debug Logging

See what's happening under the hood:

```typescript
for await (const message of execute({
	prompt: 'Analyze this project',
	options: {
		logLevel: 'debug', // Shows CLI command in console
		logFile: './amp-debug.log', // Optional: write logs to file
	},
})) {
	// Process messages
}
```

### Agent Mode

Select which agent mode to use. The mode controls the model, system prompt, and tool selection:

```typescript
for await (const message of execute({
	prompt: 'Quickly fix this typo',
	options: {
		mode: 'low', // Use low mode for faster responses
	},
})) {
	// Process messages
}
```

Available modes:

- `low`: Fast, low-cost mode for small, well-defined tasks
- `medium` (default): Balanced intelligence, speed, and cost for most tasks
- `high`: Deep reasoning for hard tasks
- `ultra`: The most capable mode for hard, open-ended tasks

### Reasoning Effort

Set model reasoning effort for supported modes:

```typescript
for await (const message of execute({
	prompt: 'Think carefully and explain your plan before coding.',
	options: {
		mode: 'medium',
		effort: 'high',
	},
})) {
	if (message.type === 'result') {
		console.log(message.result)
		break
	}
}
```

Available effort levels:

- `none`
- `minimal`
- `low`
- `medium`
- `high`
- `xhigh`
- `max`

### Thread Labels

Add labels to threads created by `execute()`.

```typescript
for await (const message of execute({
	prompt: 'Summarize this repo',
	options: {
		labels: ['sdk', 'summary'],
	},
})) {
	if (message.type === 'result') {
		console.log(message.result)
		break
	}
}
```

### Thread Visibility

Control who can see threads created by `execute()`:

```typescript
for await (const message of execute({
	prompt: 'Analyze this private codebase',
	options: {
		visibility: 'private', // Only you can see this thread
	},
})) {
	if (message.type === 'result') {
		console.log(message.result)
		break
	}
}
```

Available visibility levels:

- `workspace` (default): Visible to all workspace members
- `private`: Only visible to you
- `unlisted`: Visible to anyone with the link
- `group`: Visible to members of your user group (Enterprise)

### Tool Permissions

Control which tools Amp can use with fine-grained permissions:

```typescript
import { execute, createPermission } from '@ampcode/sdk'

for await (const message of execute({
	prompt: 'List files and run tests',
	options: {
		permissions: [
			// Allow listing files
			createPermission('Bash', 'allow', { matches: { cmd: 'ls *' } }),
			// Allow running tests
			createPermission('Bash', 'allow', { matches: { cmd: 'npm test' } }),
			// Ask before reading sensitive files
			createPermission('Read', 'ask', { matches: { path: '/etc/*' } }),
		],
	},
})) {
	// Process messages
}
```

Permission rules support:

- **Pattern matching**: Use `*` wildcards and regex patterns
- **Context control**: Restrict rules to main thread or sub-agents
- **Delegation**: Delegate permission decisions to external programs

Learn more about permissions in the [manual](https://ampcode.com/manual#permissions) and the [appendix](https://ampcode.com/manual/appendix#permissions-reference).

## Advanced Usage

### Interactive Progress Tracking

For building user interfaces that show real-time progress:

```typescript
async function executeWithProgress(prompt: string) {
	console.log('Starting task...')

	for await (const message of execute({ prompt })) {
		if (message.type === 'system' && message.subtype === 'init') {
			console.log('Tools available:', message.tools.join(', '))
		} else if (message.type === 'assistant') {
			// Show tool usage or assistant responses
			const content = message.message.content[0]
			if (content.type === 'tool_use') {
				console.log(`Using ${content.name}...`)
			} else if (content.type === 'text') {
				console.log('Assistant:', content.text.slice(0, 100) + '...')
			}
		} else if (message.type === 'result') {
			if (message.is_error) {
				console.log('Failed:', message.error)
			} else {
				console.log('Completed successfully!')
				console.log(message.result)
			}
		}
	}
}
```

### Cancellation and Timeouts

Handle long-running operations gracefully:

```typescript
async function executeWithTimeout(prompt: string, timeoutMs = 30000) {
	const signal = AbortSignal.timeout(timeoutMs)

	try {
		for await (const message of execute({
			prompt,
			signal,
			options: { dangerouslyAllowAll: true },
		})) {
			if (message.type === 'result') {
				return message.result
			}
		}
	} catch (error) {
		if (error.message.includes('aborted')) {
			throw new Error(`Operation timed out after ${timeoutMs}ms`)
		}
		throw error
	}
}
```

### MCP (Model Context Protocol) Integration

Extend Amp's capabilities with custom tools and data sources:

```typescript
import { execute, type MCPConfig } from '@ampcode/sdk'

const mcpConfig: MCPConfig = {
	playwright: {
		command: 'npx',
		args: ['-y', '@playwright/mcp@latest', '--headless'],
		env: { NODE_ENV: 'production' },
	},
	database: {
		command: 'node',
		args: ['./custom-mcp-server.js'],
		env: { DB_CONNECTION_STRING: process.env.DATABASE_URL },
	},
}

for await (const message of execute({
	prompt: 'Test the login flow on staging environment',
	options: { mcpConfig, dangerouslyAllowAll: true },
})) {
	if (message.type === 'system') {
		console.log(
			'MCP Servers:',
			message.mcp_servers.map((s) => `${s.name}: ${s.status}`),
		)
	}
	// Handle other messages...
}
```

To find out more about extending Amp with MCP servers, visit the [MCP Configuration](https://ampcode.com/manual#mcp) section of the manual.

### Multi-turn Conversations

Build streaming conversations using async generators:

```typescript
import { execute, createUserMessage } from '@ampcode/sdk'

async function* generateMessages() {
	yield createUserMessage('Start analyzing the codebase')

	// Wait for some condition or user input
	await new Promise((resolve) => setTimeout(resolve, 1000))

	yield createUserMessage('Now focus on the authentication module')
}

for await (const message of execute({
	prompt: generateMessages(),
})) {
	if (message.type === 'result') {
		console.log(message.result)
	}
}
```

### Settings File Configuration

Configure Amp's behavior with a settings file, like the `settings.json`. You can provide Amp with a custom settings file you have saved in your project:

```typescript
import { execute } from '@ampcode/sdk'

// Use a custom settings file
for await (const message of execute({
	prompt: 'Deploy the application',
	options: {
		settingsFile: './settings.json',
		logLevel: 'debug',
	},
})) {
	// Handle messages...
}
```

Example `settings.json`:

```json
{
	"amp.mcpServers": {
		"playwright": {
			"command": "npx",
			"args": ["-y", "@playwright/mcp@latest", "--headless", "--isolated"]
		}
	},
	"amp.commands.allowlist": ["npx", "node", "npm"],
	"amp.tools.disable": ["web_search", "mcp__playwright__browser_resize"]
}
```

To find all available settings, see the [Configuration Settings](https://ampcode.com/manual#configuration).

### Custom Skills

Load custom skills from a specified directory:

```typescript
for await (const message of execute({
	prompt: 'Use my custom deployment skill',
	options: {
		skills: './my-skills', // Path to custom skills directory
	},
})) {
	// Process messages
}
```

To learn more about creating custom skills, see the [Agent Skills](https://ampcode.com/manual#agent-skills) section of the Amp documentation.

## Functions

### execute()

The main function for executing Amp CLI commands programmatically.

```typescript
function execute(options: ExecuteOptions): AsyncIterable<StreamMessage>
```

#### Parameters

- `options` ([`ExecuteOptions`](#executeoptions)) - Configuration for the execution

#### Returns

- `AsyncIterable<StreamMessage>` - Stream of messages from the Amp CLI

#### Example

```typescript
import { execute } from '@ampcode/sdk'

for await (const message of execute({
	prompt: 'Analyze this codebase',
	options: {
		cwd: './my-project',
		dangerouslyAllowAll: true,
	},
})) {
	if (message.type === 'assistant') {
		console.log('Assistant:', message.message.content)
	} else if (message.type === 'result') {
		console.log('Final result:', message.result)
		break
	}
}
```

### createUserMessage()

Helper function to create properly formatted user input messages for streaming conversations.

```typescript
function createUserMessage(text: string): UserInputMessage
```

#### Parameters

- `text` (`string`) - The text content for the user message

#### Returns

- [`UserInputMessage`](#userinputmessage) - A formatted user input message

#### Example

```typescript
import { createUserMessage } from '@ampcode/sdk'

const message = createUserMessage('Analyze this code')
console.log(message)
// Output: { type: 'user', message: { role: 'user', content: [{ type: 'text', text: 'Analyze this code' }] } }
```

### createPermission()

Helper function to create permission objects for controlling tool usage.

```typescript
function createPermission(
	tool: string,
	action: 'allow' | 'reject' | 'ask' | 'delegate',
	options?: {
		matches?: Record<string, PermissionMatchCondition>
		context?: 'thread' | 'subagent'
		to?: string
	},
): Permission
```

#### Parameters

- `tool` (`string`) - The name of the tool to which this permission applies (supports glob patterns)
- `action` (`'allow' | 'reject' | 'ask' | 'delegate'`) - How Amp should proceed when matched
- `options` (`object`, optional) - Additional configuration for the permission
  - `matches` ([`Record<string, PermissionMatchCondition>`](#permissionmatchcondition)) - Match conditions for tool arguments
  - `context` (`'thread' | 'subagent'`) - Only apply this rule in specific context
  - `to` (`string`) - Command to delegate to (required when action is `'delegate'`)

#### Returns

- [`Permission`](#permission) - A permission object that can be used in the permissions array

#### Examples

```typescript
import { createPermission } from '@ampcode/sdk'

// Allow all Bash commands
createPermission('Bash', 'allow')

// Allow specific git commands
createPermission('Bash', 'allow', {
	matches: { cmd: 'git *' },
})

// Ask before allowing Read operations on sensitive paths
createPermission('Read', 'ask', {
	matches: { path: '/etc/*' },
})

// Delegate web browsing to a custom command
createPermission('mcp__playwright__*', 'delegate', {
	to: 'node browse.js',
})

// Only apply in subagent context
createPermission('Bash', 'reject', {
	context: 'subagent',
})
```

### threads.new()

Create a new empty thread and return its ID.

```typescript
async function threads.new(options?: ThreadsNewOptions): Promise<string>
```

#### Parameters

- `options` ([`ThreadsNewOptions`](#threadsnewoptions), optional) - Configuration for the new thread

#### Returns

- `Promise<string>` - The thread ID

#### Example

```typescript
import { threads } from '@ampcode/sdk'

// Create a new private thread
const threadId = await threads.new({ visibility: 'private' })
console.log('Created thread:', threadId)
```

### threads.markdown()

Get a thread rendered as markdown.

```typescript
async function threads.markdown(options: ThreadsMarkdownOptions): Promise<string>
```

#### Parameters

- `options` ([`ThreadsMarkdownOptions`](#threadsmarkdownoptions)) - Options containing the thread ID

#### Returns

- `Promise<string>` - The thread content as markdown

#### Example

```typescript
import { threads } from '@ampcode/sdk'

// Get thread content as markdown
const markdown = await threads.markdown({ threadId: 'T-abc123-def456' })
console.log(markdown)
```

### threads.setMultiplayer()

Open or close a thread for contributions (multiplayer). Only works on orb threads with shared (non-private) visibility, and only for the thread owner.

```typescript
async function threads.setMultiplayer(options: ThreadsSetMultiplayerOptions): Promise<void>
```

#### Parameters

- `options` ([`ThreadsSetMultiplayerOptions`](#threadssetmultiplayeroptions)) - The thread ID, enabled flag, and optional open-window duration

#### Returns

- `Promise<void>`

#### Example

```typescript
import { threads } from '@ampcode/sdk'

// Open a thread for contributions for the default duration (currently 3 hours)
await threads.setMultiplayer({ threadId: 'T-abc123-def456' })

// Open a thread for contributions for 12 hours
await threads.setMultiplayer({ threadId: 'T-abc123-def456', hours: 12 })

// Close a thread for contributions
await threads.setMultiplayer({ threadId: 'T-abc123-def456', enabled: false })
```

## Types

### ExecuteOptions

Configuration options for the `execute()` function.

```typescript
interface ExecuteOptions {
	prompt: string | AsyncIterable<UserInputMessage>
	options?: AmpOptions
	signal?: AbortSignal
}
```

#### Properties

| Property  | Type                                        | Required | Description                                                                                  |
| --------- | ------------------------------------------- | -------- | -------------------------------------------------------------------------------------------- |
| `prompt`  | `string \| AsyncIterable<UserInputMessage>` | Yes      | The input prompt as a string or async iterable of user messages for multi-turn conversations |
| `options` | [`AmpOptions`](#ampoptions)                 | No       | CLI configuration options                                                                    |
| `signal`  | `AbortSignal`                               | No       | Signal for cancellation support                                                              |

### AmpOptions

Configuration options that map to Amp CLI flags.

```typescript
interface AmpOptions {
	cwd?: string
	mode?: string // Prefer 'low', 'medium', 'high', or 'ultra'
	effort?: 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max'
	dangerouslyAllowAll?: boolean
	noArchiveAfterExecute?: boolean
	visibility?: 'private' | 'unlisted' | 'workspace' | 'group'
	settingsFile?: string
	logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'audit'
	logFile?: string
	mcpConfig?: string | MCPConfig
	env?: Record<string, string>
	continue?: boolean | string
	skills?: string
	enabledTools?: string[]
	permissions?: Permission[]
	labels?: string[]
	thinking?: boolean
}
```

The built-in modes are `'low'`, `'medium'`, `'high'`, and `'ultra'`. You can also pass a
string for a custom plugin-defined mode.

#### Properties

| Property                | Type                                                                     | Default         | Description                                                                                                                                                 |
| ----------------------- | ------------------------------------------------------------------------ | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `cwd`                   | `string`                                                                 | `process.cwd()` | Current working directory for execution                                                                                                                     |
| `mode`                  | `string`                                                                 | `'medium'`      | Agent mode. Prefer `'low'`, `'medium'`, `'high'`, or `'ultra'`; custom plugin-defined mode strings are also accepted                                        |
| `effort`                | `'none' \| 'minimal' \| 'low' \| 'medium' \| 'high' \| 'xhigh' \| 'max'` | -               | Reasoning effort for supported modes                                                                                                                        |
| `dangerouslyAllowAll`   | `boolean`                                                                | `undefined`     | Allow all tool usage without permission prompts. When `permissions` is provided and this is unset, the SDK forces it to `false` so permissions take effect. |
| `noArchiveAfterExecute` | `boolean`                                                                | `false`         | Leave new execute threads unarchived after execution completes                                                                                              |
| `visibility`            | `'private' \| 'unlisted' \| 'workspace' \| 'group'`                      | `'workspace'`   | Thread visibility level                                                                                                                                     |
| `settingsFile`          | `string`                                                                 | -               | Path to custom settings file                                                                                                                                |
| `logLevel`              | `'debug' \| 'info' \| 'warn' \| 'error' \| 'audit'`                      | `'info'`        | Logging verbosity level                                                                                                                                     |
| `logFile`               | `string`                                                                 | -               | Path to write logs                                                                                                                                          |
| `continue`              | `boolean \| string`                                                      | `false`         | Continue most recent thread (`true`) or specific thread by ID (`string`)                                                                                    |
| `mcpConfig`             | `string \| MCPConfig`                                                    | -               | MCP server configuration as JSON string, or config object                                                                                                   |
| `env`                   | `Record<string, string>`                                                 | -               | Additional environment variables                                                                                                                            |
| `skills`                | `string`                                                                 | -               | Folder path with custom skills                                                                                                                              |
| `enabledTools`          | `string[]`                                                               | -               | Tool name patterns to enable (maps to `amp.tools.enable`)                                                                                                   |
| `permissions`           | [`Permission[]`](#permission)                                            | -               | Permission rules for tool usage                                                                                                                             |
| `labels`                | `string[]`                                                               | -               | Labels to add to the thread                                                                                                                                 |
| `thinking`              | `boolean`                                                                | `false`         | Include thinking blocks in the result stream                                                                                                                |

## Message Types

The SDK streams various message types during execution. All messages implement the base `StreamMessage` type.

### SystemMessage

Initial message containing session information and available tools.

```typescript
interface SystemMessage {
	type: 'system'
	subtype: 'init'
	session_id: string
	cwd: string
	tools: string[]
	mcp_servers: Array<{
		name: string
		status: 'connected' | 'connecting' | 'connection-failed' | 'disabled'
	}>
}
```

#### Properties

| Property      | Type                                    | Description                                  |
| ------------- | --------------------------------------- | -------------------------------------------- |
| `session_id`  | `string`                                | Unique identifier for this execution session |
| `cwd`         | `string`                                | Current working directory                    |
| `tools`       | `string[]`                              | List of available tool names                 |
| `mcp_servers` | `Array<{name: string, status: string}>` | Status of MCP servers                        |

### AssistantMessage

AI assistant responses with text content and tool usage.

```typescript
interface AssistantMessage {
	type: 'assistant'
	session_id: string
	message: {
		id: string
		type: 'message'
		role: 'assistant'
		model: string
		content: Array<TextContent | ToolUseContent>
		stop_reason: 'end_turn' | 'tool_use' | 'max_tokens' | null
		stop_sequence: string | null
		usage?: Usage
	}
	parent_tool_use_id: string | null
}
```

#### Properties

| Property             | Type             | Description                                      |
| -------------------- | ---------------- | ------------------------------------------------ |
| `session_id`         | `string`         | Unique identifier for this execution session     |
| `message`            | `object`         | The assistant's message content                  |
| `parent_tool_use_id` | `string \| null` | ID of parent tool use if this is a tool response |

### UserMessage

User input and tool results.

```typescript
interface UserMessage {
	type: 'user'
	session_id: string
	message: {
		role: 'user'
		content: Array<TextContent | ToolResultContent>
	}
	parent_tool_use_id: string | null
}
```

#### Properties

| Property             | Type             | Description                                      |
| -------------------- | ---------------- | ------------------------------------------------ |
| `session_id`         | `string`         | Unique identifier for this execution session     |
| `message`            | `object`         | The user's message content                       |
| `parent_tool_use_id` | `string \| null` | ID of parent tool use if this is a tool response |

### ResultMessage

Final successful execution result.

```typescript
interface ResultMessage {
	type: 'result'
	subtype: 'success'
	session_id: string
	is_error: false
	result: string
	duration_ms: number
	num_turns: number
	usage?: Usage
	permission_denials?: string[]
}
```

#### Properties

| Property             | Type              | Description                                  |
| -------------------- | ----------------- | -------------------------------------------- |
| `session_id`         | `string`          | Unique identifier for this execution session |
| `result`             | `string`          | The final result from the assistant          |
| `duration_ms`        | `number`          | Total execution time in milliseconds         |
| `num_turns`          | `number`          | Number of conversation turns                 |
| `usage`              | [`Usage`](#usage) | Token usage information                      |
| `permission_denials` | `string[]`        | List of permissions that were denied         |

### ErrorResultMessage

Final error result indicating execution failure.

```typescript
interface ErrorResultMessage {
	type: 'result'
	subtype: 'error_during_execution' | 'error_max_turns'
	session_id: string
	is_error: true
	error: string
	duration_ms: number
	num_turns: number
	usage?: Usage
	permission_denials?: string[]
}
```

#### Properties

| Property             | Type              | Description                                  |
| -------------------- | ----------------- | -------------------------------------------- |
| `session_id`         | `string`          | Unique identifier for this execution session |
| `error`              | `string`          | Error message describing what went wrong     |
| `duration_ms`        | `number`          | Total execution time in milliseconds         |
| `num_turns`          | `number`          | Number of conversation turns                 |
| `usage`              | [`Usage`](#usage) | Token usage information                      |
| `permission_denials` | `string[]`        | List of permissions that were denied         |

### TextContent

Plain text content block.

```typescript
interface TextContent {
	type: 'text'
	text: string
}
```

### ToolUseContent

Tool execution request.

```typescript
interface ToolUseContent {
	type: 'tool_use'
	id: string
	name: string
	input: Record<string, unknown>
}
```

### ToolResultContent

Result from tool execution.

```typescript
interface ToolResultContent {
	type: 'tool_result'
	tool_use_id: string
	content: string
	is_error: boolean
}
```

### Usage

Token usage and billing information from API calls.

```typescript
interface Usage {
	input_tokens: number
	cache_creation_input_tokens?: number
	cache_read_input_tokens?: number
	output_tokens: number
	service_tier?: string
}
```

#### Properties

| Property                      | Type     | Description                        |
| ----------------------------- | -------- | ---------------------------------- |
| `input_tokens`                | `number` | Number of input tokens used        |
| `cache_creation_input_tokens` | `number` | Tokens used for cache creation     |
| `cache_read_input_tokens`     | `number` | Tokens read from cache             |
| `output_tokens`               | `number` | Number of output tokens generated  |
| `service_tier`                | `string` | Service tier used for this request |

## Input Types

### UserInputMessage

Formatted user input message for streaming conversations.

```typescript
interface UserInputMessage {
	type: 'user'
	message: {
		role: 'user'
		content: Array<{
			type: 'text'
			text: string
		}>
	}
}
```

### MCPConfig

Configuration for MCP (Model Context Protocol) servers. Supports both stdio-based and HTTP-based servers.

```typescript
type MCPConfig = Record<string, MCPServer>

// MCPServer is a union of stdio and HTTP server configurations
```

`MCPServer` accepts either a stdio server config (with `command`) or an HTTP server config (with `url`):

```typescript
const mcpConfig: MCPConfig = {
	playwright: { command: 'npx', args: ['-y', '@playwright/mcp'] },
	remote: { url: 'https://api.example.com/mcp' },
}
```

#### MCPServer Properties

**Stdio server:**

| Property   | Type                     | Required | Description                          |
| ---------- | ------------------------ | -------- | ------------------------------------ |
| `command`  | `string`                 | Yes      | Command to start the MCP server      |
| `args`     | `string[]`               | No       | Command line arguments               |
| `env`      | `Record<string, string>` | No       | Environment variables for the server |
| `disabled` | `boolean`                | No       | Whether this server is disabled      |

**HTTP server:**

| Property    | Type                     | Required | Description                            |
| ----------- | ------------------------ | -------- | -------------------------------------- |
| `url`       | `string`                 | Yes      | URL of the HTTP MCP server             |
| `headers`   | `Record<string, string>` | No       | HTTP headers to send with requests     |
| `transport` | `string`                 | No       | Transport type (e.g., "sse")           |
| `oauth`     | `object`                 | No       | OAuth configuration for authentication |
| `disabled`  | `boolean`                | No       | Whether this server is disabled        |

**OAuth config (for HTTP servers):**

| Property       | Type       | Required | Description             |
| -------------- | ---------- | -------- | ----------------------- |
| `clientId`     | `string`   | Yes      | OAuth client ID         |
| `clientSecret` | `string`   | No       | OAuth client secret     |
| `authUrl`      | `string`   | Yes      | OAuth authorization URL |
| `tokenUrl`     | `string`   | Yes      | OAuth token URL         |
| `scopes`       | `string[]` | No       | OAuth scopes            |
| `redirectUrl`  | `string`   | No       | OAuth redirect URL      |

### ThreadsNewOptions

Options for creating a new thread.

```typescript
interface ThreadsNewOptions {
	visibility?: 'private' | 'unlisted' | 'workspace' | 'group'
}
```

#### Properties

| Property     | Type                                                | Required | Description       |
| ------------ | --------------------------------------------------- | -------- | ----------------- |
| `visibility` | `'private' \| 'unlisted' \| 'workspace' \| 'group'` | No       | Thread visibility |

### ThreadsMarkdownOptions

Options for getting thread markdown.

```typescript
interface ThreadsMarkdownOptions {
	threadId: string
}
```

#### Properties

| Property   | Type     | Required | Description                       |
| ---------- | -------- | -------- | --------------------------------- |
| `threadId` | `string` | Yes      | The thread ID to get markdown for |

### ThreadsSetMultiplayerOptions

Options for opening or closing a thread for contributions (multiplayer). The duration options are summed; the total must be between 5 minutes and 7 days. When `enabled` is `true` and no duration is given, the server default (currently 3 hours) is used. Duration options are not allowed when `enabled` is `false`.

```typescript
interface ThreadsSetMultiplayerOptions {
	threadId: string
	enabled?: boolean
	minutes?: number
	hours?: number
	days?: number
	weeks?: number
}
```

#### Properties

| Property   | Type      | Required | Description                                                   |
| ---------- | --------- | -------- | ------------------------------------------------------------- |
| `threadId` | `string`  | Yes      | The thread ID to update                                       |
| `enabled`  | `boolean` | No       | Whether the thread is open for contributions (default `true`) |
| `minutes`  | `number`  | No       | Open-window duration in minutes                               |
| `hours`    | `number`  | No       | Open-window duration in hours                                 |
| `days`     | `number`  | No       | Open-window duration in days                                  |
| `weeks`    | `number`  | No       | Open-window duration in weeks                                 |

### Permission

Individual permission rule for controlling tool usage.

```typescript
interface Permission {
	tool: string
	matches?: Record<string, PermissionMatchCondition>
	action: 'allow' | 'reject' | 'ask' | 'delegate'
	context?: 'thread' | 'subagent'
	to?: string
}
```

#### Properties

| Property  | Type                                         | Required | Description                                                 |
| --------- | -------------------------------------------- | -------- | ----------------------------------------------------------- |
| `tool`    | `string`                                     | Yes      | Tool name (supports glob patterns like `Bash` or `mcp__*`)  |
| `matches` | `Record<string, PermissionMatchCondition>`   | No       | Match conditions for tool arguments                         |
| `action`  | `'allow' \| 'reject' \| 'ask' \| 'delegate'` | Yes      | How Amp should proceed when the rule matches                |
| `context` | `'thread' \| 'subagent'`                     | No       | Apply rule only in main thread or sub-agents                |
| `to`      | `string`                                     | No       | Command to delegate to (required when action is `delegate`) |

#### Example

```typescript
import { execute, createPermission } from '@ampcode/sdk'

for await (const message of execute({
	prompt: 'Deploy the application',
	options: {
		permissions: [
			// Allow git commands
			createPermission('Bash', 'allow', { matches: { cmd: 'git *' } }),
			// Allow reading files
			createPermission('Read', 'allow'),
		],
	},
})) {
	// Handle messages
}
```

### PermissionMatchCondition

Match condition for tool arguments. Supports strings (with glob patterns or regex), arrays (OR logic), booleans, numbers, null, undefined, and nested objects.

```typescript
type PermissionMatchCondition =
	| string
	| PermissionMatchCondition[]
	| { [key: string]: PermissionMatchCondition }
	| boolean
	| number
	| null
	| undefined
```

#### Examples

```typescript
// String pattern with wildcard
{
	cmd: 'npm *'
}

// Array for OR logic
{
	cmd: ['npm install', 'npm test', 'npm run build']
}

// Regex pattern
{
	cmd: '/^git (status|log|diff)$/'
}

// Nested object matching
{
	env: {
		NODE_ENV: 'production'
	}
}
```

## Requirements

- Node.js 18 or higher
