1<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/assets/tokens-Boj462rO.css" data-precedence="default"/><link rel="stylesheet" href="/assets/styles-DsLB1x7U.css" data-precedence="default"/><link rel="stylesheet" href="/assets/docs-MpYAhfpf.css" data-precedence="default"/><title>The Multi-Agent System</title><meta name="description" content="Union Street is the runtime for agent organizations: profiles, managers, delegation, scoped tools, memory, schedules, and OIDC identity. Deployment agnostic. Pre-alpha."/><link rel="modulepreload" href="/assets/index-bw5d4off.js"/><link rel="modulepreload" href="/assets/routes-PJ7nQklZ.js"/><link rel="modulepreload" href="/assets/CopyButton-Ct0M6exJ.js"/><link rel="modulepreload" href="/assets/ProjectPages-D68YrPpP.js"/><link rel="modulepreload" href="/assets/TopNav-C_mMMjL8.js"/><link rel="preconnect" href="https://fonts.googleapis.com"/><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous"/><link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' fill='%23000'/%3E%3Cpath d='M7 23V9h4l4.5 8V9h4v14h-3.8l-4.6-8.2V23H7z' fill='%23FF5B14'/%3E%3C/svg%3E"/></head><body><!--$--><div class="ambient" aria-hidden="true"><div class="orb orb-laser"></div><div class="orb orb-blue"></div><div class="horizon"></div><div class="grid-floor"></div></div><header class="top"><a class="mark active" href="/" data-status="active" aria-current="page">Union Street<span class="slash"> /</span></a><nav class="nav"><a href="/docs">Docs</a><a href="/api">API</a><a href="/#install">Install</a></nav></header><main><section class="hero"><p class="tag reveal is-visible">Union Street</p><h1 class="display reveal is-visible">The Multi-Agent System</h1><p class="hero-sub reveal is-visible">Profiles, managers, direct reports, scoped tools, memory, schedules, delegation, and OIDC identity â deployable on your laptop or airgapped VPC.</p><div class="cta-row reveal is-visible"><a class="btn btn-primary" href="https://github.com/UnionStreetAI/unionstreet"><svg class="btn-icon" viewBox="0 0 16 16" aria-hidden="true" focusable="false"><path fill="currentColor" d="M8 0a8 8 0 0 0-2.53 15.59c.4.07.55-.17.55-.38v-1.5c-2.24.49-2.71-.95-2.71-.95-.36-.93-.89-1.18-.89-1.18-.73-.5.06-.49.06-.49.8.06 1.22.83 1.22.83.72 1.22 1.88.87 2.33.66.07-.52.28-.87.51-1.07-1.79-.2-3.67-.9-3.67-3.98 0-.88.31-1.6.83-2.16-.08-.2-.36-1.02.08-2.13 0 0 .68-.22 2.2.83A7.68 7.68 0 0 1 8 3.8c.68 0 1.36.09 2 .27 1.53-1.05 2.2-.83 2.2-.83.44 1.11.16 1.93.08 2.13.52.56.83 1.28.83 2.16 0 3.09-1.88 3.77-3.67 3.97.29.25.55.74.55 1.5v2.22c0 .21.14.46.55.38A8 8 0 0 0 8 0Z"></path></svg>View on GitHub</a><a href="/docs" class="btn btn-ghost">Docs for humans</a></div><p class="hero-meta reveal is-visible"><a href="https://github.com/UnionStreetAI/unionstreet">UnionStreetAI/unionstreet</a><span aria-hidden="true">·</span>Pre-alpha<span aria-hidden="true">·</span>MIT</p></section><section class="quickstart section-pad" id="install"><p class="section-tag reveal is-visible">Get started</p><h2 class="section-title reveal is-visible">Install in one command</h2><div class="terminal reveal is-visible"><div class="terminal-bar"><span class="terminal-label">install</span><button type="button" class="copy">Copy</button></div><code>curl -fsSL https://unionstreet.ai/install.sh | bash</code></div><p class="terminal-note reveal is-visible"><code>us doctor</code> <span class="sep">·</span> <code>us fleet validate fleet.yaml</code> <span class="sep">·</span> <code>us tui</code></p></section><section class="intro section-pad"><p class="section-tag reveal is-visible">What it is</p><div class="intro-grid"><div class="intro-copy reveal is-visible"><h2 class="section-title">The missing control layer for agent work</h2><p class="body-lg">Every agent tool is becoming its own little worker. Union Street is the layer that names them, routes work between them, grants tools per agent, records what happened, and keeps the whole thing runnable anywhere.</p></div><div class="intro-aside reveal is-visible"><p class="aside-label">Bring</p><ul class="aside-list"><li>Claude Code and Codex-style coding agents</li><li>Hermes, OpenClaw, and Pi-style workers</li><li>MCP tools with per-agent auth</li><li>Your own scripts behind the runtime API</li></ul></div></div></section><section class="stack section-pad"><p class="section-tag reveal is-visible">The trick</p><div class="stack-grid stack-grid-4"><article class="card reveal is-visible"><p class="card-tag">Profiles</p><h3 class="card-title">Agents become addressable</h3><p class="card-body">Each agent gets a name, role, model chain, manager, direct reports, tools, memory, runtime, and schedule.</p></article><article class="card reveal is-visible"><p class="card-tag">OIDC</p><h3 class="card-title">Agents become principals</h3><p class="card-body">Subject, issuer, audience, roles, groups. Tool grants and audit attach to the agent doing the work.</p></article><article class="card reveal is-visible"><p class="card-tag">Lash</p><h3 class="card-title">Agents can hand off work</h3><p class="card-body">Wake a peer, delegate through the org chart, and collect structured reports without hiding the handoff.</p></article><article class="card reveal is-visible"><p class="card-tag">Runtime</p><h3 class="card-title">Everything is drivable</h3><p class="card-body">Prompt agents, stream events, receive webhooks, and plan fleet changes from CLI, HTTP, or SDK.</p></article></div></section><section class="identity section-pad"><p class="section-tag reveal is-visible">The oh-shit part</p><div class="contract-grid reveal is-visible"><div><h2 class="section-title">OIDC for agents</h2><p class="body-lg">Union Street treats an agent like a workload identity, not a prompt string. A profile can mint and verify OIDC-shaped claims, map external IdP groups, and fail closed when a principal is disabled.</p><p class="body-lg">That means MCP auth, runtime secrets, peer visibility, memory, usage, and audit all have something real to hang from: the agent principal.</p></div><pre class="snippet reveal is-visible" tabindex="0"><code># agent pack (excerpt) 2oidc: 3 issuer: urn:union-street:demo-enterprise 4 subject: agent:vp-eng 5 audiences: 6 - union-street:runtime 7lash: 8 delegate: direct_reports 9 report: manager</code></pre></div></section><section class="drive section-pad"><p class="section-tag reveal is-visible">Integrate</p><div class="panel reveal is-visible"><div class="panel-head"><h2 class="panel-title">Play with the runtime</h2><div class="tabs" role="tablist" aria-label="Code samples"><button type="button" role="tab" aria-selected="true">SDK</button><button type="button" role="tab" aria-selected="false">HTTP</button><button type="button" role="tab" aria-selected="false">CLI</button></div></div><pre class="code" id="code-sample" tabindex="0"><code><span class="kw">
9import</span> { <span class="ty">UnionStreetClient</span> } <span class="kw">from</span> <span class="str">"@unionstreet/us/sdk"</span>; 10 11<span class="kw">const</span> client = <span class="kw">new</span> <span class="ty">UnionStreetClient</span>({ 12 baseUrl: <span class="str">"http:<span class="</span>cm<span class="str">">//127.0.0.1:8787"</span>,</span> 13 token: <span class="ty">process</span>.env.US_RUNTIME_BEARER_TOKEN, 14}); 15 16<span class="kw">const</span> <span class="fn">health</span> = <span class="kw">await</span> client.<span class="fn">health</span>(); 17<span class="kw">const</span> <span class="fn">snapshot</span> = <span class="kw">await</span> client.<span class="fn">snapshot</span>(); 18<span class="kw">const</span> result = <span class="kw">await</span> client.<span class="fn">sendAgentPrompt</span>(<span class="str">"coo"</span>, { 19 prompt: <span class="str">"Summarize open scheduler runs and any blocked delegates."</span>, 20});</code></pre></div></section></main><footer class="foot"><p class="foot-mark">USAI<span class="dot">.</span></p><p class="foot-copy">Union Street AI · San Francisco, CA · pre-alpha</p><p class="foot-links"><a href="/install.sh">install.sh</a><span aria-hidden="true">·</span><a href="/projects">Projects</a><span aria-hidden="true">·</span><a href="/docs">Docs</a><span aria-hidden="true">·</span><a href="/api">API</a><span aria-hidden="true">·</span><a href="/lash">Lash</a><span aria-hidden="true">·</span><a href="/helios">Helios</a><span aria-hidden="true">·</span><a href="/orsi">ORSI</a><span aria-hidden="true">·</span><a href="/duck">Duck</a></p><p class="foot-credit">by Max Sonderby</p></footer>
20<script>(function(t){let s;try{s=JSON.parse(sessionStorage.getItem(t.storageKey)||"{}")}catch(e){console.error(e);return}const c=t.key||window.history.state?.__TSR_key,r=c?s[c]:void 0;if(t.shouldScrollRestoration&&r&&typeof r=="object"&&Object.keys(r).length>0){for(const e in r){const o=r[e];if(!o||typeof o!="object")continue;const l=o.scrollX,i=o.scrollY;if(!(!Number.isFinite(l)||!Number.isFinite(i))){if(e==="window")window.scrollTo({top:i,left:l,behavior:t.behavior});else if(e){let n;try{n=document.querySelector(e)}catch{continue}n&&(n.scrollLeft=l,n.scrollTop=i)}}}return}const a=window.location.hash.split("#",2)[1];if(a){const e=window.history.state?.__hashScrollIntoViewOptions??!0;if(e){const o=document.getElementById(a);o&&o.scrollIntoView(e)}return}window.scrollTo({top:0,left:0,behavior:t.behavior})})({"storageKey":"tsr-scroll-restoration-v1_3","shouldScrollRestoration":true});document.currentScript.remove()</script>
20<!--/$-->
20<script class="$tsr" id="$tsr-stream-barrier">(self.$R=self.$R||{})["tsr"]=[];self.$_TSR={h(){this.hydrated=!0,this.c()},e(){this.streamEnded=!0,this.c()},c(){this.hydrated&&this.streamEnded&&(delete self.$_TSR,delete self.$R.tsr)},p(e){this.initialized?e():this.buffer.push(e)},buffer:[]};$_TSR.router=($R=>$R[0]={manifest:$R[1]={routes:$R[2]={__root__:$R[3]={preloads:$R[4]=["/assets/index-bw5d4off.js"],assets:$R[5]=[$R[6]={tag:"script",attrs:$R[7]={type:"module",async:!0},children:"import(\"/assets/index-bw5d4off.js\")"}]},"/":$R[8]={preloads:$R[9]=["/assets/routes-PJ7nQklZ.js","/assets/CopyButton-Ct0M6exJ.js","/assets/ProjectPages-D68YrPpP.js","/assets/TopNav-C_mMMjL8.js"]}}},matches:$R[10]=[$R[11]={i:"__root__�",u:1791218198198,s:"success",ssr:!0},$R[12]={i:"��",u:1791218198202,s:"success",ssr:!0}],lastMatchId:"��"})($R["tsr"]);$_TSR.e();document.currentScript.remove()</script>
20<script type="module" async="">import("/assets/index-bw5d4off.js")</script>
20</body></html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.