> ## Documentation Index
> Fetch the complete documentation index at: https://docs.doomberg.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Session Tools

> session_context opens a traced research run, attaches the user's question, and scopes every subsequent tool call. It is always called first.

The session tools family contains a single tool — `session_context` — but it is the most important call in the entire workflow. It opens a traced research run, attaches the user's question, and scopes every subsequent tool call the agent makes.

## `session_context`

Open a traced research run and attach the user's question. Every tool call after this one is recorded against the session and streamed live to the web UI via SSE.

### Arguments

| Argument     | Type   | Required | Description                                                                                               |
| ------------ | ------ | -------- | --------------------------------------------------------------------------------------------------------- |
| `prompt`     | string | Yes      | The user's natural-language question or research goal. Stored verbatim and displayed in the web UI.       |
| `title`      | string | No       | A short human-readable title for the session. If omitted, one is derived from the first line of `prompt`. |
| `session_id` | string | No       | An existing session ID to resume. If omitted, a new session is created.                                   |

### What it does

1. Creates a new session row (or resumes an existing one) scoped to the caller's `tenant_id`.
2. Stores the `prompt` verbatim — this is the canonical record of what the human asked.
3. Returns a `session_id` that the agent includes in every subsequent tool call (either explicitly or implicitly via the MCP session context).
4. Begins streaming trace events to the web UI via SSE so the human can watch the research unfold live.

### Why it's always called first

<Callout type="warn">
  No other tool can be called before `session_context`. The MCP server rejects calls that arrive without an active session — there is no unscoped execution path. This is enforced at the server, not just by the agent's instructions.
</Callout>

Every Ithaca tool call is traced. Tracing requires a session to attach events to. Without `session_context`, there is no session, and the server returns an error:

```json theme={null}
{
  "error": "no_active_session",
  "message": "Call session_context before calling any other tool."
}
```

This guarantee is what makes the web UI's live trace and replay possible — there is never a tool call that happens "outside" a session.

### Return value

`session_context` returns a session descriptor:

| Field          | Type              | Description                                                 |
| -------------- | ----------------- | ----------------------------------------------------------- |
| `session_id`   | string (UUID)     | The session identifier. Include this in subsequent calls.   |
| `tenant_id`    | string (UUID)     | The tenant the session belongs to. Echoed for transparency. |
| `title`        | string            | The resolved session title.                                 |
| `created_at`   | string (ISO 8601) | When the session was opened.                                |
| `status`       | string            | `open` — the session is active and accepting tool calls.    |
| `trace_stream` | string (URL)      | The SSE endpoint the web UI subscribes to.                  |

### Example call

```json theme={null}
{
  "prompt": "Research NVDA — pull price history, screen peers, check fundamentals and insider activity, propose a momentum strategy, and backtest it.",
  "title": "NVDA momentum research"
}
```

### Example response

```json theme={null}
{
  "session_id": "sess_01HQKX2J3K4M5N6P7R8S9T0V1W",
  "tenant_id": "tnt_01HQKX2J3K4M5N6P7R8S9T0V1X",
  "title": "NVDA momentum research",
  "created_at": "2025-01-15T14:32:07.891Z",
  "status": "open",
  "trace_stream": "https://app.doomberg.me/api/sessions/sess_01HQKX2J3K4M5N6P7R8S9T0V1W/events/stream"
}
```

## Resuming a session

Pass `session_id` to resume an existing session instead of creating a new one. This is useful when an agent is re-invoked to continue research from a previous turn:

```json theme={null}
{
  "prompt": "Now compare the NVDA strategy against AMD using the same parameters.",
  "session_id": "sess_01HQKX2J3K4M5N6P7R8S9T0V1W"
}
```

The new `prompt` is appended to the session's prompt history. The session's `status` remains `open` and the trace stream continues from where it left off.

<Accordion title="Session lifecycle">
  * `open` — the session is active and accepting tool calls.
  * `closed` — the agent called `session_close` (or the session timed out). No further tool calls are accepted. The trace is still readable and replayable from the web UI.
  * `archived` — the session has been moved to cold storage after the retention window. Metadata is still queryable; raw trace events may take longer to load.
</Accordion>

<Tip>
  The human can close a session from the web UI at any time. When a session is closed, in-flight tool calls are allowed to finish but no new ones are accepted.
</Tip>

## Related

* [Data tools](/tools/data) — what to call after the session is open
* [Trace observability](/api/runs) — how the web UI consumes the trace stream
* [SSE streaming](/api/runs) — the transport behind the live trace
