Add your agent
Build a custom agent as a standalone agentic pod with
fred-sdk and fred-runtime, run it locally, and enroll it with a
Fred control plane — deployed on your terms, in your own repository.
Scope & audience
For developers building a custom agent for Fred. You author the agent with a small Python SDK, wrap it in an HTTP server (the "pod"), and a Fred control plane discovers and routes to it. You never fork the platform — an agent is a self-contained deployable unit that the platform enrolls.
fred_sdk +
fred_runtime). For working, maintained examples, use the
sample agents — they are the source of truth for
current patterns.
The model — an agent is a pod
Fred separates authoring from execution across three published packages. You depend on the first two:
fred-sdk — authorfred-runtime[app] — servefred-core — utilitiesYou build and run the pod from your own repository. The control plane pulls the pod's template catalog to discover its agents, a team enrolls one as a managed instance, and execution is routed back to the pod — authorized per team via Keycloak and OpenFGA.
Agent shapes
The SDK offers four authoring shapes — pick the simplest that fits:
ReActAgentGraphAgentTeamAgentsequential, dynamic, route.DeepAgentDefinitionHumanInputRequest / HumanChoiceOption
from any shape and the runtime pauses, surfaces the prompt to the UI, and resumes on the reply —
continuity handled transparently by the checkpointer.
Serve it as a pod
A pod is three tiny files plus config. The runtime does the rest — an HTTP server with execution, streaming, sessions, checkpoints, HITL, and an OpenAI-compatible endpoint.
# registry.py
from myapp.agents import WEATHER_AGENT
REGISTRY = {WEATHER_AGENT.agent_id: WEATHER_AGENT}
# main.py
from fred_runtime.app import create_agent_app, load_agent_pod_config
from myapp.registry import REGISTRY
app = create_agent_app(registry=REGISTRY, config=load_agent_pod_config())
# __main__.py
import uvicorn
uvicorn.run("myapp.main:app", host="0.0.0.0", port=8000)
A configuration.yaml (path via CONFIG_FILE) sets the pod name, base
path, host/port, the Knowledge Flow URL, observability, and optional security; a
.env (path via ENV_FILE) carries model keys. The router is mounted
under your configured base path:
/agents/templates/agents/execute · /agents/execute/stream/agents · /agents/mcp-catalog · /v1/chat/completionsRun & test locally
Start the pod, then drive it with the bundled CLI — no control plane or UI required:
# start the pod (SQLite checkpointer in dev — no database needed)
ENV_FILE=./config/.env CONFIG_FILE=./config/configuration.yaml python -m myapp
# talk to it: an interactive client for any pod
fred-agents-cli --base-url http://127.0.0.1:8000/<base_url> --agent my.weather.agent
Enroll with a control plane
The control plane is the sole authority for discovery, enrollment, and execution authorization. It pulls your pod's catalog from a static list in its configuration — point it at your pod's base URL:
# control-plane configuration.yaml
platform:
runtime_catalog_sources:
- runtime_id: my-agents # stable logical id
base_url: http://my-agents:8000/<base_url> # reachable from control-plane
ingress_prefix: /runtime/my-agents # browser-facing prefix
enabled: true
Then the lifecycle is:
- The control plane reads
GET {base_url}/agents/templatesand surfaces your agents as templates. - A team admin enrolls a template, creating a team-owned managed instance (with its own tuning — prompt overrides, model profile, selected MCP servers).
- Execution goes to the managed instance and is team-scoped: your pod authorizes each call with the caller's Keycloak JWT and an OpenFGA (ReBAC) check on the team before running.
Examples to start from
Two working references — copy from these rather than from prose:
.env, start the MCP servers, make run the pod, make chat.Deploy
A pod is an ordinary container. Build an image whose entrypoint runs your module
(python -m myapp) and externalize the config directory. Deploy it as a Kubernetes
Service reachable from the control plane, then add its runtime_catalog_sources
entry. Because the pod owns its own database checkpointer, it scales independently of the rest
of the platform.