This reference is for code running on the same Mac as Lantern or for server code using local.fetch() through an approved connection. A normal Next.js app should start with the Vercel AI SDK guide.

REST quick start

Web apps should usually use the Lantern Vercel AI SDK provider, which handles connecting, routing, signing, and streaming. The server helper also exposes local.fetch(path, init) for supported AI calls through the same connection: chat completions, messages, image generations, and image edits. Tools on the Mac can call the local endpoint with the token created during setup.

Supported AI call through Lantern
const local = lantern.server(request);

const response = await local.fetch("/v1/chat/completions", {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({
    model: local.model,
    messages: [{ role: "user", content: "Explain why the sky looks blue." }],
  }),
});
Terminal
curl http://127.0.0.1:4319/v1/chat/completions \
  -H "Authorization: Bearer $(tr -d '\n' < ~/.lantern/token)" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "codex",
    "messages": [{ "role": "user", "content": "Explain why the sky looks blue." }]
  }'

The response puts generated text in choices[0].message.content and includes token usage plus Lantern metadata from the CLI. OpenAI tools/tool_choice and Anthropic tools/tool_choice use native tool calls for Apple Intelligence, Codex App Server, and Claude.

i

Text, streaming, and client-defined tools are supported. Structured response formats are not supported yet.

HTTP endpoints

GET /health

Returns the running Lantern version so a local tool can check that the process is on.

GET /v1/catalog

Lists configured providers, their provider-named model IDs, and current CLI availability.

GET /v1/models

Lists available providers in OpenAI's model-list format.

POST /v1/chat/completions

OpenAI-compatible text and native tool calling with standard JSON or server-sent event responses.

POST /v1/messages

Anthropic-compatible text and native tool calling with Anthropic's named streaming events.

POST /v1/images/generations

OpenAI-compatible image generation through a signed-in Codex setup with working image generation. Returns one PNG.

POST /v1/images/edits

Accepts up to eight GIF, JPEG, PNG, or WebP files, 20 MB each and 64 MB total. Returns one PNG.

POST /v1/agent/runs

A trusted local workspace task with an explicit directory and read or write access level, streamed as newline-delimited events.

WS /v1/socket

The persistent multi-turn session interface described below.

AI endpoints accept Authorization: Bearer …. Anthropic clients can use x-api-key. The health endpoint is open so local process managers can check whether Lantern is running. CLI availability means the command was found when Lantern started; it does not re-check sign-in.

HTTP streaming

Add "stream": true to an OpenAI-compatible request to receive server-sent events as the CLI generates output.

Streaming body
{
  "model": "claude",
  "stream": true,
  "messages": [
    { "role": "user", "content": "Give me three names for a weather app." }
  ]
}

Lantern sends standard chat-completion chunks and finishes the stream with [DONE]. Provider diagnostics and local usage remain available as Lantern metadata.

WebSocket sessions

The lantern.v1 WebSocket protocol keeps one CLI conversation open for follow-up prompts. Browsers send the token as a WebSocket subprotocol because they cannot set an Authorization header.

i

Treat the token below like a password: it grants access to Lantern's local REST and WebSocket APIs. A browser receives it only through the older pairLocalLantern() flow. New websites should use createLanternApp so the token never enters the page.

Browser
const encoded = btoa(token)
  .replaceAll("+", "-")
  .replaceAll("/", "_")
  .replaceAll("=", "");

const socket = new WebSocket(
  "ws://127.0.0.1:4319/v1/socket",
  ["lantern.v1", `lantern.auth.${encoded}`],
);

Scripts and server processes can send the token in a normal Authorization header when opening the WebSocket. After authentication, Lantern sends a hello message with the available providers and model names.

Start a session
{
  "type": "session.start",
  "requestId": "start-1",
  "provider": "codex",
  "prompt": "Explain why the sky looks blue."
}

Lantern creates a fresh provider session and keeps it associated with this connection. To expose tools, add tools and an optional toolChoice to the start message.

Start with a native tool
{
  "type": "session.start",
  "provider": "apple",
  "prompt": "What is the weather in Berlin?",
  "tools": [{
    "name": "weather",
    "description": "Get weather for a city",
    "inputSchema": {
      "type": "object",
      "properties": { "city": { "type": "string" } },
      "required": ["city"]
    }
  }],
  "toolChoice": { "type": "auto" }
}

Session events

Lantern → Client
{ "type": "session.started", "session": { "id": "…", "state": "running" } }
{ "type": "turn.started", "sessionId": "…" }
{ "type": "output.delta", "sessionId": "…", "text": "Blue light…" }
{ "type": "tool.call", "sessionId": "…", "call": { "id": "…", "name": "weather", "arguments": { "city": "Berlin" } } }
{ "type": "turn.completed", "sessionId": "…", "status": "completed" }
{ "type": "session.state", "sessionId": "…", "state": "idle" }

Build the application UI from these shared fields. Provider-specific messages remain available under raw for diagnostics and advanced integrations.

Continue and cancel

Client → Lantern
{ "type": "session.prompt", "sessionId": "…", "prompt": "Explain that more simply." }
{ "type": "session.tool_results", "sessionId": "…", "results": [{ "id": "…", "content": "{\"temperature\":21}" }] }
{ "type": "session.cancel", "sessionId": "…" }
{ "type": "session.close", "sessionId": "…" }

Return results for every pending call together. The selected provider resumes the same native turn and can emit more calls before it completes. The creating connection owns its sessions. Closing the socket closes those provider processes as well, giving each WebSocket a clear conversation lifetime.

See the standalone WebSocket client example for a complete browser implementation.