{"protocol_version":"2.0","capabilities":{"tools":true,"streaming":{"sse":true,"jobs":true}},"server_info":{"name":"agentstack-mcp","title":"AgentStack","description":"AgentStack MCP = Work Graph control plane. After session + context.project_id: agents.work_next (mcp_work_loop_v1) -> plan_claim -> plan_execute (CAS/leases). Follow packet.next_action; catalog/discovery.search only if no packet. One-shot CRM/upload may call domain actions directly.","version":"2.0","icons":[{"src":"https://agentstack.tech/mcp/icon","mimeType":"image/png"}]},"api_key_context":{"service_caps":null,"note":"null = no restriction (full access). List = only those services are callable. Cap-gated actions: payments.* and wallets.* require 'payments'; scheduler.* requires 'scheduler'; key management requires 'api_keys'; project membership/admin writes require 'project_admin'; asset writes require 'assets_write'; data_access policy writes require 'data_access_admin'; logic/proc mutating execution requires 'logic_write'. Use apikeys.create with service_caps to provision restricted keys."},"tools":[{"name":"agentstack.execute","description":"AgentStack MCP = Work Graph control plane. After session + context.project_id: agents.work_next (mcp_work_loop_v1) -> plan_claim -> plan_execute (CAS/leases). Follow packet.next_action; catalog/discovery.search only if no packet. One-shot CRM/upload may call domain actions directly. Spine: agents.plan_get -> agents.work_next -> agents.plan_claim -> agents.plan_execute. Anti-pattern: Do not pick tools from catalog when packet.next_action is present. Mandatory session order: authenticate -> session probe auth.get_profile (alias auth.me) -> select/create project -> set context.project_id on every batch -> Work Graph loop. Playbook GET /mcp/prompts/get?name=agentstack_session_setup (recipe mcp_session_setup). Sync POST /mcp is lane mcp_batch (60000 ms) for the whole batch - not an RBAC cap. One expensive step per sync execute (bots.simulate, knowledge.playground, agents.run with wait=true, agents.plan_*, context.get); LLM-heavy steps widen to ai_stream (180000 ms). Large suites: options.async=true then poll discovery.job_status (REST GET /mcp/jobs/{{{{job_id}}}}). Cite catalog_actions_public from GET /mcp/actions/summary. There is one execute tool (agentstack.execute); do not quote tools_count as 'N tools'. Do not invent rules.* or webhooks.* (prefer logic.* and integrations.*).","inputSchema":{"type":"object","description":"Batch execute. One tool; each step names a dotted action.","properties":{"steps":{"type":"array","minItems":1,"description":"Ordered steps. Cheap list/get may batch. At most one heavy LLM action (bots.simulate, knowledge.playground, …) per sync execute.","items":{"type":"object","description":"One action invocation inside the batch.","properties":{"id":{"type":"string","description":"Step id unique within this batch. Referenced by options.observed."},"action":{"type":"string","description":"Canonical dotted action id from GET /mcp/actions (example: auth.get_profile)."},"params":{"type":"object","description":"Action arguments. Shape comes from discovery.describe for that action.","additionalProperties":true},"if":{"type":"object","description":"Optional predicate. The step runs only when this condition matches.","additionalProperties":true}},"required":["id","action"]}},"context":{"type":"object","description":"Execute scope. Set project_id on every batch after the session probe.","properties":{"project_id":{"type":"integer","description":"Tenant project id. Required for project-scoped actions."},"user_id":{"type":"integer","description":"Caller user id. Usually taken from the session; do not invent it."},"generation_env_uuid":{"type":"string","description":"Sandbox generation anchor (env_uuid). Not a recipe input."}},"additionalProperties":true},"options":{"type":"object","description":"Batch controls: async jobs, recipes, playbook progress, and error policy.","properties":{"async":{"type":"boolean","description":"Queue the batch (durable job). Required for more than one heavy LLM step. Poll discovery.job_status or GET /mcp/jobs/{job_id}."},"idempotency_key":{"type":"string","description":"Client retry key. The same key returns the same receipt."},"workflow_run_id":{"type":"string","description":"Goal run id. Separate from trace_id. Returned on the completion receipt."},"goal":{"type":"string","description":"The same user goal. When set, the envelope names the next playbook step."},"observed":{"type":"object","description":"Playbook progress. completed_steps holds step ids, not action names.","additionalProperties":true},"density":{"type":"string","description":"Wording of the current step. The allowed action set stays the same.","enum":["strict","guided","autonomous"]},"publish_asked":{"type":"boolean","description":"The user already asked to publish. Skips a second confirm."},"enforce_approval":{"type":"boolean","description":"When true, financial, destructive, and access-control steps pause for approval."},"stopOnError":{"type":"boolean","description":"Stop the batch at the first failed step. Default true."},"continueOnError":{"type":"boolean","description":"Keep later steps running after a failure. Opposite of stopOnError."},"envelope":{"type":"string","description":"Batch step payload shape. compact omits duplicate data/capability_result.","enum":["compact","full"]},"recipe_id":{"type":"string","description":"Expand a registered MCP recipe into steps before execute (see GET /mcp/recipes)."},"recipe_params":{"type":"object","description":"Values for {{placeholders}} in the recipe.","additionalProperties":true}},"additionalProperties":true}},"required":["steps"]}}],"ai_instructions":{"summary":"Use agentstack.execute for all operations. Sync batch is 60s mcp_batch; at most one heavy LLM step (bots.simulate). Full guidance: /mcp/ai_prompt and prompt agentstack_execute_budget.","full_prompt_url":"/mcp/ai_prompt"},"execute_budget":{"sync_lane":"mcp_batch","sync_lane_ms":60000,"timeout_ms":60000,"single_heavy_lane":"ai_stream","single_heavy_lane_ms":180000,"single_heavy_timeout_ms":180000,"max_sync_heavy_actions":1,"max_steps":50,"heavy_actions":["bots.simulate","knowledge.playground"],"heavy_prefixes":["ai_builder.generate","media.generate"],"cpu_heavy_actions":["agents.plan_apply_proposal","agents.plan_propose","agents.plan_recovery_scan","context.get"],"agents_run_wait_is_heavy":true,"async":{"enable":"options.async=true","poll_action":"discovery.job_status","poll_rest":"GET /mcp/jobs/{job_id}","lease_ms":1200000},"rule":"One expensive action per sync agentstack.execute (LLM-heavy or CPU-heavy). Cheap actions may share the 60s batch. Do not pack six bots.simulate into one execute."},"write_modes":{"param":"write_mode","required_when":"Writing a collection (bot commands, keyed lists), a document body (knowledge.content.patch text), or a prompt field (knowledge.prompt.patch plan_instructions / system_preamble). Metadata-only patches may omit it. Path writes use projects.patch_data (REST PATCH /projects/{id}/data).","mutation_kinds":{"entity":"CRUD verb in the action name (.create/.update/.delete). No write_mode.","collection":"Keyed list: write_mode merge|upsert|replace|delete.","body":"Document text: write_mode replace|append|prepend.","path":"One PathAtom / DNA leaf: projects.patch_data or path_updates.","none":"Read-only or no collection/body/path payload."},"modes":{"merge":"PATCH / protein merge_keyed: overlay by key (trigger, uid). Never drops siblings missing from the payload.","patch":"Alias of merge (REST PATCH / path_updates / OperationType.DELTA).","upsert":"Merge plus insert missing keys. Same as merge for bot commands.","replace":"PUT snapshot: incoming list/body is the full new value. Studio command Publish uses this. Empty collection is blocked.","write":"Alias of replace (full document body).","append":"Document body: concatenate after the existing joined text.","prepend":"Document body: concatenate before the existing joined text.","delete":"Explicit remove of named keys/items (incoming = delete set). A short replace list is never treated as delete."},"rest":{"PUT":"replace snapshot","PATCH":"merge / path_updates / protein DELTA / PATCH /projects/{id}/data","DELETE":"delete (dedicated route or write_mode=delete)","If-Match":"lost-update guard (CRM stage, social chat index)"},"protein":{"diff_op_kinds":["set","delete","merge_keyed","upsert_entity"],"operation_type":["get","create","update","delete","delta"]},"tools":{"bots.update":"Pass write_mode with commands. Prefer bots.commands.upsert for one command.","bots.commands.upsert":"Always merge-by-trigger; never replaces the menu.","knowledge.content.patch":"text is a full body unless write_mode=append|prepend. GET the document first; shrinking a long body needs allow_shrink=true. SDK Studio sets allow_shrink for operator save — AI must GET first.","knowledge.prompt.patch":"omit-unset keeps unsent keys only. A sent plan_instructions / system_preamble replaces that entire string. GET first; write_mode=append for a new bullet; stub replace → prompt_shrink_blocked.","agents.update":"section and path_updates default to merge (objects merge, lists replace). write_mode=replace sets the section or leaf wholesale. A full agent_spec without section/path_updates is a replace. write_mode=merge with only a partial agent_spec is rejected.","logic.update":"triggers/space/schedulers are keyed lists: pass write_mode. Prefer path_updates for one node.","projects.patch_data":"Leaf path SET (REST PATCH /projects/{id}/data). write_mode=replace sets the path; merge overlays an object; delete removes it.","hosting.bucket.file.patch":"search_replace does not need a prior GET. write_mode: replace|append|prepend|unified_diff|search_replace — not storage.upload. Omit bucket_id on the primary site. Identical bytes skip the write and gzip. A real change refreshes the .gz sibling. Do not delete it. Pass expected_sha256 when you have it. A mismatch writes nothing.","hosting.bucket.file.get":"Read UTF-8 text + content_sha256 (≤2MB) when you need the bytes. search_replace does not require this first. Use bucket_name or bucket_id (same resolver as hosting.files.put).","hosting.files.put":"Full-file PUT for one path. A small text edit is hosting.bucket.file.patch, not a GET and not dry_run. Not storage.upload — this writes the live site bucket tree.","hosting.deploy_files":"Batch publish many paths (≤50/call). Not for single CSS line — use file.patch. After publish poll hosting.site.edge_health.","social.chat.index_put":"Exception: subset-as-delete with If-Match. A short list can drop missing keys. Do not apply bots-style merge defaults here.","checklist.set":"checklist.set replaces the full items list — write_mode defaults to replace.","bots.reset_message_quota":"path","knowledge.config.patch":"body","knowledge.policy_templates.apply":"body","preflight.check":"path","projects.patch_my_data":"collection","projects.put_notify_policy":"path"},"errors":{"write_mode_invalid":"Unknown write_mode token.","write_mode_unsupported":"This payload cannot use that mode (e.g. merge on markdown body).","commands_empty_blocked":"Refusing to wipe bot_spec.commands to [].","content_shrink_blocked":"New KB body is much shorter than the indexed doc; pass allow_shrink.","prompt_shrink_blocked":"New plan_instructions / system_preamble is much shorter than the stored field. GET knowledge.prompt.get and send the full string, or write_mode=append, or allow_shrink=true.","use_path_updates":"Partial agent_spec with write_mode=merge requires path_updates."},"rule":"Always pass write_mode for collection/body writes. Omitting it infers a safe default (merge a partial command list; replace a KB body or prompt field with a shrink guard). Never send one command, one markdown section, or a 7-line plan_instructions stub as a full replace. Nested project.data leaves: projects.patch_data, not projects.update_project.","prompt":"agentstack_write_modes","doc":"agentstack-core/mcp/WRITE_MODES.md"},"common_workflows":[{"name":"Work Graph agent loop","description":"After context.project_id: plan_get -> work_next -> plan_claim -> plan_execute. node_id and revision come from the packet, not from this example.","tools":["agents.plan_get","agents.work_next","agents.plan_claim","agents.plan_execute"],"recipe_id":"mcp_work_loop_v1","example":{"steps":[{"id":"s1","action":"auth.get_profile","params":{}},{"id":"s2","action":"agents.plan_get","params":{"project_id":"{{context.project_id}}","include_execution_eligibility":true}},{"id":"s3","action":"agents.work_next","params":{"project_id":"{{context.project_id}}"}},{"id":"s4","action":"agents.ensure_agent","params":{"project_id":"{{context.project_id}}","node_id":"{{recipe_params.node_id}}","create":false}},{"id":"s5","action":"agents.plan_claim","params":{"project_id":"{{context.project_id}}","node_ids":["{{recipe_params.node_id}}"],"if_match_revision":"{{recipe_params.revision}}"}},{"id":"s6","action":"agents.plan_execute","params":{"project_id":"{{context.project_id}}","node_id":"{{recipe_params.node_id}}","via_work_next":true}},{"id":"s7","action":"agents.plan_recovery_scan","params":{"project_id":"{{context.project_id}}"}}],"options":{"stopOnError":true}}},{"name":"Session setup (auth + projects)","description":"Verify identity, list workspaces, then bind context.project_id","tools":["auth.get_profile","projects.get_projects"],"recipe_id":"mcp_session_setup","example":{"steps":[{"id":"s1","action":"auth.get_profile","params":{}},{"id":"s2","action":"projects.get_projects","params":{"limit":50,"include_membership":true}},{"id":"s3","action":"projects.get_users","params":{"project_id":"{{context.project_id}}"}},{"id":"s4","action":"context.resolve","params":{}}],"options":{"stopOnError":true}}},{"name":"Read-only session bootstrap","description":"Profile, stats, limits, quota with continueOnError","tools":["auth.get_profile","projects.get_stats","buffs.get_effective_limits","storage.get_quota"],"recipe_id":"mcp_read_bootstrap","example":{"steps":[{"id":"s1","action":"auth.get_profile","params":{"include_settings":false,"include_subscriptions":false}},{"id":"s2","action":"projects.get_stats","params":{}},{"id":"s3","action":"buffs.get_effective_limits","params":{}},{"id":"s4","action":"storage.get_quota","params":{}},{"id":"s5","action":"hosting.project.status","params":{}}],"options":{"stopOnError":true}}},{"name":"Publish hosted /s/ site","description":"Hosting status → deploy files → edge health. publish already snapshots.","tools":["hosting.project.status","hosting.site.resolve","hosting.deploy_files","hosting.site.edge_health"],"recipe_id":"mcp_hosting_quickstart","example":{"steps":[{"id":"s1","action":"hosting.project.status","params":{}},{"id":"s2","action":"hosting.site.resolve","params":{}},{"id":"s3","action":"hosting.deploy_files","params":{"files":"{{files}}"}},{"id":"s4","action":"hosting.site.edge_health","params":{}}],"options":{"stopOnError":true}}},{"name":"Publish static HTML landing","description":"Quick start bucket → deploy files → edge health","tools":["hosting.site.quick_start","hosting.deploy_files","hosting.site.edge_health"],"recipe_id":"mcp_hosting_static_landing_v1","example":{"steps":[{"id":"s1","action":"hosting.site.quick_start","params":{}},{"id":"s2","action":"hosting.site.resolve","params":{}},{"id":"s3","action":"hosting.deploy_files","params":{"publish":true}},{"id":"s4","action":"hosting.site.edge_health","params":{}}],"options":{"stopOnError":true}}},{"name":"Site growth ladder","description":"Read profile, hosting status, quota, and project config, then pick the next recipe","tools":["auth.get_profile","hosting.project.status","storage.get_quota","projects.get_data"],"recipe_id":"mcp_site_growth_v1","example":{"steps":[{"id":"s1","action":"auth.get_profile","params":{}},{"id":"s2","action":"hosting.project.status","params":{}},{"id":"s3","action":"storage.get_quota","params":{}},{"id":"s4","action":"projects.get_data","params":{"path":"config"}}],"options":{"stopOnError":true}}},{"name":"Notification channels","description":"List bots, read prefs, read in-app inbox. Send with notifications.deliver (email, telegram, max, whatsapp, instagram).","tools":["bots.list","notifications.list_prefs","notifications.inbox_list"],"recipe_id":"mcp_notify_channels_v1","example":{"steps":[{"id":"s1","action":"bots.list","params":{}},{"id":"s2","action":"notifications.list_prefs","params":{}},{"id":"s3","action":"notifications.inbox_list","params":{"project_id":"{{project_id}}"}},{"id":"s4","action":"channels.resolve_routing","params":{"category":"security","requested_channels":["telegram","email","in_app"]}},{"id":"s5","action":"notifications.deliver","params":{"channel":"email","category":"security","title":"Channel setup test","body":"If you see this, reachability works.","correlation_key":"recipe:mcp_notify_channels_v1:test"}}],"options":{"stopOnError":true}}},{"name":"Platform flows","description":"Preflight, sandbox list, integration catalog, then an existing product recipe","tools":["preflight.check","generation.list","integrations.list_recipes"],"recipe_id":"mcp_platform_flows_v1","example":{"steps":[{"id":"s1","action":"preflight.check","params":{}},{"id":"s2","action":"generation.list","params":{"project_id":"{{project_id}}","include_gates":false}},{"id":"s3","action":"integrations.list_recipes","params":{}}],"options":{"stopOnError":true}}},{"name":"Compass playbook match","description":"Canonical PlaybookIds: guidance.list. NL goal → playbook via goal_text (aliases goal/query/intent coerced); match returns catalog_entry + verifyKinds from enriched compass_playbooks_intents_v1.json (51/51). Then guidance.start_path. PTC catalog: guidance.list_capability_tasks.","tools":["guidance.list","guidance.match_playbook","guidance.list_capability_tasks","guidance.start_path"],"recipe_id":"mcp_guidance_match","example":{"steps":[{"id":"s1","action":"guidance.list","params":{}},{"id":"s2","action":"guidance.match_playbook","params":{"goal_text":"{{goal_text}}"}}],"options":{"stopOnError":true}}},{"name":"Deploy React/Vite dist","description":"One hosting.deploy_files. Publish writes the archive. Do not snapshot or promote again. No npm in MCP.","tools":["hosting.project.status","hosting.deploy_files","hosting.site.edge_health"],"recipe_id":"mcp_hosting_react_dist_v1","example":{"steps":[{"id":"s1","action":"hosting.project.status","params":{}},{"id":"s2","action":"hosting.deploy_files","params":{}},{"id":"s3","action":"hosting.site.edge_health","params":{}}],"options":{"stopOnError":true}}},{"name":"Create an App Studio tree","description":"Template phase. compose.apply with blueprint_id and branch. Skip when the tree already exists.","tools":["ai_builder.compose.apply"],"recipe_id":"mcp_app_studio_create_v1","example":{"steps":[{"id":"s1","action":"ai_builder.compose.apply","params":{"blueprint_id":"{{blueprint_id}}","branch":"{{branch}}"}}],"options":{"stopOnError":true}}},{"name":"Edit an App Studio slot","description":"Known string: one source.patch replacements. Whole function: symbols [{name, replace}]. view=skeleton only to learn the name. Pass expected_sha256; a mismatch writes nothing. agent_completion.done starts the build batch.","tools":["ai_builder.source.get","ai_builder.source.patch"],"recipe_id":"mcp_app_studio_edit_v1","example":{"steps":[{"id":"s1","action":"ai_builder.source.patch","params":{"path":"{{path}}","branch":"{{branch}}","replacements":[{"find":"{{find}}","replace":"{{replace}}"}]}}],"options":{"stopOnError":true}}},{"name":"Build an App Studio tree","description":"enqueue then status. Omit build_uuid. On failed: read errors[0].file and line, patch that src file (not package.json), enqueue again. Does not publish.","tools":["ai_builder.build.enqueue","ai_builder.build.status"],"recipe_id":"mcp_app_studio_build_v1","example":{"steps":[{"id":"s1","action":"ai_builder.build.enqueue","params":{"branch":"{{branch}}"}},{"id":"s2","action":"ai_builder.build.status","params":{}}],"options":{"stopOnError":true}}},{"name":"Publish an App Studio build","description":"Only when the user asks to publish. Omit bucket_id when a primary site exists.","tools":["ai_builder.publish"],"recipe_id":"mcp_app_studio_publish_v1","example":{"steps":[{"id":"s1","action":"ai_builder.publish","params":{"branch":"{{branch}}"}}],"options":{"stopOnError":true}}},{"name":"Edit one hosted text file","description":"One hosting.bucket.file.patch search_replace. The write refreshes .gz. Omit file.get. Pass expected_sha256 when the prior read returned one.","tools":["hosting.bucket.file.patch"],"recipe_id":"mcp_hosting_edit_text_file_v1","example":{"steps":[{"id":"s1","action":"hosting.bucket.file.patch","params":{"path":"{{path}}","write_mode":"search_replace","replacements":[{"find":"{{find}}","replace":"{{replace}}"}],"dry_run":false}}],"options":{"stopOnError":true}}},{"name":"Edit published hosted site safely","description":"Existing /s/ site, multi-file: status, snapshot, deploy_files, edge, promote. One text file is mcp_hosting_edit_text_file_v1. Do not generation.fork. Do not quick_start a second site.","tools":["hosting.project.status","hosting.release.snapshot","generation.fork","hosting.deploy_files","hosting.site.edge_health","hosting.release.promote"],"recipe_id":"mcp_hosting_edit_site_safe","example":{"steps":[{"id":"s1","action":"hosting.project.status","params":{}},{"id":"s2","action":"hosting.release.snapshot","params":{}},{"id":"s3","action":"hosting.deploy_files","params":{}},{"id":"s4","action":"hosting.site.edge_health","params":{}},{"id":"s5","action":"hosting.release.promote","params":{}}],"options":{"stopOnError":true}}},{"name":"Integration recipe + CRM contact","description":"Install connector recipe, check health, upsert CRM contact","tools":["integrations.list_recipes","integrations.install_recipe","integrations.connection_health","crm.upsert_contact"],"recipe_id":"mcp_integrations_checkout_crm","example":{"steps":[{"id":"s1","action":"integrations.list_recipes","params":{}},{"id":"s2","action":"integrations.install_recipe","params":{"recipe_id":""}},{"id":"s3","action":"integrations.connection_health","params":{}},{"id":"s4","action":"crm.upsert_contact","params":{}}],"options":{"stopOnError":true}}},{"name":"Agents Fleet approval queue","description":"List agents and pending approvals. Enqueue, poll, and promote are later recipes.","tools":["agents.list","agents.list_pending_approvals"],"recipe_id":"mcp_agents_run_approve","example":{"steps":[{"id":"s1","action":"agents.list","params":{}},{"id":"s2","action":"agents.list_pending_approvals","params":{}}],"options":{"stopOnError":true}}},{"name":"Knowledge KB ingest","description":"Config → kb.ingest → health (playground in separate batch)","tools":["knowledge.config.get","knowledge.kb.ingest","knowledge.health"],"recipe_id":"mcp_knowledge_ingest","example":{"steps":[{"id":"s1","action":"knowledge.config.get","params":{}},{"id":"s2","action":"knowledge.kb.ingest","params":{"collection_id":"content_registry","documents":[{"content":"{{document_text}}","metadata":{"title":"{{document_title}}"}}]}},{"id":"s3","action":"knowledge.health","params":{}},{"id":"s4","action":"knowledge.config.get","params":{}}],"options":{"stopOnError":true}}},{"name":"Knowledge mentor playground","description":"One heavy playground turn (mentor simulate with RAG trace)","tools":["knowledge.playground"],"recipe_id":"mcp_knowledge_playground","example":{"steps":[{"id":"s1","action":"knowledge.playground","params":{"text":"{{user_question}}"}}],"options":{"stopOnError":true}}},{"name":"Knowledge answer tune","description":"prompt.get → prompt.patch → playground → diff → gates → promote","tools":["knowledge.prompt.get","knowledge.prompt.patch","knowledge.playground","generation.diff_vs_prod","generation.gates","generation.promote"],"recipe_id":"mcp_knowledge_answer_tune","example":{"steps":[{"id":"s1","action":"generation.supply_status","params":{}},{"id":"s2","action":"generation.settings.get","params":{}},{"id":"s3","action":"knowledge.prompt.get","params":{}},{"id":"s4","action":"knowledge.prompt.patch","params":{"write_mode":"append","plan_instructions":"{{bullet_or_section}}"}},{"id":"s5","action":"knowledge.playground","params":{"text":"{{smoke_query}}"}},{"id":"s6","action":"generation.diff_vs_prod","params":{"env_uuid":{"from":"s4.result.generation_meta.env_uuid"}}},{"id":"s7","action":"generation.gates","params":{"env_uuid":{"from":"s4.result.generation_meta.env_uuid"}}},{"id":"s8","action":"generation.checkpoint","params":{"env_uuid":{"from":"s4.result.generation_meta.env_uuid"}}},{"id":"s9","action":"generation.promote","params":{"env_uuid":{"from":"s4.result.generation_meta.env_uuid"}}}],"options":{"stopOnError":true}}},{"name":"Knowledge acceptance → promote","description":"acceptance.run → diff → gates → promote","tools":["knowledge.acceptance.run","generation.diff_vs_prod","generation.gates","generation.promote"],"recipe_id":"mcp_knowledge_acceptance_promote","example":{"steps":[{"id":"s1","action":"generation.supply_status","params":{}},{"id":"s2","action":"generation.settings.get","params":{}},{"id":"s3","action":"knowledge.acceptance.run","params":{"group":"{{acceptance_group}}","eval_mode":"retrieval"}},{"id":"s4","action":"generation.diff_vs_prod","params":{"env_uuid":"{{env_uuid}}"}},{"id":"s5","action":"generation.diff_vs_prod","params":{"env_uuid":{"from":"s3.result.generation_meta.env_uuid"}}},{"id":"s6","action":"generation.gates","params":{"env_uuid":{"from":"s3.result.generation_meta.env_uuid"}}},{"id":"s7","action":"generation.checkpoint","params":{"env_uuid":{"from":"s3.result.generation_meta.env_uuid"}}},{"id":"s8","action":"generation.promote","params":{"env_uuid":{"from":"s3.result.generation_meta.env_uuid"}}}],"options":{"stopOnError":true}}},{"name":"CRM contact + deal","description":"List contacts, upsert lead, create deal, move stage","tools":["crm.list_contacts","crm.upsert_contact","crm.create_deal","crm.move_deal_stage"],"recipe_id":"mcp_crm_contact_deal","example":{"steps":[{"id":"s1","action":"crm.list_contacts","params":{}},{"id":"s2","action":"crm.upsert_contact","params":{"contact":{"display_name":"{{display_name}}"}}},{"id":"s3","action":"crm.create_deal","params":{"deal":{"title":"{{deal_title}}"}}},{"id":"s4","action":"crm.list_board","params":{}},{"id":"s5","action":"crm.move_deal_stage","params":{"deal_id":"{{deal_id}}","stage_id":"{{stage_id}}"}},{"id":"s6","action":"crm.get_contact_360","params":{}},{"id":"s7","action":"crm.get_contact_360","params":{}}],"options":{"stopOnError":true}}},{"name":"Hosted vertical workspace bootstrap","description":"Bootstrap pipeline/persona, checklist, CRM verify, demo plan","tools":["vertical_workspace.bootstrap","checklist.get","crm.list_contacts","vertical_demo.seed_plan","vertical_demo.repair_due_dates"],"recipe_id":"mcp_hosted_vertical_bootstrap","example":{"steps":[{"id":"s1","action":"vertical_workspace.bootstrap","params":{"preset":"freelancer_ops"}},{"id":"s2","action":"checklist.get","params":{}},{"id":"s3","action":"crm.list_contacts","params":{"per_page":10}},{"id":"s4","action":"vertical_demo.seed_plan","params":{}}],"options":{"stopOnError":true}}},{"name":"Key2Unity auth portal supply","description":"Bucket resolve, persona leaves, bot identity, generation promote — not vertical_workspace.bootstrap","tools":["hosting.site.resolve","projects.patch_data","bots.update","generation.diff_vs_prod","generation.promote"],"recipe_id":"mcp_key2unity_auth_portal","example":{"steps":[{"id":"s1","action":"generation.settings.get","params":{}},{"id":"s2","action":"hosting.site.resolve","params":{"bucket_name":"key2unity"}},{"id":"s3","action":"projects.patch_data","params":{"path":"config.vertical","value":{},"write_mode":"merge","env_uuid":""}},{"id":"s4","action":"generation.diff_vs_prod","params":{"env_uuid":""}},{"id":"s5","action":"generation.gates","params":{"env_uuid":{"from":"s4.params.env_uuid"}}},{"id":"s6","action":"generation.promote","params":{"env_uuid":{"from":"s4.params.env_uuid"},"require_gates_passed":false,"strategy":"immediate"}},{"id":"s7","action":"bots.update","params":{"bot_id":"700d602d-d54a-4374-b093-283f4d2e3194","identity":{"enabled":true,"auth_modes":["web_link","email"],"activate_site_url":"https://agentstack.tech/s/1444/key2unity/","activate_route":"#/activate"}}},{"id":"s8","action":"bots.get","params":{"bot_id":"700d602d-d54a-4374-b093-283f4d2e3194"}}],"options":{"stopOnError":true}}},{"name":"Support staff inbox","description":"Eligibility → inbox queue → thread history","tools":["social.support.eligibility","social.support.inbox","social.support.history"],"recipe_id":"mcp_support_inbox","example":{"steps":[{"id":"s1","action":"social.support.eligibility","params":{}},{"id":"s2","action":"social.support.inbox","params":{}},{"id":"s3","action":"social.support.history","params":{}}],"options":{"stopOnError":true}}},{"name":"Bots list + simulate","description":"Fleet list then one heavy simulate turn","tools":["bots.list","bots.simulate"],"recipe_id":"mcp_bots_simulate","example":{"steps":[{"id":"s1","action":"bots.list","params":{}},{"id":"s2","action":"bots.get","params":{"bot_id":{"from":"s1.result.bots[0].id"}}},{"id":"s3","action":"bots.simulate","params":{"bot_id":{"from":"s1.result.bots[0].id"},"message":"hello"}}],"options":{"stopOnError":true}}},{"name":"Generation diff vs prod","description":"List generations, diff sandbox vs prod, run gates","tools":["generation.list","generation.diff_vs_prod","generation.gates"],"recipe_id":"mcp_generation_diff","example":{"steps":[{"id":"s1","action":"generation.list","params":{}},{"id":"s2","action":"generation.diff_vs_prod","params":{"env_uuid":""}},{"id":"s3","action":"generation.gates","params":{"env_uuid":{"from":"s2.params.env_uuid"}}}],"options":{"stopOnError":true}}},{"name":"Project orchestrator operator","description":"Provision orchestrator, run dev_operator task, diff, gates, promote","tools":["projects.orchestrator.get","agents.orchestrate","generation.diff_vs_prod","generation.gates"],"recipe_id":"mcp_project_operator_session","example":{"steps":[{"id":"s1","action":"discovery.list","params":{}},{"id":"s2","action":"projects.orchestrator.get","params":{}}],"options":{"stopOnError":true}}},{"name":"Orchestrator memory bootstrap","description":"Context bundle + memory search for orchestrator threads","tools":["context.get","rag.memory_search"],"recipe_id":"mcp_orchestrator_memory_bootstrap","example":{"steps":[{"id":"s1","action":"context.get","params":{"task":"bootstrap","sources":["rag","memory"],"token_budget":3000}},{"id":"s2","action":"rag.memory_search","params":{"query":"recent conversation","limit":8}}],"options":{"stopOnError":true}}},{"name":"Agent knowledge + episodic memory","description":"RAG collection, ingest docs, seed episodic memory, verify search","tools":["rag.collection_create","rag.document_add","rag.memory_add","rag.memory_search"],"recipe_id":"mcp_agent_knowledge_memory_setup","example":{"steps":[{"id":"s1","action":"rag.collection_create","params":{"name":"{{collection_name}}","description":"{{collection_description}}"}},{"id":"s2","action":"rag.document_add","params":{"collection_id":"{{rag_collection_id}}","content":"{{document_text}}","metadata":{"title":"{{document_title}}"}}},{"id":"s3","action":"rag.memory_add","params":{"collection_id":"{{rag_collection_id}}","content":"{{memory_snippet}}","metadata":{"source":"agent_bootstrap"}}},{"id":"s5","action":"rag.memory_search","params":{"query":"{{memory_query}}","limit":5}}],"options":{"stopOnError":true}}},{"name":"FAQ orchestrator bootstrap","description":"Patch FAQ persona and smoke read-only orchestrator run","tools":["projects.orchestrator.patch","agents.orchestrate"],"recipe_id":"mcp_project_faq_bootstrap","example":{"steps":[{"id":"s1","action":"projects.orchestrator.get","params":{}},{"id":"s2","action":"projects.orchestrator.patch","params":{"patch":{"channel_persona":{"bot":"faq","messenger":"support"}}}},{"id":"s3","action":"knowledge.playground","params":{"text":"What can you help with?","action":"capabilities"}}],"options":{"stopOnError":true}}},{"name":"Grant OS pipeline ops","description":"Hub snapshot, opportunity upsert, packet sync, compose, bundle","tools":["grants.crm.hub_snapshot","grants.opportunity.upsert","grants.crm.sync","grants.compose.checklist","grants.bundle.download"],"recipe_id":"mcp_grants_os_crm_ops","example":{"steps":[{"id":"s1","action":"grants.crm.hub_snapshot","params":{}},{"id":"s2","action":"grants.opportunity.upsert","params":{"program_id":"","patch":{"title":"","kind":"crypto_chain","apply_url":""},"seed_crm":true}},{"id":"s3","action":"grants.crm.sync","params":{"program_id":{"from":"s2.params.program_id"}}},{"id":"s4","action":"grants.compose.checklist","params":{"program_id":{"from":"s2.params.program_id"}}},{"id":"s5","action":"grants.bundle.download","params":{"program_id":{"from":"s2.params.program_id"}}}],"options":{"stopOnError":true}}},{"name":"Studio diagnostic SoW","description":"Render kickoff SoW from catalog + optional CRM persist","tools":["services.diagnostic_sow_draft"],"recipe_id":"mcp_studio_diagnostic_sow","example":{"steps":[{"id":"s1","action":"services.diagnostic_sow_draft","params":{"persist":true}},{"id":"s2","action":"crm.log_activity","params":{"kind":"note"}}],"options":{"stopOnError":true}}},{"name":"Studio phase-1 knowledge mentor","description":"Delivery slot, hosting, RAG, bot, promote","tools":["services.apply_delivery_slot","hosting.site.quick_start","rag.collection_create","bots.create","generation.promote"],"recipe_id":"mcp_studio_phase1_knowledge_mentor","example":{"steps":[{"id":"s1","action":"services.apply_delivery_slot","params":{"head_project_id":"{{project_id}}","sku":"{{sku}}"}},{"id":"s2","action":"hosting.site.quick_start","params":{}},{"id":"s3","action":"rag.collection_create","params":{"name":"kb"}},{"id":"s4","action":"bots.create","params":{"name":"mentor"}},{"id":"s5","action":"knowledge.policy_templates.status","params":{}},{"id":"s6","action":"energy.get_balance","params":{}},{"id":"s7","action":"generation.promote","params":{"require_gates_passed":true}}],"options":{"stopOnError":true}}},{"name":"Webhook + scheduler iPaaS","description":"Inbound webhook recipe + scheduled task","tools":["integrations.list_recipes","integrations.install_recipe","scheduler.create_task"],"recipe_id":"mcp_integrations_webhook_scheduler","example":{"steps":[{"id":"s1","action":"integrations.list_recipes","params":{}},{"id":"s2","action":"integrations.install_recipe","params":{"recipe_id":"recipe_generic_inbound"}},{"id":"s3","action":"scheduler.create_task","params":{}}],"options":{"stopOnError":true}}},{"name":"CRM lead + notify","description":"Lead capture recipe + staff notification","tools":["integrations.install_recipe","integrations.connection_health","notifications.send_push"],"recipe_id":"mcp_integrations_crm_lead_notify","example":{"steps":[{"id":"s1","action":"integrations.install_recipe","params":{"recipe_id":"recipe_crm_lead_capture"}},{"id":"s2","action":"integrations.connection_health","params":{}},{"id":"s3","action":"notifications.send_push","params":{"user_id":{"from":"context.user_id"},"title":"New CRM lead","body":"Lead captured via integration recipe.","tag":"crm:lead"}}],"options":{"stopOnError":true}}},{"name":"Studio phase-1 data migration","description":"Migrator cutover: discovery, tenant, DNA leaf, gates, promote","tools":["services.apply_delivery_slot","discovery.list","auth.get_profile","projects.create_project","projects.patch_data","storage.get_quota","logic.create","scheduler.create_task","generation.diff_vs_prod","generation.gates","generation.promote"],"recipe_id":"mcp_studio_phase1_data_migration","example":{"steps":[{"id":"s1","action":"services.apply_delivery_slot","params":{"head_project_id":"{{project_id}}","sku":"{{sku}}"}},{"id":"s2","action":"discovery.list","params":{}},{"id":"s3","action":"auth.get_profile","params":{}},{"id":"s4","action":"projects.create_project","params":{"name":"Migration target"}},{"id":"s5","action":"projects.patch_data","params":{"path":"migration.entity_map","value":{"status":"draft"},"write_mode":"merge"}},{"id":"s6","action":"storage.get_quota","params":{}},{"id":"s7","action":"logic.create","params":{}},{"id":"s8","action":"scheduler.create_task","params":{}},{"id":"s9","action":"generation.diff_vs_prod","params":{}},{"id":"s10","action":"generation.gates","params":{}},{"id":"s11","action":"generation.promote","params":{"require_gates_passed":true}}],"options":{"stopOnError":true}}},{"name":"Agents fleet orientation (binding + diagnostics)","description":"Fleet diagnostics, binding reconcile when stale, then template catalog.","tools":["agents.fleet_diagnostics","agents.reconcile_binding","agents.templates_list","agents.list"],"recipe_id":"mcp_agents_fleet_orientation_v1","example":{"steps":[{"id":"s1","action":"agents.fleet_diagnostics","params":{}},{"id":"s2","action":"agents.reconcile_binding","params":{"repair":true}},{"id":"s3","action":"agents.templates_list","params":{}},{"id":"s4","action":"agents.list","params":{}}],"options":{"stopOnError":true}}},{"name":"Agents fleet orientation","description":"Read templates, fleet, health, and automation ownership before any write.","tools":["agents.templates_list","agents.list","agents.health","agents.automation_map"],"recipe_id":"mcp_agents_fleet_orient","example":{"steps":[{"id":"s1","action":"agents.templates_list","params":{}},{"id":"s2","action":"agents.list","params":{}},{"id":"s3","action":"agents.health","params":{}},{"id":"s4","action":"agents.automation_map","params":{}}],"options":{"stopOnError":true}}},{"name":"Create agent from template","description":"Preview a catalog template, then create. Copy uuid into the next recipe.","tools":["agents.template_preview","agents.create_from_template"],"recipe_id":"mcp_agents_create_from_template","example":{"steps":[{"id":"s1","action":"agents.template_preview","params":{"template_id":"{{template_id}}","name":"{{name}}"}},{"id":"s2","action":"agents.create_from_template","params":{"template_id":"{{template_id}}","name":"{{name}}","owner":"project"}}],"options":{"stopOnError":true}}},{"name":"Inspect one agent","description":"Spec, policy preview, and automation map for one agent.","tools":["agents.get","agents.policy_preview","agents.automation_map"],"recipe_id":"mcp_agents_inspect","example":{"steps":[{"id":"s1","action":"agents.get","params":{"agent_id":"{{agent_id}}"}},{"id":"s2","action":"agents.policy_preview","params":{"capabilities":"{{capabilities}}"}},{"id":"s3","action":"agents.automation_map","params":{}}],"options":{"stopOnError":true}}},{"name":"Merge one agent section","description":"Deep-merge one AgentSpec section via update_agent_spec. Lists replace; objects merge.","tools":["agents.update"],"recipe_id":"mcp_agents_patch_section","example":{"steps":[{"id":"s1","action":"agents.update","params":{"agent_id":"{{agent_id}}","section":"{{section}}","section_value":"{{section_value}}","write_mode":"merge"}}],"options":{"stopOnError":true}}},{"name":"Mark agent ready","description":"Set lifecycle state to ready so triggers can fire. Does not set live.","tools":["agents.update"],"recipe_id":"mcp_agents_set_ready","example":{"steps":[{"id":"s1","action":"agents.update","params":{"agent_id":"{{agent_id}}","section":"state","section_value":"ready","write_mode":"merge"}}],"options":{"stopOnError":true}}},{"name":"Bind RAG collections to an agent","description":"Confirm a collection, then merge rag_settings.collection_ids. Does not create the collection.","tools":["rag.collection_get","agents.update"],"recipe_id":"mcp_agents_bind_rag","example":{"steps":[{"id":"s1","action":"rag.collection_get","params":{"collection_id":"{{collection_id}}"}},{"id":"s2","action":"agents.update","params":{"agent_id":"{{agent_id}}","section":"rag_settings","section_value":{"enabled":true,"collection_ids":["{{collection_id}}"]},"write_mode":"merge"}}],"options":{"stopOnError":true}}},{"name":"Schedule an agent","description":"Merge scheduler.tick plus a preset. Do not add chat triggers if support or a bot already owns the agent.","tools":["agents.update"],"recipe_id":"mcp_agents_schedule","example":{"steps":[{"id":"s1","action":"agents.update","params":{"agent_id":"{{agent_id}}","section":"bindings","section_value":{"triggers":["scheduler.tick","manual"],"schedule_preset":"{{schedule_preset}}"},"write_mode":"merge"}}],"options":{"stopOnError":true}}},{"name":"Import agent from asset","description":"Load an asset, then fulfill it. The asset object is passed as recipe_params.asset from assets.get.","tools":["assets.get"],"recipe_id":"mcp_agents_import_asset","example":{"steps":[{"id":"s1","action":"assets.get","params":{"asset_id":"{{asset_id}}"}}],"options":{"stopOnError":true}}},{"name":"Fulfill agent asset","description":"Create an agent from a commerce asset object returned by assets.get.","tools":["agents.import_from_asset"],"recipe_id":"mcp_agents_import_apply","example":{"steps":[{"id":"s1","action":"agents.import_from_asset","params":{"asset":"{{asset}}"}}],"options":{"stopOnError":true}}},{"name":"Fork an agent generation","description":"DNA child generation of one agent. This is not generation.fork.","tools":["agents.fork"],"recipe_id":"mcp_agents_fork","example":{"steps":[{"id":"s1","action":"agents.fork","params":{"agent_id":"{{agent_id}}"}}],"options":{"stopOnError":true}}},{"name":"Enqueue an agent run","description":"Queue one run with wait false. Poll is a separate recipe.","tools":["agents.run"],"recipe_id":"mcp_agents_run_enqueue","example":{"steps":[{"id":"s1","action":"agents.run","params":{"agent_id":"{{agent_id}}","input":{"text":"{{message}}"},"idempotency_key":"{{idempotency_key}}","wait":false}}],"options":{"stopOnError":true}}},{"name":"Poll an agent run","description":"Read run status. run_id is the previous run_uuid.","tools":["agents.run_get"],"recipe_id":"mcp_agents_run_poll","example":{"steps":[{"id":"s1","action":"agents.run_get","params":{"agent_id":"{{agent_id}}","run_id":"{{run_id}}"}}],"options":{"stopOnError":true}}},{"name":"Debug an agent run","description":"Status, traces, and recent timeline for one agent.","tools":["agents.run_get","agents.traces","agents.timeline"],"recipe_id":"mcp_agents_debug","example":{"steps":[{"id":"s1","action":"agents.run_get","params":{"agent_id":"{{agent_id}}","run_id":"{{run_id}}"}},{"id":"s2","action":"agents.traces","params":{"agent_id":"{{agent_id}}","run_id":"{{run_id}}"}},{"id":"s3","action":"agents.timeline","params":{"agent_id":"{{agent_id}}","limit":20}}],"options":{"stopOnError":true}}},{"name":"Approve a waiting run","description":"List pending approvals, then approve one run. Not part of create.","tools":["agents.list_pending_approvals","agents.approve_run"],"recipe_id":"mcp_agents_approve_run","example":{"steps":[{"id":"s1","action":"agents.list_pending_approvals","params":{}},{"id":"s2","action":"agents.approve_run","params":{"agent_id":"{{agent_id}}","run_id":"{{run_id}}"}}],"options":{"stopOnError":true}}},{"name":"Stop an agent run","description":"Cancel one queued or running run.","tools":["agents.stop"],"recipe_id":"mcp_agents_stop","example":{"steps":[{"id":"s1","action":"agents.stop","params":{"agent_id":"{{agent_id}}","run_id":"{{run_id}}"}}],"options":{"stopOnError":true}}},{"name":"Kill an agent","description":"Set lifecycle to killed so new runs stop. Not for a single stuck run — use mcp_agents_stop.","tools":["agents.kill"],"recipe_id":"mcp_agents_kill","example":{"steps":[{"id":"s1","action":"agents.kill","params":{"agent_id":"{{agent_id}}"}}],"options":{"stopOnError":true}}},{"name":"Configure project orchestrator","description":"Read and patch project orchestrator config. Does not call agents.orchestrate.","tools":["projects.orchestrator.get","projects.orchestrator.patch"],"recipe_id":"mcp_agents_orchestrator_configure","example":{"steps":[{"id":"s1","action":"projects.orchestrator.get","params":{}},{"id":"s2","action":"projects.orchestrator.patch","params":{"patch":"{{patch}}"}}],"options":{"stopOnError":true}}},{"name":"Run project orchestrator once","description":"One agents.orchestrate call with wait false. Poll the returned run_uuid as run_id.","tools":["agents.orchestrate"],"recipe_id":"mcp_agents_orchestrate_once","example":{"steps":[{"id":"s1","action":"agents.orchestrate","params":{"channel":"{{channel}}","message":"{{message}}","conversation_id":"{{conversation_id}}","bot_uuid":"{{bot_uuid}}","wait":false}}],"options":{"stopOnError":true}}},{"name":"Enqueue a handoff run","description":"Parent run carries handoff_to_agent_id. The child starts only after the parent completes.","tools":["agents.run"],"recipe_id":"mcp_agents_handoff_enqueue","example":{"steps":[{"id":"s1","action":"agents.run","params":{"agent_id":"{{agent_id}}","input":{"text":"{{message}}"},"idempotency_key":"{{idempotency_key}}","wait":false,"handoff_to_agent_id":"{{handoff_to_agent_id}}","handoff_reason":"{{handoff_reason}}"}}],"options":{"stopOnError":true}}},{"name":"Review agent sandbox diff","description":"Diff and gates for an existing sandbox anchor. Not in the same batch as agents.update.","tools":["generation.diff_vs_prod","generation.gates"],"recipe_id":"mcp_agents_generation_review","example":{"steps":[{"id":"s1","action":"generation.diff_vs_prod","params":{"env_uuid":"{{env_uuid}}"}},{"id":"s2","action":"generation.gates","params":{"env_uuid":"{{env_uuid}}"}}],"options":{"stopOnError":true}}},{"name":"Promote an agent version","description":"Agent version gates and agents.promote. Not generation.promote.","tools":["agents.metrics","agents.gates","agents.promote"],"recipe_id":"mcp_agents_version_promote","example":{"steps":[{"id":"s1","action":"agents.metrics","params":{"agent_id":"{{agent_id}}"}},{"id":"s2","action":"agents.gates","params":{"agent_id":"{{agent_id}}"}},{"id":"s3","action":"agents.promote","params":{"agent_id":"{{agent_id}}"}}],"options":{"stopOnError":true}}},{"name":"Bind agent as bot brain","description":"Set bot brain.mode=agent and brain.agent_uuid. Merge keeps other brain fields. No simulate in this batch.","tools":["bots.get","bots.update"],"recipe_id":"mcp_agents_bind_bot_brain","example":{"steps":[{"id":"s1","action":"bots.get","params":{"bot_id":"{{bot_id}}"}},{"id":"s2","action":"bots.update","params":{"bot_id":"{{bot_id}}","brain":{"mode":"agent","agent_uuid":"{{agent_id}}"}}}],"options":{"stopOnError":true}}},{"name":"Bind agent to support config","description":"Set support config ai_agent_uuid and ai_mode, then read binding health. Does not add chat triggers or a bot brain.","tools":["social.support.config.patch","social.support.ai_binding_health"],"recipe_id":"mcp_agents_bind_support","example":{"steps":[{"id":"s1","action":"social.support.config.patch","params":{"patch":{"ai_agent_uuid":"{{agent_id}}","ai_mode":"{{ai_mode}}"}}},{"id":"s2","action":"social.support.ai_binding_health","params":{}}],"options":{"stopOnError":true}}},{"name":"Implementer then browser verifier","description":"Enqueue orchestrator implementer run, poll status, then enqueue verifier template with writes_allowed=false (browser_verification evidence on parent).","tools":["agents.orchestrate","agents.run_get","agents.create","agents.run_get"],"recipe_id":"mcp_agents_implementer_verifier_v1","example":{"steps":[{"id":"s1","action":"agents.orchestrate","params":{"message":"{{message}}","channel":"mcp","wait":false}},{"id":"s2","action":"agents.run_get","params":{"agent_id":"{{agent_id}}","run_id":"{{run_id}}"}},{"id":"s3","action":"agents.create","params":{"template_id":"verifier_browser@v1","template_input":{"verification_url":"{{verification_url}}","parent_run_id":"{{run_uuid}}"}}},{"id":"s4","action":"agents.run_get","params":{"agent_id":"{{agent_id}}","run_id":"{{run_id}}"}}],"options":{"stopOnError":true}}},{"name":"Commerce orientation","description":"Read balance, wallets, and assets before any charge or deposit.","tools":["payments.get_balance","wallets.list","assets.list"],"recipe_id":"mcp_commerce_orient","example":{"steps":[{"id":"s1","action":"payments.get_balance","params":{"project_id":"{{project_id}}"}},{"id":"s2","action":"wallets.list","params":{"project_id":"{{project_id}}"}},{"id":"s3","action":"assets.list","params":{"project_id":"{{project_id}}"}}],"options":{"stopOnError":true}}},{"name":"Open a wallet","description":"Create one wallet. Deposit is the next recipe after you copy wallet_id.","tools":["wallets.create"],"recipe_id":"mcp_commerce_wallet_open","example":{"steps":[{"id":"s1","action":"wallets.create","params":{"project_id":"{{project_id}}","name":"{{name}}","currency":"{{currency}}"}}],"options":{"stopOnError":true}}},{"name":"Deposit to a wallet","description":"Credit a wallet you already listed. Do not invent wallet_id from the same batch.","tools":["wallets.deposit"],"recipe_id":"mcp_commerce_wallet_deposit","example":{"steps":[{"id":"s1","action":"wallets.deposit","params":{"project_id":"{{project_id}}","wallet_id":"{{wallet_id}}","amount":"{{amount}}","currency":"{{currency}}"}}],"options":{"stopOnError":true}}},{"name":"Treasury and wallets","description":"Project treasury portfolio beside personal or commerce wallets.","tools":["finance.project.portfolio","wallets.list"],"recipe_id":"mcp_treasury_read","example":{"steps":[{"id":"s1","action":"finance.project.portfolio","params":{"project_id":"{{project_id}}"}},{"id":"s2","action":"wallets.list","params":{"project_id":"{{project_id}}"}}],"options":{"stopOnError":true}}},{"name":"Logic rules orientation","description":"List rules and processors before creating another rule.","tools":["logic.list","logic.get_processors"],"recipe_id":"mcp_logic_orient","example":{"steps":[{"id":"s1","action":"logic.list","params":{"project_id":"{{project_id}}"}},{"id":"s2","action":"logic.get_processors","params":{"project_id":"{{project_id}}"}}],"options":{"stopOnError":true}}},{"name":"Create a logic rule","description":"Create one rule from recipe_params. Dry-run that id in the next recipe.","tools":["logic.create"],"recipe_id":"mcp_logic_create","example":{"steps":[{"id":"s1","action":"logic.create","params":{"project_id":"{{project_id}}","name":"{{name}}","triggers":"{{triggers}}","space":"{{space}}","enabled":true}}],"options":{"stopOnError":true}}},{"name":"Dry-run a logic rule","description":"Simulate an existing rule. logic.dry_run needs logic_id, not a spec.","tools":["logic.dry_run"],"recipe_id":"mcp_logic_dry_run","example":{"steps":[{"id":"s1","action":"logic.dry_run","params":{"project_id":"{{project_id}}","logic_id":"{{logic_id}}","command_data":"{{command_data}}"}}],"options":{"stopOnError":true}}},{"name":"Scheduled tasks","description":"List cron tasks. Create is a separate recipe.","tools":["scheduler.list_tasks"],"recipe_id":"mcp_scheduler_orient","example":{"steps":[{"id":"s1","action":"scheduler.list_tasks","params":{"project_id":"{{project_id}}"}}],"options":{"stopOnError":true}}},{"name":"Create a scheduled task","description":"One scheduler.create_task. Required shape is name, cron, and command. timezone defaults to UTC. execute_at is a single run; cron without it stays recurring.","tools":["scheduler.create_task"],"recipe_id":"mcp_scheduler_task","example":{"steps":[{"id":"s1","action":"scheduler.create_task","params":{"project_id":"{{project_id}}","name":"{{name}}","cron":"{{cron}}","command":"{{command}}","enabled":true}}],"options":{"stopOnError":true}}},{"name":"Storage quota and files","description":"Quota and the root folder. Upload bytes stay on REST.","tools":["storage.get_quota","storage.list_files"],"recipe_id":"mcp_storage_orient","example":{"steps":[{"id":"s1","action":"storage.get_quota","params":{"project_id":"{{project_id}}","scope":"project"}},{"id":"s2","action":"storage.list_files","params":{"project_id":"{{project_id}}","scope":"project","folder":"_"}}],"options":{"stopOnError":true}}},{"name":"Match a Compass playbook","description":"Map a goal sentence to a playbook id. Start that path in the next recipe.","tools":["guidance.list","guidance.match_playbook"],"recipe_id":"mcp_guidance_match","example":{"steps":[{"id":"s1","action":"guidance.list","params":{}},{"id":"s2","action":"guidance.match_playbook","params":{"goal_text":"{{goal_text}}"}}],"options":{"stopOnError":true}}},{"name":"Start a Compass path","description":"Start a known playbook and read path status.","tools":["guidance.start_path","guidance.path_status"],"recipe_id":"mcp_guidance_start","example":{"steps":[{"id":"s1","action":"guidance.start_path","params":{"project_id":"{{project_id}}","playbook_id":"{{playbook_id}}"}},{"id":"s2","action":"guidance.path_status","params":{"project_id":"{{project_id}}","playbook_id":"{{playbook_id}}"}}],"options":{"stopOnError":true}}},{"name":"Search a knowledge collection","description":"One rag.search. Ingest and playground stay in the knowledge recipes.","tools":["rag.search"],"recipe_id":"mcp_rag_search","example":{"steps":[{"id":"s1","action":"rag.search","params":{"project_id":"{{project_id}}","collection_id":"{{collection_id}}","query":"{{query}}","top_k":5}}],"options":{"stopOnError":true}}},{"name":"List messenger channels","description":"Discover channels. History is the next recipe once you have channel_id.","tools":["social.channels.list"],"recipe_id":"mcp_messenger_channels","example":{"steps":[{"id":"s1","action":"social.channels.list","params":{"home_project_id":"{{project_id}}"}}],"options":{"stopOnError":true}}},{"name":"Read a messenger channel","description":"Read one channel. Posting is social.chat.post in a later batch.","tools":["social.chat.history"],"recipe_id":"mcp_messenger_history","example":{"steps":[{"id":"s1","action":"social.chat.history","params":{"home_project_id":"{{project_id}}","channel_id":"{{channel_id}}"}}],"options":{"stopOnError":true}}},{"name":"Business organism read","description":"Org summary and command snapshot for a head project.","tools":["business.get_org","business.command_snapshot"],"recipe_id":"mcp_business_read","example":{"steps":[{"id":"s1","action":"business.get_org","params":{"project_id":"{{project_id}}"}},{"id":"s2","action":"business.command_snapshot","params":{"project_id":"{{project_id}}"}}],"options":{"stopOnError":true}}},{"name":"Create a business composite","description":"One business.create_composite. Organs are a list you pass in.","tools":["business.create_composite"],"recipe_id":"mcp_business_composite","example":{"steps":[{"id":"s1","action":"business.create_composite","params":{"name":"{{name}}","organs":"{{organs}}"}}],"options":{"stopOnError":true}}},{"name":"Create a scoped API key","description":"Mint one agent PAT. The secret is returned once.","tools":["apikeys.create"],"recipe_id":"mcp_apikey_scoped","example":{"steps":[{"id":"s1","action":"apikeys.create","params":{"project_id":"{{project_id}}","name":"{{name}}","service_caps":"{{service_caps}}"}}],"options":{"stopOnError":true}}},{"name":"Effective buff limits","description":"Read effective limits before creating or applying a buff template.","tools":["buffs.get_effective_limits"],"recipe_id":"mcp_buffs_orient","example":{"steps":[{"id":"s1","action":"buffs.get_effective_limits","params":{"project_id":"{{project_id}}"}}],"options":{"stopOnError":true}}},{"name":"Create a buff template","description":"Create a PENDING buff template. For subscription/SKU entitlements use grant rails (grant_tenant_subscription / grant_subscription / mcp_tenant_subscription_monetization) — not mcp_buffs_apply. mcp_buffs_apply is for non-subscription templates (promo, event, limits).","tools":["buffs.create_buff"],"recipe_id":"mcp_buffs_create","example":{"steps":[{"id":"s1","action":"buffs.create_buff","params":{"project_id":"{{project_id}}","entity_id":"{{entity_id}}","entity_kind":"{{entity_kind}}","name":"{{name}}","type":"{{buff_type}}","category":"{{category}}","duration_days":"{{duration_days}}","effects":"{{effects}}","config":"{{config}}"}}],"options":{"stopOnError":true}}},{"name":"Apply a buff","description":"Activate a PENDING buff on a user or project. buff_id comes from create, not from this batch. Platform tiers: buffs.grant_subscription (PID=1). Tenant manual: buffs.grant_tenant_subscription. Tenant paid checkout: webhook/C24 auto-grant — not this recipe after payments.create.","tools":["buffs.apply_buff"],"recipe_id":"mcp_buffs_apply","example":{"steps":[{"id":"s1","action":"buffs.apply_buff","params":{"project_id":"{{project_id}}","buff_id":"{{buff_id}}","entity_id":"{{entity_id}}","entity_kind":"{{entity_kind}}"}}],"options":{"stopOnError":true}}},{"name":"Apply field-access defaults","description":"Copy missing FAP resources onto a user project. Does not target ecosystem project 1.","tools":["data_access.apply_defaults_template"],"recipe_id":"mcp_fap_defaults","example":{"steps":[{"id":"s1","action":"data_access.apply_defaults_template","params":{"target_project_id":"{{project_id}}"}}],"options":{"stopOnError":true}}},{"name":"Send one notice","description":"Deliver one notice after mcp_notify_channels_v1. The recipient must already be enrolled on a bot channel.","tools":["notifications.deliver"],"recipe_id":"mcp_notify_deliver","example":{"steps":[{"id":"s1","action":"notifications.deliver","params":{"project_id":"{{project_id}}","channels":"{{channels}}","title":"{{title}}","message":"{{message}}"}}],"options":{"stopOnError":true}}},{"name":"Plan a storefront seed","description":"Dry-run a catalog pack. Apply is the next recipe and needs the plan object.","tools":["commerce.storefront.seed_plan"],"recipe_id":"mcp_storefront_plan","example":{"steps":[{"id":"s1","action":"commerce.storefront.seed_plan","params":{"project_id":"{{project_id}}","pack_id":"{{pack_id}}"}}],"options":{"stopOnError":true}}},{"name":"Apply a storefront seed","description":"Write the plan returned by commerce.storefront.seed_plan.","tools":["commerce.storefront.seed_apply"],"recipe_id":"mcp_storefront_apply","example":{"steps":[{"id":"s1","action":"commerce.storefront.seed_apply","params":{"project_id":"{{project_id}}","plan":"{{plan}}","idempotency_key":"{{idempotency_key}}"}}],"options":{"stopOnError":true}}},{"name":"Safety text probe","description":"Evaluate one text. Config patch and promote stay in later batches.","tools":["safety.evaluate"],"recipe_id":"mcp_safety_probe","example":{"steps":[{"id":"s1","action":"safety.evaluate","params":{"project_id":"{{project_id}}","text":"{{text}}"}}],"options":{"stopOnError":true}}},{"name":"List hosted bucket files","description":"List files on the primary site or a named bucket. This is the /s/ tree, not storage.","tools":["hosting.bucket.files.list"],"recipe_id":"mcp_site_file_list","example":{"steps":[{"id":"s1","action":"hosting.bucket.files.list","params":{"project_id":"{{project_id}}","bucket_name":"{{bucket_name}}","prefix":"{{prefix}}"}}],"options":{"stopOnError":true}}},{"name":"Read one hosted text file","description":"Read one UTF-8 bucket file when the bytes are unknown. A known string is mcp_hosting_edit_text_file_v1 and does not need this digest.","tools":["hosting.bucket.file.get"],"recipe_id":"mcp_site_file_read","example":{"steps":[{"id":"s1","action":"hosting.bucket.file.get","params":{"project_id":"{{project_id}}","path":"{{path}}","bucket_name":"{{bucket_name}}"}}],"options":{"stopOnError":true}}},{"name":"Snapshot a hosted bucket","description":"Immutable copy before a text write. The orchestrator allows this on mcp or workspace when competence_tier is dev_operator.","tools":["hosting.release.snapshot"],"recipe_id":"mcp_site_file_snapshot","example":{"steps":[{"id":"s1","action":"hosting.release.snapshot","params":{"project_id":"{{project_id}}","bucket_name":"{{bucket_name}}","label":"{{label}}"}}],"options":{"stopOnError":true}}},{"name":"Search-replace a hosted text file","description":"Prefer mcp_hosting_edit_text_file_v1: one search_replace, no GET and no dry_run. This recipe previews then applies only when expected_sha256 is already in hand.","tools":["hosting.bucket.file.patch","hosting.bucket.file.patch"],"recipe_id":"mcp_site_file_replace","example":{"steps":[{"id":"s1","action":"hosting.bucket.file.patch","params":{"project_id":"{{project_id}}","path":"{{path}}","bucket_name":"{{bucket_name}}","write_mode":"search_replace","replacements":"{{replacements}}","expected_sha256":"{{expected_sha256}}","dry_run":true}},{"id":"s2","action":"hosting.bucket.file.patch","params":{"project_id":"{{project_id}}","path":"{{path}}","bucket_name":"{{bucket_name}}","write_mode":"search_replace","replacements":"{{replacements}}","expected_sha256":"{{expected_sha256}}","dry_run":false}}],"options":{"stopOnError":true}}},{"name":"Replace a hosted text file","description":"Whole-file replace when the new body is already known. A substring edit is mcp_hosting_edit_text_file_v1. agent_completion.done means skip edge_health.","tools":["hosting.bucket.file.patch","hosting.bucket.file.patch"],"recipe_id":"mcp_site_file_write","example":{"steps":[{"id":"s1","action":"hosting.bucket.file.patch","params":{"project_id":"{{project_id}}","path":"{{path}}","bucket_name":"{{bucket_name}}","write_mode":"replace","content":"{{content}}","expected_sha256":"{{expected_sha256}}","allow_shrink":"{{allow_shrink}}","dry_run":true}},{"id":"s2","action":"hosting.bucket.file.patch","params":{"project_id":"{{project_id}}","path":"{{path}}","bucket_name":"{{bucket_name}}","write_mode":"replace","content":"{{content}}","expected_sha256":"{{expected_sha256}}","allow_shrink":"{{allow_shrink}}","dry_run":false}}],"options":{"stopOnError":true}}},{"name":"Check hosted edge","description":"After hosting.deploy_files, until edge_ready. A file.patch result with agent_completion.done does not need this read.","tools":["hosting.site.edge_health"],"recipe_id":"mcp_site_edge","example":{"steps":[{"id":"s1","action":"hosting.site.edge_health","params":{"project_id":"{{project_id}}","bucket_name":"{{bucket_name}}"}}],"options":{"stopOnError":true}}},{"name":"List user or project files","description":"List attachment files for the signed-in user or the project folder. Not the hosted /s/ tree.","tools":["storage.list_files"],"recipe_id":"mcp_storage_scope","example":{"steps":[{"id":"s1","action":"storage.list_files","params":{"project_id":"{{project_id}}","scope":"{{scope}}","folder":"{{folder}}","include_folders":true}}],"options":{"stopOnError":true}}},{"name":"Storage upload contract","description":"Return the REST multipart contract. MCP does not carry file bytes. A user avatar is POST /api/profile/avatar, not this recipe.","tools":["storage.upload"],"recipe_id":"mcp_storage_upload_gate","example":{"steps":[{"id":"s1","action":"storage.upload","params":{"project_id":"{{project_id}}","folder":"{{folder}}","filename":"{{filename}}"}}],"options":{"stopOnError":true}}},{"name":"Delete one stored file","description":"Delete one registry file. file_id comes from a previous list.","tools":["storage.delete_file"],"recipe_id":"mcp_storage_delete","example":{"steps":[{"id":"s1","action":"storage.delete_file","params":{"project_id":"{{project_id}}","scope":"{{scope}}","folder_key":"{{folder_key}}","file_id":"{{file_id}}"}}],"options":{"stopOnError":true}}},{"name":"FAQ reply desk","description":"Bot and messenger answer from docs. Rebinds every bot brain. Does not bind support.","tools":["projects.orchestrator.patch"],"recipe_id":"mcp_orch_faq_desk","example":{"steps":[{"id":"s1","action":"projects.orchestrator.patch","params":{"project_id":"{{project_id}}","patch":"{{patch}}"}}],"options":{"stopOnError":true}}},{"name":"Support reply desk","description":"Messenger support replies. Does not rebind bot brains.","tools":["projects.orchestrator.patch"],"recipe_id":"mcp_orch_support_desk","example":{"steps":[{"id":"s1","action":"projects.orchestrator.patch","params":{"project_id":"{{project_id}}","patch":"{{patch}}"}}],"options":{"stopOnError":true}}},{"name":"API reply desk","description":"External system calls the orchestrator run REST path with channel api. Key is mcp_apikey_scoped.","tools":["projects.orchestrator.patch"],"recipe_id":"mcp_orch_api_desk","example":{"steps":[{"id":"s1","action":"projects.orchestrator.patch","params":{"project_id":"{{project_id}}","patch":"{{patch}}"}}],"options":{"stopOnError":true}}},{"name":"Dev operator desk","description":"mcp and workspace may snapshot and patch site text. Reply sync flags stay as they are.","tools":["projects.orchestrator.patch"],"recipe_id":"mcp_orch_dev_desk","example":{"steps":[{"id":"s1","action":"projects.orchestrator.patch","params":{"project_id":"{{project_id}}","patch":"{{patch}}"}}],"options":{"stopOnError":true}}},{"name":"Docs memory desk","description":"Point orchestrator memory at collection ids copied from a prior search or ingest.","tools":["projects.orchestrator.patch"],"recipe_id":"mcp_orch_docs_desk","example":{"steps":[{"id":"s1","action":"projects.orchestrator.patch","params":{"project_id":"{{project_id}}","patch":{"memory_profile":{"enabled":true,"thread_policy":"per_user_per_channel","token_budget":2000,"sources":["rag","memory"],"auto_record_turns":true,"collection_ids":"{{collection_ids}}","summarize_after_turns":40}}}}],"options":{"stopOnError":true}}},{"name":"Elevate operator capabilities","description":"Replace policy.capabilities with the elevated list, including file delete and role change.","tools":["agents.update"],"recipe_id":"mcp_orch_operator_caps","example":{"steps":[{"id":"s1","action":"agents.update","params":{"project_id":"{{project_id}}","agent_id":"{{agent_id}}","section":"policy","section_value":{"capabilities":"{{capabilities}}"},"write_mode":"merge"}}],"options":{"stopOnError":true}}},{"name":"List project users","description":"Read project members. Role change is the next recipe.","tools":["projects.get_users"],"recipe_id":"mcp_users_list","example":{"steps":[{"id":"s1","action":"projects.get_users","params":{"project_id":"{{project_id}}"}}],"options":{"stopOnError":true}}},{"name":"Change a project role","description":"Set a member role. user_id comes from mcp_users_list. Owner cannot be assigned here.","tools":["projects.update_user_role"],"recipe_id":"mcp_users_role","example":{"steps":[{"id":"s1","action":"projects.update_user_role","params":{"project_id":"{{project_id}}","user_id":"{{user_id}}","role":"{{role}}"}}],"options":{"stopOnError":true}}}],"tool_combinations":[{"task":"Finding and updating entities","tools":["commands.execute","commands.execute"],"description":"Use commands.execute with get operation, then update operation"},{"task":"Creating logic rules","tools":["logic.get_processors","logic.get_commands","logic.create"],"description":"First discover available processors and commands, then create rule"},{"task":"Project management","tools":["projects.get_projects","projects.get_project","projects.update_project"],"description":"List projects, get details, then update settings"},{"task":"User management","tools":["projects.get_users","projects.add_user","projects.update_user_role"],"description":"List users, add new user, update user role"},{"task":"Payment processing","tools":["payments.create","payments.get","payments.list_transactions"],"description":"Create payment, check status, list transaction history"},{"task":"Auto-trial on user signup","tools":["logic.create","buffs.apply_temporary_effect"],"description":"Create logic rule with trigger 'user.created' that applies temporary trial buff. Perfect for SaaS platforms.","synergy":"Logic Engine (automation) + Buffs (temporary effects)"},{"task":"Subscription with auto-renewal","tools":["buffs.create_buff","commerce.sell.activate","payments.create","buffs.grant_tenant_subscription","scheduler.create_task"],"description":"Tenant SaaS: sell.activate + payment webhook auto-grant; manual/support uses grant_tenant_subscription; schedule renewal.","synergy":"Commerce sell + Buffs grant rails + Payments + Scheduler"},{"task":"Promo campaign for all users","tools":["buffs.create_buff","buffs.apply_buff"],"description":"Create promo buff for project (affects all users), apply it. Use logic.create for notification side-effects if needed.","synergy":"Buffs (promo effects) on project = global event for everyone"},{"task":"Setup project economy (currencies and wallets)","tools":["projects.create_project_anonymous","assets.create","wallets.create","wallets.deposit"],"description":"Create project, add currencies as assets (type=currency), create wallet, deposit. Full economy setup.","synergy":"Projects + Assets (currencies) + Wallets (list/create/deposit/transfer)"},{"task":"Monitor and auto-scale limits","tools":["logic.create","analytics.project_snapshot","buffs.apply_temporary_effect"],"description":"Create logic rule that monitors usage, automatically increases limits via buffs when threshold reached. PARADIGM: Buffs as auto-scaler!","synergy":"Logic Engine (monitoring) + Analytics (usage) + Buffs (auto-scaling)","paradigm_note":"Buffs = temporary limit increase that auto-reverts"},{"task":"In-app purchase workflow","tools":["payments.create","buffs.apply_persistent_effect"],"description":"Process payment for in-app purchase, then apply persistent effect (currency, items, upgrades). Perfect for games. PARADIGM: Buffs as permanent reward system!","synergy":"Payments (monetization) + Buffs (permanent effects)","paradigm_note":"Buffs with persistent=True = permanent item grants"},{"task":"Global event for all players","tools":["buffs.apply_temporary_effect"],"description":"Apply buff to PROJECT (entity_kind='project') to affect ALL users instantly. PARADIGM: Project buffs = global events!","synergy":"Buffs on project = instant global effects for everyone","paradigm_note":"entity_kind='project' → affects all users, auto-expires"},{"task":"NPC system with AI behavior","tools":["commands.execute","buffs.apply_temporary_effect","logic.create"],"description":"Store NPCs as user entities (email: 'npc@game', data: {ai, inventory}). PARADIGM: Users = universal containers!","synergy":"Users as NPCs + Buffs for status effects + Logic for AI","paradigm_note":"Users can be NPCs, bots, sessions - anything with data!"}],"actions_url":"/mcp/actions"}