Osaurus Plugin Authoring

May 11, 2026 · View on GitHub

Welcome. This is the entry point for everything related to building Osaurus plugins.

Plugins are macOS dynamic libraries (.dylib) that extend Osaurus with new tools, HTTP routes, web UIs, and background tasks. They run in-process with full access to a curated host API for inference, storage, secrets, networking, and dispatch.

Pick your path

I want to...Read
Get a Hello World plugin running in 5 minutesQUICKSTART.md
Understand the manifest, lifecycle, and capabilitiesAUTHORING.md
Look up a specific host API callbackHOST_API.md
Build HTTP routes or a web UI for my pluginROUTES_AND_WEB.md
Sign, package, and distribute my pluginPACKAGING.md
Test my plugin (tools dev loop, unit tests with OsaurusPluginTestKit)TESTING.md
Debug why my plugin won't loadDEBUGGING.md
See what changed in each ABI versionABI_VERSIONS.md
Find an answer to a quick questionFAQ.md

What you get from the host

Plugins target the v6 host API surface (current). Callbacks span:

  • Config — read/write per-plugin secrets backed by Keychain (config_get, config_set, config_delete)
  • Storage — per-plugin SQLite database (encrypted at rest, 100 MiB default cap), db_exec / db_query
  • Logginglog plus structured log_structured (v5) for searchable JSON fields in Insights
  • Inference — synchronous and streaming chat completion (complete, complete_stream, complete_cancel) plus embeddings (embed), against the same models the main chat uses
  • Dispatch — fire-and-forget background tasks (dispatch, task_status, dispatch_cancel, dispatch_interrupt, send_draft, list_active_tasks)
  • HTTP — outbound requests with SSRF protection and a 60 req/min per-(plugin, agent) cap
  • File I/O — read shared artifacts the user has explicitly provided
  • Agent contextget_active_agent_id (v4) for per-agent state keying
  • Memoryhost->free_string (v6) to release strings the host returned, replacing the previously ambiguous "free with the plugin's free_string" path

Older plugins compiled against v1–v5 keep loading; the struct layout is frozen and v6 only appends one new optional slot. See ABI_VERSIONS.md for the per-version evolution and the defensive host->version >= N check pattern.

The full reference for each callback lives in HOST_API.md.

What plugins look like at a glance

A plugin is a single .dylib that exports one symbol:

const osr_plugin_api* osaurus_plugin_entry_v2(const osr_host_api* host);

It returns a struct describing how to:

  • Initialize and tear down the plugin (init, destroy)
  • Describe its capabilities to Osaurus (get_manifest)
  • Run tool calls from chat (invoke)
  • Optionally handle HTTP routes (handle_route)
  • Optionally react to config changes and task lifecycle events

The host pointer gives the plugin everything it needs to call back into Osaurus.

Repository

The plugin registry lives at github.com/osaurus-ai/osaurus-tools. Approved plugins are mirrored to the in-app marketplace. See PACKAGING.md to publish.