Skip to content

Commit a4ef720

Browse files
committed
docs(acp-server): refresh README
Reviewed the updated packages/acp-server/README.md, preserved the new layout and client example, and committed the changes.
1 parent 981b6d5 commit a4ef720

File tree

1 file changed

+151
-46
lines changed

1 file changed

+151
-46
lines changed

packages/acp-server/README.md

Lines changed: 151 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,117 @@
1-
# ACP Next.js Server
1+
# 🚀 Headless Coder ACP Server
22

3-
This Next.js 15 application exposes the Headless Coder SDK through the [Agent Communication Protocol](https://agentcommunicationprotocol.dev/introduction/welcome) (ACP). It loads adapter availability from `acp.config.json`, registers the requested providers (Codex, Claude, Gemini), and serves ACP-compatible endpoints under `/api/acp/*` with NDJSON streaming support.
3+
The **ACP Server** is a Next.js application that exposes the **Headless Coder SDK** via the [Agent Communication Protocol (ACP)](https://agentcommunicationprotocol.dev/introduction/welcome).
4+
It dynamically loads available adapters from `acp.config.json`, registers enabled providers (**Codex**, **Claude**, **Gemini**), and exposes ACP-compatible REST + streaming endpoints under `/api/acp/*`.
45

5-
## Prerequisites
6-
- Node.js 20+
7-
- The Headless Coder workspace dependencies installed (`pnpm install` or `npm install` at repo root)
8-
- Optional: `ACP_TOKEN` environment variable to require bearer authentication
9-
- Provider-specific credentials (Codex CLI, Claude agent, Gemini CLI) available to the underlying adapters
6+
---
107

11-
## Configuration
12-
1. Review `packages/acp-server/acp.config.json` to enable/disable adapters and adjust default model/working directory/sandbox options. The file is validated against `acp.config.schema.json` at runtime.
13-
2. Set `ACP_TOKEN` in `.env.local` (see `.env.local.example`) if you want the API to enforce authentication.
8+
## ✨ Key Features
9+
10+
- ⚙️ **Dynamic provider configuration** using `acp.config.json`
11+
- 🔄 **NDJSON streaming** for real-time AI-coder responses
12+
- 🔐 Optional **Bearer token authentication** via `ACP_TOKEN`
13+
- 🧠 **Structured output** support via JSON schemas
14+
- 🧰 Unified interface across Codex, Claude, and Gemini adapters
15+
- 🚀 Built with **Next.js (Node runtime)** — deploy anywhere
16+
17+
---
18+
19+
## 🧩 Prerequisites
20+
21+
- **Node.js 20+**
22+
- Headless Coder SDK installed (`pnpm install` or `npm install` at repo root)
23+
- Optional: environment variable `ACP_TOKEN` for authentication
24+
- Provider-specific credentials available (e.g. Codex binary, Claude API key, Gemini CLI)
25+
26+
---
27+
28+
## ⚙️ Configuration
29+
30+
1. Open and edit `apps/acp-next/acp.config.json` to enable or disable adapters.
31+
The config is validated against `acp.config.schema.json` at runtime.
32+
33+
**Example:**
34+
```json
35+
{
36+
"enabledAgents": ["codex", "gemini"],
37+
"defaults": {
38+
"workingDirectory": ".",
39+
"model": null,
40+
"sandboxMode": "read-only"
41+
}
42+
}
43+
```
44+
45+
2. (Optional) To enforce authentication, add an `ACP_TOKEN` variable in your environment:
46+
```bash
47+
ACP_TOKEN=my-secret-token
48+
```
49+
Copy `.env.local.example``.env.local` and fill in your desired values.
50+
51+
---
52+
53+
## ▶️ Running the Server
54+
55+
From the repository root:
1456

15-
## Running the server
16-
From the monorepo root:
1757
```bash
1858
# Start the ACP server on port 8000
19-
yarn workspace packages/acp-server dev # or npm/pnpm equivalent
59+
pnpm --filter acp-next dev
60+
# or
61+
npm run dev --workspace acp-next
2062
```
21-
The API now serves:
22-
- `GET /api/acp/agents` – returns enabled agents
23-
- `POST /api/acp/sessions` – creates a new session/thread
24-
- `POST /api/acp/messages?stream=true` – streams Headless Coder events as NDJSON frames
2563

26-
## Building the server
64+
Once started, the API will serve the following routes:
65+
66+
| Method | Endpoint | Description |
67+
|---------|-----------|-------------|
68+
| **GET** | `/api/acp/agents` | Lists enabled agents defined in `acp.config.json`. |
69+
| **POST** | `/api/acp/sessions` | Creates a new Headless Coder thread/session. |
70+
| **POST** | `/api/acp/messages?stream=true` | Streams Headless Coder events as NDJSON frames. |
71+
72+
**Sample NDJSON stream output:**
73+
```json
74+
{"type":"delta","text":"Hello world!"}
75+
{"type":"done"}
76+
```
77+
78+
---
79+
80+
## 🏗️ Building and Deploying
81+
2782
```bash
28-
yarn workspace packages/acp-server build
83+
pnpm --filter acp-next build
84+
pnpm --filter acp-next start
2985
```
30-
Then deploy with `yarn workspace packages/acp-server start` (or npm analog) pointing at the same configuration/credentials.
3186

32-
## Example client
33-
A simple TypeScript client lives in `packages/acp-server/client`. It can be used as a template for your own integrations.
87+
### Deployment options
88+
- **Vercel** — ideal for quick serverless deployment (`runtime: nodejs` required).
89+
- **Docker** — portable containerized deployment.
90+
- **Render / Fly.io / AWS** — any Node 20+ runtime will work.
91+
92+
Make sure your deployment includes:
93+
- `ACP_TOKEN` (if auth required)
94+
- Correct provider credentials (Codex CLI, Claude, Gemini)
3495

96+
---
97+
98+
## 🧪 Testing & Client Example
99+
100+
An example TypeScript client is available under `apps/acp-next/client`.
101+
102+
### Run built-in tests
35103
```bash
36-
# Run the ACP server first (see above)
37-
# In a second terminal, execute the client tests
38-
npm run acp:e2e
104+
pnpm --filter acp-next dev # start server
105+
pnpm run acp:e2e # execute client integration tests
39106
```
40-
The e2e script launches the server, waits for readiness, then runs `client/src/test.ts` inside this package which:
107+
108+
The E2E test:
41109
1. Calls `GET /api/acp/agents`
42-
2. Validates that at least one agent is available
110+
2. Opens a session for the first provider
111+
3. Sends a structured output request
112+
4. Streams and validates NDJSON frames
43113

44-
### “Interesting” client example
45-
Below is a minimal Node client (can live anywhere) that:
46-
1. Lists agents.
47-
2. Creates a session for the first provider.
48-
3. Sends a prompt requesting structured JSON output.
49-
4. Streams NDJSON frames and prints them as they arrive.
114+
### Minimal standalone client
50115

51116
```ts
52117
import fetch from 'node-fetch';
@@ -57,16 +122,14 @@ const headers = process.env.ACP_TOKEN
57122
: { 'Content-Type': 'application/json' };
58123

59124
async function main() {
60-
const agentsRes = await fetch(`${BASE_URL}/api/acp/agents`, { headers });
61-
const agents = (await agentsRes.json()).agents;
62-
const provider = agents[0].id;
125+
const agents = await (await fetch(`${BASE_URL}/api/acp/agents`, { headers })).json();
126+
const provider = agents.agents[0].id;
63127

64-
const sessionRes = await fetch(`${BASE_URL}/api/acp/sessions`, {
128+
const session = await (await fetch(`${BASE_URL}/api/acp/sessions`, {
65129
method: 'POST',
66130
headers,
67131
body: JSON.stringify({ provider }),
68-
});
69-
const { sessionId } = await sessionRes.json();
132+
})).json();
70133

71134
const schema = {
72135
type: 'object',
@@ -81,8 +144,8 @@ async function main() {
81144
method: 'POST',
82145
headers,
83146
body: JSON.stringify({
84-
sessionId,
85-
content: 'Review the latest commit and explain top risks.',
147+
sessionId: session.sessionId,
148+
content: 'Review the latest commit and explain key risks.',
86149
outputSchema: schema,
87150
}),
88151
});
@@ -96,10 +159,52 @@ async function main() {
96159
}
97160
}
98161

99-
main().catch(err => {
100-
console.error('Client failed', err);
101-
process.exit(1);
102-
});
162+
main().catch(console.error);
103163
```
104164

105-
Feel free to expand the client to create sessions, send prompts, and consume streamed NDJSON frames using the same APIs demonstrated in the script.
165+
---
166+
167+
## 📊 API Flow Overview
168+
169+
```mermaid
170+
sequenceDiagram
171+
participant Client
172+
participant ACP-Next Server
173+
participant HeadlessCoder SDK
174+
participant Provider (Codex/Claude/Gemini)
175+
176+
Client->>ACP-Next Server: POST /api/acp/sessions
177+
ACP-Next Server->>HeadlessCoder SDK: createCoder() + startThread()
178+
ACP-Next Server-->>Client: { sessionId }
179+
180+
Client->>ACP-Next Server: POST /api/acp/messages?stream=true
181+
ACP-Next Server->>HeadlessCoder SDK: thread.runStreamed()
182+
HeadlessCoder SDK->>Provider: execute task
183+
loop Streaming NDJSON
184+
ACP-Next Server-->>Client: {"type":"delta","text":"..."}
185+
end
186+
ACP-Next Server-->>Client: {"type":"done"}
187+
```
188+
189+
---
190+
191+
## 🛠️ Development Notes
192+
193+
- **Dynamic imports** ensure only enabled adapters are bundled.
194+
- Routes export `runtime = 'nodejs'` for CLI-based adapters (Codex, Gemini).
195+
- Sessions are in-memory by default; add Redis/Postgres for persistence.
196+
- Works with official ACP SDK clients (e.g. BeeAI, Zed).
197+
198+
---
199+
200+
## 🧾 License
201+
202+
MIT © 2025 [Ohad Assulin](https://github.com/OhadAssulin)
203+
204+
---
205+
206+
### 🤝 Contributing
207+
208+
Pull requests and issues are welcome!
209+
If you encounter a bug or have ideas for improvement, open an issue on GitHub:
210+
👉 [https://github.com/OhadAssulin/headless-coder-sdk/issues](https://github.com/OhadAssulin/headless-coder-sdk/issues)

0 commit comments

Comments
 (0)