How to Use DeepSeek TUI's HTTP SSE Runtime API for Headless Agent Workflows

DeepSeek TUI provides a local-only HTTP/SSE runtime API on 127.0.0.1:7878 that enables external programs to drive AI agent workflows without a terminal interface, featuring durable thread storage and replayable event streams with monotonic sequence numbers.

DeepSeek TUI ships with a built-in HTTP server that exposes the assistant's capabilities through Server-Sent Events (SSE). This runtime API, implemented in crates/tui/src/runtime_api.rs, allows developers to build headless automation tools that create threads, stream model responses, and manage conversation state programmatically.

Architecture of the HTTP SSE Runtime API

The runtime daemon launches via deepseek serve --http and binds to localhost by default. According to the source code in crates/tui/src/runtime_api.rs, the server implements a durable thread/turn/item storage model found in runtime_threads.rs, ensuring conversations persist beyond individual connections.

Each SSE event carries a globally monotonic seq value, enabling clients to resume streams from any point using the since_seq query parameter.

Event Payload Structure

Events follow a standardized JSON schema defined in docs/RUNTIME_API.md:

{
  "seq": 42,
  "timestamp": "2026-02-11T20:18:49.123Z",
  "thread_id": "thr_1234abcd",
  "turn_id": "turn_5678efgh",
  "item_id": "item_90ab12cd",
  "event": "item.delta",
  "payload": { "delta": "partial output", "kind": "agent_message" }
}

Core API Endpoints

The runtime API exposes REST endpoints for thread management and SSE streaming:

  • GET /health - Returns {"status":"ok"} for health checks
  • POST /v1/threads - Creates a new conversation thread
  • POST /v1/threads/{id}/turns - Submits messages and initiates SSE streams
  • GET /v1/threads/{id}/events?since_seq=N - Provides replayable SSE event streams
  • POST /v1/threads/{id}/turns/{turn_id}/interrupt - Stops ongoing generation
  • POST /v1/threads/{id}/turns/{turn_id}/steer - Sends steering prompts to active turns
  • POST /v1/threads/{id}/compact - Manually triggers context compaction

SSE Streaming Mechanics

When posting to /v1/threads/{id}/turns, the server returns HTTP 200 with Content-Type: text/event-stream. The connection remains open while the model generates tokens, emitting data: lines containing JSON events.

Replay Capability

The since_seq query parameter enables historical replay. Setting since_seq=0 returns the complete conversation history followed by live updates, making it ideal for recovering dropped connections or debugging agent workflows.

Security Model and Configuration

The API binds exclusively to 127.0.0.1 with no authentication or TLS, creating a safe local automation boundary. As documented in docs/RUNTIME_API.md, the server never exposes the DeepSeek API key, reporting only the source (env, config, or missing).

CORS origins can be configured via the [runtime_api] table in ~/.deepseek/config.toml:

[runtime_api]
cors_origins = ["http://localhost:5173"]

Building Headless Agent Workflows

Implementing a complete headless workflow involves four steps:

  1. Start the server:
deepseek serve --http
  1. Create a thread:
curl -s -X POST http://127.0.0.1:7878/v1/threads \
     -H "Content-Type: application/json" \
     -d '{"title":"automation-agent"}' | jq .
  1. Send messages with SSE streaming:
curl -N -X POST http://127.0.0.1:7878/v1/threads/<thread_id>/turns \
     -H "Content-Type: application/json" \
     -d '{"messages":[{"role":"user","content":"Analyze this data"}]}'
  1. Consume events:
curl -N http://127.0.0.1:7878/v1/threads/<thread_id>/events?since_seq=0

Rust Client Implementation

For native integration, the DeepSeekClient struct in crates/tui/src/client/chat.rs provides SSE parsing utilities. Below is a minimal implementation:

use deepseek_tui::client::{DeepSeekClient, SseEvent};
use tokio_stream::StreamExt;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let client = DeepSeekClient::new_default()?;
    let thread = client.create_thread(None).await?;
    
    let _turn = client
        .post_turn(&thread.id, vec!["Write a haiku about clouds."])
        .await?;

    let mut stream = client.sse_events(&thread.id, 0).await?;
    while let Some(event) = stream.next().await {
        match event? {
            SseEvent::ItemDelta { delta, .. } => print!("{delta}"),
            SseEvent::ItemCompleted { .. } => break,
            _ => {}
        }
    }
    Ok(())
}

This uses the same parse_sse_chunk logic found in the CLI client at crates/tui/src/client/chat.rs.

Summary

  • DeepSeek TUI exposes a local HTTP/SSE API via deepseek serve --http on port 7878
  • The durable thread model in crates/tui/src/runtime_api.rs supports conversation replay through monotonic seq values
  • SSE streaming delivers real-time token generation via GET /v1/threads/{id}/events
  • Security boundaries restrict access to localhost and never expose API keys
  • Rust clients can leverage internal structures from crates/tui/src/client/chat.rs for robust parsing

Frequently Asked Questions

How do I restart the SSE stream if my connection drops?

Use the since_seq query parameter to resume from the last received sequence number. Setting since_seq=0 replays the entire thread history, while specific values continue from that point. This durability feature is implemented in crates/tui/src/runtime_threads.rs.

Can I expose the DeepSeek TUI API to other machines on my network?

While possible using --host 0.0.0.0, the runtime API lacks authentication and TLS. According to the security documentation in docs/RUNTIME_API.md, this is not recommended for production deployments as the server is designed for local automation only.

How do I interrupt a running agent turn programmatically?

Send a POST request to /v1/threads/{id}/turns/{turn_id}/interrupt. This endpoint immediately halts token generation for the specified turn ID, allowing your headless workflow to implement timeout or cancellation logic.

What file contains the main HTTP server implementation?

The HTTP/SSE server logic resides in crates/tui/src/runtime_api.rs, while data structures for payloads are defined in crates/tui/src/models.rs. The SSE parsing utilities used by the CLI are located in crates/tui/src/client/chat.rs.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →