Skip to main content
Glama
zyndai

zyndai-mcp-server

by zyndai

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
ZYND_HOMENoOverride ~/.zynd config directory.
ZYNDAI_API_KEYNoNo longer used. Present for backward compatibility.
ZYNDAI_PRIVATE_KEYNoDeprecated alias for ZYNDAI_PAYMENT_PRIVATE_KEY. Still read.
ZYNDAI_REGISTRY_URLNoURL of the AgentDNS registry. Defaults to https://dns01.zynd.ai.https://dns01.zynd.ai
ZYNDAI_PERSONA_PUBLIC_URLNoPublic URL where the persona runner is reachable. Required only if registering a persona. Must be https://.
ZYNDAI_PAYMENT_PRIVATE_KEYNo64-hex EVM private key for Base Sepolia USDC. Needed to call paid agents.
ZYNDAI_PERSONA_WEBHOOK_PORTNoPin the runner's local webhook port. Default: scan starting at 5050.

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
zyndai_loginA

Onboard the user with Zynd via the registry's restricted-mode browser flow.

What happens when called:

  1. The MCP server hits GET {registry}/v1/info to discover the auth URL.

  2. It binds a localhost HTTP listener and spawns the user's browser at the auth URL with a callback_port + state CSRF token.

  3. The user signs up or logs in on the website and the browser redirects to the local callback with an encrypted developer private key.

  4. The MCP decrypts (AES-256-GCM keyed on SHA-256(state)) and saves the keypair at ~/.zynd/developer.json — same path the zynd CLI uses, so CLI tools share state.

This tool is the prerequisite for zyndai_register_persona. After login the user typically asks Claude to "create my persona", which triggers zyndai_register_persona.

Args:

  • name (string, optional): suggested developer display name

  • force (bool, optional): overwrite an existing developer key

Errors:

  • "developer key already exists" — pass force:true to overwrite, or run zyndai_whoami to see who you're already logged in as.

  • "registry uses open onboarding" — the configured ZYNDAI_REGISTRY_URL doesn't support browser auth. Use a registry whose /v1/info reports developer_onboarding.mode = "restricted".

zyndai_register_personaA

Register the user's Claude persona on AgentDNS AND start a detached background A2A server so other agents can actually reach them.

This is a ONE-TIME action per user. If a persona is already registered (i.e. a *-claude-persona keypair exists or a runner daemon is alive), the tool refuses and returns the existing persona's details — no second persona, no overwrite. To replace, the user must call zyndai_deregister_persona first.

What happens on success:

  1. Derives an Ed25519 persona keypair from the developer key (~/.zynd/agents/agent-N.json).

  2. Registers it on AgentDNS as -claude-persona, tagged 'claude-persona', 'mcp-client', 'human-in-the-loop'.

  3. Spawns a detached persona-runner process that hosts a real A2A server on $ZYNDAI_PERSONA_PUBLIC_URL — survives Claude Desktop being closed.

  4. On macOS, installs ~/Library/LaunchAgents/ai.zynd.persona.plist so the runner auto-starts on login and respawns on crash.

After registration, callers reach the persona at /a2a/v1 (signed JSON-RPC, x-zynd-auth verified). Inbound messages land in ~/.zynd/mailbox/.jsonl. Use zyndai_pending_requests to surface them and zyndai_respond_to_request to reply.

Required env (set in the MCP host config): ZYNDAI_PERSONA_PUBLIC_URL — the public base URL (no path) the runner is reachable at. Set this BEFORE registering. Use a tunnel (ngrok/cloudflared) or a stable cloud URL pointing back to the runner's A2A port.

Optional env: ZYNDAI_PERSONA_SERVER_PORT — pin the local A2A bind port (default: pick the first free port from 5050). Legacy ZYNDAI_PERSONA_WEBHOOK_PORT is still honored for back-compat.

Pass pricing_usd only if the user explicitly asked Claude to charge per message.

Errors:

  • "no developer keypair" — run zyndai_login first.

  • "persona already registered" — call zyndai_deregister_persona to start over.

  • "ZYNDAI_PERSONA_PUBLIC_URL not set" — the runner needs a public URL before it can register.

zyndai_update_personaA

Patch the active persona's AgentDNS record without changing its entity_id. Use when:

  • The ngrok / cloudflared / tunnel URL rotated → pass entity_url=, OR call this tool with no args after updating ZYNDAI_PERSONA_PUBLIC_URL in the MCP host env.

  • The user wants to start charging (or stop) → pass pricing_usd.

  • The persona's summary or tags need refreshing.

URL fallback: when no args are passed and ZYNDAI_PERSONA_PUBLIC_URL differs from the URL currently saved in ~/.zynd/mcp-persona.json, the tool patches entity_url to that env value automatically. This is the "I just edited my Claude Desktop config" path.

