ai-v2 demo

A generic tool-calling AI service, driven entirely by an application's own MCP server.

ai-v2 runs the agent loop and talks to the LLM. It knows nothing about any particular business — no tools, no domain, no persona of its own. The application it serves supplies all of that over one MCP endpoint, and ai-v2 discovers it live on every chat turn.

What you are talking to here is example-app: a small coffee shop with eight products, six sales and three staff. It hosts its own MCP server, declares its own assistant persona, and answers in Khmer. Point ai-v2 at a different MCP server and it becomes a different assistant, with no change to ai-v2 itself — that is the whole claim this demo exists to test.

you ──▶ POST /api/v1/chat example-app's chat gateway │ ▼ ai-v2 (private) ──▶ POST /mcp back into example-app for the data

Ask it something

curl -s -X POST https://HOST/api/v1/chat/complete \
  -H 'Content-Type: application/json' \
  -d '{"message":"What did we sell most of, and how much did we take?"}'

Watch tools_used in the reply: it is how you tell an answer grounded in the shop's data from one the model invented. Ask a follow-up in the same conversation by passing back the conversation_id you got:

curl -s -X POST https://HOST/api/v1/chat/complete \
  -H 'Content-Type: application/json' \
  -d '{"message":"And who sold the most?","conversation_id":"<id>"}'

Or read the reply as it is written, as server-sent events:

curl -N -X POST https://HOST/api/v1/chat \
  -H 'Content-Type: application/json' \
  -d '{"message":"តើទំនិញមួយណាលក់ដាច់ជាងគេ?"}'

Look at the tools it has

The assistant can only do what the shop's MCP server offers it. That list is public — call the MCP endpoint directly. Both headers matter: replies come back as SSE, not plain JSON.

curl -s -X POST https://HOST/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Six of the seven are read-only. The one write, note_reminder, is offered to the model only because it is annotated destructiveHint: false — without that annotation ai-v2 withholds it, which is the default for any write whose blast radius it cannot know.

Everything else

Swagger lists every endpoint with a Try it out button — the shop's conversations, its dashboard, and the chat gateway.

Before you type anything real