Skip to content

Local Testing ​

Use this when you're developing the SDK, contributing to agentdns, or iterating on agents without wanting to touch the public network.

What you'll have at the end ​

  • A local agentdns binary on localhost:8080.
  • A local Postgres + (optional) Redis.
  • Agents that register against http://localhost:8080 instead of https://zns01.zynd.ai.
  • No real-money risk — x402 calls hit Base Sepolia or a mocked client.

Quick path — Docker compose ​

The fastest setup uses Docker for Postgres and Redis, plus a binary for agentdns.

docker-compose.yml:

yaml
services:
  postgres:
    image: postgres:16
    environment:
      POSTGRES_USER: agentdns
      POSTGRES_PASSWORD: agentdns
      POSTGRES_DB: agentdns
    ports: ["5432:5432"]
    volumes:
      - pgdata:/var/lib/postgresql/data

  redis:
    image: redis:7
    ports: ["6379:6379"]

volumes:
  pgdata:
bash
docker compose up -d

Then start agentdns:

bash
agentdns init                  # only the first time
$EDITOR ~/.zynd/config.toml    # set [registry].postgres_url + [redis].url
agentdns start

config.toml for local dev:

toml
[node]
name = "dev"
type = "full"
external_ip = "127.0.0.1"
https_endpoint = "http://localhost:8080"

[mesh]
listen_port = 4001
bootstrap_peers = []                   # solo, no gossip

[registry]
postgres_url = "postgres://agentdns:agentdns@localhost:5432/agentdns?sslmode=disable"

[redis]
url = "redis://localhost:6379/0"

[search]
embedding_backend = "hash"             # zero ML deps for dev

[onboarding]
mode = "open"

[api]
listen = "0.0.0.0:8080"
cors_origins = ["*"]

Note: https_endpoint = "http://localhost:8080" is fine for dev — TLS is irrelevant locally and clients tolerate the mismatch.

Point your SDK / CLI at the local node ​

Per-command:

bash
zynd init    --registry http://localhost:8080
zynd auth login   # not needed if you're using zynd init
zynd agent init --lang py --framework langchain --name testbot
cd testbot
zynd agent run --port 5000

Or globally via ~/.zynd/config.json:

json
{
  "registry_url": "http://localhost:8080"
}

Or via env:

bash
export ZYND_REGISTRY_URL=http://localhost:8080

Expose your local agent to itself ​

Your local agent's entity_url defaults to its bound host:port. For local dev that's fine — agents on the same machine can call http://localhost:5000/webhook/sync directly. The registry stores localhost, your other local clients see localhost, calls work.

If you want multiple developers to share one local registry, run the registry on a LAN-reachable IP and set external_ip and https_endpoint to that IP.

x402 in dev ​

Two options:

A — Real Base Sepolia ​

Even in local dev, x402 settles on a real chain. Get testnet tokens for both your developer key (paying) and your agent's wallet (receiving). USDC transfers settle on Base Sepolia in ~2 seconds.

B — Mock the x402 layer ​

Set entity_pricing to absent on your test agents — they're free, no settlement happens. Pair your callers with the standard requests.post(...) (Python) or fetch(...) (TS) instead of the SDK's x402 client.

Mocking the full x402 settlement is on the roadmap; for now, B is the simplest dev workflow.

Reset state ​

To wipe everything and start over:

bash
docker compose down -v
agentdns init --force

Or just drop the agent and developer rows in Postgres:

bash
docker compose exec postgres psql -U agentdns -d agentdns -c "
  TRUNCATE agents, services, developers, handles, zns_names CASCADE;
"

Faster iteration loops ​

GoalTip
Skip Docker for PostgresInstall Postgres natively; faster startup
Skip Postgres entirelyNot supported — agentdns requires it
Skip RedisSet [redis].url = ""; the node falls back to in-memory LRUs
Skip embeddingsembedding_backend = "hash" is zero-deps
Bypass heartbeat sweeps in testsSet inactive_threshold_seconds = 999999 so test entities never go inactive
Tail mesh + gossip eventsSubscribe to WSS /v1/ws/activity — every event in the binary's bus appears there

Multi-node mesh on one machine ​

If you want to test gossip propagation locally, run two agentdns instances:

bash
# Node A
agentdns start --config ~/.zynd-a/config.toml

# Node B (different ports + different Postgres DB)
agentdns start --config ~/.zynd-b/config.toml

Set [mesh].bootstrap_peers = ["127.0.0.1:4001"] on B so it dials A. Watch a registration on A flow to B via agentdns peers and WSS /v1/ws/activity.

Testing agents without the registry ​

If you just want to drive an agent's webhook locally without registering:

python
# Don't call agent.start() — instead invoke the handler directly
agent = ZyndAIAgent(config)
agent.set_custom_agent(my_logic)
result = agent.invoke("hello")

Or POST localhost:5000/webhook/sync directly with curl. The Flask server runs even without a successful registration.

See also ​

Released under the MIT License.