Creating Agents
An agent is a YAML config file that tells society what handler to use and which port to listen on. Society discovers agent configs from a directory (default: agents/).
Agent config format
Section titled “Agent config format”name: my-agentdescription: What this agent doesport: 8010handler: execbackend: command: my-tool args: ["--flag", "value"] session_flag: "--session" resume_flag: "--resume" env: - API_KEY=sk-xxxskills: - id: summarize name: Summarize description: Summarizes documentsFields
Section titled “Fields”| Field | Required | Description |
|---|---|---|
name | Yes | Unique agent name |
description | No | Human-readable description |
port | No | HTTP listen port (1-65535) |
handler | Yes | echo, greeter, or exec |
backend | Only for exec | External command configuration |
skills | No | List of capabilities the agent advertises |
Built-in handlers
Section titled “Built-in handlers”Returns the input message unchanged. Useful for testing.
name: echoport: 8001handler: echogreeter
Section titled “greeter”Prepends “Hello! You said: ” to every message. Another test handler.
name: greeterport: 8002handler: greeterThe real workhorse. Wraps any CLI tool as an agent. The tool receives the message text on its arguments and should output a response.
name: claudeport: 8003handler: execbackend: command: claude args: ["-p", "--output-format", "json"] session_flag: "--session-id" resume_flag: "--resume"How exec works
Section titled “How exec works”For each incoming message:
- Extracts text from the message parts
- Loads or creates a conversation thread (
~/.society/threads/<id>.json) - Builds the command:
command args... <message-text> - On first message: appends
session_flag <session-id>if configured - On follow-ups: appends
resume_flag <session-id>instead - Runs the command, captures stdout
- Parses JSON output if possible (looks for
{"result": "..."}format), otherwise uses raw stdout - Saves the exchange to the thread file
Examples
Section titled “Examples”Wrap Claude Code:
name: claudeport: 8003handler: execbackend: command: claude args: ["-p", "--output-format", "json"] session_flag: "--session-id" resume_flag: "--resume"Wrap a custom script:
name: translatorport: 8010handler: execbackend: command: python3 args: ["translate.py"] env: - DEEPL_API_KEY=your-keyWrap any LLM CLI:
name: ollama-llamaport: 8020handler: execbackend: command: ollama args: ["run", "llama3.2"]Running agents
Section titled “Running agents”Single agent:
society run --config agents/my-agent.yamlAll agents in a directory:
society daemon run --agents ./agentsSpecific agents only:
society daemon run echo claudeSTDIO mode
Section titled “STDIO mode”Agents can also run over stdio instead of HTTP, useful for embedding:
society run --config agents/echo.yaml --stdioIn this mode, the agent reads JSON-RPC requests from stdin and writes responses to stdout, one per line.