Skip to main content

Configuration

AntSeed stores configuration at ~/.antseed/config.json. This file is the normal source of truth for your node.

The intended workflow is:

  1. Create or update config.json with antseed seller setup or antseed config ...
  2. Keep non-secret settings there: providers, services, pricing, categories, ports, bootstrap nodes
  3. Keep secrets in environment variables: API keys, identity key
  4. Start your node with the grouped runtime commands

Once your config file is populated, the normal seller startup path is just:

antseed seller start

And the normal buyer startup path is:

antseed buyer start

You only need extra flags when you want to override the saved config for a specific run.

How the Config File Gets Created

You do not need to hand-write ~/.antseed/config.json unless you want to.

Common ways to create it:

# Interactive seller onboarding
antseed seller setup

# Add or update config entries directly
antseed config seller add-provider together --plugin openai --base-url https://api.together.ai
antseed config seller add-service together deepseek-v3.1 \
--upstream "deepseek-ai/DeepSeek-V3.1" \
--input 0.6 --cached 0.06 --output 1.7
antseed config set identity.displayName "Acme Inference"

--cached is optional. Set it (on either add-provider --cached ... for defaults or add-service --cached ... per service) when your upstream charges a reduced rate for cached-input tokens (e.g. Anthropic prompt caching, OpenAI prompt caching).

You can also edit the JSON file directly if that is easier for automation or deployment.

Config vs Environment Variables

Use config.json for durable node behavior. Use env vars for secrets and temporary overrides.

Put it in config.jsonPut it in env vars
Provider/plugin selectionOPENAI_API_KEY, ANTHROPIC_API_KEY
baseUrl for OpenAI-compatible providersANTSEED_IDENTITY_HEX
Service list and categoriesANTSEED_DEBUG=1
Pricing defaults and per-service pricingOne-off runtime overrides in deployment scripts
payments.crypto.rpcUrl for durable RPC configANTSEED_BASE_RPC_URL for deployment-specific Base RPC endpoints
Buyer proxy port and peer refresh intervalANTSEED_DATA_DIR for per-process buyer state isolation
Bootstrap nodes

For example, this is a normal production pattern:

{
"seller": {
"providers": {
"together": {
"plugin": "openai",
"baseUrl": "https://api.together.ai",
"services": {
"deepseek-v3.1": {
"upstreamModel": "deepseek-ai/DeepSeek-V3.1",
"pricing": {
"inputUsdPerMillion": 0.6,
"cachedInputUsdPerMillion": 0.06,
"outputUsdPerMillion": 1.7
},
"categories": ["chat", "coding", "math"]
}
}
}
}
}
}
export OPENAI_API_KEY=<your-key>
export ANTSEED_IDENTITY_HEX=<your-identity-key>
antseed seller start

Override Precedence

When the same setting exists in multiple places, AntSeed resolves it in this order:

  1. CLI flags for the current command
  2. Environment variables
  3. config.json
  4. Built-in defaults

So if config.json already contains your provider and service setup, you can still do a one-off run like:

antseed seller start --provider together --input-usd-per-million 0.7

That changes only the current process. It does not rewrite config.json.

Data Directory vs Config File

config.json controls durable settings, but buyer runtime state is isolated by the data directory. The default data directory is ~/.antseed; it contains buyer.state.json, SQLite databases, payment-channel files, and the fallback identity.key.

For each independent buyer node, service integration, isolated test, or concurrent process, use a separate data directory:

export BUYDIR="$HOME/.antseed-buyer-myapp"
mkdir -p "$BUYDIR"

ANTSEED_DATA_DIR="$BUYDIR" \
antseed --data-dir "$BUYDIR" buyer start \
--peer <peer-id> \
--port 8380

Prefer --data-dir in service/systemd scripts. ANTSEED_DATA_DIR is equivalent when the flag is not supplied. If buyer behavior looks stale or files appear in an unexpected place, check the startup log for the resolved data directory and buyer.state.json path. Do not rely on ANTSEED_HOME for CLI buyer state isolation.

Config Sections

