[{"data":1,"prerenderedAt":1399},["ShallowReactive",2],{"docs-nav":3,"docs:\u002Fdocs\u002Fmcp":139},[4,7,10,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58,61,64,67,70,73,76,79,82,85,88,91,94,97,100,103,106,109,112,115,118,121,124,127,130,133,136],{"path":5,"title":6},"\u002Fdocs\u002Faccess-gating","Protect a local route",{"path":8,"title":9},"\u002Fdocs\u002Farchitecture\u002Fsecurity-and-trust","Security and trust",{"path":11,"title":12},"\u002Fdocs\u002Fconcepts\u002Fbuilds-and-deployments","Build and deploy",{"path":14,"title":15},"\u002Fdocs\u002Fconcepts\u002Fconfiguration-ownership","Where configuration belongs",{"path":17,"title":18},"\u002Fdocs\u002Fconcepts\u002Fenvironments-and-secrets","Environment values and secrets",{"path":20,"title":21},"\u002Fdocs\u002Fconcepts\u002Fmental-model","How projects fit together",{"path":23,"title":24},"\u002Fdocs\u002Fconcepts\u002Fplans-and-apply","Plans and apply",{"path":26,"title":27},"\u002Fdocs\u002Fconcepts\u002Ftargets-and-runtimes","Choose a target and runtime",{"path":29,"title":30},"\u002Fdocs\u002Fcontribute\u002Freleases","Publish a release",{"path":32,"title":33},"\u002Fdocs\u002Fdevelopment-mounts","Development mounts",{"path":35,"title":36},"\u002Fdocs\u002Fgetting-started","Getting started",{"path":38,"title":39},"\u002Fdocs\u002Fhelp\u002Ffaq","FAQ",{"path":41,"title":42},"\u002Fdocs\u002Fhelp\u002Ftroubleshooting","Troubleshooting",{"path":44,"title":45},"\u002Fdocs\u002Fhow-to\u002Fdeploy-production","Prepare a deployment environment",{"path":47,"title":48},"\u002Fdocs\u002Fhow-to\u002Fswarm-cluster","Run on a multi-node Swarm",{"path":50,"title":51},"\u002Fdocs","mm documentation",{"path":53,"title":54},"\u002Fdocs\u002Fjobs-and-schedules","Jobs and schedules",{"path":56,"title":57},"\u002Fdocs\u002Flocal-dashboard","Local dashboard",{"path":59,"title":60},"\u002Fdocs\u002Flocal-https","Local HTTPS",{"path":62,"title":63},"\u002Fdocs\u002Flocal-services","Local services",{"path":65,"title":66},"\u002Fdocs\u002Fmcp","Let an AI agent work on your project",{"path":68,"title":69},"\u002Fdocs\u002Fmulti-project-hosts","Run multiple projects on one host",{"path":71,"title":72},"\u002Fdocs\u002Fonboarding","Set up a project",{"path":74,"title":75},"\u002Fdocs\u002Fopenbao","Use OpenBao",{"path":77,"title":78},"\u002Fdocs\u002Fproject\u002Fcontributing","Contributing",{"path":80,"title":81},"\u002Fdocs\u002Fproject\u002Flicense","License",{"path":83,"title":84},"\u002Fdocs\u002Fproject\u002Fsecurity","Security",{"path":86,"title":87},"\u002Fdocs\u002Freference\u002Fcapability-matrix","Supported features and platforms",{"path":89,"title":90},"\u002Fdocs\u002Freference\u002Fcli","CLI command reference",{"path":92,"title":93},"\u002Fdocs\u002Freference\u002Fconfiguration","Configuration",{"path":95,"title":96},"\u002Fdocs\u002Freference\u002Fenvironment-variables","Environment variables",{"path":98,"title":99},"\u002Fdocs\u002Freference\u002Ferrors-and-exit-codes","Errors and exit codes",{"path":101,"title":102},"\u002Fdocs\u002Freference\u002Fknown-issues","Known limitations",{"path":104,"title":105},"\u002Fdocs\u002Fremote-access","Manage remote access",{"path":107,"title":108},"\u002Fdocs\u002Fremote-daemon","Set up a remote host",{"path":110,"title":111},"\u002Fdocs\u002Fruntime-observability","Status, logs, and commands",{"path":113,"title":114},"\u002Fdocs\u002Fsecret-delivery","Pass secrets to your app",{"path":116,"title":117},"\u002Fdocs\u002Fsecret-providers","Choose a secret store",{"path":119,"title":120},"\u002Fdocs\u002Fstart\u002Finstall","Install mm",{"path":122,"title":123},"\u002Fdocs\u002Fterminal-ui","Terminal UI",{"path":125,"title":126},"\u002Fdocs\u002Ftutorials\u002Fdotnet-web-api",".NET web API example",{"path":128,"title":129},"\u002Fdocs\u002Ftutorials\u002Ffirst-local-app","First local app",{"path":131,"title":132},"\u002Fdocs\u002Ftutorials\u002Flaravel-rust","Laravel and Rust example",{"path":134,"title":135},"\u002Fdocs\u002Ftutorials\u002Fnode-fullstack","Node full stack example",{"path":137,"title":138},"\u002Fdocs\u002Fvault","Use HashiCorp Vault",{"id":140,"title":66,"body":141,"description":1392,"extension":1393,"meta":1394,"navigation":1395,"path":65,"seo":1396,"stem":1397,"__hash__":1398},"docs\u002Fdocs\u002Fmcp.md",{"type":142,"value":143,"toc":1381},"minimark",[144,157,172,177,184,223,249,325,335,338,342,356,421,427,495,498,543,546,634,638,641,674,687,691,698,886,900,904,949,952,956,959,1009,1028,1031,1035,1085,1089,1103,1172,1193,1197,1335,1342,1349,1352,1377],[145,146,147,148,152,153,156],"p",{},"An AI agent works with mm through ",[149,150,151],"code",{},"mm mcp serve",", a Model Context Protocol (MCP)\nserver that your coding tool starts. The project's ",[149,154,155],{},"agents:"," block sets what an\nagent may do in each environment. For anything else, the agent gets the exact\ncommand and asks you to run it.",[145,158,159,160,163,164,167,168,171],{},"For example: an agent deploys and runs commands in ",[149,161,162],{},"local",", restarts jobs in\n",[149,165,166],{},"staging",", and only reads status and logs in ",[149,169,170],{},"production",".",[173,174,176],"h2",{"id":175},"connect-a-coding-tool","Connect a coding tool",[145,178,179,180,183],{},"Run this in the project, review the changes it lists, then run it with ",[149,181,182],{},"--yes",":",[185,186,191],"pre",{"className":187,"code":188,"language":189,"meta":190,"style":190},"language-sh shiki shiki-themes mm","mm agent setup\nmm agent setup --yes\n","sh","",[149,192,193,209],{"__ignoreMap":190},[194,195,198,202,206],"span",{"class":196,"line":197},"line",1,[194,199,201],{"class":200},"svrjQ","mm",[194,203,205],{"class":204},"sv8ni"," agent",[194,207,208],{"class":204}," setup\n",[194,210,212,214,216,219],{"class":196,"line":211},2,[194,213,201],{"class":200},[194,215,205],{"class":204},[194,217,218],{"class":204}," setup",[194,220,222],{"class":221},"sbRf1"," --yes\n",[145,224,225,226,229,230,233,234,237,238,237,241,244,245,248],{},"Without ",[149,227,228],{},"--client",", mm connects the tools it finds on ",[149,231,232],{},"PATH",". Name one with\n",[149,235,236],{},"--client claude-code",", ",[149,239,240],{},"opencode",[149,242,243],{},"codex",", or ",[149,246,247],{},"cursor",". Commit the files it\nwrites:",[250,251,252,265],"table",{},[253,254,255],"thead",{},[256,257,258,262],"tr",{},[259,260,261],"th",{},"File",[259,263,264],{},"Purpose",[266,267,268,291,308],"tbody",{},[256,269,270,285],{},[271,272,273,237,276,237,279,237,282],"td",{},[149,274,275],{},".mcp.json",[149,277,278],{},"opencode.json",[149,280,281],{},".cursor\u002Fmcp.json",[149,283,284],{},".codex\u002Fconfig.toml",[271,286,287,288,290],{},"Start ",[149,289,151],{}," for this project",[256,292,293,303],{},[271,294,295,298,299,302],{},[149,296,297],{},"AGENTS.md"," (and ",[149,300,301],{},"CLAUDE.md"," importing it)",[271,304,305,306],{},"Tell agents to use the mm tools and never run ",[149,307,201],{},[256,309,310,315],{},[271,311,312],{},[149,313,314],{},".claude\u002Fsettings.json",[271,316,317,318,320,321,324],{},"Deny Claude Code running ",[149,319,201],{}," and ",[149,322,323],{},"mmd"," directly",[145,326,327,330,331,334],{},[149,328,329],{},"mm agent setup --user --yes"," registers the server in each tool's own\nconfiguration instead, for every project. ",[149,332,333],{},".\u002Finstall.sh"," does this for Claude\nCode and OpenCode when they are installed.",[145,336,337],{},"The server uses standard input and output and opens no network port. It serves\nthe project in the directory the tool starts it in.",[173,339,341],{"id":340},"set-what-agents-may-do","Set what agents may do",[145,343,344,345,347,348,351,352,355],{},"Add an ",[149,346,155],{}," block to ",[149,349,350],{},".config\u002Fmm.yaml",". ",[149,353,354],{},"mm init"," writes this one:",[185,357,361],{"className":358,"code":359,"language":360,"meta":190,"style":190},"language-yaml shiki shiki-themes mm","agents:\n  \"*\": view # every environment not listed\n  local: { level: deploy, exec: true }\n","yaml",[149,362,363,373,387],{"__ignoreMap":190},[194,364,365,369],{"class":196,"line":197},[194,366,368],{"class":367},"sWZmh","agents",[194,370,372],{"class":371},"sIbZ0",":\n",[194,374,375,378,380,383],{"class":196,"line":211},[194,376,377],{"class":204},"  \"*\"",[194,379,183],{"class":371},[194,381,382],{"class":204}," view",[194,384,386],{"class":385},"sP7nD"," # every environment not listed\n",[194,388,390,393,395,398,401,403,406,409,412,414,418],{"class":196,"line":389},3,[194,391,392],{"class":367},"  local",[194,394,183],{"class":371},[194,396,397],{"class":371}," {",[194,399,400],{"class":367}," level",[194,402,183],{"class":371},[194,404,405],{"class":204}," deploy",[194,407,408],{"class":371},",",[194,410,411],{"class":367}," exec",[194,413,183],{"class":371},[194,415,417],{"class":416},"s1Wbj"," true",[194,419,420],{"class":371}," }\n",[145,422,423,424,183],{},"Each environment takes a level, and optionally ",[149,425,426],{},"exec",[250,428,429,439],{},[253,430,431],{},[256,432,433,436],{},[259,434,435],{},"Setting",[259,437,438],{},"Allows",[266,440,441,451,463,475,485],{},[256,442,443,448],{},[271,444,445],{},[149,446,447],{},"view",[271,449,450],{},"status, services, routes, jobs, redacted logs, and plans of any change",[256,452,453,458],{},[271,454,455],{},[149,456,457],{},"operate",[271,459,460,462],{},[149,461,447],{}," plus run, cancel, and retry jobs, and run a schedule now",[256,464,465,470],{},[271,466,467],{},[149,468,469],{},"deploy",[271,471,472,474],{},[149,473,457],{}," plus apply configuration edits, builds, and deployments, reconcile schedules, and enable or disable them",[256,476,477,482],{},[271,478,479],{},[149,480,481],{},"exec: true",[271,483,484],{},"run a command in any service container",[256,486,487,492],{},[271,488,489],{},[149,490,491],{},"exec: [api, …]",[271,493,494],{},"run a command in the listed services only",[145,496,497],{},"Rules:",[499,500,501,507,517,537],"ul",{},[502,503,504,505,171],"li",{},"Without a block, and for an environment the block does not cover, agents get\n",[149,506,447],{},[502,508,509,510,513,514,516],{},"Agents are never ",[149,511,512],{},"admin",". No level includes ",[149,515,426],{},"; grant it separately.",[502,518,519,522,523,525,526,529,530,533,534,171],{},[149,520,521],{},"mm.overrides.yaml"," cannot set ",[149,524,368],{},". To give the block its own reviewers,\nrun ",[149,527,528],{},"mm config split agents"," and list ",[149,531,532],{},".config\u002Fmm\u002Fagents.yaml"," in ",[149,535,536],{},"CODEOWNERS",[502,538,539,542],{},[149,540,541],{},"mm config validate"," checks the block.",[145,544,545],{},"A longer example:",[185,547,549],{"className":358,"code":548,"language":360,"meta":190,"style":190},"agents:\n  \"*\": view\n  local: { level: deploy, exec: true }\n  staging: { level: operate, exec: [api] }\n  production: view\n",[149,550,551,557,566,590,624],{"__ignoreMap":190},[194,552,553,555],{"class":196,"line":197},[194,554,368],{"class":367},[194,556,372],{"class":371},[194,558,559,561,563],{"class":196,"line":211},[194,560,377],{"class":204},[194,562,183],{"class":371},[194,564,565],{"class":204}," view\n",[194,567,568,570,572,574,576,578,580,582,584,586,588],{"class":196,"line":389},[194,569,392],{"class":367},[194,571,183],{"class":371},[194,573,397],{"class":371},[194,575,400],{"class":367},[194,577,183],{"class":371},[194,579,405],{"class":204},[194,581,408],{"class":371},[194,583,411],{"class":367},[194,585,183],{"class":371},[194,587,417],{"class":416},[194,589,420],{"class":371},[194,591,593,596,598,600,602,604,607,609,611,613,616,619,622],{"class":196,"line":592},4,[194,594,595],{"class":367},"  staging",[194,597,183],{"class":371},[194,599,397],{"class":371},[194,601,400],{"class":367},[194,603,183],{"class":371},[194,605,606],{"class":204}," operate",[194,608,408],{"class":371},[194,610,411],{"class":367},[194,612,183],{"class":371},[194,614,615],{"class":371}," [",[194,617,618],{"class":204},"api",[194,620,621],{"class":371},"]",[194,623,420],{"class":371},[194,625,627,630,632],{"class":196,"line":626},5,[194,628,629],{"class":367},"  production",[194,631,183],{"class":371},[194,633,565],{"class":204},[173,635,637],{"id":636},"trust-the-block","Trust the block",[145,639,640],{},"An agent can edit files in your checkout, including this block. So mm applies\nthe block only after you trust it on your machine:",[185,642,644],{"className":187,"code":643,"language":189,"meta":190,"style":190},"mm agent trust                       # shows the block and its hash\nmm agent trust --plan HASH --yes\n",[149,645,646,658],{"__ignoreMap":190},[194,647,648,650,652,655],{"class":196,"line":197},[194,649,201],{"class":200},[194,651,205],{"class":204},[194,653,654],{"class":204}," trust",[194,656,657],{"class":385},"                       # shows the block and its hash\n",[194,659,660,662,664,666,669,672],{"class":196,"line":211},[194,661,201],{"class":200},[194,663,205],{"class":204},[194,665,654],{"class":204},[194,667,668],{"class":221}," --plan",[194,670,671],{"class":204}," HASH",[194,673,222],{"class":221},[145,675,676,677,679,680,682,683,686],{},"Until then, and again after any edit to the block, agents have ",[149,678,447],{},"\neverywhere. ",[149,681,354],{}," trusts the block it writes. ",[149,684,685],{},"mm agent status"," shows what\nthe block grants, what is in force, and whether it is trusted.",[173,688,690],{"id":689},"when-the-agent-may-not-do-something","When the agent may not do something",[145,692,693,694,697],{},"A tool call outside the grant changes nothing. It returns ",[149,695,696],{},"MM_AGENT_HANDOFF","\nwith the commands for you, and the agent shows them to you:",[185,699,703],{"className":700,"code":701,"language":702,"meta":190,"style":190},"language-json shiki shiki-themes mm","{\n  \"error\": {\n    \"code\": \"MM_AGENT_HANDOFF\",\n    \"message\": \"Agents have 'view' in environment 'production'; this needs exec. The user can run it instead.\",\n    \"handoff\": {\n      \"reason\": \"not_granted\",\n      \"environment\": \"production\",\n      \"granted\": \"view\",\n      \"requires\": \"exec\",\n      \"user_commands\": [\n        \"mm --environment production service exec api -- rails db:migrate\"\n      ]\n    }\n  }\n}\n","json",[149,704,705,710,726,743,759,772,790,807,824,841,856,862,868,874,880],{"__ignoreMap":190},[194,706,707],{"class":196,"line":197},[194,708,709],{"class":371},"{\n",[194,711,712,715,718,721,723],{"class":196,"line":211},[194,713,714],{"class":371},"  \"",[194,716,717],{"class":367},"error",[194,719,720],{"class":371},"\"",[194,722,183],{"class":371},[194,724,725],{"class":371}," {\n",[194,727,728,731,733,735,737,740],{"class":196,"line":389},[194,729,730],{"class":371},"    \"",[194,732,149],{"class":367},[194,734,720],{"class":371},[194,736,183],{"class":371},[194,738,739],{"class":204}," \"MM_AGENT_HANDOFF\"",[194,741,742],{"class":371},",\n",[194,744,745,747,750,752,754,757],{"class":196,"line":592},[194,746,730],{"class":371},[194,748,749],{"class":367},"message",[194,751,720],{"class":371},[194,753,183],{"class":371},[194,755,756],{"class":204}," \"Agents have 'view' in environment 'production'; this needs exec. The user can run it instead.\"",[194,758,742],{"class":371},[194,760,761,763,766,768,770],{"class":196,"line":626},[194,762,730],{"class":371},[194,764,765],{"class":367},"handoff",[194,767,720],{"class":371},[194,769,183],{"class":371},[194,771,725],{"class":371},[194,773,775,778,781,783,785,788],{"class":196,"line":774},6,[194,776,777],{"class":371},"      \"",[194,779,780],{"class":367},"reason",[194,782,720],{"class":371},[194,784,183],{"class":371},[194,786,787],{"class":204}," \"not_granted\"",[194,789,742],{"class":371},[194,791,793,795,798,800,802,805],{"class":196,"line":792},7,[194,794,777],{"class":371},[194,796,797],{"class":367},"environment",[194,799,720],{"class":371},[194,801,183],{"class":371},[194,803,804],{"class":204}," \"production\"",[194,806,742],{"class":371},[194,808,810,812,815,817,819,822],{"class":196,"line":809},8,[194,811,777],{"class":371},[194,813,814],{"class":367},"granted",[194,816,720],{"class":371},[194,818,183],{"class":371},[194,820,821],{"class":204}," \"view\"",[194,823,742],{"class":371},[194,825,827,829,832,834,836,839],{"class":196,"line":826},9,[194,828,777],{"class":371},[194,830,831],{"class":367},"requires",[194,833,720],{"class":371},[194,835,183],{"class":371},[194,837,838],{"class":204}," \"exec\"",[194,840,742],{"class":371},[194,842,844,846,849,851,853],{"class":196,"line":843},10,[194,845,777],{"class":371},[194,847,848],{"class":367},"user_commands",[194,850,720],{"class":371},[194,852,183],{"class":371},[194,854,855],{"class":371}," [\n",[194,857,859],{"class":196,"line":858},11,[194,860,861],{"class":204},"        \"mm --environment production service exec api -- rails db:migrate\"\n",[194,863,865],{"class":196,"line":864},12,[194,866,867],{"class":371},"      ]\n",[194,869,871],{"class":196,"line":870},13,[194,872,873],{"class":371},"    }\n",[194,875,877],{"class":196,"line":876},14,[194,878,879],{"class":371},"  }\n",[194,881,883],{"class":196,"line":882},15,[194,884,885],{"class":371},"}\n",[145,887,888,889,891,892,895,896,899],{},"Run the command in your own terminal, outside the agent session. Plans work\nthe same way: an agent with ",[149,890,447],{}," can plan a production deployment, and the\nplan says ",[149,893,894],{},"\"applied_by\": \"user\""," with the ",[149,897,898],{},"mm deploy"," commands for you.",[173,901,903],{"id":902},"mm-refuses-to-run-for-an-agent","mm refuses to run for an agent",[145,905,906,907,237,910,237,913,237,916,742,919,237,922,237,925,742,928,237,931,934,935,938,939,941,942,944,945,948],{},"Coding tools set environment variables for the commands their agents run. mm\nchecks for ",[149,908,909],{},"CLAUDECODE",[149,911,912],{},"OPENCODE",[149,914,915],{},"CODEX_CI",[149,917,918],{},"CODEX_THREAD_ID",[149,920,921],{},"CODEX_SANDBOX",[149,923,924],{},"CODEX_SANDBOX_NETWORK_DISABLED",[149,926,927],{},"CURSOR_AGENT",[149,929,930],{},"GEMINI_CLI",[149,932,933],{},"AI_AGENT",", and ",[149,936,937],{},"AGENT",". When one is set, every ",[149,940,201],{}," command\nexcept ",[149,943,151],{}," exits with code 3 and points the agent at the MCP tools.\nSet ",[149,946,947],{},"MM_AGENT=1"," to get the same behavior in a tool mm does not know.",[145,950,951],{},"This also applies to commands you type into the agent's own shell. Use a\nseparate terminal.",[173,953,955],{"id":954},"remote-environments","Remote environments",[145,957,958],{},"A remote host limits agents itself, so a change in someone's checkout cannot\nwiden what an agent does there. The MCP server reaches a remote host only with\na separate agent key:",[185,960,962],{"className":187,"code":961,"language":189,"meta":190,"style":190},"mm key create --agent\nmm team join --agent                  # reviewed edit of your users entry\nmm team join --agent --plan HASH --yes\n",[149,963,964,977,993],{"__ignoreMap":190},[194,965,966,968,971,974],{"class":196,"line":197},[194,967,201],{"class":200},[194,969,970],{"class":204}," key",[194,972,973],{"class":204}," create",[194,975,976],{"class":221}," --agent\n",[194,978,979,981,984,987,990],{"class":196,"line":211},[194,980,201],{"class":200},[194,982,983],{"class":204}," team",[194,985,986],{"class":204}," join",[194,988,989],{"class":221}," --agent",[194,991,992],{"class":385},"                  # reviewed edit of your users entry\n",[194,994,995,997,999,1001,1003,1005,1007],{"class":196,"line":389},[194,996,201],{"class":200},[194,998,983],{"class":204},[194,1000,986],{"class":204},[194,1002,989],{"class":221},[194,1004,668],{"class":221},[194,1006,671],{"class":204},[194,1008,222],{"class":221},[145,1010,1011,1012,1014,1015,1018,1019,1022,1023,171],{},"Commit the change and have it merged. After the environment is deployed or\nsynced, the host gives the agent key your access limited by the ",[149,1013,155],{}," block\nof the commit it deployed. ",[149,1016,1017],{},"mm team sync"," plans show the agent as its own\nline, such as ",[149,1020,1021],{},"alice (agent): none -> view, +1 key(s)",". See\n",[1024,1025,1027],"a",{"href":1026},".\u002Fremote-access#agent-keys","remote access",[145,1029,1030],{},"Without an agent key, tools for a remote environment return a handoff with\nthese commands.",[173,1032,1034],{"id":1033},"what-this-does-and-does-not-protect","What this does and does not protect",[499,1036,1037,1047,1057,1074],{},[502,1038,1039,1043,1044,1046],{},[1040,1041,1042],"strong",{},"Remote environments are enforced by the host."," An agent key gets only what\nthe deployed commit's ",[149,1045,155],{}," block allows, whatever the checkout or the\nagent says.",[502,1048,1049,1052,1053,1056],{},[1040,1050,1051],{},"Your own key must stay out of the agent's reach."," An agent that can read\nyour key file can act as you. Use a security key (",[149,1054,1055],{},"mm key create --security-key","), which needs a touch for every connection, or run the agent\nwhere it cannot read your mm home.",[502,1058,1059,1062,1063,1066,1067,1070,1071,1073],{},[1040,1060,1061],{},"Local environments are a guardrail."," An agent with a shell on your machine\ncan call ",[149,1064,1065],{},"docker"," or ",[149,1068,1069],{},"podman"," directly. The block, the trust step, and the\nrefusal to run ",[149,1072,201],{}," stop an agent that follows its instructions; they do not\ncontain one that works around them. Restrict the agent's shell in your coding\ntool if you need that.",[502,1075,1076,1081,1082,1084],{},[1040,1077,1078,1080],{},[149,1079,426],{}," output is not redacted."," A command in a container can print what the\nservice can read, including its secrets. Grant ",[149,1083,426],{}," only where the agent\nmay see that.",[173,1086,1088],{"id":1087},"private-limits-on-your-machine","Private limits on your machine",[145,1090,1091,1092,1095,1096,1099,1100,183],{},"To cap agents on one machine below what a project grants, create ",[149,1093,1094],{},"mcp.json"," in\nyour mm home (normally ",[149,1097,1098],{},"~\u002F.mm","), owned by you with mode ",[149,1101,1102],{},"0600",[185,1104,1106],{"className":700,"code":1105,"language":702,"meta":190,"style":190},"{\n  \"schema_version\": 2,\n  \"ceiling\": { \"*\": \"operate\", \"production\": \"view\" }\n}\n",[149,1107,1108,1112,1128,1168],{"__ignoreMap":190},[194,1109,1110],{"class":196,"line":197},[194,1111,709],{"class":371},[194,1113,1114,1116,1119,1121,1123,1126],{"class":196,"line":211},[194,1115,714],{"class":371},[194,1117,1118],{"class":367},"schema_version",[194,1120,720],{"class":371},[194,1122,183],{"class":371},[194,1124,1125],{"class":416}," 2",[194,1127,742],{"class":371},[194,1129,1130,1132,1135,1137,1139,1141,1144,1147,1149,1151,1154,1156,1158,1160,1162,1164,1166],{"class":196,"line":389},[194,1131,714],{"class":371},[194,1133,1134],{"class":367},"ceiling",[194,1136,720],{"class":371},[194,1138,183],{"class":371},[194,1140,397],{"class":371},[194,1142,1143],{"class":371}," \"",[194,1145,1146],{"class":367},"*",[194,1148,720],{"class":371},[194,1150,183],{"class":371},[194,1152,1153],{"class":204}," \"operate\"",[194,1155,408],{"class":371},[194,1157,1143],{"class":371},[194,1159,170],{"class":367},[194,1161,720],{"class":371},[194,1163,183],{"class":371},[194,1165,821],{"class":204},[194,1167,420],{"class":371},[194,1169,1170],{"class":196,"line":592},[194,1171,885],{"class":371},[145,1173,1174,1175,1178,1179,1182,1183,237,1186,934,1189,1192],{},"The file is optional and can only narrow the project's block. It also accepts\n",[149,1176,1177],{},"principal"," (the name in audit records, default ",[149,1180,1181],{},"agent","),\n",[149,1184,1185],{},"maximum_page_size",[149,1187,1188],{},"maximum_response_bytes",[149,1190,1191],{},"request_timeout_ms",".\nA version 1 file, which listed environments and capabilities, is rejected:\ndelete it or replace it with the form above.",[173,1194,1196],{"id":1195},"tools","Tools",[250,1198,1199,1212],{},[253,1200,1201],{},[256,1202,1203,1206,1209],{},[259,1204,1205],{},"Tool",[259,1207,1208],{},"Needs",[259,1210,1211],{},"Does",[266,1213,1214,1227,1241,1255,1270,1293,1315],{},[256,1215,1216,1221,1224],{},[271,1217,1218],{},[149,1219,1220],{},"mm_access",[271,1222,1223],{},"nothing",[271,1225,1226],{},"Lists environments and what the agent may do in each",[256,1228,1229,1234,1238],{},[271,1230,1231],{},[149,1232,1233],{},"mm_read",[271,1235,1236],{},[149,1237,447],{},[271,1239,1240],{},"One category: project, environments, targets, plans, services, routes, health, operations, jobs, schedules, gates",[256,1242,1243,1248,1252],{},[271,1244,1245],{},[149,1246,1247],{},"mm_logs",[271,1249,1250],{},[149,1251,447],{},[271,1253,1254],{},"Up to 200 redacted log records of one service",[256,1256,1257,1262,1267],{},[271,1258,1259],{},[149,1260,1261],{},"mm_exec",[271,1263,1264,1266],{},[149,1265,426],{}," for the service",[271,1268,1269],{},"Runs an exact argv in a service container; no shell, TTY, or stdin; up to 300 seconds and 256 KiB of output",[256,1271,1272,1286,1290],{},[271,1273,1274,237,1277,237,1280,237,1283],{},[149,1275,1276],{},"mm_config_plan",[149,1278,1279],{},"mm_build_plan",[149,1281,1282],{},"mm_deploy_plan",[149,1284,1285],{},"mm_job_plan",[271,1287,1288],{},[149,1289,447],{},[271,1291,1292],{},"Reviews a change without making it",[256,1294,1295,1300,1306],{},[271,1296,1297],{},[149,1298,1299],{},"mm_job_apply",[271,1301,1302,1066,1304],{},[149,1303,457],{},[149,1305,469],{},[271,1307,1308,1309,1311,1312,1314],{},"Runs, cancels, or retries a job (",[149,1310,457],{},"); reconciles or toggles schedules (",[149,1313,469],{},")",[256,1316,1317,1328,1332],{},[271,1318,1319,237,1322,237,1325],{},[149,1320,1321],{},"mm_config_apply",[149,1323,1324],{},"mm_build_apply",[149,1326,1327],{},"mm_deploy_apply",[271,1329,1330],{},[149,1331,469],{},[271,1333,1334],{},"Applies the plan just reviewed",[145,1336,1337,1338,1341],{},"Only the environment is required in a tool's ",[149,1339,1340],{},"scope","; the target and runtime\ndefault to what the project and your machine select.",[145,1343,1344,1345,1348],{},"An apply tool takes the plan hash, the plan's single-use token, and the\nconfirmation ",[149,1346,1347],{},"apply:\u003Cplan_hash>",". Tokens expire after ten minutes. If apply\nreports stale state, request a new plan.",[145,1350,1351],{},"Not available through MCP: an interactive shell, port forwards, secret values,\nedits to the users file, and target, key, and host administration. Every call\nthat names an environment, including each refusal, is recorded in the local\naudit journal with its operation and outcome, and without its arguments.",[145,1353,1354,1355,742,1359,742,1363,1367,1368,1372,1373,1376],{},"Generated snapshots are available for the\n",[1024,1356,1358],{"href":1357},"\u002Fschema\u002Fmcp-tools.schema.json","tool contract",[1024,1360,1362],{"href":1361},"\u002Fschema\u002Fmcp-resources.schema.json","resource contract",[1024,1364,1366],{"href":1365},"\u002Fschema\u002Fmcp-project.schema.json","project contract",", and\n",[1024,1369,1371],{"href":1370},"\u002Fschema\u002Fmcp-config.schema.json","private limits",". They come from the MCP\nrouter and the Rust types through ",[149,1374,1375],{},".\u002Fscripts\u002Fgenerate-artifacts.sh"," and must\nnot be edited directly.",[1378,1379,1380],"style",{},"html pre.shiki code .svrjQ, html code.shiki .svrjQ{--shiki-default:var(--mm-code-function)}html pre.shiki code .sv8ni, html code.shiki .sv8ni{--shiki-default:var(--mm-code-string)}html pre.shiki code .sbRf1, html code.shiki .sbRf1{--shiki-default:var(--mm-code-option)}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 pre.shiki code .sWZmh, html code.shiki .sWZmh{--shiki-default:var(--mm-code-key)}html pre.shiki code .sIbZ0, html code.shiki .sIbZ0{--shiki-default:var(--mm-code-punctuation)}html pre.shiki code .sP7nD, html code.shiki .sP7nD{--shiki-default:var(--mm-code-comment)}html pre.shiki code .s1Wbj, html code.shiki .s1Wbj{--shiki-default:var(--mm-code-constant)}",{"title":190,"searchDepth":211,"depth":211,"links":1382},[1383,1384,1385,1386,1387,1388,1389,1390,1391],{"id":175,"depth":211,"text":176},{"id":340,"depth":211,"text":341},{"id":636,"depth":211,"text":637},{"id":689,"depth":211,"text":690},{"id":902,"depth":211,"text":903},{"id":954,"depth":211,"text":955},{"id":1033,"depth":211,"text":1034},{"id":1087,"depth":211,"text":1088},{"id":1195,"depth":211,"text":1196},"Connect a coding tool to mm's MCP server and set what agents may do in each environment.","md",{},true,{"title":66,"description":1392},"docs\u002Fmcp","DKEZSdmHoqMemeUbBSQc-aJowH8zSwbyXkNumZtyX-U",1794512545910]