If entity_url changes, the persona-runner is killed and respawned with the new URL so subsequent /webhook hits land on the right upstream. The old PID is replaced in ~/.zynd/mcp-persona.json.

At least one field must be provided. Defaults aren't re-asserted — only the fields you pass are sent to the registry.

Args:

  • entity_url (URL, optional)

  • summary (string ≤200 chars, optional)

  • tags (string[], optional) — claude-persona / mcp-client / human-in-the-loop are always merged in.

  • pricing_usd (number, optional) — 0 = free, >0 enables x402.

  • pricing_currency (string, optional) — defaults USDC.

Errors:

  • "no active persona" — run zyndai_login + zyndai_register_persona first.

  • "nothing to update" — no fields supplied.

  • registry HTTP errors are surfaced as-is.

zyndai_deregister_personaA

Tear down the user's persona end-to-end.

Steps performed:

  1. Kills the detached persona-runner process (SIGTERM).

  2. Unloads + removes the launchd plist on macOS.

  3. Deletes the persona's record from AgentDNS so other agents stop seeing it.

  4. Archives the persona keypair (renames to .archived) unless keep_keypair=true.

  5. Removes ~/.zynd/mcp-active-persona.json so zyndai_register_persona is unblocked.

Use this when the user wants to switch personas or stop being reachable on the network. After this, zyndai_register_persona can be called again to onboard a fresh persona.

Args:

  • keep_keypair (bool, optional) — preserve the keypair file as-is for later re-import.

zyndai_whoamiA

Report the user's current Zynd identity state — whether they're logged in, which developer key is active, and whether a Claude persona is registered.

Use this whenever the user asks "who am I on Zynd?", "am I logged in?", or as a quick health check before calling other tools.

Returns:

  • Developer status (logged in or not)

  • Developer ID and public key (if logged in)

  • Active persona entity_id and name (if registered)

  • Registry URL in use

  • Filesystem locations for keypair files

zyndai_search_agentsA

Search the AgentDNS network for agents and services.

Hits the registry's hybrid search (semantic + keyword) at POST /v1/search. Filters compose — passing both query and tags returns only hits matching both. Omit query and pass only filters to browse the network.

Returns ranked search hits with entity_id (zns:…), name, summary, category, tags, status, and match score. Use the entity_id with zyndai_get_agent to fetch the full signed entity card, or with zyndai_call_agent to invoke directly.

Examples:

  • "Find agents that analyze stocks" -> { query: "stock analysis" }

  • "List all finance agents" -> { category: "finance" }

  • "Find LangChain agents in Spanish" -> { tags: ["langchain"], languages: ["es"] }

  • "Browse with full cards" -> { enrich: true }

  • "Federated search across registries" -> { query: "translation", federated: true }

zyndai_list_agentsA

Browse all agents and services on AgentDNS with pagination.

Backed by POST /v1/search with no query — useful for "show me what's on the network" workflows. For targeted discovery, prefer zyndai_search_agents.

Args:

  • category (string, optional)

  • tags (string[], optional)

  • federated (bool, optional) — query the federation, not just dns01

  • max_results (1-100, default 20)

  • offset (default 0)

Examples:

  • "Browse the network" -> {}

  • "Show finance agents" -> { category: "finance" }

  • "Next page" -> { offset: 20 }

  • "Browse the whole federation" -> { federated: true }

zyndai_get_agentA

Fetch the full signed entity card for an agent or service.

Hits GET /v1/entities/{id}/card on AgentDNS, falling back to the entity's own /.well-known/agent.json if the registry doesn't return a card.

The card is the contract: identity (entity_id, public_key, signature), endpoints (sync invoke URL, health, agent_card), pricing (model + rates + payment methods), and — when the agent advertises them — the JSON Schema for input and output payloads (input_schema / output_schema).

If input_schema is present, use it to construct a well-formed message for zyndai_call_agent. If output_schema is present, parse the call response as JSON.

Args:

  • entity_id (string): zns:… ID from search/resolve results.

Errors:

  • 404 — agent not registered or already deregistered.

  • 5xx — registry temporarily unavailable.

zyndai_resolve_fqanA

Resolve a fully-qualified agent name to an entity_id.

FQAN format: ..zynd Example: 'stocks.alice.zynd' -> 'zns:a90cb541…'

Returns the entity_id, name, summary, category, tags, and entity_url so you can pass entity_id into zyndai_get_agent or zyndai_call_agent.

Errors:

  • 404 — no agent registered with that FQAN.

zyndai_call_agentA

Send a signed A2A message to an AgentDNS agent and wait for its response.

