[{"data":1,"prerenderedAt":661},["ShallowReactive",2],{"navigation_docs":3,"-guides-remote-access":270,"-guides-remote-access-surround":656},[4,28,51,110,243],{"title":5,"path":6,"stem":7,"children":8},"Get started","\u002Fget-started","1.get-started",[9,12,16,20,24],{"title":10,"path":6,"stem":11},"Overview","1.get-started\u002Findex",{"title":13,"path":14,"stem":15},"Why Kraft","\u002Fget-started\u002Fwhy-kraft","1.get-started\u002F0.why-kraft",{"title":17,"path":18,"stem":19},"Install","\u002Fget-started\u002Finstall","1.get-started\u002F1.install",{"title":21,"path":22,"stem":23},"Your first work item","\u002Fget-started\u002Ffirst-work-item","1.get-started\u002F2.first-work-item",{"title":25,"path":26,"stem":27},"Troubleshooting and FAQ","\u002Fget-started\u002Ftroubleshooting","1.get-started\u002F3.troubleshooting",{"title":29,"path":30,"stem":31,"children":32},"Concepts","\u002Fconcepts","2.concepts",[33,35,39,43,47],{"title":10,"path":30,"stem":34},"2.concepts\u002Findex",{"title":36,"path":37,"stem":38},"Vocabulary","\u002Fconcepts\u002Fvocabulary","2.concepts\u002F1.vocabulary",{"title":40,"path":41,"stem":42},"How a work item runs","\u002Fconcepts\u002Fhow-a-work-item-runs","2.concepts\u002F2.how-a-work-item-runs",{"title":44,"path":45,"stem":46},"Caps and budgets","\u002Fconcepts\u002Fcaps-and-budgets","2.concepts\u002F3.caps-and-budgets",{"title":48,"path":49,"stem":50},"Why a permission gate","\u002Fconcepts\u002Fpermission-gate","2.concepts\u002F4.permission-gate",{"title":52,"path":53,"stem":54,"children":55},"Guides","\u002Fguides","3.guides",[56,58,62,66,70,74,78,82,86,90,94,98,102,106],{"title":10,"path":53,"stem":57},"3.guides\u002Findex",{"title":59,"path":60,"stem":61},"Use Kraft from your agent","\u002Fguides\u002Fagent-integration","3.guides\u002F01.agent-integration",{"title":63,"path":64,"stem":65},"Kraft Lite","\u002Fguides\u002Fkraft-lite","3.guides\u002F02.kraft-lite",{"title":67,"path":68,"stem":69},"Remote access","\u002Fguides\u002Fremote-access","3.guides\u002F03.remote-access",{"title":71,"path":72,"stem":73},"Add or override a harness","\u002Fguides\u002Fadding-a-harness","3.guides\u002F04.adding-a-harness",{"title":75,"path":76,"stem":77},"Schedule or webhook work","\u002Fguides\u002Fschedule-and-webhook-work","3.guides\u002F05.schedule-and-webhook-work",{"title":79,"path":80,"stem":81},"Add a security review or a gate reviewer","\u002Fguides\u002Fadd-review-agents","3.guides\u002F06.add-review-agents",{"title":83,"path":84,"stem":85},"Kraft for VS Code","\u002Fguides\u002Fvscode","3.guides\u002F07.vscode",{"title":87,"path":88,"stem":89},"Reviewing a change","\u002Fguides\u002Freview-a-change","3.guides\u002F08.review-a-change",{"title":91,"path":92,"stem":93},"Write your own chain","\u002Fguides\u002Fwrite-your-own-chain","3.guides\u002F09.write-your-own-chain",{"title":95,"path":96,"stem":97},"Switch a harness","\u002Fguides\u002Fswitch-harness","3.guides\u002F10.switch-harness",{"title":99,"path":100,"stem":101},"Upgrade your templates","\u002Fguides\u002Fupgrading-templates","3.guides\u002F11.upgrading-templates",{"title":103,"path":104,"stem":105},"Operations","\u002Fguides\u002Foperations","3.guides\u002F12.operations",{"title":107,"path":108,"stem":109},"Worker Kit","\u002Fguides\u002Fworker-kit","3.guides\u002F13.worker-kit",{"title":111,"path":112,"stem":113,"children":114},"Reference","\u002Freference","4.reference",[115,117,139,183,201,205,227,231,235,239],{"title":10,"path":112,"stem":116},"4.reference\u002Findex",{"title":118,"path":119,"stem":120,"children":121},"CLI","\u002Freference\u002Fcli","4.reference\u002F1.cli\u002Findex",[122,123,127,131,135],{"title":10,"path":119,"stem":120},{"title":124,"path":125,"stem":126},"Item verbs","\u002Freference\u002Fcli\u002Fitem","4.reference\u002F1.cli\u002F2.item",{"title":128,"path":129,"stem":130},"View verbs","\u002Freference\u002Fcli\u002Fview","4.reference\u002F1.cli\u002F3.view",{"title":132,"path":133,"stem":134},"Repo verbs","\u002Freference\u002Fcli\u002Frepo","4.reference\u002F1.cli\u002F4.repo",{"title":136,"path":137,"stem":138},"Admin verbs","\u002Freference\u002Fcli\u002Fadmin","4.reference\u002F1.cli\u002F5.admin",{"title":140,"path":141,"stem":142,"children":143},"Configuration","\u002Freference\u002Fconfiguration","4.reference\u002F2.configuration\u002Findex",[144,145,155,159,163,167,171,175,179],{"title":10,"path":141,"stem":142},{"title":146,"path":147,"stem":148,"children":149},"Repos","\u002Freference\u002Fconfiguration\u002Frepos","4.reference\u002F2.configuration\u002F2.repos\u002Findex",[150,151],{"title":10,"path":147,"stem":148},{"title":152,"path":153,"stem":154},"Workspaces","\u002Freference\u002Fconfiguration\u002Frepos\u002Fworkspaces","4.reference\u002F2.configuration\u002F2.repos\u002F3.workspaces",{"title":156,"path":157,"stem":158},"Policy","\u002Freference\u002Fconfiguration\u002Fpolicy","4.reference\u002F2.configuration\u002F3.policy",{"title":160,"path":161,"stem":162},"Library and chains","\u002Freference\u002Fconfiguration\u002Flibrary-and-chains","4.reference\u002F2.configuration\u002F4.library-and-chains",{"title":164,"path":165,"stem":166},"Harnesses file","\u002Freference\u002Fconfiguration\u002Fharnesses-file","4.reference\u002F2.configuration\u002F5.harnesses-file",{"title":168,"path":169,"stem":170},"Access","\u002Freference\u002Fconfiguration\u002Faccess","4.reference\u002F2.configuration\u002F6.access",{"title":172,"path":173,"stem":174},"Intake","\u002Freference\u002Fconfiguration\u002Fintake","4.reference\u002F2.configuration\u002F7.intake",{"title":176,"path":177,"stem":178},"Sandbox host","\u002Freference\u002Fconfiguration\u002Fsandbox","4.reference\u002F2.configuration\u002F8.sandbox",{"title":180,"path":181,"stem":182},"Environment variables","\u002Freference\u002Fconfiguration\u002Fenvironment-variables","4.reference\u002F2.configuration\u002F9.environment-variables",{"title":184,"path":185,"stem":186,"children":187},"Chain nodes","\u002Freference\u002Fchain-nodes","4.reference\u002F3.chain-nodes\u002Findex",[188,189,193,197],{"title":10,"path":185,"stem":186},{"title":190,"path":191,"stem":192},"Subprocess tasks","\u002Freference\u002Fchain-nodes\u002Fsubprocess-tasks","4.reference\u002F3.chain-nodes\u002F2.subprocess-tasks",{"title":194,"path":195,"stem":196},"Fix loop and judge","\u002Freference\u002Fchain-nodes\u002Ffix-loop","4.reference\u002F3.chain-nodes\u002F3.fix-loop",{"title":198,"path":199,"stem":200},"Result file","\u002Freference\u002Fchain-nodes\u002Fresult-file","4.reference\u002F3.chain-nodes\u002F4.result-file",{"title":202,"path":203,"stem":204},"Permission gate","\u002Freference\u002Fpermissions","4.reference\u002F4.permissions",{"title":206,"path":207,"stem":208,"children":209},"Agent harnesses","\u002Freference\u002Fharnesses","4.reference\u002F5.harnesses\u002Findex",[210,211,215,219,223],{"title":10,"path":207,"stem":208},{"title":212,"path":213,"stem":214},"Unattended runs","\u002Freference\u002Fharnesses\u002Funattended-runs","4.reference\u002F5.harnesses\u002F2.unattended-runs",{"title":216,"path":217,"stem":218},"Agent profiles","\u002Freference\u002Fharnesses\u002Fagent-profiles","4.reference\u002F5.harnesses\u002F3.agent-profiles",{"title":220,"path":221,"stem":222},"Harness files","\u002Freference\u002Fharnesses\u002Fharness-files","4.reference\u002F5.harnesses\u002F4.harness-files",{"title":224,"path":225,"stem":226},"Fallback and escalation","\u002Freference\u002Fharnesses\u002Ffallback-and-escalation","4.reference\u002F5.harnesses\u002F5.fallback-and-escalation",{"title":228,"path":229,"stem":230},"Inbound triggers","\u002Freference\u002Ftriggers","4.reference\u002F6.triggers",{"title":232,"path":233,"stem":234},"HTTP API","\u002Freference\u002Fhttp-api","4.reference\u002F7.http-api",{"title":236,"path":237,"stem":238},"MCP tools","\u002Freference\u002Fmcp-tools","4.reference\u002F8.mcp-tools",{"title":240,"path":241,"stem":242},"Events","\u002Freference\u002Fevents","4.reference\u002F9.events",{"title":244,"path":245,"stem":246,"children":247},"Project","\u002Fproject","5.project",[248,250,254,258,262,266],{"title":10,"path":245,"stem":249},"5.project\u002Findex",{"title":251,"path":252,"stem":253},"Architecture","\u002Fproject\u002Farchitecture","5.project\u002F1.architecture",{"title":255,"path":256,"stem":257},"Contributing","\u002Fproject\u002Fcontributing","5.project\u002F2.contributing",{"title":259,"path":260,"stem":261},"Security","\u002Fproject\u002Fsecurity","5.project\u002F3.security",{"title":263,"path":264,"stem":265},"Data and privacy","\u002Fproject\u002Fdata-and-privacy","5.project\u002F4.data-and-privacy",{"title":267,"path":268,"stem":269},"Status and support","\u002Fproject\u002Fstatus-and-support","5.project\u002F5.status-and-support",{"id":271,"title":67,"body":272,"description":649,"extension":650,"links":651,"meta":652,"navigation":653,"path":68,"seo":654,"stem":69,"__hash__":655},"docs\u002F3.guides\u002F03.remote-access.md",{"type":273,"value":274,"toc":641},"minimark",[275,284,289,299,302,319,323,333,348,352,468,471,475,501,560,564,625,629,637],[276,277,278,279,283],"p",{},"Reach the Kraft board from a phone or another machine by binding it off\nloopback and turning on password auth. You need a password, an\n",[280,281,282],"code",{},"allowed_hosts"," entry for the hostname you will type, and a non-loopback bind.",[285,286,288],"h2",{"id":287},"before-you-start","Before you start",[276,290,291,292,295,296,298],{},"Kraft binds ",[280,293,294],{},"127.0.0.1"," by default and skips auth for local clients. Any other\nbind makes Kraft require the password from every client, local ones included,\nand check browser Host headers against ",[280,297,282],{},".",[276,300,301],{},"Pick the narrowest bind that works:",[303,304,305,313],"ul",{},[306,307,308,312],"li",{},[309,310,311],"strong",{},"Tailscale (recommended)."," Bind the machine's Tailscale address. Only\ndevices on your tailnet can reach the board, and your LAN cannot.",[306,314,315,318],{},[309,316,317],{},"Cloudflare Quick Tunnel."," Put the board on the public internet. Use it\nonly if you cannot use Tailscale.",[285,320,322],{"id":321},"set-a-password","Set a password",[276,324,325,326,328,329,332],{},"Set a password in Settings → Access while you are still on ",[280,327,294],{},".\n",[280,330,331],{},"kraft admin start"," refuses a non-loopback bind without one.",[276,334,335,336,339,340,343,344,347],{},"The port is 8765 unless you set ",[280,337,338],{},"port"," in ",[280,341,342],{},"access.yaml"," or pass ",[280,345,346],{},"--port",". Use\nyour port wherever this page says 8765.",[285,349,351],{"id":350},"over-tailscale","Over Tailscale",[353,354,355,398,430,461],"ol",{},[306,356,357,358],{},"Find the machine's Tailscale address and name:",[359,360,365],"pre",{"className":361,"code":362,"language":363,"meta":364,"style":364},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","tailscale ip -4        # e.g. 100.101.102.103\ntailscale status       # the first line names this machine\n","bash","",[280,366,367,387],{"__ignoreMap":364},[368,369,372,376,380,383],"span",{"class":370,"line":371},"line",1,[368,373,375],{"class":374},"sBMFI","tailscale",[368,377,379],{"class":378},"sfazB"," ip",[368,381,382],{"class":378}," -4",[368,384,386],{"class":385},"sHwdD","        # e.g. 100.101.102.103\n",[368,388,390,392,395],{"class":370,"line":389},2,[368,391,375],{"class":374},[368,393,394],{"class":378}," status",[368,396,397],{"class":385},"       # the first line names this machine\n",[306,399,400,401,403,404,407,408,411,412,414,415,417,418,421,422,425,426,429],{},"In ",[280,402,342],{},", through Settings → Access or by hand, set ",[280,405,406],{},"bind"," to that\naddress and add the machine's tailnet name, such as\n",[280,409,410],{},"mybox.tailnet-name.ts.net",", to ",[280,413,282],{},". Setting ",[280,416,406],{}," in the file,\nrather than passing ",[280,419,420],{},"--host",", keeps the ",[280,423,424],{},"kraft"," CLI in your other shells\npointed at the same address. Run ",[280,427,428],{},"kraft admin doctor"," to confirm the file\nparses.",[306,431,432,433,436,437],{},"Stop any running server and start it again, so it reads the new bind.\n",[280,434,435],{},"kraft admin restart"," would reuse the old bind, so it cannot switch it:",[359,438,440],{"className":361,"code":439,"language":363,"meta":364,"style":364},"kraft admin stop\nkraft admin start\n",[280,441,442,452],{"__ignoreMap":364},[368,443,444,446,449],{"class":370,"line":371},[368,445,424],{"class":374},[368,447,448],{"class":378}," admin",[368,450,451],{"class":378}," stop\n",[368,453,454,456,458],{"class":370,"line":389},[368,455,424],{"class":374},[368,457,448],{"class":378},[368,459,460],{"class":378}," start\n",[306,462,463,464,467],{},"From a device on your tailnet, open ",[280,465,466],{},"http:\u002F\u002Fmybox.tailnet-name.ts.net:8765\u002F",".\nTailscale encrypts the traffic between your devices.",[276,469,470],{},"Start Tailscale before Kraft: the Tailscale address does not exist until\nTailscale is up, and the bind fails without it.",[285,472,474],{"id":473},"over-a-cloudflare-quick-tunnel","Over a Cloudflare Quick Tunnel",[476,477,478,479,482,483,488,489,492,493,496,497,500],"warning",{},"A Quick Tunnel puts the board on the public internet. Anyone who finds the\n",[280,480,481],{},"*.trycloudflare.com"," URL reaches the login page, and the password is the\nbarrier. Kraft locks an address out for 15 minutes after 5 failed logins, but\nif the tunnel does not pass on the visitor's address, every visitor counts as\none address and a stranger's guesses can lock you out too. See\n",[484,485,487],"a",{"href":486},"\u002Fproject\u002Fsecurity#login","Login",". Open only the tunnel's ",[280,490,491],{},"https:\u002F\u002F"," URL, so the\nsession cookie is marked ",[280,494,495],{},"Secure",". The tunnel also needs\n",[280,498,499],{},"--host 0.0.0.0",", which listens on every interface, your LAN included. If your\nLAN is untrusted, block the port at your firewall for other interfaces.",[353,502,503,535,545],{},[306,504,505,506],{},"Stop any running server, then start it off loopback:",[359,507,509],{"className":361,"code":508,"language":363,"meta":364,"style":364},"kraft admin stop\nkraft admin start --host 0.0.0.0\n",[280,510,511,519],{"__ignoreMap":364},[368,512,513,515,517],{"class":370,"line":371},[368,514,424],{"class":374},[368,516,448],{"class":378},[368,518,451],{"class":378},[368,520,521,523,525,528,531],{"class":370,"line":389},[368,522,424],{"class":374},[368,524,448],{"class":378},[368,526,527],{"class":378}," start",[368,529,530],{"class":378}," --host",[368,532,534],{"class":533},"sbssI"," 0.0.0.0\n",[306,536,537,538,541,542,544],{},"Run ",[280,539,540],{},"cloudflared tunnel --url http:\u002F\u002Flocalhost:8765",". It prints a\n",[280,543,481],{}," URL.",[306,546,547,548,339,550,552,553,555,556,559],{},"Add that hostname to ",[280,549,282],{},[280,551,342],{},", then run\n",[280,554,435],{},", which keeps the non-loopback bind. The URL changes\nevery time ",[280,557,558],{},"cloudflared"," starts, so repeat this step each time.",[285,561,563],{"id":562},"verify","Verify",[353,565,566,610,617],{},[306,567,568,569,602,605,606,609],{},"From the phone or other machine, request the health endpoint, which needs\nno login:",[359,570,572],{"className":361,"code":571,"language":363,"meta":364,"style":364},"curl -s https:\u002F\u002F\u003Cyour-tunnel-hostname>\u002Fapi\u002Fhealth\n",[280,573,574],{"__ignoreMap":364},[368,575,576,579,582,585,589,592,596,599],{"class":370,"line":371},[368,577,578],{"class":374},"curl",[368,580,581],{"class":378}," -s",[368,583,584],{"class":378}," https:\u002F\u002F",[368,586,588],{"class":587},"sMK4o","\u003C",[368,590,591],{"class":378},"your-tunnel-hostnam",[368,593,595],{"class":594},"sTEyZ","e",[368,597,598],{"class":587},">",[368,600,601],{"class":378},"\u002Fapi\u002Fhealth\n",[603,604],"br",{},"Over Tailscale, use ",[280,607,608],{},"http:\u002F\u002Fmybox.tailnet-name.ts.net:8765\u002Fapi\u002Fhealth",". A\nJSON status confirms the request reaches Kraft.",[306,611,612,613,616],{},"Open the same address without ",[280,614,615],{},"\u002Fapi\u002Fhealth"," in a browser. You should see the\nlogin page. Log in with your password.",[306,618,619,620,622,623,298],{},"If the browser shows a 403 with \"unexpected Host\", the hostname is missing\nfrom ",[280,621,282],{},". Add it and run ",[280,624,435],{},[285,626,628],{"id":627},"related","Related",[276,630,631,632,634,635,298],{},"You get the real board, with the same auth. For the threat model, see\n",[484,633,259],{"href":260},". To call the API from off-machine, see\n",[484,636,228],{"href":229},[638,639,640],"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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}",{"title":364,"searchDepth":389,"depth":389,"links":642},[643,644,645,646,647,648],{"id":287,"depth":389,"text":288},{"id":321,"depth":389,"text":322},{"id":350,"depth":389,"text":351},{"id":473,"depth":389,"text":474},{"id":562,"depth":389,"text":563},{"id":627,"depth":389,"text":628},"Approve or reject a gate from a phone, over Tailscale or a tunnel, using the same password auth as the local board.","md",null,{},true,{"title":67,"description":649},"_J6MdxjoBKg3iFfGIRGSxGrbHzyGDUniJARqNEVtqP0",[657,659],{"title":63,"path":64,"stem":65,"description":658,"children":-1},"The Kraft Lite plugin, which runs a chain inside one agent session with no service, and its slash commands.",{"title":71,"path":72,"stem":73,"description":660,"children":-1},"Add an agent CLI to Kraft with a YAML file, override a shipped harness, and set up Amp, Cursor or Antigravity credentials.",1790824505985]