Model Context Protocol server for LLM-native consumers (OpenWebUI Pipelines, custom apps with MCP-aware LLM clients). Hosted as a separate service in the compose stack, on port 4002.
Connection
Endpoints
| name | type | required | default | notes |
|---|
| GET /health | — | — | no auth | Healthcheck. Returns { ok: true, service, version }. |
| POST /mcp | — | yes | Bearer | Streamable HTTP transport — JSON-RPC over HTTP+SSE. |
| GET /mcp | — | yes | Bearer | Server-initiated SSE stream (rarely needed in stateless mode). |
| DELETE /mcp | — | yes | Bearer | Session shutdown — no-op in stateless mode. |
Sample client (TypeScript / Node)
tsimport { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const TOKEN = process.env.MCP_TOKEN; // "evs_…" issued at /settings/tokens
const transport = new StreamableHTTPClientTransport(
new URL("http://<host>:4002/mcp"),
{ requestInit: { headers: { Authorization: `Bearer ${TOKEN}` } } },
);
const client = new Client(
{ name: "my-app", version: "0.1.0" },
{ capabilities: {} },
);
await client.connect(transport);
const { tools } = await client.listTools();
console.log(tools.map((t) => t.name));
const result = await client.callTool({
name: "recommend_for_use_case",
arguments: { query: "I need a heavy electric truck for hauling", max: 3 },
});
const payload = JSON.parse(result.content[0].text);
console.log(payload.vehicles);
await client.close();
OpenWebUI Pipelines
In OpenWebUI's MCP Pipelines config, point at http://<host>:4002/mcp with the Bearer header set to a token from /settings/tokens. All 8 tools become available to the model as functions.
Tools (v1)
Each tool's input schema and detailed description ship in the MCP protocol itself — call client.listTools() for the live, authoritative copy. Summaries below are for orientation.
search_vehicles
Filter the verified EV catalog by typed criteria.
get_vehicle
Full detail for one verified vehicle by slug.
recommend_for_use_case
NL query → ranked list with reasoning (never fabricates).
compare_vehicles
Side-by-side comparison for up to 10 slugs.
find_similar
Cosine similarity over per-category spec vector.
check_thailand_availability
B2B / B2C availability + country of origin + notes.
list_categories
Categories with at least one verified vehicle.
list_manufacturers
Manufacturers with vehicle counts, optionally per category.
Tool result shape
Every tool returns a CallToolResult:
ts{
content: [{ type: "text", text: "<JSON-stringified result>" }],
structuredContent: { /* same payload as a typed object — convenience for LLM clients */ }
}