---
title: "Stream an LLM chat turn that uses the MCP server as its toolbelt"
method: POST
path: "/v1/mcp-chat/stream"
tags: ["mcp-chat"]
---

# Stream an LLM chat turn that uses the MCP server as its toolbelt

`POST /v1/mcp-chat/stream`

SSE stream of one chat turn.

The LLM (Claude) sees every tool registered on our MCP server. When
the model wants a tool, we dispatch it via ``mcp.call_tool`` — same
code path as remote MCP clients hitting ``/mcp/`` — and feed the
result back. ``end_user_id`` (optional) pins all end-user-scoped
tool calls to that contact.

The endpoint streams an event-stream of:

- ``text_delta`` — incremental assistant text (append to the bubble).
- ``tool_call`` — model decided to call a tool (name, input).
- ``tool_result`` — JSON-string result (or error).
- ``turn_end`` — one Claude turn finished (may loop again for tools).
- ``done`` — full turn complete.
- ``error`` — fatal; stream closes.

No RBAC dependency on this endpoint itself — tools enforce their
own permissions via the ``@cx_tool`` registry, so a viewer-role
caller chatting here can only invoke the read tools.

## Request body

- ChatStreamRequest — Body for ``POST /v1/mcp-chat/stream``. ``messages`` is the full rolling history. ``end_user_id`` (optional) pins the bound end-user for the MCP tool calls — same semantics as the ``x-end-user-id`` header on the MCP HTTP endpoint.
  - `messages` ChatMessage[], required
    - `role` 'user' | 'assistant', required
    - `content` string, required
  - `end_user_id` string, uuid, nullable
  - `model` string — Chat completions model identifier (OpenAI).
  - `max_tokens` integer

## Response `200`

Successful Response

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/oneloop-hq/apis/feather-api.md) · [All operations](https://skmtc.net/oneloop-hq/apis/feather-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/oneloop-hq/feather-api/revisions/5a5597ebb2d6/schema)
