@takutakahashi/claude-agentapi
v0.19.0
Published
coder/agentapi compatible HTTP API server using Claude Agent SDK on AWS Bedrock
Maintainers
Readme
claude-agentapi
A coder/agentapi compatible HTTP API server that uses Claude Agent SDK TypeScript on AWS Bedrock.
Overview
This project implements a server compatible with the coder/agentapi specification, allowing you to interact with Claude AI agents through a standardized HTTP API. The server uses the Claude Agent SDK V2 and can be configured to use either AWS Bedrock or the Anthropic API.
Features
- ✅ Full
coder/agentapicompatibility - ✅ Claude Agent SDK V2 integration
- ✅ AWS Bedrock support
- ✅ Anthropic API support (API Key and OAuth Token)
- ✅ Claude Code compatible configuration (
.claude/config.json) - ✅ MCP (Model Context Protocol) servers support
- ✅ Plugin marketplace support
- ✅ Prometheus metrics export (Claude Code compatible)
- ✅ Server-Sent Events (SSE) for real-time updates
- ✅ Multi-turn conversation support
- ✅ AskUserQuestion and ExitPlanMode tool handling
- ✅ TypeScript with strict type checking
- ✅ Problem+JSON error responses
Documentation
- 📖 /action エンドポイント使用ガイド - エージェントとの対話的なやり取りの詳細な使用方法
Prerequisites
- Node.js 20.x or higher
- AWS account with Bedrock access (if using Bedrock)
- Or Anthropic API key or OAuth token (if using Anthropic API)
Installation
Quick Start with npx/bunx (Recommended)
From GitHub Packages
# Create a .env file with your configuration
cat > .env << 'EOF'
PORT=3000
HOST=localhost
CLAUDE_CODE_USE_BEDROCK=0
ANTHROPIC_MODEL=default
ANTHROPIC_OAUTH_TOKEN=your_oauth_token_here
EOF
# Configure npm to use GitHub Packages
echo "@takutakahashi:registry=https://npm.pkg.github.com" >> .npmrc
# Run with npx
npx @takutakahashi/claude-agentapi
# Or install globally
npm install -g @takutakahashi/claude-agentapi
claude-agentapiFrom npm Registry (if published)
# Create a .env file with your configuration
cat > .env << 'EOF'
PORT=3000
HOST=localhost
CLAUDE_CODE_USE_BEDROCK=0
ANTHROPIC_MODEL=default
ANTHROPIC_OAUTH_TOKEN=your_oauth_token_here
EOF
# Run with npx (npm)
npx claude-agentapi
# Or with bunx (Bun)
bunx claude-agentapiManual Installation
- Clone the repository:
git clone <repository-url>
cd claude-agentapi- Install dependencies:
npm install- Configure environment variables:
cp .env.example .env
# Edit .env with your configurationConfiguration
This server supports two configuration methods:
- Claude Code compatible
.claude/config.json- For MCP servers and hooks - Environment variables - For server settings and API credentials
Claude Config File (.claude/config.json)
This server uses the Claude Agent SDK v1 API (query function) which supports MCP servers, hooks, and other configurations. Configuration files are loaded in the following order (later configs override earlier ones):
- Global:
~/.claude/config.json - Project:
.claude/config.json(current working directory) - Working directory:
{CLAUDE_WORKING_DIRECTORY}/.claude/config.json
Supported Configuration:
- ✅
mcpServers- MCP server configurations (fully supported) - ✅
hooks- Hook callbacks for responding to events - ✅
plugins- Loaded from~/.claude/settings.jsonenabledPlugins- Automatically resolves plugin paths from marketplaces
- Supports custom marketplaces via
extraKnownMarketplaces - Example:
"code-simplifier@claude-plugins-official": true
- ⏳
commands- Custom command configurations (not yet implemented)
Example .claude/config.json
{
"mcpServers": {
"example-server": {
"command": "node",
"args": ["/path/to/mcp-server.js"],
"env": {
"API_KEY": "your-api-key"
}
}
}
}See .claude/config.json.example for a complete example with all supported options.
Configuration Structure
mcpServers: MCP (Model Context Protocol) server configurationscommand: Command to execute the MCP serverargs: Array of command-line argumentsenv: Environment variables for the server processdisabled: Set totrueto disable a server without removing its configuration
plugins/skills: Plugin/skill configurationsenabled: Whether the plugin is enabledconfig: Plugin-specific configuration object
hooks: Hook configurations for executing commands at specific eventscommand: Command to execute when the hook is triggeredargs: Array of command-line argumentsenv: Environment variables for the hook process- Common hooks:
user-prompt-submit-hook,tool-call-hook
commands: Custom command definitionscommand: Command to executeargs: Array of command-line argumentsenv: Environment variables for the command processdescription: Description of what the command does
Environment Variables
Create a .env file based on .env.example:
Server Configuration
PORT- Server port (default: 3000)HOST- Server host (default: localhost)
Model Configuration
ANTHROPIC_MODEL- Claude model name (default: default)
AWS Bedrock Configuration (when using Bedrock)
CLAUDE_CODE_USE_BEDROCK=1- Enable BedrockAWS_REGION- AWS region (e.g., us-east-1)AWS_ACCESS_KEY_ID- AWS access keyAWS_SECRET_ACCESS_KEY- AWS secret keyAWS_SESSION_TOKEN- AWS session token (optional)
Anthropic API Configuration (when not using Bedrock)
Use either API Key or OAuth Token (not both):
ANTHROPIC_API_KEY- Your Anthropic API keyANTHROPIC_OAUTH_TOKEN- Your Anthropic OAuth token
Agent Permission Configuration
CLAUDE_WORKING_DIRECTORY- Working directory for the agent (default: current working directory)CLAUDE_PERMISSION_MODE- Permission mode:default,acceptEdits, orbypassPermissions(default: default)DANGEROUSLY_SKIP_PERMISSIONS- Set totrueto skip all permission checks (equivalent tobypassPermissionsmode)CLAUDE_CODE_EXECUTABLE_PATH- Custom path to Claude Code executable (optional, uses SDK built-in executable by default)
Permission Modes:
default- Standard permission checks with user prompts for confirmationsacceptEdits- Automatically approve file edits (still prompts for other operations)bypassPermissions- Skip all permission checks (⚠️ use with extreme caution)
Telemetry Configuration
CLAUDE_CODE_ENABLE_TELEMETRY- Enable OpenTelemetry metrics export (set to1to enable)PROMETHEUS_PORT- Prometheus metrics server port (default: 9464)
Other Configuration
DEBUG- Enable debug logging (default: false)MAX_MESSAGE_HISTORY- Maximum messages to keep in history (default: 100)
Usage
Run with npx/bunx
If you used npx/bunx for installation:
# Make sure you have a .env file in the current directory
npx claude-agentapi
# or
bunx claude-agentapiDevelopment Mode
npm run devProduction Mode
npm run build
npm startType Checking
npm run type-checkLinting
npm run lint
npm run lint:fixCLI Options
The CLI accepts the following command-line options:
--dangerously-skip-permissions
Disables all permission checks by setting the permission mode to bypassPermissions. This allows the agent to perform any operation without asking for confirmation.
⚠️ WARNING: Use this option with extreme caution! The agent will have unrestricted access to your filesystem and can execute any commands without prompts.
npx claude-agentapi --dangerously-skip-permissions--working-directory <path> or -w <path>
Sets the working directory for the agent. This allows the agent to access files relative to the specified directory, including .claude and other configuration directories.
npx claude-agentapi --working-directory /path/to/your/project
# or
npx claude-agentapi -w /path/to/your/project--permission-mode <mode> or -p <mode>
Sets the permission mode for the agent. Valid options are default, acceptEdits, or bypassPermissions.
npx claude-agentapi --permission-mode acceptEdits
# or
npx claude-agentapi -p acceptEditsExample with multiple options:
npx claude-agentapi \
--working-directory /path/to/project \
--permission-mode acceptEditsAPI Endpoints
The server implements the following coder/agentapi compatible endpoints:
GET /health
Health check endpoint.
Response:
{
"status": "ok"
}GET /status
Get current agent status.
Response:
{
"agent_type": "claude",
"status": "running" | "stable"
}GET /messages
Get conversation message history (user and assistant messages only).
Response:
{
"messages": [
{
"id": 1,
"role": "user" | "assistant",
"content": "Message content",
"time": "2024-01-01T00:00:00.000Z",
"type": "normal" | "question" | "plan"
}
]
}GET /tool_status
Get currently active tool executions. When a tool starts executing, it appears in this list. When the tool completes (success or error), it is removed from the list.
Response:
{
"messages": [
{
"id": 2,
"role": "agent",
"content": "{\"type\":\"tool_use\",\"name\":\"Read\",\"id\":\"toolu_123\",\"input\":{\"file_path\":\"/path/to/file\"}}",
"time": "2024-01-01T00:00:00.000Z",
"toolUseId": "toolu_123"
}
]
}POST /message
Send a message to the agent.
Request:
{
"content": "Your message",
"type": "user" | "raw"
}Response:
{
"ok": true
}Error (409 - Agent Busy):
{
"type": "about:blank",
"title": "Agent is busy",
"status": 409,
"detail": "The agent is currently processing another request."
}GET /action
Get a list of pending actions that require user response.
Response:
{
"pending_actions": [
{
"type": "answer_question",
"tool_use_id": "toolu_123",
"content": {
"questions": [
{
"question": "Which library should we use?",
"header": "Library",
"multiSelect": false,
"options": [
{ "label": "React", "description": "UI library" },
{ "label": "Vue", "description": "Progressive framework" }
]
}
]
}
}
]
}POST /action
Send an action to the agent. Supports multiple action types for different agent interactions.
📖 詳細な使用方法については /action エンドポイント使用ガイド を参照してください。
Action Type: answer_question
Answer questions from the AskUserQuestion tool.
Request:
{
"type": "answer_question",
"answers": {
"question1": "answer1",
"question2": "answer2"
}
}Response:
{
"ok": true
}Error (409 - No Active Question):
{
"type": "about:blank",
"title": "No active question",
"status": 409,
"detail": "There is no active question to answer. The agent must be running and waiting for user input."
}Action Type: approve_plan
Approve or reject a plan presented by the ExitPlanMode tool.
Request (Approve):
{
"type": "approve_plan",
"approved": true
}Request (Reject):
{
"type": "approve_plan",
"approved": false
}Response:
{
"ok": true
}Error (409 - No Active Plan):
{
"type": "about:blank",
"title": "No active plan",
"status": 409,
"detail": "There is no active plan to approve. The agent must be running and waiting for plan approval."
}Action Type: stop_agent
Stop the currently running agent.
Request:
{
"type": "stop_agent"
}Response:
{
"ok": true
}Note: This action can be called at any time, regardless of agent status.
GET /events
Server-Sent Events (SSE) stream for real-time updates.
Events:
init- Initial state on connection
{
"messages": [...],
"status": "stable"
}message_update- New message
{
"id": "msg_1_1234567890",
"role": "assistant",
"content": "Message content",
"time": "2024-01-01T00:00:00.000Z"
}status_change- Agent status changed
{
"status": "running" | "stable"
}Architecture
src/
├── index.ts # Application entry point
├── server.ts # Express server configuration
├── routes/ # API route handlers
│ ├── status.ts # GET /status
│ ├── messages.ts # GET /messages
│ ├── message.ts # POST /message
│ ├── action.ts # POST /action
│ ├── tool_status.ts # GET /tool_status
│ └── events.ts # GET /events (SSE)
├── services/ # Business logic
│ ├── agent.ts # Claude Agent SDK integration
│ ├── session.ts # SSE session management
│ └── metrics.ts # Prometheus metrics collection
├── types/ # TypeScript type definitions
│ ├── api.ts # API types
│ ├── agent.ts # Agent types
│ └── config.ts # Configuration types
└── utils/ # Utility functions
├── logger.ts # Logging utility
├── sse.ts # SSE helper
├── config.ts # Configuration loader
└── telemetry.ts # OpenTelemetry setupMCP Servers and Plugins
MCP Servers
This server supports Model Context Protocol (MCP) servers, allowing you to extend Claude's capabilities with custom tools and integrations.
MCP servers are configured in .claude/config.json under the mcpServers key. Each server configuration includes:
- The command to execute
- Optional arguments
- Environment variables
- An optional
disabledflag to temporarily disable a server
Example MCP server configuration:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/directory"]
},
"database": {
"command": "docker",
"args": ["run", "-i", "my-mcp-db-server"],
"env": {
"DATABASE_URL": "postgresql://localhost/mydb"
}
}
}
}Plugins and Skills
Plugins extend Claude's functionality with additional capabilities. Configure plugins in .claude/config.json under the plugins or skills key.
Example plugin configuration:
{
"plugins": {
"code-reviewer": {
"enabled": true,
"config": {
"strictness": "high",
"languages": ["typescript", "python"]
}
}
}
}Note: The skills key is an alias for plugins and works identically.
Hooks
Hooks allow you to execute custom commands when specific events occur during agent operation. Configure hooks in .claude/config.json under the hooks key.
Example hook configuration:
{
"hooks": {
"user-prompt-submit-hook": {
"command": "bash",
"args": ["-c", "echo 'User prompt submitted'"],
"env": {
"HOOK_TYPE": "user-prompt-submit"
}
},
"tool-call-hook": {
"command": "node",
"args": ["/path/to/tool-call-logger.js"]
}
}
}Common hook types:
user-prompt-submit-hook: Triggered when a user submits a prompttool-call-hook: Triggered when the agent calls a tool- And more depending on Claude Agent SDK support
Custom Commands
Define custom commands that can be invoked during agent operation. Configure commands in .claude/config.json under the commands key.
Example command configuration:
{
"commands": {
"deploy": {
"command": "bash",
"args": ["-c", "npm run deploy"],
"description": "Deploy the application to production",
"env": {
"NODE_ENV": "production"
}
},
"test": {
"command": "npm",
"args": ["test"],
"description": "Run the test suite"
}
}
}Commands can be invoked by the agent or used for custom workflows within your application.
Prometheus Metrics
This server implements OpenTelemetry metrics export to Prometheus, following Claude Code's metric naming and structure.
Enabling Metrics
Enable metrics collection by setting the following environment variables:
# Enable telemetry
export CLAUDE_CODE_ENABLE_TELEMETRY=1
# Optional: Set custom Prometheus port (default: 9464)
export PROMETHEUS_PORT=9464Once enabled, Prometheus metrics will be available at:
http://localhost:9464/metricsAvailable Metrics
The following metrics are exported following Claude Code's naming conventions:
| Metric Name | Description | Unit | Attributes |
|-------------|-------------|------|------------|
| claude_code.session.count | Count of sessions started | count | session.id, app.version, terminal.type |
| claude_code.token.usage | Number of tokens used | tokens | session.id, app.version, terminal.type, model, type (input/output/cacheRead/cacheCreation) |
| claude_code.cost.usage | Cost of the session | USD | session.id, app.version, terminal.type, model |
| claude_code.lines_of_code.count | Lines of code modified | count | session.id, app.version, terminal.type, type (added/removed) |
| claude_code.code_edit_tool.decision | Code editing tool permission decisions | count | session.id, app.version, terminal.type, tool (Edit/Write/NotebookEdit), decision (accept/reject), language |
| claude_code.active_time.total | Total active time | seconds | session.id, app.version, terminal.type |
Standard Attributes
All metrics include the following standard attributes:
session.id- Unique session identifier (UUID)app.version- Application version from package.jsonterminal.type- Terminal type (fromTERMenvironment variable)
Prometheus Configuration
Example Prometheus configuration:
scrape_configs:
- job_name: 'claude-agentapi'
static_configs:
- targets: ['localhost:9464']
scrape_interval: 60sGrafana Dashboard
You can visualize these metrics using Grafana. Example queries:
# Total sessions started
sum(claude_code_session_count)
# Token usage by type
sum by (type) (claude_code_token_usage)
# Total cost in USD
sum(claude_code_cost_usage)
# Lines of code added vs removed
sum by (type) (claude_code_lines_of_code_count)Special Features
Agent Actions (POST /action)
The /action endpoint provides a unified interface for interacting with the agent through different action types:
1. Answer Questions (answer_question)
When the agent uses the AskUserQuestion tool:
- The server automatically formats and broadcasts the question with
type: "question"(❓ emoji prefix) - Client sends answers via
/actionwithtype: "answer_question" - Answers are sent back to the agent as a
tool_result
Example workflow:
- Agent calls
AskUserQuestion→ Server broadcasts question message - Client sends:
POST /actionwith{"type": "answer_question", "answers": {"q1": "a1"}} - Server forwards answer to agent as
tool_result
2. Approve/Reject Plans (approve_plan)
When the agent uses the ExitPlanMode tool:
- The server formats and broadcasts the plan with
type: "plan"(📋 emoji prefix) - Client approves or rejects via
/actionwithtype: "approve_plan" - Approval/rejection is sent back to the agent as a
tool_result
Example workflow:
- Agent calls
ExitPlanMode→ Server broadcasts plan message - Client sends:
POST /actionwith{"type": "approve_plan", "approved": true} - Server forwards approval to agent as
tool_result
3. Stop Agent (stop_agent)
Allows interrupting the agent at any time:
- Can be called regardless of agent status
- Immediately interrupts the running query
- Sets agent status to
stable
Example:
- Client sends:
POST /actionwith{"type": "stop_agent"} - Server interrupts agent and returns to stable state
Error Handling
The server uses the Problem+JSON format (RFC 7807) for error responses:
{
"type": "about:blank",
"title": "Error title",
"status": 400,
"detail": "Detailed error message"
}Limitations
- Single session only (no multi-session support)
- Raw message type (
type: "raw") not yet implemented - File upload endpoint (
POST /upload) not yet implemented
Development
Project Structure
The project follows a modular architecture with clear separation of concerns:
- Routes: Handle HTTP requests/responses
- Services: Implement business logic
- Types: Define TypeScript interfaces
- Utils: Provide shared utilities
Adding New Features
- Define types in
src/types/ - Implement logic in
src/services/ - Create route handlers in
src/routes/ - Register routes in
src/server.ts
License
MIT
