Skip to main content

Setup

Everything on this page is shared by all three tracks. Do it once. By the end you’ll have an agent identity, three secrets in a .env file, a short script that proves those credentials talk to the platform, and the one call that turns the identity into an agent Swarmd will actually route to.
Already have SWARMD_AGENT_ID and SWARMD_CLIENT_SECRET from someone on your team? Skip to Step 4.

Step 1: Get a tenant

A tenant is your organisation on Swarmd. Everything — agents, users, policies, subscriptions — lives inside one. If your organisation is already on Swarmd, ask an admin to add you. Otherwise create one:
Verify the email that arrives, then log in to get a bearer token:
This page covers only what the SDK needs. The surrounding tenant-auth flows — email verification, token refresh, inviting teammates — are in the API reference, or do them in the dashboard.

Step 2: Create your agent identity

Registration takes two calls, and the one that hands you credentials comes first. POST /registry/v1/agents creates an identity: a name, an OAuth2 service account, and a webhook signing key. It asks for no URLs, because your agent doesn’t exist yet.
Credentials first, code second. This is deliberate: you get working credentials before you have anything to point Swarmd at, so you can build, run and test the agent locally with real identity.What you hold after this call is an unbootstrapped shell — an identity with no A2A agent card behind it. It can mint tokens, but it cannot be subscribed to anything, cannot send or receive relay traffic, and cannot be sent a webhook. The registry reports its status as BOOTSTRAP_REQUIRED and refuses to use it: “Agent must be bootstrapped before it can be used.”You clear that in Step 7, once there’s a real agent serving a real card.

Step 3: Save the three secrets

The response contains three values:
All three are shown exactly once. Swarmd never returns them again — copy them into your secret store now. What recovery looks like differs by secret:
  • clientSecret — rotate it in place. POST /registry/v1/agents/{agentId}/credential mints a fresh one and returns { "clientId": "…", "clientSecret": "…" }. The clientId is the agent id and does not change, so the agent keeps its identity, its subscriptions and its grants. Update SWARMD_CLIENT_SECRET and you’re done.
  • webhookSecret — no rotation endpoint. .../credential neither returns nor changes it. Recovering it means deregistering the agent (DELETE /registry/v1/agents/{agentId}) and reactivating it (POST /registry/v1/agents/{agentId}/reactivate), which mints a fresh clientSecret and a fresh webhookSecret against the same agent id. Deregistration deactivates the agent’s subscriptions, and reactivation does not restore them — an operator has to re-create the grants.
The agentId is not a secret. It’s your client id, and you can read it back from GET /registry/v1/agents at any time.
Your agent still works. Outbound calls are unaffected — they only use clientSecret.What you lose is push. When an operator subscribes your agent to a new sub-agent or grants it a new MCP server, Swarmd normally POSTs a signed kick to your agent’s /admin/webhook and the agent re-discovers its catalogue in place. Without the secret, that endpoint refuses every delivery with 503, and somebody has to POST /admin/refresh (or restart the pod) by hand after each change.Set it. It costs one line of .env.

Step 4: Install the SDK

Install the package for your track. The wrappers pull in swarmd-sdk plus their framework, so you only install one thing.
Use a virtualenv. The wrappers pin a2a-sdk, mcp, and their framework to tested ranges, and those ranges have real teeth — see dependency ranges.

Step 5: Write your .env

The SDK reads configuration from environment variables and loads a .env file automatically via python-dotenv.
.env
.env holds live secrets. Add it to .gitignore before you add anything to it. In production, inject these as environment variables from your secret manager rather than shipping a file.
For swarmd-sdk on its own, you don’t — SwarmDClient.from_env() falls back to the production URLs.For the wrappers you do. Their create_runtime() only configures the runtime when all four of SWARMD_AGENT_ID, SWARMD_CLIENT_SECRET, SWARMD_BASE_URL and SWARMD_TOKEN_URL are present. Leave any one unset and you get standalone mode: the agent boots and serves, but discovers no sub-agents and no MCP tools.That’s a deliberate escape hatch for local development without a Swarmd account — but it’s also the single most common “why can’t my agent see anything?” cause. If discovery is silently empty, check all four.

Step 6: Confirm it works

Before writing any agent code, prove the credentials are good:
check.py
get_agent_subscriptions() takes your own agent id as an argument even though the client already authenticates as that agent — the endpoint is shared with tenant-admin callers who can query any agent. When an agent calls it, the registry compares the id against the JWT subject and rejects a mismatch with 403, so passing anything other than your own id will fail.
Three possible outcomes:
Correct. An unbootstrapped shell has no subscriptions and can’t be given any until its card is attached, and even a bootstrapped agent starts with none until an operator grants them. Your credentials work — that’s what this step was checking. Move on.
.env isn’t being found or isn’t being read. Confirm the file sits in the directory you run python from, and that the variable names match exactly (SWARMD_AGENT_ID, not SWARMD_AGENTID).
The token endpoint rejected your client credentials. Usually one of:
  • SWARMD_CLIENT_SECRET was truncated on copy — it has no separators, so a partial paste looks plausible.
  • The secret was rotated with POST /registry/v1/agents/{agentId}/credential and .env still holds the old one.
  • The agent was deregistered, which revokes its service account.
  • SWARMD_TOKEN_URL points at the wrong realm or the wrong environment.
See Troubleshooting.

Step 7: Attach your agent card

This is the second half of registration, and the one that makes the agent real. Come back to it once your agent is running and serving its card — the SDK serves it at /.well-known/agent-card.json — on a URL Swarmd can reach. You can build, run and iterate on the agent before this call; nothing that involves another party — subscriptions, relay traffic, webhooks — works until after it.
With the card attached, the shell becomes a routable agent: operators can subscribe it to sub-agents and grant it MCP servers, the relay will carry its traffic, and the webhook kicks described in Core concepts start arriving.
Every PUT appends a version. It is a full replacement, not a patch — send the complete body each time. Swarmd re-resolves the card, appends a new immutable version, and leaves the previous one intact; GET /registry/v1/agents/{agentId}/versions returns the history. Bump registryVersion on each publish.To change just the tenant-facing name or description, use PATCH /registry/v1/agents/{agentId} instead — that edits identity metadata and doesn’t touch the card.
Routine card drift doesn’t need a PUT. POST /registry/v1/agents/{agentId}/refresh-card re-fetches the card at the URL already on file and updates the cached metadata if it has changed. The Google ADK wrapper calls it on boot for you; with the core SDK or LangChain, call client.refresh_agent_card(agent_id) yourself. It cannot bootstrap a shell — until you PUT a card URL there is nothing for it to fetch.

Next

Core concepts

What the runtime, the two token audiences, and the refresh loop actually do. Ten minutes that make every helper obvious.

Skip to building

Straight into code: Core SDK, Google ADK, or LangChain.