[{"data":1,"prerenderedAt":655},["ShallowReactive",2],{"navigation_docs":3,"-build-plugins-develop-and-test":320,"-build-plugins-develop-and-test-surround":650},[4,35,69,109,133,193,228,262,305],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting started",false,"\u002Fgetting-started","1.getting-started",[10,15,20,25,30],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-ph-house",{"title":16,"path":17,"stem":18,"icon":19},"Quickstart","\u002Fgetting-started\u002Fquickstart","1.getting-started\u002F2.quickstart","i-ph-rocket-launch",{"title":21,"path":22,"stem":23,"icon":24},"Concepts","\u002Fgetting-started\u002Fconcepts","1.getting-started\u002F3.concepts","i-ph-book-open",{"title":26,"path":27,"stem":28,"icon":29},"Install","\u002Fgetting-started\u002Finstall","1.getting-started\u002F4.install","i-ph-download-simple",{"title":31,"path":32,"stem":33,"icon":34},"What works today","\u002Fgetting-started\u002Fstatus","1.getting-started\u002F5.status","i-ph-list-checks",{"title":21,"icon":6,"path":36,"stem":37,"children":38,"page":6},"\u002Fconcepts","2.concepts",[39,44,49,54,59,64],{"title":40,"path":41,"stem":42,"icon":43},"Architecture","\u002Fconcepts\u002Farchitecture","2.concepts\u002F1.architecture","i-ph-planet",{"title":45,"path":46,"stem":47,"icon":48},"Jobs and durability","\u002Fconcepts\u002Fjobs","2.concepts\u002F2.jobs","i-ph-infinity",{"title":50,"path":51,"stem":52,"icon":53},"Routing","\u002Fconcepts\u002Frouting","2.concepts\u002F3.routing","i-ph-path",{"title":55,"path":56,"stem":57,"icon":58},"Security model","\u002Fconcepts\u002Fsecurity","2.concepts\u002F4.security","i-ph-shield-check",{"title":60,"path":61,"stem":62,"icon":63},"Tenants","\u002Fconcepts\u002Ftenants","2.concepts\u002F5.tenants","i-ph-buildings",{"title":65,"path":66,"stem":67,"icon":68},"Temporal","\u002Fconcepts\u002Ftemporal","2.concepts\u002F6.temporal","i-ph-clock",{"title":70,"icon":6,"path":71,"stem":72,"children":73,"page":6},"Run a fleet","\u002Ffleet","3.fleet",[74,79,84,89,94,99,104],{"title":75,"path":76,"stem":77,"icon":78},"Dev mode","\u002Ffleet\u002Fdev-mode","3.fleet\u002F1.dev-mode","i-ph-laptop",{"title":80,"path":81,"stem":82,"icon":83},"Run a cluster","\u002Ffleet\u002Fcluster","3.fleet\u002F2.cluster","i-ph-hard-drives",{"title":85,"path":86,"stem":87,"icon":88},"Join nodes","\u002Ffleet\u002Fjoin-nodes","3.fleet\u002F3.join-nodes","i-ph-plugs-connected",{"title":90,"path":91,"stem":92,"icon":93},"Manage nodes","\u002Ffleet\u002Fmanage-nodes","3.fleet\u002F4.manage-nodes","i-ph-list-bullets",{"title":95,"path":96,"stem":97,"icon":98},"Secrets","\u002Ffleet\u002Fsecrets","3.fleet\u002F5.secrets","i-ph-key",{"title":100,"path":101,"stem":102,"icon":103},"High availability","\u002Ffleet\u002Fhigh-availability","3.fleet\u002F6.high-availability","i-ph-copy",{"title":105,"path":106,"stem":107,"icon":108},"Upgrades, backups and restores","\u002Ffleet\u002Fupgrades","3.fleet\u002F7.upgrades","i-ph-arrows-clockwise",{"title":110,"icon":6,"path":111,"stem":112,"children":113,"page":6},"Use plugins","\u002Fplugins","4.plugins",[114,119,124,128],{"title":115,"path":116,"stem":117,"icon":118},"What a plugin is","\u002Fplugins\u002Foverview","4.plugins\u002F1.overview","i-ph-puzzle-piece",{"title":120,"path":121,"stem":122,"icon":123},"Install and update","\u002Fplugins\u002Finstall","4.plugins\u002F2.install","i-ph-package",{"title":125,"path":126,"stem":127,"icon":123},"Existing MCP packages","\u002Fplugins\u002Fpackages","4.plugins\u002F3.packages",{"title":129,"path":130,"stem":131,"icon":132},"The catalog","\u002Fplugins\u002Fcatalog","4.plugins\u002F4.catalog","i-ph-books",{"title":134,"icon":6,"path":135,"stem":136,"children":137,"page":6},"Build plugins","\u002Fbuild-plugins","5.build-plugins",[138,143,148,153,158,163,168,173,178,183,188],{"title":139,"path":140,"stem":141,"icon":142},"Your first plugin","\u002Fbuild-plugins\u002Ffirst-plugin","5.build-plugins\u002F1.first-plugin","i-ph-hammer",{"title":144,"path":145,"stem":146,"icon":147},"Harnesses","\u002Fbuild-plugins\u002Fharnesses","5.build-plugins\u002F10.harnesses","i-ph-cpu",{"title":149,"path":150,"stem":151,"icon":152},"Example: support triage","\u002Fbuild-plugins\u002Fexample-support-triage","5.build-plugins\u002F11.example-support-triage","i-ph-lifebuoy",{"title":154,"path":155,"stem":156,"icon":157},"Tools","\u002Fbuild-plugins\u002Ftools","5.build-plugins\u002F2.tools","i-ph-wrench",{"title":159,"path":160,"stem":161,"icon":162},"Agents","\u002Fbuild-plugins\u002Fagents","5.build-plugins\u002F3.agents","i-ph-robot",{"title":164,"path":165,"stem":166,"icon":167},"Skills","\u002Fbuild-plugins\u002Fskills","5.build-plugins\u002F4.skills","i-ph-graduation-cap",{"title":169,"path":170,"stem":171,"icon":172},"Develop and test","\u002Fbuild-plugins\u002Fdevelop-and-test","5.build-plugins\u002F5.develop-and-test","i-ph-flask",{"title":174,"path":175,"stem":176,"icon":177},"Publish and version","\u002Fbuild-plugins\u002Fpublish","5.build-plugins\u002F6.publish","i-ph-tag",{"title":179,"path":180,"stem":181,"icon":182},"Hooks","\u002Fbuild-plugins\u002Fhooks","5.build-plugins\u002F7.hooks","i-ph-anchor",{"title":184,"path":185,"stem":186,"icon":187},"Flows","\u002Fbuild-plugins\u002Fflows","5.build-plugins\u002F8.flows","i-ph-flow-arrow",{"title":189,"path":190,"stem":191,"icon":192},"Evals and quality gates","\u002Fbuild-plugins\u002Fevals","5.build-plugins\u002F9.evals","i-ph-seal-check",{"title":194,"icon":6,"path":195,"stem":196,"children":197,"page":6},"Run agents","\u002Fagents","6.agents",[198,203,208,213,218,223],{"title":199,"path":200,"stem":201,"icon":202},"Run jobs","\u002Fagents\u002Frun-jobs","6.agents\u002F1.run-jobs","i-ph-play",{"title":204,"path":205,"stem":206,"icon":207},"Models and keys","\u002Fagents\u002Fmodels-and-keys","6.agents\u002F2.models-and-keys","i-ph-sparkle",{"title":209,"path":210,"stem":211,"icon":212},"Delegation","\u002Fagents\u002Fdelegation","6.agents\u002F3.delegation","i-ph-git-fork",{"title":214,"path":215,"stem":216,"icon":217},"Contracts and limits","\u002Fagents\u002Fcontracts-and-limits","6.agents\u002F4.contracts-and-limits","i-ph-ruler",{"title":219,"path":220,"stem":221,"icon":222},"Runtime API","\u002Fagents\u002Fruntime-api","6.agents\u002F5.runtime-api","i-ph-plug",{"title":224,"path":225,"stem":226,"icon":227},"Approvals","\u002Fagents\u002Fapprovals","6.agents\u002F6.approvals","i-ph-hand-palm",{"title":229,"icon":6,"path":230,"stem":231,"children":232,"page":6},"Monitor","\u002Fmonitor","7.monitor",[233,238,243,248,253,258],{"title":234,"path":235,"stem":236,"icon":237},"Web UI","\u002Fmonitor\u002Fweb-ui","7.monitor\u002F0.web-ui","i-ph-monitor",{"title":239,"path":240,"stem":241,"icon":242},"Cost and usage","\u002Fmonitor\u002Fcost-and-usage","7.monitor\u002F1.cost-and-usage","i-ph-coins",{"title":244,"path":245,"stem":246,"icon":247},"Node health","\u002Fmonitor\u002Fnodes","7.monitor\u002F2.nodes","i-ph-heartbeat",{"title":249,"path":250,"stem":251,"icon":252},"Job history","\u002Fmonitor\u002Fhistory","7.monitor\u002F3.history","i-ph-clock-counter-clockwise",{"title":254,"path":255,"stem":256,"icon":257},"Tracing and metrics","\u002Fmonitor\u002Fobservability","7.monitor\u002F4.observability","i-ph-chart-line",{"title":259,"path":260,"stem":261,"icon":152},"Troubleshooting","\u002Fmonitor\u002Ftroubleshooting","7.monitor\u002F5.troubleshooting",{"title":263,"icon":6,"path":264,"stem":265,"children":266,"page":6},"Reference","\u002Freference","8.reference",[267,281,286,290,295,300],{"title":268,"icon":269,"path":270,"stem":271,"children":272,"page":6},"CLI","i-ph-terminal-window","\u002Freference\u002Fcli","8.reference\u002F1.cli",[273,277],{"title":274,"path":275,"stem":276},"orchestrator-zero","\u002Freference\u002Fcli\u002Forchestrator-zero","8.reference\u002F1.cli\u002F1.orchestrator-zero",{"title":278,"path":279,"stem":280},"orchestrator-zero-node","\u002Freference\u002Fcli\u002Forchestrator-zero-node","8.reference\u002F1.cli\u002F2.orchestrator-zero-node",{"title":282,"path":283,"stem":284,"icon":285},"oz0-plugin.yaml","\u002Freference\u002Fplugin-manifest","8.reference\u002F2.plugin-manifest","i-ph-file-code",{"title":287,"path":288,"stem":289,"icon":162},"Agent definition","\u002Freference\u002Fagent-definition","8.reference\u002F3.agent-definition",{"title":291,"path":292,"stem":293,"icon":294},"Ports","\u002Freference\u002Fports","8.reference\u002F4.ports","i-ph-network",{"title":296,"path":297,"stem":298,"icon":299},"Environment variables","\u002Freference\u002Fenvironment","8.reference\u002F5.environment","i-ph-brackets-curly",{"title":301,"path":302,"stem":303,"icon":304},"Files and directories","\u002Freference\u002Ffiles","8.reference\u002F6.files","i-ph-tree-structure",{"title":306,"icon":6,"path":307,"stem":308,"children":309,"page":6},"About","\u002Fabout","9.about",[310,315],{"title":311,"path":312,"stem":313,"icon":314},"Licensing","\u002Fabout\u002Flicensing","9.about\u002F1.licensing","i-ph-scales",{"title":316,"path":317,"stem":318,"icon":319},"About these docs","\u002Fabout\u002Fcontributing-docs","9.about\u002F2.contributing-docs","i-ph-pencil-simple",{"id":321,"title":169,"body":322,"description":643,"extension":644,"links":645,"meta":646,"navigation":647,"path":170,"seo":648,"stem":171,"__hash__":649},"docs\u002F5.build-plugins\u002F5.develop-and-test.md",{"type":323,"value":324,"toc":636},"minimark",[325,330,357,364,372,375,405,412,437,441,474,479,483,490,536,543,547,550,574,577,581,596,632],[326,327,329],"h2",{"id":328},"the-dev-loop","The dev loop",[331,332,338],"pre",{"className":333,"code":334,"filename":335,"language":336,"meta":337,"style":337},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","orchestrator-zero dev            # in the plugin's folder, or: orchestrator-zero dev .\u002Fmy-plugin\n","Terminal","bash","",[339,340,341],"code",{"__ignoreMap":337},[342,343,346,349,353],"span",{"class":344,"line":345},"line",1,[342,347,274],{"class":348},"sBMFI",[342,350,352],{"class":351},"sfazB"," dev",[342,354,356],{"class":355},"sHwdD","            # in the plugin's folder, or: orchestrator-zero dev .\u002Fmy-plugin\n",[358,359,360,363],"p",{},[339,361,362],{},"dev"," lints the plugin, starts a dev server on free ports and a node, installs the plugin from its working tree (no commit needed) and waits until the node reports its functions. Then it watches the folder and reinstalls the plugin within seconds of every change.",[331,365,370],{"className":366,"code":368,"language":369,"meta":337},[367],"language-text","Dev server ready. In another terminal:\n  export OZ0_CONTEXT=\u002Ftmp\u002F...\u002Foperator\u002Fcontext.json\nTemporal UI: http:\u002F\u002F127.0.0.1:...\nNode started (log: \u002Ftmp\u002F...\u002Fnode.log)\nmy-plugin dev-... ready in 14.0s: my_plugin.hello\nWatching for changes; Ctrl+C stops.\nmy-plugin dev-... reloaded in 8.5s: my_plugin.hello, my_plugin.goodbye\n","text",[339,371,368],{"__ignoreMap":337},[358,373,374],{},"What it needs:",[376,377,378,392],"ul",{},[379,380,381,383,384,387,388,391],"li",{},[339,382,278],{}," next to the server binary or on ",[339,385,386],{},"PATH",", or ",[339,389,390],{},"--node-binary",".",[379,393,394,395,387,398,401,402,391],{},"A runtime bundle: ",[339,396,397],{},"--runtime-bundle",[339,399,400],{},"$OZ0_RUNTIME_BUNDLE",", or the newest in ",[339,403,404],{},".\u002Fdist\u002Fruntime",[358,406,407,408,411],{},"The node's uv, Python and Node.js are cached between runs (",[339,409,410],{},"--cache-dir","), so only the first start is slow. The server starts empty every time.",[358,413,414,415,418,419,421,422,425,426,429,430,433,434,436],{},"Secrets in the plugin's ",[339,416,417],{},"requires.secrets"," come from your environment: ",[339,420,362],{}," and ",[339,423,424],{},"plugin test"," copy each one that is set into the dev server's tenant before installing, so ",[339,427,428],{},"export JEV_API_KEY=..."," before ",[339,431,432],{},"orchestrator-zero dev"," is all a tool with a key needs. A declared secret that is not set keeps the node from starting the plugin, and ",[339,435,362],{}," says which.",[326,438,440],{"id":439},"lint","Lint",[331,442,444],{"className":333,"code":443,"filename":335,"language":336,"meta":337,"style":337},"orchestrator-zero plugin lint            # or: orchestrator-zero plugin lint .\u002Fmy-plugin\norchestrator-zero plugin lint --json     # the checked bundle and its problems, for CI\n",[339,445,446,459],{"__ignoreMap":337},[342,447,448,450,453,456],{"class":344,"line":345},[342,449,274],{"class":348},[342,451,452],{"class":351}," plugin",[342,454,455],{"class":351}," lint",[342,457,458],{"class":355},"            # or: orchestrator-zero plugin lint .\u002Fmy-plugin\n",[342,460,462,464,466,468,471],{"class":344,"line":461},2,[342,463,274],{"class":348},[342,465,452],{"class":351},[342,467,455],{"class":351},[342,469,470],{"class":351}," --json",[342,472,473],{"class":355},"     # the checked bundle and its problems, for CI\n",[358,475,476,478],{},[339,477,439],{}," runs the same checks the edge runs before it installs a plugin: the manifest (unknown fields are errors), the agents it lists, its skills and the files they refer to. It exits non-zero on errors; warnings, such as an unpinned package, do not fail it. Run it in your plugin's CI.",[326,480,482],{"id":481},"call-a-tool-directly","Call a tool directly",[358,484,485,486,489],{},"Agents call tools for you. To call one yourself, for debugging, run ",[339,487,488],{},"ToolCallWorkflow"," on a node:",[331,491,493],{"className":333,"code":492,"filename":335,"language":336,"meta":337,"style":337},"orchestrator-zero job run --workflow ToolCallWorkflow --task-queue oz0.default \\\n  --input '{\"tool\": \"my_plugin.hello\", \"arguments\": {\"name\": \"you\"}}'\n",[339,494,495,521],{"__ignoreMap":337},[342,496,497,499,502,505,508,511,514,517],{"class":344,"line":345},[342,498,274],{"class":348},[342,500,501],{"class":351}," job",[342,503,504],{"class":351}," run",[342,506,507],{"class":351}," --workflow",[342,509,510],{"class":351}," ToolCallWorkflow",[342,512,513],{"class":351}," --task-queue",[342,515,516],{"class":351}," oz0.default",[342,518,520],{"class":519},"sTEyZ"," \\\n",[342,522,523,526,530,533],{"class":344,"line":461},[342,524,525],{"class":351},"  --input",[342,527,529],{"class":528},"sMK4o"," '",[342,531,532],{"class":351},"{\"tool\": \"my_plugin.hello\", \"arguments\": {\"name\": \"you\"}}",[342,534,535],{"class":528},"'\n",[358,537,538,539,542],{},"Use ",[339,540,541],{},"--task-queue node.\u003Cnode-id>"," to call it on a particular node.",[326,544,546],{"id":545},"run-the-mcp-server-by-hand","Run the MCP server by hand",[358,548,549],{},"Your tool is a normal MCP server, so you can also run it outside Orchestrator Zero:",[331,551,553],{"className":333,"code":552,"filename":335,"language":336,"meta":337,"style":337},"uv run python -m my_plugin.server        # speaks MCP over stdio\n",[339,554,555],{"__ignoreMap":337},[342,556,557,560,562,565,568,571],{"class":344,"line":345},[342,558,559],{"class":348},"uv",[342,561,504],{"class":351},[342,563,564],{"class":351}," python",[342,566,567],{"class":351}," -m",[342,569,570],{"class":351}," my_plugin.server",[342,572,573],{"class":355},"        # speaks MCP over stdio\n",[358,575,576],{},"Any MCP client or inspector can talk to it.",[326,578,580],{"id":579},"test-it","Test it",[358,582,583,586,587,591,592,595],{},[339,584,585],{},"orchestrator-zero plugin test"," runs the plugin's ",[588,589,590],"a",{"href":190},"evals"," on a dev server and a node of its own, with model answers recorded once (",[339,593,594],{},"--record",") and replayed after, so tests are fast, free and repeatable, in CI too:",[331,597,599],{"className":333,"code":598,"filename":335,"language":336,"meta":337,"style":337},"orchestrator-zero plugin test .\u002Fmy-plugin --record   # once, with your API key\norchestrator-zero plugin test .\u002Fmy-plugin            # after: no key, no tokens\n",[339,600,601,619],{"__ignoreMap":337},[342,602,603,605,607,610,613,616],{"class":344,"line":345},[342,604,274],{"class":348},[342,606,452],{"class":351},[342,608,609],{"class":351}," test",[342,611,612],{"class":351}," .\u002Fmy-plugin",[342,614,615],{"class":351}," --record",[342,617,618],{"class":355},"   # once, with your API key\n",[342,620,621,623,625,627,629],{"class":344,"line":461},[342,622,274],{"class":348},[342,624,452],{"class":351},[342,626,609],{"class":351},[342,628,612],{"class":351},[342,630,631],{"class":355},"            # after: no key, no tokens\n",[633,634,635],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}",{"title":337,"searchDepth":461,"depth":461,"links":637},[638,639,640,641,642],{"id":328,"depth":461,"text":329},{"id":439,"depth":461,"text":440},{"id":481,"depth":461,"text":482},{"id":545,"depth":461,"text":546},{"id":579,"depth":461,"text":580},"The dev loop with live reload, linting, and calling a tool directly.","md",null,{},{"icon":172},{"title":169,"description":643},"-s1-HrmxgsPHiqRhj8xXrbAU13QY4PxA-FNEhLXgiEQ",[651,653],{"title":164,"path":165,"stem":166,"description":652,"icon":167,"children":-1},"Folders with a SKILL.md that teach agents when and how to use something.",{"title":174,"path":175,"stem":176,"description":654,"icon":177,"children":-1},"Ship a plugin with a Git tag, and control exactly what every node runs.",1791135411342]