metheus-governance-mcp-cli
v0.2.59
Published
Metheus Governance MCP CLI (setup + stdio proxy)
Readme
metheus-governance-mcp-cli
Metheus Governance MCP helper CLI.
Compatibility note: legacy command alias metheus-governance-mcp is still supported.
metheus-governance-mcp-cli(no args): bootstrap mode- checks auth token
- if token is missing/expired, starts
auth login - checks Codex/Claude/Gemini/Antigravity/Cursor MCP registration
- registers only missing clients
setup: registermetheus-governance-mcpinto Codex/Claude/Gemini/Antigravity/Cursor (if installed)doctor: run end-to-end health checks (auth/registration/gateway/project/ctxpack/tools)proxy: stdio MCP bridge to Metheus HTTPS gatewayauth: save/check/clear local Metheus token used by proxy
Install
npm install -g metheus-governance-mcp-cli@latestInstall creates local provider settings templates here:
~/.metheus/telegram.env~/.metheus/slack.env~/.metheus/kakaotalk.env~/.metheus/bot-runner.json
These files are for local provider bot secrets only.
- Store locally:
TELEGRAM_BOT_TOKENSLACK_BOT_TOKENKAKAOTALK_BOT_TOKEN
- Server-side Metheus stores project chat destination metadata separately:
- provider
chat_id/ channel / room identifier- label / active state
- Do not put project chat destination identifiers in local env files.
Example templates:
# ~/.metheus/telegram.env
TELEGRAM_BOT_TOKEN=
# ~/.metheus/slack.env
SLACK_BOT_TOKEN=
# ~/.metheus/kakaotalk.env
KAKAOTALK_BOT_TOKEN=Runner template:
{
"version": 1,
"routes": [
{
"name": "telegram-monitor",
"enabled": false,
"project_id": "<project_uuid>",
"provider": "telegram",
"role": "monitor",
"command": "metheus-governance-mcp-cli local-bot-bridge --client codex --no-update"
}
]
}One command bootstrap (recommended)
Run in your project folder:
metheus-governance-mcp-cli --project-id <project_uuid> --ctxpack-key "<ctxpack_key>" --base-url https://metheus.gesiaplatform.comIf auth is not ready, login starts automatically, then MCP registration is completed.
Setup
metheus-governance-mcp-cli setup --project-id <project_uuid> --ctxpack-key "<ctxpack_key>" --base-url https://metheus.gesiaplatform.comTechnical fallback: project-id can be auto-detected if your current folder (or parent) has .metheus_ctxpack_sync.json.
setup defaults to --workspace-dir auto (dynamic workspace detection).
Use an explicit path only when you intentionally want a fixed workspace.
Ops policy (recommended):
- Always pass explicit
--project-id <project_uuid>during setup. - Omit
--project-idonly in advanced cases where.metheus_ctxpack_sync.jsonis already present and verified.
Recommended for Codex/Claude/Gemini/Antigravity/Cursor multi-workspace sessions:
metheus-governance-mcp-cli setup --project-id <project_uuid> --ctxpack-key "<ctxpack_key>" --base-url https://metheus.gesiaplatform.com --workspace-dir autosetup also ensures local provider templates exist:
~/.metheus/telegram.env~/.metheus/slack.env~/.metheus/kakaotalk.env~/.metheus/bot-runner.json
Fill only provider bot tokens locally. Project chat destination identifiers should be managed on the Metheus server as project chat destinations, not as local env values and not inside legacy Chat Hooks/webhooks.
~/.metheus/bot-runner.json is the local automation profile for:
- which project to watch
- which provider/role bot profile to use
- which local AI command to run on new archived chat messages
Built-in helper command:
metheus-governance-mcp-cli local-bot-bridge --client codex --no-updateSupported --client values:
codexclaudegeminisample
Use sample first for smoke tests before switching to a real AI client.
Gemini CLI note:
gemini mcpcommands require Gemini auth to be configured first (GEMINI_API_KEYor~/.gemini/settings.jsonauth).setupregisters Gemini in bothuserandprojectscopes to improve auto-discovery across folders.
Workspace signal guardrail:
- default recommendation is
--workspace-dir autowith no fixed fallback path. - if a client session does not provide trusted workspace signals (
workspaceFolders/rootUri/cwd), ctxpack local write is blocked (sync_status=guarded,local_file_count=0). - use
--workspace-fallback-dironly when you intentionally want a shared fallback root.
Guardrail note:
- By default, CLI blocks reading/writing ctxpack sync metadata when workspace root resolves to the home directory.
- Override only when intentional:
METHEUS_ALLOW_HOME_WORKSPACE=1.
Project ID behavior (verified)
setup --project-id <A>sets default proxy scope to projectA.- Proxy forwards
project_idto gateway query, and gateway setsMCP_PROJECT_IDfor MCP runtime. - If a tool call includes
project_idin its arguments, that value overrides setup-time default scope. - If tool arguments omit
project_id, server falls back toMCP_PROJECT_ID. - If both are missing, the call fails with
project_id is required. - For single-project sessions, keep one pinned
--project-idand avoid sending a differentproject_idunless intentional.
Doctor
metheus-governance-mcp-cli doctor --project-id <project_uuid> --base-url https://metheus.gesiaplatform.comChecks:
- auth token status (+ auto refresh attempt)
- local provider env template presence
- local provider token presence for active project destinations
- codex/claude/gemini/antigravity/cursor registration state
- gateway
tools/listreachability project.summaryaccess- ctxpack auto sync status
- smoke calls:
workitem.list,evidence.list,decision.list
Direct bot posting:
me.send-bot-messageuses local provider tokens from~/.metheus/<provider>.env- it does not use a server-stored bot token
- the destination identifier is resolved from the current project's saved Chat Destinations on the Metheus server
- if multiple active destinations exist for the same provider, pass
destination_idordestination_label - direct local delivery is implemented today for:
- Telegram
- Slack
- KakaoTalk profiles and destinations can be stored now, but direct local delivery is not implemented yet
Local bot runner
The local runner closes the loop:
- provider bot receives a room message
- Metheus archives the message into Governance discussion comments
- local runner reads new archived comments
- local AI command generates a reply
- CLI sends the reply back through
me.send-bot-message - the sent reply is mirrored back into the archive
Commands:
metheus-governance-mcp-cli runner once
metheus-governance-mcp-cli runner startCommon flags:
metheus-governance-mcp-cli runner once --project-id <project_uuid> --provider telegram --role monitor --command "node C:\\path\\to\\my-runner.js"
metheus-governance-mcp-cli runner start --project-id <project_uuid> --provider telegram --role monitor --command "python C:\\path\\to\\reply.py" --poll-interval-ms 5000Recommended production path:
- keep provider bot token in
~/.metheus/<provider>.env - keep project room identifier in server-side Chat Destinations
- keep automation route config in
~/.metheus/bot-runner.json
Runner command contract:
- stdin: JSON payload containing project, destination, trigger message, and recent context comments
- stdout:
- plain text reply, or
- JSON object like
{"reply":"...","reply_to_message_id":123}, or - JSON skip result like
{"skip":true,"reason":"not actionable"}
Notes:
runner onceprocesses the most recent pending archived inbound messagerunner startkeeps polling and stores per-route cursor state in~/.metheus/bot-runner-state.json- first start primes the cursor to the latest inbound message and does not reply to old backlog
local-bot-bridgereads stdin JSON from the runner and can call Codex/Claude/Gemini for you- today this automation path is implemented for Telegram end-to-end
- Slack can use direct local send, but automatic inbound runner flow is not completed yet
- KakaoTalk config can be stored now, but direct send/runner flow is not implemented yet
Use in MCP
setup auto-registers this server for codex, claude, gemini, antigravity, and cursor when those CLIs are available.
Antigravity note:
- this CLI manages MCP registration via Antigravity local config because Antigravity does not provide full
mcp list/get/removesubcommands. - primary config path:
~/.gemini/antigravity/mcp_config.json - legacy mirror path:
%APPDATA%/Antigravity/User/mcp.json(Windows) for compatibility - for compatibility across Antigravity variants, setup writes both
mcpServersandserverskeys. - proxy stdio now supports both
Content-Lengthframed MCP and JSONL input for VS Code-family clients.
Cursor note:
- this CLI manages MCP registration via Cursor global MCP config (
~/.cursor/mcp.json).
Tool naming compatibility:
- Claude/Codex/Gemini keep canonical MCP tool names (
project.summary,ctxpack.merge.brief, ...). - Cursor/Antigravity sessions use safe aliases only (
project_summary,ctxpack_merge_brief, ...). - Proxy maps safe alias calls back to canonical names automatically.
Local bootstrap tools exposed by proxy:
project.summaryproject.describe(alias)project.get(alias)ctxpack.merge.briefctxpack.merge.execute
These tools accept project_id and return:
- access state (
granted,unauthorized,denied,not_found) - project metadata (name, org, template, owners, visibility)
- agenda preview from ctxpack (when available)
project.summary automatically syncs ctxpack to local cache:
- missing local cache -> download
- same version -> keep current
- newer server version -> update local cache
- workspace path -> auto-detected from client metadata/env by default
- if workspace signal is missing in auto mode, sync is guarded (no local write)
- use
--workspace-fallback-dir <path>only when you intentionally want fallback writes
Project-ID first-call rule:
- when user gives only
Project ID, callproject.summaryfirst. - call
ctxpack.ensureafterproject.summaryonly when extra ctxpack refresh/export context is needed. - for support/ops workflows, do not run ctxpack sync/download before a successful
project.summary.
Ctxpack merge safety flow:
- call
ctxpack.merge.brieffirst - review who changed what (
created_by,changed_paths, metadata summary) - get explicit owner decision in chat
- then call
ctxpack.merge.executewithowner_confirmation
Manual ctxpack pull/update:
metheus-governance-mcp-cli ctxpack pull --project-id <project_uuid> --base-url https://metheus.gesiaplatform.comWhen workitem.list returns empty, proxy appends a hint to call project.summary first.
For ctxpack push conflicts (ctxpack_conflict / stale baseline), proxy behavior:
- standard conflict message with pull/merge/retry guidance
- auto ctxpack pull-to-local on conflict by default (
--auto-pull-on-conflict=true)
Auth flow (recommended)
- Auto login and save token once (default flow:
device -> callback -> manual hint):
metheus-governance-mcp-cli auth login --base-url https://metheus.gesiaplatform.comOptional flags:
metheus-governance-mcp-cli auth login --callback-port 43819 --open-browser true
metheus-governance-mcp-cli auth login --flow device
metheus-governance-mcp-cli auth login --flow callback --callback-port 43819
metheus-governance-mcp-cli auth login --client-id metheus-cli --realm master --keycloak-url https://oauth3.gesia.ioKeycloak client requirement for auto login:
- Device flow:
- Enable OAuth 2.0 Device Authorization Grant for the client.
- Callback flow:
- Add localhost callback URI to redirect list (example):
http://127.0.0.1/*
- Add localhost callback URI to redirect list (example):
- If callback URI is not configured, CLI can still work via
--flow device.
Manual fallback:
metheus-governance-mcp-cli auth login --manual true --base-url https://metheus.gesiaplatform.com- Check token status:
metheus-governance-mcp-cli auth status- If token is rotated, set directly:
metheus-governance-mcp-cli auth set --token "<access_token>" --refresh-token "<refresh_token>"- Remove local token:
metheus-governance-mcp-cli auth clearproxy priority:
METHEUS_TOKEN
MCP_AUTH_TOKEN
- local file
~/.metheus/governance-mcp-auth.json
- local file
You can still use env token directly:
export METHEUS_TOKEN="<access_token>"PowerShell:
$env:METHEUS_TOKEN="<access_token>"npm publish token (where to store)
Use this local file in this folder:
tools/governance-mcp-cli/.env.npm.local(create from.env.npm.local.example)
Template:
NPM_TOKEN=__PASTE_NPM_TOKEN_HERE__Load token before publish:
PowerShell:
$env:NPM_TOKEN = (Get-Content .\.env.npm.local | Where-Object { $_ -match '^NPM_TOKEN=' } | ForEach-Object { $_.Split('=',2)[1] } | Select-Object -First 1).Trim()
npm publish --access publicbash/zsh:
export NPM_TOKEN="$(grep '^NPM_TOKEN=' ./.env.npm.local | head -n1 | cut -d'=' -f2-)"
npm publish --access publicRelease commands
npm run check
npm run test:compat
npm run publish:dryActual publish:
npm run publish:publicIf npm returns You cannot publish over the previously published versions, bump package.json version and retry.
If npm account uses 2FA, pass OTP:
node release.mjs --otp <6-digit-code>Regression and smoke checks
Local compatibility selftest (no network):
npm run test:compatProxy smoke test (initialize -> tools/list -> project summary -> ctxpack local sync):
npm run smoke:proxy -- --project-id <project_uuid> --ctxpack-key "<ctxpack_key>" --workspace-dir <workspace_path>Optional:
--client cursor-vscode(default) or--client antigravity--base-url https://metheus.gesiaplatform.com/governance/mcp
Workspace fallback guardrail:
- If
METHEUS_WORKSPACE_DIRis accidentally set to a non-existing boolean suffix path likeC:\code_test\true, proxy now recovers to the parent workspace (C:\code_test) instead of pinning to the bad path.
