Quickstart

Get acp-server running, create a Covenant, and record your first contribution in under five minutes. Prerequisites: Go 1.25+ installed. No other dependencies.

1. Build & run the server

1

Clone and build

bash
git clone https://github.com/ymow/acp-server
cd acp-server
go build ./...

Produces two binaries: acp-server (HTTP API) and acp-mcp (MCP adapter for AI clients).

2

Start the server

bash
ACP_ADDR=:8080 ACP_DB_PATH=./acp.db ./acp-server

The server listens on :8080. SQLite DB is created automatically at./acp.db. No migrations to run.

On first start the server generates a fresh master key at$HOME/.acp/keys/v1.key (mode 0600) and prints its fingerprint. Back this file up — losing it permanently breaks decryption of any encrypted column. Override the location with ACP_KEY_FILE=/abs/path/master.key (the keyring lives in the sibling keys/ directory). To rotate later run acp-server rotate-key followed by acp-server reencrypt.

2. Create a Covenant

3

Create the Covenant and get your owner token

bash
curl -s -X POST http://localhost:8080/covenants \
  -H "Content-Type: application/json" \
  -d '{"name": "my-project"}' | jq .

Response includes a covenant_id (e.g. cvnt_a54e1c43) and an owner_token. Save both — the owner token is shown once.

Store your owner token securely. It controls all admin operations.
4

Configure contribution tiers

bash
curl -s -X POST http://localhost:8080/covenants/$CVNT_ID/tiers \
  -H "X-Owner-Token: $OWNER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '[
    {"name":"core",    "multiplier": 3.0},
    {"name":"feature", "multiplier": 2.0, "entry_fee_tokens": 50},
    {"name":"review",  "multiplier": 1.5},
    {"name":"docs",    "multiplier": 1.0}
  ]'
entry_fee_tokens is optional (Phase 4.6.C, ACR-50 §7). When non-zero, an applicant joining at that tier must commit the fee from their own balance — surfaces in the audit log via the entry-fee ledger entry.
5

Transition Covenant to OPEN

bash
curl -s -X POST http://localhost:8080/covenants/$CVNT_ID/transition \
  -H "X-Owner-Token: $OWNER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"to": "OPEN"}'

Participants can now apply to join.

3. Add a participant via the ACR-50 access gate

Phase 4.6 introduced ACR-50: a structured access flow where applicants apply before being approved, owners review applications, and entry fees (if configured) are captured. The legacy /join + approve_agent path still works for back-compat, but new integrations should use apply_to_covenant / approve_agent_access.
6

Applicant submits an access request

bash
curl -s -X POST http://localhost:8080/covenants/$CVNT_ID/apply \
  -H "Content-Type: application/json" \
  -d '{
    "platform_id": "github:alice",
    "tier_id": "feature",
    "payment_ref": "stripe:ch_xxx",
    "self_declaration": "I built the auth flow"
  }' | jq .

Public endpoint — applicants don't yet have a session. Returns a request_id and a 12-char platform_id_hash_prefix so the applicant can verify the server received their submission without the server re-echoing the raw platform_id (sealed at rest under ACR-700).

7

Owner approves the access request

bash
curl -s -X POST http://localhost:8080/tools/approve_agent_access \
  -H "X-Covenant-ID: $CVNT_ID" \
  -H "X-Owner-Token: $OWNER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"params": {"request_id": "REQUEST_ID_FROM_ABOVE"}}'

On approval the server creates the covenant_members row, mints a session token bound to the applicant, and (if the tier has entry_fee_tokens) records the entry-fee ledger entry. Pending requests are also surfaced via list_members for owner triage.

The applicant can poll status before approval:

bash
curl -s -X POST http://localhost:8080/tools/get_agent_access_status \
  -H "Content-Type: application/json" \
  -d '{"params": {"covenant_id": "$CVNT_ID", "request_id": "REQUEST_ID"}}'
8

Transition Covenant to ACTIVE

bash
curl -s -X POST http://localhost:8080/covenants/$CVNT_ID/transition \
  -H "X-Owner-Token: $OWNER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"to": "ACTIVE"}'

Once ACTIVE, approved participants can submit passages.

9

Submit and approve a passage

bash
# Participant proposes a contribution
curl -s -X POST http://localhost:8080/tools/propose_passage \
  -H "X-Covenant-ID: $CVNT_ID" \
  -H "X-Agent-ID: agent_alice" \
  -H "X-Session-Token: $SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"params": {
    "tier": "feature",
    "unit_count": 200,
    "description": "Implement user authentication flow"
  }}' | jq .

# Owner approves (use log_id from the response)
curl -s -X POST http://localhost:8080/tools/approve_draft \
  -H "X-Covenant-ID: $CVNT_ID" \
  -H "X-Owner-Token: $OWNER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"params": {"log_id": "LOG_ID_FROM_ABOVE", "acceptance_ratio": 0.9}}'

Tokens calculated: 200 × 2.0 × 0.9 = 360 ink

4. Settle the Covenant

10

Lock and generate settlement

bash
# Lock the Covenant (no more contributions)
curl -s -X POST http://localhost:8080/covenants/$CVNT_ID/transition \
  -H "X-Owner-Token: $OWNER_TOKEN" \
  -d '{"to": "LOCKED"}'

# Generate settlement output
curl -s -X POST http://localhost:8080/tools/generate_settlement_output \
  -H "X-Covenant-ID: $CVNT_ID" \
  -H "X-Owner-Token: $OWNER_TOKEN" | jq .

# Confirm (makes it immutable)
curl -s -X POST http://localhost:8080/tools/confirm_settlement_output \
  -H "X-Covenant-ID: $CVNT_ID" \
  -H "X-Owner-Token: $OWNER_TOKEN"

The Covenant is now in SETTLED state. The hash chain is verified. Ink totals are permanent.

Verify the hash chain at any time: GET /covenants/{id}/audit/verify

Next steps