Files
magpie/docs/integrating.md
T
yetone df95ac6bc2 docs, site: Integrating your app or agent with magpie, at docs/integrating.md and usemagpie.ai/docs/integrate (#918, Magixyne)
A developer of an AI app asked how to work with magpie and whether an app can
register itself after one confirmation. The page says what exists: the
gateway (find it via /api/hello and settings.json's port, the OpenAI,
Anthropic, Responses and Gemini endpoints, /v1/models' fields), how a key
magpie-<id> or the User-Agent's first word names the app in Usage, a row on
the Agents page by an adapter PR in internal/agent (config-edit, Cindy-style
own import link confirmed in the app, or a local API) with what the PR needs,
what plugins can and can't do, and what isn't there: no link or API registers
an app or installs a plugin, and magpie://import adds providers only. English
and Chinese pages, linked from every docs page's nav and footer.
TestThirdPartyAppIsCountedAsItself pins the attribution the page promises.
go vet and the gateway tests pass; site node tests pass; pages checked in
headless Chromium (no errors, TOC, no horizontal scroll at 390px).
2026-10-05 22:46:35 +08:00

146 lines
7.7 KiB
Markdown

# Integrating your app or agent with magpie
For developers of an AI app, agent or client who want it to work well with
magpie. There are three levels, from no work on magpie's side to a row of
your own on the Agents page. The web version is
<https://usemagpie.ai/docs/integrate>.
| You want | Route | Change to magpie |
| ----------------------------------------------------- | ------------------------------ | ---------------- |
| Your app's requests served by magpie, counted under its own name in Usage | [Talk to the gateway](#1-talk-to-the-gateway) | none |
| A row on the Agents page: detected, its model picked there, put back on disconnect | [An agent adapter](#2-a-row-on-the-agents-page) | a pull request |
| A new model source (a subscription, a vendor), or rewriting requests | [A plugin](#3-plugins) | none |
## 1. Talk to the gateway
magpie runs a local LLM gateway. Every model the user has in magpie
(subscriptions, API keys, local models, routing groups) is served there
under one id each, so your app needs one provider entry, not one per
vendor.
**Find it.** The gateway listens on `127.0.0.1:3425`, or on the port in
`port` of magpie's `settings.json` (`~/.config/magpie/settings.json`, the
same path under the user's folder on Windows; `$XDG_CONFIG_HOME/magpie`
when that is set). `GET /api/hello` answers
`{"name":"magpie","version":"…"}` when it is magpie. Read that file, never
write it. magpie must be running (the app or `magpie serve`). An app that
finds nothing there should offer its own providers as usual.
**Endpoints.** Requests go straight through when the vendor speaks your
API, and are translated otherwise, streaming, tool calls, images and
reasoning included:
| Path | API |
| ---- | --- |
| `/v1/chat/completions` | OpenAI Chat Completions |
| `/v1/responses` | OpenAI Responses |
| `/v1/messages`, `/v1/messages/count_tokens` | Anthropic Messages |
| `/v1beta/models/{model}:generateContent` (and `:streamGenerateContent`) | Google Gemini |
| `/v1/models` | the catalog |
So the base URL is `http://127.0.0.1:<port>/v1` for an OpenAI client and
`http://127.0.0.1:<port>` for an Anthropic or Gemini one.
**The key names your app.** On this machine the gateway takes any key.
Send `magpie-<your-app-id>` (`Authorization: Bearer magpie-acme`, or
`x-api-key`) and every call is counted as `acme` in Usage, the Requests
log and the routing rules that match on agents. Without it, magpie counts
the call by the first word of your `User-Agent` (`Acme/1.4 (darwin)` is
`Acme`); an SDK's own User-Agent (`OpenAI/JS …`, `ai-sdk/…`) would count it
as that SDK. From another computer (Settings → Share on local network) the
key must be one of the user's gateway keys, and the User-Agent names your
app.
**Models.** `GET /v1/models` lists what the user has turned on: `id`
(`provider/model`, or a routing group's name, which you send as it is),
`display_name`, `owned_by` (the provider), `reasoning` and
`supported_reasoning_levels` (`[{"effort":"low"},…]`), `context_window`
and `max_output_tokens` when known, `modalities` when magpie knows whether
it takes images. List them from there rather than shipping a list: the
user adds and removes providers in magpie. Reasoning is asked in your
API's own field (`reasoning_effort`, `reasoning.effort`, Anthropic's
`thinking` or `output_config.effort`). `?format=text` gives the ids one a
line.
**Optional.** Send `X-Magpie-Session: <id>` with a conversation's requests
and `GET /v1/magpie/route?session=<id>` says which model a routing group
picked for the turn and the fallbacks it tried, before the first token
(long-poll with `after=<seq>&wait=<s>`). `GET /v1/magpie/quotas` lists the
user's subscription allowances. Both answer only this machine, or another
with a gateway key. [Connecting anything else](reference.md#connecting-anything-else)
has the details.
**Keep the user's providers.** Add magpie as one more provider (named
Magpie) beside the ones the user set up in your app, rather than replacing
them, so turning magpie off is picking another provider.
## 2. A row on the Agents page
The agents magpie lists (Claude Code, Codex, OpenCode, dsh, Alma, Cindy…)
are adapters in [`internal/agent`](../internal/agent), one file each,
listed in [`agents.go`](../internal/agent/agents.go). A row gets your
app's name and icon, shows when your app is installed, lets the user pick
its model (and reasoning) from magpie's catalog, follows the catalog as
providers change, and on disconnect puts back what your app had before.
There is no runtime registration: a row is added by a pull request to
this repository, and ships in the next release.
An adapter is an [`Agent`](../internal/agent/agent.go) value. What your
app offers decides its shape:
- **magpie edits your config file** (most adapters; [`fx.go`](../internal/agent/fx.go),
[`empryo.go`](../internal/agent/empryo.go)). `Dir`, `Path` and `Bin` find
the app; each `Field` (`model`, `effort`, …) has `Get`, `Set` and
`Options`. Connecting adds a `magpie` provider at the gateway, keyed
`magpie-<id>`, and sets your model to one of magpie's; `Set("")` (the
agent's default) or `Unwire` takes magpie's entries out and restores
what was there. Only the keys magpie sets are touched; the user's other
settings, providers and comments stay. `Notice` says when your app must
be restarted to see a change; `Sync` rewrites a model list your app keeps
in a file rather than asking `/v1/models`.
- **Your app takes a provider only through its own import link, which the
user confirms in your app** ([`cindy.go`](../internal/agent/cindy.go)).
`Import` returns the link (`yourapp://provider/import?…` carrying the
gateway's URL, the key `magpie-<id>` and the endpoints), the row's button
opens it, and the user says yes once, in your app. `Added` reads,
read-only, whether your app has magpie already. magpie writes nothing of
yours. This suits an app that keeps its providers in a database or
encrypted.
- **Your app has a local API while it runs** (Alma, at `localhost:23001`):
magpie adds itself as a provider and sets the default model through it.
A pull request needs: the adapter and its registration, `UA` (what your
User-Agent begins with, lower-case) so Usage knows your calls, an icon in
`internal/gui/assets/icons`, tests that run under a temporary `HOME`
(connect, switch, disconnect restoring the original file), and a row in
the [Agents table](reference.md#agents). What helps us most is a stable,
documented config format or import link, and where your app keeps it on
each system.
## 3. Plugins
A plugin is an npm package magpie runs; the user installs it from
Settings → Plugins or with `magpie plugin add <package>`. There are two
kinds ([plugin guide](https://usemagpie.ai/docs/plugins)):
- **Provider plugins**, OpenCode's `auth` hook or a pi package: a new
source of models, such as a subscription magpie doesn't sign in to
itself. They sign in, list models and make requests.
- **Gateway middleware**: rewrites requests and replies as they pass
(`onRequest`, `onEvent`, `onResponse`).
A plugin can't add a row to the Agents page or write another app's
config, so it is not how an app registers itself.
## What isn't there
- No API or link lets another app register itself as an agent, or install
a plugin, without the user: plugins are installed in magpie by the user,
and agent rows come from adapters in magpie's source.
- `magpie://import` links add a *provider* (a source of models, with its
key), not an agent or an app; see [Import links](reference.md#import-links).
Questions, or an adapter you'd like to discuss first: open an issue at
<https://github.com/yetone/magpie/issues> or ask on
[Discord](https://discord.gg/vGSnD3ZKQF).