SectionDescription
identityDisplay name
sellerPer-provider service offerings (plugin, pricing, categories, upstream model mapping), reserve floor, max concurrent buyers, agent directory
buyerMax pricing thresholds, proxy port, DHT peer refresh interval
paymentsChain ID (base-mainnet by default)
networkBootstrap nodes

Seller Shape

Everything a seller announces lives under seller.providers[name]. The key under providers is a user-chosen label, and plugin identifies the provider plugin package that powers it. The list of services, pricing, upstream model mapping, and normie-friendly category tags lives under seller.providers[name].services[id].

{
"seller": {
"reserveFloor": 10,
"maxConcurrentBuyers": 5,
"providers": {
"together": {
"plugin": "openai",
"baseUrl": "https://api.together.ai",
"defaults": {
"inputUsdPerMillion": 1,
"outputUsdPerMillion": 2,
"cachedInputUsdPerMillion": 0.1
},
"services": {
"deepseek-v3.1": {
"upstreamModel": "deepseek-ai/DeepSeek-V3.1",
"categories": ["chat", "math", "coding"],
"pricing": {
"inputUsdPerMillion": 0.60,
"outputUsdPerMillion": 1.70,
"cachedInputUsdPerMillion": 0.06
}
},
"qwen3.5-9b": {
"upstreamModel": "Qwen/Qwen3.5-9B",
"categories": ["chat", "fast", "free"],
"pricing": { "inputUsdPerMillion": 0, "outputUsdPerMillion": 0 }
}
}
}
}
}
}

Each service entry supports three optional fields:

FieldTypeDescription
upstreamModelstringThe model id the provider plugin will forward requests to. Defaults to the service id itself.
categoriesstring[]Normie-friendly tags announced in peer metadata (e.g. chat, coding, math, study, fast, free).
pricingobjectPer-service pricing in USD per million tokens. If omitted, the provider's defaults are used.

baseUrl on the provider block is forwarded to plugins that honor it (the openai plugin uses it as OPENAI_BASE_URL for Together, OpenRouter, etc.).

If you store baseUrl in config.json, you do not need to export OPENAI_BASE_URL separately. The CLI reads the JSON and passes it to the plugin runtime automatically.

Adding a Provider (CLI)

Use antseed config seller add-provider to create a provider entry and install the matching plugin package:

# Add a provider backed by the openai plugin, pointed at Together AI
# --cached sets the default cached-input price for every service under
# this provider (overridable per service). Omit it if your upstream does
# not offer a cached-input discount.
antseed config seller add-provider together \
--plugin openai \
--base-url https://api.together.ai \
--input 1 --cached 0.1 --output 2

# Add another using the same plugin for OpenRouter
antseed config seller add-provider openrouter \
--plugin openai \
--base-url https://openrouter.ai/api/v1

# Remove a provider
antseed config seller remove-provider openrouter

After adding a provider, you typically add one or more services and then start with:

export OPENAI_API_KEY=<your-key>
antseed seller start

Adding a Service (CLI)

Use antseed config seller add-service to add a service entry in one shot:

antseed config seller add-service together deepseek-v3.1 \
--upstream "deepseek-ai/DeepSeek-V3.1" \
--input 0.60 --output 1.70 --cached 0.06 \
--categories chat,math,coding \
--base-url https://api.together.ai

To remove one:

antseed config seller remove-service together deepseek-v3.1

You can also edit individual fields directly:

antseed config seller set providers.together.services.deepseek-v3.1.pricing.inputUsdPerMillion 0.55
antseed config seller set providers.together.services.deepseek-v3.1.categories '["chat","math","coding","fast"]'

Buyer Settings

Buyers can cap what they're willing to pay to avoid expensive providers:

antseed config buyer set maxPricing.defaults.inputUsdPerMillion 25
antseed config buyer set maxPricing.defaults.outputUsdPerMillion 75

The buyer proxy refreshes its discovered peer cache from the DHT in the background. The default is 5 minutes, and you can tune it in milliseconds:

antseed config buyer set peerRefreshIntervalMs 300000

Each discovered endpoint is then queried over HTTP for signed peer metadata. The default per-endpoint metadata fetch timeout is 1500ms; raise it for high-latency networks or lower it to make discovery skip slow/offline endpoints faster:

