Skip to content

USE CASE

Embed a copilot in the product you already have.

Your app keeps routes and auth. SvedaClient talks to sveda-server. The visitor gets a scoped token. The stream carries text, tools, and MCP events.

:8787

sveda-server default bind

session.send

one POST per turn

sveda_embed_

token minted on the host

The challenge without a sidecar

Product teams want a copilot in the surface they already ship. Without Sveda they grow an orchestration repo, a prompt router, a stream parser, and a second deploy — then try to hide it behind a widget. The host should keep routes and auth. The agent loop should sit beside the app, not inside it.

Control plane first

Workers, session stores, and a custom SSE dialect appear before a visitor can send a turn. Weeks of glue before the product sees a token.

Widget lock-in

A framework island replaces the host UI. Auth leaks into the browser, or the loop lands in the application request cycle.

Two sources of truth

Eval harnesses, tool registries, and model keys live in a different repo from the product. Shipping a copilot means shipping that repo too.

How Sveda solves it

Mint a scoped embed token on the host. Attach SvedaClient in any JavaScript host. Run sveda-server beside the app. You do not replace the product, and you do not stand up a control plane.

Mint on the host

POST /sveda/embed/token issues a sveda_embed_ token scoped to visitor_id. The browser never holds the host key.

  • Host authenticates with x-sveda-host-key
  • Token is HMAC, prefixed sveda_embed_
  • Client sends x-sveda-embed-token
  • TTL is set on the runtime, minimum 60 seconds
  • Optional host MCP credentials ride the same handshake

Attach any JS host

Install @sveda-ai/core. SvedaClient holds endpoints, headers, and frontend tools. session.send posts the turn.

  • Works wherever fetch exists — not a Vue-only SDK
  • endpoints.stream is the attach surface
  • headers may be static or a function
  • Frontend tools register on the client, not in a second repo
  • Optional UI packages are not required to send a turn

Runtime beside the app

sveda-server binds 0.0.0.0:8787 by default. Agent loop, catalog, tools, and MCP live there — not in your request cycle.

  • Your routes, auth, and deploy stay yours
  • POST /sveda/stream is the turn
  • GET /sveda/health is the liveness check
  • Proxy the runtime or call it on the LAN
  • You do not replace the application

EMBED TOKEN

Auth stays on the host.

The host mints the token. The visitor gets a scoped credential. SvedaClient only sends it. That split is the copilot path: product auth does not move into the agent, and the agent does not learn your host secret.

If you pass host_mcp_url and host_mcp_token together on the same POST, the runtime can store them per visitor_id when a host API key is configured. The copilot still attaches with one client.

Read the embed token page and the embed token docs for the handshake.

POST /sveda/embed/token host
x-sveda-host-key required
visitor_id scoped
token sveda_embed_…

Browser sends x-sveda-embed-token. Host key never leaves the origin.

STREAM
session.send
message.startopen
text.deltatoken
tool.callfrontend | backend
tool.resulthost
message.end done

STREAM EVENTS

The product stays the product.

session.send posts one turn. The runtime answers with text/event-stream. The client asked for application/vnd.sveda.stream+json. Tokens, tools, and errors travel that pipe. You do not rewrite the host to own an agent loop.

sveda-server sits on :8787 beside the app. Proxy it if you want a same-origin stream. Keep your routes. Keep your deploy. The copilot is an attach, not a rewrite.

See the stream protocol and get started for the shortest path to a live turn.

Related

Ship a copilot this weekend.

Mint a token on the host. Attach SvedaClient. Run sveda-server beside the app. You do not replace the product.

Get started