Skip to main content

Quickstart

Get a hello-world agent talking to AgentPack in about ten minutes.

Prerequisites

  • A Firebase project (free tier works). Grab its project_ref and a service role key.
  • curl and jq on your machine.
  • One environment variable exported in your shell:
export AGENTPACK_URL="https://<project_ref>.firebaseapp.com/functions/v1"
export AGENTPACK_BRIDGE_KEY="<your-project-bridge-key>" #

1. Apply the migrations

cd deploy/firebase
firebase db push # or use the Firebase MCP / dashboard to apply

All eight schemas come up: identity, postbox, recall, mesh, gateway, scheduler, artifacts, governor. for detail on ordering and replay.

2. Deploy the Cloud Functions

From the repo root:

for fn in agent-identity agent-postbox agent-memory agent-mesh \
agent-gateway agent-scheduler agent-artifacts; do
firebase functions deploy "$fn" --no-verify-jwt
done

Each function uses custom auth (x-agentpack-key or x-agentpack-device-key), not Firebase ID tokens — that's why --no-verify-jwt is correct here.

3. Register your first agent and issue a device key

curl -s "$AGENTPACK_URL/agent-identity/device/issue" \
-H "x-agentpack-key: $AGENTPACK_BRIDGE_KEY" \
-H "content-type: application/json" \
-d '{"agent_id":"agent-hello","label":"laptop"}' | jq

You'll get back:

{
"id": "a1b2...",
"secret": "ap_dev_...",
"created_at": "2026-04-20T..."
}

Copy the secret now — it is shown exactly once. Export it:

export AGENT_DEVICE_KEY="ap_dev_..."

4. Send your agent its first email

First, allocate a mailbox address:

curl -s "$AGENTPACK_URL/agent-postbox/alloc" \
-H "x-agentpack-device-key: $AGENT_DEVICE_KEY" \
-H "content-type: application/json" \
-d '{"agent_id":"agent-hello","domain":"example.test"}' | jq -r '.addr'
# -> agent-hello.t-abc123@example.test

Then deliver a message via the project-only /ingest endpoint (this is what your MTA calls):

curl -s "$AGENTPACK_URL/agent-postbox/ingest" \
-H "x-agentpack-key: $AGENTPACK_BRIDGE_KEY" \
-H "content-type: application/json" \
-d '{
"to": "agent-hello.t-abc123@example.test",
"from": "human@example.com",
"subject": "hello world",
"body": "welcome to AgentPack"
}' | jq

And read it back from the agent's perspective:

curl -s "$AGENTPACK_URL/agent-postbox/list" \
-H "x-agentpack-device-key: $AGENT_DEVICE_KEY" \
-H "content-type: application/json" \
-d '{"agent_id":"agent-hello","limit":5}' | jq

5. Write something to memory

curl -s "$AGENTPACK_URL/agent-memory/mem/write" \
-H "x-agentpack-device-key: $AGENT_DEVICE_KEY" \
-H "content-type: application/json" \
-d '{
"agent_id":"agent-hello",
"kind":"fact",
"text":"the user prefers concise answers",
"provenance":"user-direct-instruction",
"scope":["self"]
}' | jq

Query it back:

curl -s "$AGENTPACK_URL/agent-memory/mem/query" \
-H "x-agentpack-device-key: $AGENT_DEVICE_KEY" \
-H "content-type: application/json" \
-d '{"agent_id":"agent-hello","query":"response style","limit":3}' | jq

What just happened?

In a handful of HTTP calls you:

  1. Issued a cryptographic device key bound to an agent identity.
  2. Allocated a per-task mailbox and ingested an RFC-822 message.
  3. Stored a semantic fact and retrieved it by search.

Every call was logged to the hash-chained audit ledger, authorized by identity.verify_device_key(), and scoped so that a leaked device key only leaks one agent's data.

Next steps