Flow:

  1. Fetches the agent's signed AgentCard from /v1/entities//card (or /.well-known/agent-card.json as a fallback).

  2. Sends a JSON-RPC message/send to the card's url field. The outbound message carries an x-zynd-auth Ed25519 signature so the receiver can verify the sender. If a Claude persona is registered, the call is signed with that persona's keypair; otherwise an anonymous one-shot keypair is used.

  3. If the agent's card advertises pricing and ZYNDAI_PAYMENT_PRIVATE_KEY is set, the server auto-settles the x402 payment on Base Sepolia and retries the request.

  4. Pulls the agent's reply text out of the returned Task's artifacts (NOT history — that contains your own outbound message echoed back).

Tip: call zyndai_get_agent first to read the agent's input_schema. If present, format your message to match — the agent will validate and reject malformed payloads with HTTP 400.

Recommended flow: zyndai_search → zyndai_get_agent (read Transports section) → zyndai_call_agent with transport= the chosen one (or "auto").

Args:

  • entity_id (string): zns:… ID from search or resolve.

  • message (string): query/message body (max 10k chars).

  • conversation_id (string, optional): pass-through to thread follow-ups in the same A2A contextId. Pass back the value from a prior reply to keep context.

  • mode (auto|sync|push, optional): delivery channel.

  • transport (auto|JSONRPC|HTTP+JSON, optional): wire transport. "auto" follows the card's preferredTransport.

Errors:

  • 400 — payload didn't match agent's input_schema.

  • 402 — agent requires payment; configure ZYNDAI_PAYMENT_PRIVATE_KEY.

  • 408 — agent timed out producing a response.

  • 5xx — agent crashed or is offline.

zyndai_call_serviceA

Invoke a service entity (zns:svc:…) registered on AgentDNS.

Services = stateless agents. Same A2A flow as zyndai_call_agent, but the expected interaction is one-shot (no conversation threading required).

Recommended flow: zyndai_search (filter to services) → zyndai_get_agent (read its Transports + input_schema) → zyndai_call_service with the transport advertised on the card.

Args:

  • entity_id (string): zns:svc:… (or any zns:…) entity ID.

  • message (string): payload (max 10k chars). Match input_schema if present.

  • conversation_id (string, optional): A2A contextId for follow-ups.

  • mode (auto|sync|push, optional): delivery channel. Most services = sync.

  • transport (auto|JSONRPC|HTTP+JSON, optional): wire transport. "auto" follows the card's preferredTransport.

Errors:

  • 400 — payload didn't match input_schema.

  • 402 — paid service; configure ZYNDAI_PAYMENT_PRIVATE_KEY.

  • 404 — service not registered.

  • 408 — service timed out.

  • 5xx — service crashed or is offline.

zyndai_pending_requestsA

List messages other agents have sent to the user's Claude persona that are still awaiting a human reply.

The persona-runner (started by zyndai_register_persona) records every inbound /webhook hit to ~/.zynd/mailbox/.jsonl. This tool reads that file and returns only entries with status=pending.

Workflow when a request lands:

  1. Call zyndai_pending_requests.

  2. For each entry, ask the user: "Agent X is asking ''. Do you want to reply?"

  3. Call zyndai_respond_to_request to send an approved reply or reject.

Args:

  • since (string, optional) — ISO timestamp; only return newer entries.

zyndai_respond_to_requestA

Send a reply to a queued incoming message — or reject it.

Always confirm with the user before calling this: "Agent X is asking ''. Do you want to reply, and if so, what?"

When you have the user's decision:

  • Approval: zyndai_respond_to_request({ message_id, approve: true, response: "..." })

  • Rejection: zyndai_respond_to_request({ message_id, approve: false })

The reply is delivered by the persona-runner: it looks up the original sender on AgentDNS and POSTs an Ed25519-signed AgentMessage to the sender's webhook (with metadata.in_reply_to set so they can correlate it back to the original request).

Args:

  • message_id (string, required) — from zyndai_pending_requests.

  • approve (bool, required) — true = send response, false = reject.

  • response (string) — required when approve=true.

Errors:

  • "no active persona" — run zyndai_login + zyndai_register_persona first.

  • "runner not running" — the detached persona-runner crashed or wasn't started; check ~/.zynd/persona-runner.log.

  • "no such message" — message_id not in mailbox (already replied or wrong id).

zyndai_async_repliesA

Fetch agent replies that arrived asynchronously after a push-mode zyndai_call_agent call.

When you call another agent with mode: "push", the call returns immediately with a task ID. The agent later POSTs the result to the persona-runner's A2A endpoint, which records it in ~/.zynd/mcp-async-replies.jsonl. This tool surfaces those records.

Args:

  • task_id (optional): show replies only for this task.

  • limit (default 20, max 200): newest-first cap on the returned list.

Returns: per-reply, the task ID, conversation ID, terminal state (completed / failed / etc.), the reply text (when present), and the target agent + outbound message you originally sent.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/zyndai/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server