> ## 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.

# How agents work

> The subprocess model, host capabilities, and registration flow.

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** - `pip install` additional pure-Python packages into the agent environment

**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 <Tooltip tip="An internal message bus used for agent invocation and session streaming.">NATS</Tooltip> 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.

```python agent.py theme={null}
from friday_agent_sdk import agent, ok, AgentContext, run

@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__":
    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:

| Capability   | What you use it for              | Why Friday handles it                          |
| ------------ | -------------------------------- | ---------------------------------------------- |
| `ctx.llm`    | Generate text or structured data | API keys, rate limits, provider routing        |
| `ctx.http`   | Call external APIs               | TLS, timeouts, audit logging                   |
| `ctx.tools`  | Invoke MCP servers               | External processes run outside the agent       |
| `ctx.stream` | Show progress in the UI          | Real-time updates to connected clients         |
| `ctx.env`    | Read configured secrets          | No host environment access from the subprocess |

Route I/O through `ctx` for production work. This keeps credentials out of your code, enables audit logging, and lets Friday handle rate limits and provider routing. You can install `requests` or `anthropic` directly for local debugging, but host capabilities are preferred for anything that runs in a space.

## Registration

Register an agent from anywhere on your machine:

```bash theme={null}
friday agent register ./my-agent
```

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`:

```yaml workspace.yml theme={null}
agents:
  my-agent:
    type: user
    description: "Does something useful"
```

## Current constraints

**Dependencies**

* The `friday_agent_sdk` and Python standard library are available by default
* You can `pip install` additional packages - native C extensions (NumPy, Pydantic) work if the environment has them
* All I/O should still route through `ctx.llm`, `ctx.http`, `ctx.tools` for audit logging and credential management

**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:

```bash theme={null}
vim my-agent/agent.py
friday agent register ./my-agent
```

Test with the [Agent Tester](/guides/agent-tester) or via the CLI:

```bash theme={null}
friday agent exec my-agent -i "test input"
```

## See also

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/sdk/quickstart">
    Step-by-step walkthrough of building your first agent.
  </Card>

  <Card title="Python reference" icon="code" href="/sdk/python-reference/agent-decorator">
    Complete API documentation for the SDK.
  </Card>
</CardGroup>

* [Quickstart](/sdk/quickstart) — Step-by-step walkthrough of building your first agent.
* [Python reference](/sdk/python-reference/agent-decorator) — Complete API documentation for the SDK.
