Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.hellofriday.ai/llms.txt

Use this file to discover all available pages before exploring further.

Your agent runs as a Python subprocess spawned per invocation. The daemon sends it one request, the agent handles it and exits. Here’s what that means in practice. What this gives you:
  • No API keys in your code — Friday manages providers and authentication
  • Secure external access — HTTP and tools route through Friday’s audited channels
  • Simple development — write a Python file, register it, it runs immediately
  • No dependency conflicts — only the Python standard library plus friday_agent_sdk inside the agent
How you work with it:
  • Write normal Python using the @agent decorator and execute() function
  • Access the outside world through ctx.llm, ctx.http, ctx.tools, ctx.stream
  • Register with the daemon — no restart required

Execution model

Each invocation spawns a fresh process. The daemon sends one NATS message, the agent handles it, returns a result, and exits. State does not persist between calls — if you need to store state, write to memory via MCP tools or return it in the result.
agent.py
from friday_agent_sdk import agent, ok, AgentContext

@agent(id="my-agent", version="1.0.0", description="Does something useful")
def execute(prompt: str, ctx: AgentContext):
    # prompt: the task passed from the job FSM
    # ctx: bridges to Friday's capabilities
    return ok({"result": "done"})

if __name__ == "__main__":
    from friday_agent_sdk import run
    run()  # connects to NATS and handles the request
The if __name__ == "__main__": run() block is required — it’s how the subprocess connects to the daemon.

Host capabilities

Your agent calls Friday for any external interaction:
CapabilityWhat you use it forWhy Friday handles it
ctx.llmGenerate text or structured dataAPI keys, rate limits, provider routing
ctx.httpCall external APIsTLS, timeouts, audit logging
ctx.toolsInvoke MCP serversExternal processes run outside the agent
ctx.streamShow progress in the UIReal-time updates to connected clients
ctx.envRead configured secretsNo host environment access from the subprocess
Do not use requests, httpx, anthropic, or openai directly — route everything through ctx. This enforces the security model and lets Friday handle credentials.

Registration

Register an agent from anywhere on your machine:
curl -X POST http://localhost:18080/api/agents/register \
  -H "Content-Type: application/json" \
  -d '{"entrypoint": "/abs/path/to/agent.py"}'
# → {"ok": true, "agent": {"id": "my-agent", "version": "1.0.0", "path": "..."}}
The daemon validates the agent (spawns it with FRIDAY_VALIDATE_ID, reads metadata via NATS), copies all source files from the same directory to the Friday home directory under agents/{id}@{version}/, and hot-reloads the registry. No daemon restart required. Once registered, reference the agent by ID in workspace.yml:
workspace.yml
agents:
  my-agent:
    type: user
    agent: "my-agent"
    description: "Does something useful"

Current constraints

Dependencies
  • The friday_agent_sdk and Python standard library are all that’s available inside an agent
  • External packages (NumPy, Pydantic, etc.) are not supported — use ctx.llm, ctx.http, ctx.tools for external capabilities
State
  • Every invocation is a fresh process — module-level state resets each time
  • Persist through MCP tools or return data in ok()
One agent per file
  • One @agent decorator per Python file. A second raises RuntimeError. Split into separate files.

Iteration workflow

Edit your agent source and re-register:
vim my-agent/agent.py
curl -X POST http://localhost:18080/api/agents/register \
  -H "Content-Type: application/json" \
  -d '{"entrypoint": "/abs/path/to/my-agent/agent.py"}'
Test with the Agent Tester or via the CLI:
friday agent exec my-agent -i "test input"

See also

Quickstart

Step-by-step walkthrough of building your first agent.

Python reference

Complete API documentation for the SDK.