PageSourceSearch

https://cruvero.ai/assets/js/3d002c3f.ab7a4fb8.js

js cruvero.ai collected 2026-10-05 15:20:38 UTC 16,548 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunksite=globalThis.webpackChunksite||[]).push([[136],{89174(e,n,s){s.r(n),s.d(n,{assets:()=>t,contentTitle:()=>l,default:()=>a,frontMatter:()=>i,metadata:()=>r,toc:()=>o});const r=JSON.parse('{"id":"mcp-operations","title":"MCP Operations","description":"This guide covers operational MCP workflows around discovery, heartbeat, code-exec tooling, and gateway fleet wiring.","source":"@site/docs/develop/mcp-operations.md","sourceDirName":".","slug":"/mcp-operations","permalink":"/develop/mcp-operations","draft":false,"unlisted":false,"editUrl":"https://github.com/roygabriel/cruvero/tree/dev/docs/develop/mcp-operations.md","tags":[],"version":"current","frontMatter":{"title":"MCP Operations","description":"This guide covers operational MCP workflows around discovery, heartbeat, code-exec tooling, and gateway fleet wiring.","source_path":"docs/manual/mcp-operations.md","generated":true},"sidebar":"developSidebar","previous":{"title":"MCP Integration","permalink":"/develop/mcp-integration"},"next":{"title":"Prompt Library","permalink":"/develop/prompt-library"}}');var c=s(74848),d=s(28453);const i={title:"MCP Operations",description:"This guide covers operational MCP workflows around discovery, heartbeat, code-exec tooling, and gateway fleet wiring.",source_path:"docs/manual/mcp-operations.md",generated:!0},l="MCP Operations Guide",t={},o=[{value:"Operational Topology",id:"operational-topology",level:2},{value:"<code>mcp-announce</code> CLI",id:"mcp-announce-cli",level:2},{value:"Flags",id:"flags",level:3},{value:"Examples",id:"examples",level:3},{value:"<code>mcp-code-exec</code> service",id:"mcp-code-exec-service",level:2},{value:"Environment variables",id:"environment-variables",level:3},{value:"Example",id:"example",level:3},{value:"Discovery and Lifecycle Subjects",id:"discovery-and-lifecycle-subjects",level:2},{value:"MCP Gateway Subjects",id:"mcp-gateway-subjects",level:2},{value:"Transport Modes",id:"transport-modes",level:2},{value:"MCP transport selection",id:"mcp-transport-selection",level:3},{value:"Monitoring and Troubleshooting",id:"monitoring-and-troubleshooting",level:2},{value:"Operational Config Checklist",id:"operational-config-checklist",level:2},{value:"Related Docs",id:"related-docs",level:2}];function h(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsxs)(n.blockquote,{children:["\n",(0,c.jsxs)(n.p,{children:["Source: ",(0,c.jsx)(n.a,{href:"https://github.com/cruvero/cruvero-platform/blob/main/docs/manual/mcp-operations.md",children:(0,c.jsx)(n.code,{children:"docs/manual/mcp-operations.md"})})]}),"\n",(0,c.jsxs)(n.p,{children:["This page is generated by ",(0,c.jsx)(n.code,{children:"site/scripts/sync-manual-docs.mjs"}),"."]}),"\n"]}),"\n",(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"mcp-operations-guide",children:"MCP Operations Guide"})}),"\n",(0,c.jsx)(n.p,{children:"This guide covers operational MCP workflows around discovery, heartbeat, code-exec tooling, and gateway fleet wiring."}),"\n",(0,c.jsxs)(n.p,{children:["Source: ",(0,c.jsx)(n.code,{children:"cmd/mcp-announce/*"}),", ",(0,c.jsx)(n.code,{children:"cmd/mcp-code-exec/*"}),", ",(0,c.jsx)(n.code,{children:"internal/tools/mcp_announce.go"}),", ",(0,c.jsx)(n.code,{children:"internal/tools/mcp_bridge.go"}),", ",(0,c.jsx)(n.code,{children:"internal/mcpgw/*"})]}),"\n",(0,c.jsx)(n.h2,{id:"operational-topology",children:"Operational Topology"}),"\n",(0,c.jsx)(n.p,{children:"Cruvero MCP operations typically involve three paths:"}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["Server advertises itself (",(0,c.jsx)(n.code,{children:"mcp-announce"}),") over NATS."]}),"\n",(0,c.jsxs)(n.li,{children:["Cruvero MCP bridge ingests discovery events and exposes tools as ",(0,c.jsx)(n.code,{children:"mcp.<server>.<tool>"}),"."]}),"\n",(0,c.jsxs)(n.li,{children:["Optional gateway integration publishes/consumes ",(0,c.jsx)(n.code,{children:"mcpgw.<gateway>.{events|config}.*"})," subjects."]}),"\n"]}),"\n",(0,c.jsxs)(n.h2,{id:"mcp-announce-cli",children:[(0,c.jsx)(n.code,{children:"mcp-announce"})," CLI"]}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"cmd/mcp-announce"})," discovers tools from an MCP endpoint and publishes lifecycle events."]}),"\n",(0,c.jsx)(n.h3,{id:"flags",children:"Flags"}),"\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Flag"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"--server"})}),(0,c.jsx)(n.td,{children:"MCP server name (required)"})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"--nats-url"})}),(0,c.jsx)(n.td,{children:"NATS URL for lifecycle events"})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"--transport"})}),(0,c.jsx)(n.td,{children:"`stdio"})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"--endpoint"})}),(0,c.jsxs)(n.td,{children:["Required for ",(0,c.jsx)(n.code,{children:"http"})," and ",(0,c.jsx)(n.code,{children:"sse"})," transports"]})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"--heartbeat"})}),(0,c.jsx)(n.td,{children:"Heartbeat interval (must be > 0)"})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"--prefix"})}),(0,c.jsxs)(n.td,{children:["Subject prefix (default from ",(0,c.jsx)(n.code,{children:"CRUVERO_EVENTS_SUBJECT_PREFIX"}),")"]})]})]})]}),"\n",(0,c.jsxs)(n.p,{children:["For ",(0,c.jsx)(n.code,{children:"stdio"}),", pass command args after ",(0,c.jsx)(n.code,{children:"--"}),"."]}),"\n",(0,c.jsx)(n.h3,{id:"examples",children:"Examples"}),"\n",(0,c.jsx)(n.p,{children:"HTTP transport:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"go run ./cmd/mcp-announce \\\n  --server weather \\\n  --transport http \\\n  --endpoint http://localhost:8089/mcp \\\n  --heartbeat 30s\n"})}),"\n",(0,c.jsx)(n.p,{children:"Stdio transport:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"go run ./cmd/mcp-announce \\\n  --server local-tools \\\n  --transport stdio \\\n  --heartbeat 15s \\\n  -- ./bin/local-mcp-server --mode prod\n"})}),"\n",(0,c.jsxs)(n.h2,{id:"mcp-code-exec-service",children:[(0,c.jsx)(n.code,{children:"mcp-code-exec"})," service"]}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"cmd/mcp-code-exec"})," hosts ",(0,c.jsx)(n.code,{children:"python_exec"})," and ",(0,c.jsx)(n.code,{children:"bash_exec"})," as MCP tools over streamable HTTP."]}),"\n",(0,c.jsx)(n.h3,{id:"environment-variables",children:"Environment variables"}),"\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Variable"}),(0,c.jsx)(n.th,{children:"Default"}),(0,c.jsx)(n.th,{children:"Purpose"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"MCP_CODE_EXEC_PORT"})}),(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"8080"})}),(0,c.jsx)(n.td,{children:"Listener port"})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"MCP_CODE_EXEC_TIMEOUT"})}),(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"30s"})}),(0,c.jsx)(n.td,{children:"Per-call execution timeout"})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"MCP_CODE_EXEC_MAX_OUTPUT"})}),(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"1048576"})}),(0,c.jsx)(n.td,{children:"Max output bytes returned to caller"})]})]})]}),"\n",(0,c.jsx)(n.h3,{id:"example",children:"Example"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"MCP_CODE_EXEC_PORT=8088 MCP_CODE_EXEC_TIMEOUT=20s go run ./cmd/mcp-code-exec\n"})}),"\n",(0,c.jsx)(n.p,{children:"If you require MCP routing for code execution, set:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"CRUVERO_CODE_EXEC_MCP_REQUIRED=true"})}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"In that mode, runtime code-exec tools fail closed when MCP transport is unavailable."}),"\n",(0,c.jsx)(n.h2,{id:"discovery-and-lifecycle-subjects",children:"Discovery and Lifecycle Subjects"}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"mcp-announce"})," publishes to these subjects (with optional custom prefix):"]}),"\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Event"}),(0,c.jsx)(n.th,{children:"Subject"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Announce"}),(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"<prefix>.mcp.announce"})})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Heartbeat"}),(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"<prefix>.mcp.heartbeat"})})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Deregister"}),(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"<prefix>.mcp.deregister"})})]})]})]}),"\n",(0,c.jsx)(n.p,{children:"Payload event type values:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"mcp.announce"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"mcp.heartbeat"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"mcp.deregister"})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"mcp-gateway-subjects",children:"MCP Gateway Subjects"}),"\n",(0,c.jsxs)(n.p,{children:["Gateway integration uses fixed ",(0,c.jsx)(n.code,{children:"mcpgw"})," subjects (not prefixed by ",(0,c.jsx)(n.code,{children:"cruvero"}),"):"]}),"\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Direction"}),(0,c.jsx)(n.th,{children:"Subject Pattern"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Gateway -> Cruvero events"}),(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"mcpgw.<gateway_id>.events.<event_type>"})})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Cruvero -> Gateway config"}),(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"mcpgw.<gateway_id>.config.<scope>"})})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Gateway reconnect request"}),(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"mcpgw.<gateway_id>.config.request"})})]})]})]}),"\n",(0,c.jsx)(n.p,{children:"Common event types handled by subscriber:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"server.registered"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"server.deregistered"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"server.health_changed"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"policy.violated"})}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"Config scopes published by Cruvero:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"policy"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"servers"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"server_settings"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"auth"})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"transport-modes",children:"Transport Modes"}),"\n",(0,c.jsx)(n.h3,{id:"mcp-transport-selection",children:"MCP transport selection"}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"CRUVERO_MCP_TRANSPORT"})," supports:"]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"stdio"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"http"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"gateway"})}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"mcp-announce"})," itself supports discovery over ",(0,c.jsx)(n.code,{children:"stdio|http|sse"}),"; gateway transport is configured in Cruvero runtime MCP settings."]}),"\n",(0,c.jsx)(n.h2,{id:"monitoring-and-troubleshooting",children:"Monitoring and Troubleshooting"}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsx)(n.li,{children:"Check server lifecycle events:"}),"\n"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"go run ./cmd/event-bus subscribe 'cruvero.mcp.>'\n"})}),"\n",(0,c.jsxs)(n.ol,{start:"2",children:["\n",(0,c.jsx)(n.li,{children:"Confirm gateway events are flowing:"}),"\n"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"go run ./cmd/event-bus subscribe 'mcpgw.>
1'\n"})}),"\n",(0,c.jsxs)(n.ol,{start:"3",children:["\n",(0,c.jsx)(n.li,{children:"Validate MCP server visibility in UI (admin route):"}),"\n"]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"/mcp"})}),"\n"]}),"\n",(0,c.jsxs)(n.ol,{start:"4",children:["\n",(0,c.jsx)(n.li,{children:"Validate subject prefix consistency:"}),"\n"]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"CRUVERO_EVENTS_SUBJECT_PREFIX"})}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"--prefix"})," for ",(0,c.jsx)(n.code,{children:"mcp-announce"})]}),"\n"]}),"\n",(0,c.jsxs)(n.ol,{start:"5",children:["\n",(0,c.jsx)(n.li,{children:"Validate NATS connectivity and streams:"}),"\n"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"go run ./cmd/event-bus status\ngo run ./cmd/event-bus streams\n"})}),"\n",(0,c.jsx)(n.h2,{id:"operational-config-checklist",children:"Operational Config Checklist"}),"\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Variable"}),(0,c.jsx)(n.th,{children:"Purpose"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"CRUVERO_EVENTS_BACKEND"})}),(0,c.jsxs)(n.td,{children:["Must be ",(0,c.jsx)(n.code,{children:"nats"})," for event-driven MCP discovery"]})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"CRUVERO_NATS_URL"})}),(0,c.jsx)(n.td,{children:"NATS endpoint"})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"CRUVERO_MCP_DISCOVERY"})}),(0,c.jsx)(n.td,{children:"`static"})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"CRUVERO_MCP_HEARTBEAT_INTERVAL"})}),(0,c.jsx)(n.td,{children:"Heartbeat staleness cadence"})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"CRUVERO_MCP_STALE_THRESHOLD"})}),(0,c.jsx)(n.td,{children:"Server stale threshold"})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"CRUVERO_MCPGW_ENABLED"})}),(0,c.jsx)(n.td,{children:"Enable gateway integration path"})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"CRUVERO_MCPGW_GATEWAY_ID"})}),(0,c.jsx)(n.td,{children:"Gateway subject scope id"})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.code,{children:"CRUVERO_MCPGW_TENANT_ID"})}),(0,c.jsx)(n.td,{children:"Tenant context for server/settings publication"})]})]})]}),"\n",(0,c.jsx)(n.h2,{id:"related-docs",children:"Related Docs"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"/develop/mcp-integration",children:"MCP Integration"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"/develop/event-bus-and-jetstream",children:"Event Bus and NATS JetStream"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"/develop/web-ui",children:"Web UI"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"/api/cli-reference",children:"CLI Reference"})}),"\n"]})]})}function a(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(h,{...e})}):h(e)}},28453(e,n,s){s.d(n,{R:()=>i,x:()=>l});var r=s(96540);const c={},d=r.createContext(c);function i(e){const n=r.useContext(d);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:i(e.components),r.createElement(d.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.