JSPM

@ampcode/sdk

0.1.0-20260605144103-g77da114
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 469
  • Score
    100M100P100Q88880F
  • License Amp Commercial License

TypeScript SDK for Amp CLI - Build custom AI agents with Amp's capabilities

Package Exports

  • @ampcode/sdk

Readme

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

# 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:

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 at ampcode.com/settings.

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:

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:

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:

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:

// 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:

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:

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:

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

Available modes:

  • deep: Extended reasoning for complex tasks
  • smart (default): Balanced mode with full capabilities
  • rush: Faster responses with streamlined tool usage
  • large: 1M-token long-context workhorse

Reasoning Effort

Set model reasoning effort for supported modes (deep and smart):

for await (const message of execute({
    prompt: 'Think carefully and explain your plan before coding.',
    options: {
        mode: 'smart',
        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().

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():

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:

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 and the appendix.

Advanced Usage

Interactive Progress Tracking

For building user interfaces that show real-time progress:

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:

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:

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 section of the manual.

Multi-turn Conversations

Build streaming conversations using async generators:

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:

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:

{
    "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.

Custom Tools

Extend Amp's capabilities with custom toolbox scripts:

for await (const message of execute({
    prompt: 'Use my custom deployment scripts',
    options: {
        toolbox: '/usr/repository-path/toolbox', // Path to toolbox scripts
    },
})) {
    // Handle messages...
}

To find out more about Amp Toolboxes, see the Toolboxes section of the Amp documentation.

Custom Skills

Load custom skills from a specified directory:

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 section of the Amp documentation.

Functions

execute()

The main function for executing Amp CLI commands programmatically.

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

Parameters

Returns

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

Example

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.

function createUserMessage(text: string): UserInputMessage

Parameters

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

Returns

Example

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.

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>) - 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 - A permission object that can be used in the permissions array

Examples

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.

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

Parameters

Returns

  • Promise<string> - The thread ID

Example

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.

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

Parameters

Returns

  • Promise<string> - The thread content as markdown

Example

import { threads } from '@ampcode/sdk'

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

Types

ExecuteOptions

Configuration options for the execute() function.

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 No CLI configuration options
signal AbortSignal No Signal for cancellation support

AmpOptions

Configuration options that map to Amp CLI flags.

interface AmpOptions {
    cwd?: string
    mode?: 'deep' | 'smart' | 'rush' | 'large'
    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
    toolbox?: string
    skills?: string
    enabledTools?: string[]
    permissions?: Permission[]
    labels?: string[]
    thinking?: boolean
}

Properties

Property Type Default Description
cwd string process.cwd() Current working directory for execution
mode 'deep' | 'smart' | 'rush' | 'large' 'smart' Agent mode - controls model, system prompt, and tool selection
effort 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max' - Reasoning effort for supported modes (deep and smart)
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
toolbox string - Folder path with toolbox scripts
skills string - Folder path with custom skills
enabledTools string[] - Tool name patterns to enable (maps to amp.tools.enable)
permissions 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.

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.

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.

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.

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 Token usage information
permission_denials string[] List of permissions that were denied

ErrorResultMessage

Final error result indicating execution failure.

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 Token usage information
permission_denials string[] List of permissions that were denied

TextContent

Plain text content block.

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

ToolUseContent

Tool execution request.

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

ToolResultContent

Result from tool execution.

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

Usage

Token usage and billing information from API calls.

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.

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.

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):

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.

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.

interface ThreadsMarkdownOptions {
    threadId: string
}

Properties

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

Permission

Individual permission rule for controlling tool usage.

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

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.

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

Examples

// 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