antseed config buyer set metadataFetchTimeoutMs 1500

For one process, use either the runtime flag or env var instead of writing config:

antseed buyer start --metadata-fetch-timeout-ms 1500
ANTSEED_BUYER_METADATA_FETCH_TIMEOUT_MS=1500 antseed buyer start

Identity and Metadata

antseed config set identity.displayName "Acme Inference - us-east-1"
antseed config seller set publicAddress "peer.example.com:6882"

Provider Authentication

Provider plugins authenticate with their upstream AI service. Credentials live in environment variables — they never belong in config.json.

ProviderAuth env varNotes
anthropicANTHROPIC_API_KEY
openaiOPENAI_API_KEYSet providers.<name>.baseUrl in config.json for Together/OpenRouter/etc.
claude-codekeychainReads from claude-code secure storage
local-llmnoneOllama/llama.cpp

The separation is intentional:

  • config.json says what you offer
  • env vars say how to authenticate

That means you can commit deployment config templates safely while injecting secrets at runtime.

Ant Agent

Providers can wrap their service with an ant agent — a knowledge-augmented AI service that injects a persona, guardrails, and on-demand knowledge into buyer requests.

{
"seller": {
"agentDir": "./my-agent"
}
}

The agent directory contains an agent.json manifest defining persona, guardrails, knowledge modules, and custom tools. The LLM decides which knowledge to load during the conversation. Buyers see only the final response.

Per-service agents (different agents for different services):

{
"seller": {
"agentDir": {
"social-strategist": "./agents/social",
"code-reviewer": "./agents/coding",
"*": "./agents/default"
}
}
}

See the @antseed/ant-agent README for the full manifest reference.

Identity Storage

PriorityMethodBest for
1ANTSEED_IDENTITY_HEX env varCLI and server deployments
2Desktop keychain (Electron safeStorage)AntSeed Desktop app
3Custom IdentityStoreKMS/HSM integrations
4~/.antseed/identity.key (plaintext)Not recommended for production

For production servers, pass the key from a secrets manager:

export ANTSEED_IDENTITY_HEX="$(vault kv get -field=key secret/antseed/identity)"

Base RPC URL

Sellers should configure a dedicated Base JSON-RPC endpoint for production deployments. Public defaults are fine for testing, but provider RPCs (Alchemy, Infura, QuickNode, self-hosted nodes, etc.) are more reliable for seller registration, staking, reserve, settle, and close transactions.

Use payments.crypto.rpcUrl for durable config:

antseed config set payments.crypto.rpcUrl "https://base-mainnet.g.alchemy.com/v2/<key>"

Or use runtime overrides when you do not want to edit config.json:

export ANTSEED_BASE_RPC_URL=https://base-mainnet.g.alchemy.com/v2/<key>
antseed seller start

# one-off process override
antseed seller start --base-rpc-url https://base-mainnet.infura.io/v3/<key>

Precedence is: CLI flag, then ANTSEED_BASE_RPC_URL, then payments.crypto.rpcUrl, then built-in Base defaults.

Runtime Environment Variables

Only secrets, global toggles, and deployment-specific runtime overrides are set via env vars — everything else is in config.json.

VariableDescription
ANTSEED_IDENTITY_HEXIdentity private key (64 hex chars, optional 0x prefix)
ANTSEED_BASE_RPC_URLRuntime Base JSON-RPC endpoint override for seller on-chain operations
ANTSEED_BUYER_METADATA_FETCH_TIMEOUT_MSRuntime buyer peer-discovery metadata fetch timeout in milliseconds
ANTHROPIC_API_KEYUpstream Anthropic API key (used by the anthropic provider plugin)
OPENAI_API_KEYUpstream OpenAI-compatible API key (used by the openai provider plugin)
ANTSEED_SETTLEMENT_IDLE_MSIdle time before settling a session (default: 600000 / 10 min)
ANTSEED_DEFAULT_DEPOSIT_USDCDefault lock amount per session (default: 1)
ANTSEED_DEBUGEnable debug logging (set to 1)