FastAPI Server

Mango ships with a ready-made FastAPI server that exposes your agent over HTTP with Server-Sent Events streaming.

Setup

from mango.servers.fastapi import MangoFastAPIServer

server = MangoFastAPIServer(agent)
server.run()  # http://localhost:8000

Endpoints

POST /api/v1/ask/stream

Stream a question as SSE events.

Request:

{
  "question": "How many users signed up last month?",
  "session_id": "optional-session-id"
}

Response (SSE stream):

data: {"type": "tool_call", "tool_name": "run_mql", "tool_args": {...}}
data: {"type": "tool_result", "tool_name": "run_mql", "success": true, "preview": "[{\"count\": 1247}]"}
data: {"type": "answer", "text": "1,247 users signed up last month."}
data: {"type": "done", "iterations": 2, "input_tokens": 1820, "output_tokens": 94, "memory_hits": 1, "tool_calls_made": ["run_mql"]}

Pass the same session_id across requests to maintain conversation history.

Custom configuration

from fastapi import FastAPI
from mango.servers.fastapi import MangoFastAPIServer

server = MangoFastAPIServer(
    agent=agent,
    host="0.0.0.0",
    port=8000,
    cors_origins=["https://myapp.com"],
)

# Access the underlying FastAPI app
app: FastAPI = server.app
app.add_middleware(...)  # add your own middleware

server.run()

Consuming SSE in JavaScript

const response = await fetch('/api/v1/ask/stream', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ question: 'How many orders last week?' }),
})

const reader = response.body.getReader()
const decoder = new TextDecoder()

while (true) {
  const { done, value } = await reader.read()
  if (done) break

  const lines = decoder.decode(value).split('\n')
  for (const line of lines) {
    if (!line.startsWith('data: ')) continue
    const event = JSON.parse(line.slice(6))

    if (event.type === 'answer') console.log(event.text)
    if (event.type === 'done') console.log(`Used ${event.input_tokens} tokens`)
  }
}