Quickstart
Deploy an agent and chat with it. This takes about two minutes, assuming you have completed Installation.
1. Define an Agent
An agent is a folder with a CLAUDE.md file. The CLAUDE.md is the system prompt -- it tells the agent who it is and how to behave.
mkdir my-agent
cat > my-agent/CLAUDE.md << 'EOF'
You are a helpful coding assistant.
Answer questions about JavaScript and TypeScript.
Keep answers concise. Include working code examples.
EOF
That is the only required file. For production agents, you can add .claude/settings.json (tool permissions), .claude/skills/ (reusable skills), and .mcp.json (MCP server connections). See Key Concepts for more.
2. Deploy and Chat
ash deploy ./my-agent --name my-agent
ash chat my-agent "What is a closure in JavaScript?"
The response streams back in real time, with the session ID printed at the end:
A closure is a function that retains access to variables from its enclosing
scope, even after the outer function has returned...
Session: 550e8400-e29b-41d4-a716-446655440000
The session stays alive so you can continue the conversation:
ash chat --session 550e8400-e29b-41d4-a716-446655440000 "Now explain with an example"
When you are done, end the session:
ash session end 550e8400-e29b-41d4-a716-446655440000
Use ash chat --end for one-shot messages that don't need follow-ups -- it ends the session automatically after the response.
Detailed Flow (Optional)
If you need more control -- multiple messages, pause/resume, or session inspection -- use the session commands directly:
# Create a session
ash session create my-agent
# → { "id": "550e8400-...", "status": "active", "agentName": "my-agent" }
# Send messages (replace SESSION_ID with the actual ID)
ash session send SESSION_ID "What is a closure in JavaScript?"
ash session send SESSION_ID "Now explain it with an example"
# End the session when done
ash session end SESSION_ID
Using the SDKs
The CLI is convenient for testing. For applications, use one of the SDKs.
- TypeScript
- Python
- curl
npm install @ash-ai/sdk
import { AshClient } from '@ash-ai/sdk';
const client = new AshClient({
serverUrl: 'http://localhost:4100',
apiKey: process.env.ASH_API_KEY,
});
// Create a session
const session = await client.createSession('my-agent');
// Send a message and stream the response
for await (const event of client.sendMessageStream(session.id, 'What is a closure?')) {
if (event.type === 'message') {
process.stdout.write(event.data);
}
}
// Clean up
await client.endSession(session.id);
pip install ash-ai-sdk
from ash_ai import AshClient
client = AshClient(
server_url="http://localhost:4100",
api_key=os.environ.get("ASH_API_KEY"),
)
# Create a session
session = client.create_session("my-agent")
# Send a message and stream the response
for event in client.send_message_stream(session.id, "What is a closure?"):
if event.type == "message":
print(event.data, end="")
# Clean up
client.end_session(session.id)
# Create a session
curl -s -X POST http://localhost:4100/api/sessions \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ASH_API_KEY" \
-d '{"agent":"my-agent"}'
# Send a message (returns an SSE stream)
curl -N -X POST http://localhost:4100/api/sessions/SESSION_ID/messages \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ASH_API_KEY" \
-d '{"content":"What is a closure?"}'
# End the session
curl -s -X DELETE http://localhost:4100/api/sessions/SESSION_ID \
-H "Authorization: Bearer $ASH_API_KEY"
What Just Happened
When you ran those commands, here is what Ash did under the hood:
ash deploy-- Copied your agent folder to the server's agent registry and recorded it in the database.ash session create-- Created a session record in the database and spawned an isolated sandbox process. Inside that sandbox, a bridge process started and loaded yourCLAUDE.mdas the system prompt.ash session send-- Sent your message to the bridge over a Unix socket. The bridge called the Claude Agent SDK, which streamed the response back. Ash proxied each chunk as a Server-Sent Event (SSE) over HTTP to your terminal.ash session end-- Marked the session as ended in the database and destroyed the sandbox process.
The sandbox is an isolated child process with a restricted environment -- only allowlisted variables reach it, and on Linux it runs with cgroup resource limits and filesystem isolation via bubblewrap.
Next Steps
- Key Concepts -- Understand agents, sessions, sandboxes, bridges, and the server
- CLI Reference -- All commands and flags
- API Reference -- REST endpoints, SSE format, request/response schemas
- TypeScript SDK -- Full TypeScript client documentation
- Python SDK -- Full Python client documentation