We keep shipping features that solve the same underlying problem: how do you take a piece of AI work — an agent, a tool, a workflow — out of the machine it was built on, without losing what makes it useful?

Share Agent solves it for knowledge. The MCP Tool Wizard solves it for capability. Runbook export/import and provenance solve it for process. Individually they read like three features. Together they're one idea: the Composition Model — treat agents, tools, and runbooks as portable, composable units instead of hub-locked state.

The bet in one sentence

A unit of AI work should be exportable as a file, importable with explicit consent, and traceable back to what produced it — without requiring a shared filesystem, a shared hub, or a leap of faith.

Pillar 1: Share Agent — knowledge you can hydrate, not just re-index

Repo agents already supported MCP export/import, but import meant re-indexing from the same absolute path — useless the moment a friend or coworker doesn't have /Users/you/dev/thing on their machine. Learnings, custom rules, and LoRA metadata didn't travel with the bundle at all.

Share Agent changes the contract:

# Export
POST /api/agents/{id}/share  →  share-agent-bundle.json

# Import with hydration (no local repo required)
POST /api/import  { "hydrate": true, "repository_path": "" }

In the desktop app, Agent Info now has a Share button instead of a bare export link, and Import Agent exposes the hydrate option directly — the file picker path and the "trust this machine's copy of the code" path are finally two different, explicit choices.

Pillar 2: MCP Tool Wizard — grant a tool to one agent, not the world

Custom experts (/create-expert) were persona-and-rules only — no tool loop. If you wanted your homemade expert to fetch a public API, you were writing Go and a pack sidecar.

The wizard's first template is deliberately narrow: an HTTP-fetch tool — name, URL, method, headers, optional JSON-path extraction — granted to chosen agents by display name, because agent IDs regenerate across hub restarts but names don't.

POST /api/mcp/user-tools               create a tool
POST /api/mcp/user-tools/{id}/test     preview output before granting
POST /api/mcp/user-tools/{id}/grant    { "agent_name": "Widget Expert", "grant": true }

Grants are enforced through the same SSRF gate as fetch_url: no loopback, no private ranges, no non-HTTP schemes. Custom experts get a real in-process MCP server the moment a tool is granted — and it's empty overhead otherwise.

The second template ships alongside it, off by default: external media tools (media_submit / media_status / media_fetch) for wiring a granted agent to a third-party image/video/audio API. BaseURL defaults to empty — the tools simply don't attach until an operator configures a real endpoint. Both templates share one in-process MCP server per custom expert, so an agent with both kinds of grants gets a single unified tool surface instead of two.

Pillar 3: Runbooks as portable, provenance-tracked definitions

Runbook definitions already lived in a versioned library. What was missing was getting one out of your library and into someone else's, and knowing where a run actually came from after the fact.

GET  /api/runbook-definitions/{id}/export        → DefinitionBundle (schema_version, exported_at, definition)
POST /api/runbook-definitions/import             → mints a fresh ID by default (no collisions)
POST /api/runbook-definitions/import?keep_id=true → round-trips the same ID, bumps the version

Provenance ties a run back to the definition and version that produced it, plus the full append-only event trace (phase transitions, task dispatch/completion/failure):

GET /api/runbook-runs/{collabID}/provenance
→ { run, definition, collaboration, events[] }

And because "is this runbook actually moving" is a different question than "what happened historically," there's a lightweight progress endpoint that reuses the same dependency-ready logic the dispatcher uses internally:

GET /api/runbook-runs/{collabID}/progress
→ { total_tasks, counts, percent_complete, queued_task_ids, in_progress_task_ids, blocked_task_ids }

What ties it together

None of these three pillars share code by accident — they share a shape:

  1. A bundle (JSON, self-describing, versioned) — the export
  2. A grant or explicit import action — consent, not ambient trust
  3. A way to check what's actually running or where something came from — provenance/progress, not vibes

Agents, tools, and runbooks all get exported the same way, granted the same way, and audited the same way. That consistency is the point: once you understand Share Agent's bundle-and-hydrate pattern, the runbook export/import API and the tool grant model look exactly like what you'd expect.

Try it

Personal open-source project — macOS, Windows, Linux.

make pull-models
make start-all

Download: https://github.com/camronwood/neural-junkie/releases/latest

Docs:
- MCP integration
- MCP exports
- Runbooks v2
- Future enhancements

If a Share Agent bundle hydrates wrong, a granted tool trips the SSRF gate when it shouldn't, or a provenance call comes back empty for a run you know happened — GitHub issues welcome. That feedback becomes the next test case.

Camron Wood — Neural Junkie (personal project)