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:
- Hydrate, don't re-index —
HydrateFromExportrebuilds an agent's in-memory index directly from the resources embedded in the bundle. No disk scan, no path assumption. - Bring the whole agent, not just files — custom-rules markdown and agent-scoped learnings are merged in on import (
Hub.ImportShareLearningsdedupes by content hash so re-importing the same bundle twice doesn't double up). - LoRA travels as metadata — when a specialist has an active adapter, its base and composed Ollama tags ride along in the bundle for the receiving hub to resolve.
# 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:
- A bundle (JSON, self-describing, versioned) — the export
- A grant or explicit import action — consent, not ambient trust
- 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)