{"id":51429737,"url":"https://github.com/msradam/deploy-gate-agent","last_synced_at":"2026-07-05T03:02:34.811Z","repository":{"id":360132834,"uuid":"1248739337","full_name":"msradam/deploy-gate-agent","owner":"msradam","description":"A change/deploy-gate MCP agent built with Theodosia: ordered gates, a health gate, an audit trail, and a call to a filesystem MCP server.","archived":false,"fork":false,"pushed_at":"2026-05-25T05:16:12.000Z","size":2012,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-25T07:14:48.360Z","etag":null,"topics":["apache-burr","example","llm-agents","mcp","model-context-protocol","state-machine","theodosia"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/msradam.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-25T02:20:29.000Z","updated_at":"2026-05-25T05:16:38.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/msradam/deploy-gate-agent","commit_stats":null,"previous_names":["msradam/deploy-gate-agent"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/msradam/deploy-gate-agent","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msradam%2Fdeploy-gate-agent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msradam%2Fdeploy-gate-agent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msradam%2Fdeploy-gate-agent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msradam%2Fdeploy-gate-agent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/msradam","download_url":"https://codeload.github.com/msradam/deploy-gate-agent/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msradam%2Fdeploy-gate-agent/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35141967,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-05T02:00:06.290Z","response_time":100,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apache-burr","example","llm-agents","mcp","model-context-protocol","state-machine","theodosia"],"created_at":"2026-07-05T03:02:31.178Z","updated_at":"2026-07-05T03:02:34.757Z","avatar_url":"https://github.com/msradam.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# deploy-gate-agent\n\nA change/deploy-gate agent built with\n[Theodosia](https://github.com/msradam/theodosia): a deployment workflow defined as\na [Burr](https://burr.dagworks.io/) state machine and served as an\n[MCP](https://modelcontextprotocol.io/) server. An LLM walks the change one\nenforced transition at a time, and every step is recorded to an audit trail.\n\n```mermaid\nstateDiagram-v2\n    [*] --\u003e open_change\n    open_change --\u003e run_checks\n    run_checks --\u003e run_checks\n    run_checks --\u003e approve\n    approve --\u003e deploy\n    deploy --\u003e verify\n    verify --\u003e resolve\n    verify --\u003e rollback\n    resolve --\u003e [*]\n    rollback --\u003e [*]\n```\n\nThis diagram is the contract, and this is the serious end of the spectrum: a\nworkflow where order matters and a mistake is expensive. Two kinds of gate are\nenforced for you:\n\n- **Structural gates** (the graph). There is no path that lets the agent\n  `deploy` before `approve`, or `approve` before `run_checks`. An out-of-order\n  call returns `invalid_transition` with the reachable actions.\n- **A body-level gate.** `resolve` refuses if the post-deploy health check did\n  not pass, so closing out green only happens on a healthy deploy. The unhealthy\n  path is `rollback`.\n\nThe runbook is the graph, and the server holds the line, rather than the model\nbeing asked to remember it.\n\nAn LLM drives the whole change over MCP. Here fast-agent connects a\nLlama-3.3-70B model (on Together) and the model walks open, checks, approve,\ndeploy, verify, resolve, one enforced step at a time:\n\n![deploy-gate-agent driven by an LLM](demos/deploy-gate-agent-agent.gif)\n\nThe same workflow is observable from the terminal. `deploy-gate-agent render`\nprints the graph; `deploy-gate-agent sessions show` replays a recorded change,\nwith the refused `resolve` in red:\n\n![deploy-gate-agent observability](demos/deploy-gate-agent.gif)\n\n## Using another MCP server\n\n`run_checks` confirms the change is documented by reading `CHANGELOG.md` from a\nseparate filesystem MCP server. The action body calls it through Theodosia's\n`call_upstream`, wired in `cli.py`:\n\n```python\ncli = build_cli(\n    \"deploy-gate-agent\",\n    application=build_application,\n    upstream={\"fs\": {\"command\": \"npx\", \"args\": [\"-y\", \"@modelcontextprotocol/server-filesystem\", \".\"]}},\n)\n```\n\n```python\nchangelog = await call_upstream(\"fs\", \"read_file\", {\"path\": \"CHANGELOG.md\"})\n```\n\nThe agent connects to one server (this one) and sees one tool, `step`. The\nfilesystem server is reached from inside the action, so the call advances state\nlike any other step. This path needs Node and `npx` available for the filesystem\nserver.\n\n## Install\n\n```bash\ngit clone https://github.com/msradam/deploy-gate-agent.git\ncd deploy-gate-agent\nuv venv --python 3.13\nuv pip install -e .\n```\n\n## Run it as an agent\n\nThe repo ships an `.mcp.json` pointing a client at `deploy-gate-agent serve`.\n\n### Claude Code\n\n```bash\nclaude mcp add --transport stdio deploy-gate-agent -- uv run deploy-gate-agent serve\nclaude\n```\n\nThen: \"Ship version v2.4.0 of checkout-api. Follow the change process.\" The\nagent opens the change, runs checks, gets approval, deploys, verifies, and\nresolves or rolls back. Try telling it to deploy immediately and watch the\nserver refuse.\n\n### fast-agent (terminal REPL)\n\nThe repo ships a `fastagent.config.yaml` defining this server, so:\n\n```bash\nuvx fast-agent-mcp go --servers deploy-gate-agent -m \"Ship v2.4.0 of checkout-api. Follow the change process; health check passes.\"\n```\n\nIt uses Gemini by default (set `GOOGLE_API_KEY`). To drive it with a Together\nmodel instead, set `GENERIC_API_KEY` and add\n`--model generic.meta-llama/Llama-3.3-70B-Instruct-Turbo`.\n\n### MCPJam (one npx command, browser playground, free models)\n\n```bash\nnpx @mcpjam/inspector\n```\n\nAdd the server with command `uv`, args `run deploy-gate-agent serve`.\n\n## The audit trail\n\nEvery change is a recorded session: who approved, what was deployed, whether it\nverified, and how it ended.\n\n```bash\nuv run deploy-gate-agent sessions show   # full timeline, refusals in red\nuv run deploy-gate-agent watch           # live-tail an in-flight change\nuv run deploy-gate-agent ui              # open Burr's web UI to replay it\n```\n\nEvery gate decision (each step and each refusal) is also hash-chained into a\ntamper-evident ledger, written as `ledger.jsonl` next to the session's tracker\nlog. To check that a recorded change was not altered after the fact:\n\n```bash\nuv run deploy-gate-agent verify          # most recent session\nuv run deploy-gate-agent verify \u003capp-id\u003e # a specific session\n```\n\nIt recomputes the chain and exits nonzero if any record was edited, reordered,\nor deleted, naming the exact line where the chain broke. The chain proves the\naudit trail's integrity, not its confidentiality: it shows the records have not\nbeen tampered with, it does not encrypt them.\n\n## License\n\nApache 2.0. Built on [Theodosia](https://github.com/msradam/theodosia),\n[Apache Burr](https://github.com/apache/burr), and\n[FastMCP](https://github.com/jlowin/fastmcp).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmsradam%2Fdeploy-gate-agent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmsradam%2Fdeploy-gate-agent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmsradam%2Fdeploy-gate-agent/lists"}