generated from coulomb/repo-seed
feat(mcp): SSE/HTTP mode, workplan OPS-WP-0002 done
- Add --http flag to MCP server for SSE transport on port 8002 - Add make mcp-http / mcp-stop targets - Pin fastmcp<3.1.0 to stabilize dependency - Update session-protocol: Step 0 tunnel health check before orient - Mark OPS-WP-0002 and all its tasks done Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,14 @@ State Hub: http://127.0.0.1:8000
|
||||
|
||||
### Session Protocol
|
||||
|
||||
**Step 0 — Tunnel health**
|
||||
|
||||
Before anything else:
|
||||
```bash
|
||||
bridge status
|
||||
```
|
||||
Bring up any stopped or stale tunnels before accessing remote services.
|
||||
|
||||
**Step 1 — Orient**
|
||||
|
||||
Read the offline-safe brief first:
|
||||
|
||||
8
Makefile
8
Makefile
@@ -1,4 +1,4 @@
|
||||
.PHONY: test lint install
|
||||
.PHONY: test lint install mcp-http mcp-stop
|
||||
|
||||
test:
|
||||
uv run pytest
|
||||
@@ -8,3 +8,9 @@ lint:
|
||||
|
||||
install:
|
||||
uv tool install -e .
|
||||
|
||||
mcp-http: ## Start MCP server in SSE mode (default port 8002)
|
||||
BRIDGE_MCP_PORT=$${BRIDGE_MCP_PORT:-8002} uv run python src/bridge/mcp_server/server.py --http
|
||||
|
||||
mcp-stop: ## Stop MCP server running on port 8002
|
||||
@lsof -ti:$${BRIDGE_MCP_PORT:-8002} | xargs -r kill -TERM && echo "MCP server stopped" || echo "No MCP server running on port $${BRIDGE_MCP_PORT:-8002}"
|
||||
|
||||
@@ -11,7 +11,7 @@ dependencies = [
|
||||
"typer>=0.12",
|
||||
"pyyaml>=6.0",
|
||||
"httpx>=0.27",
|
||||
"fastmcp>=2.0.0",
|
||||
"fastmcp>=2.0.0,<3.1.0",
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
|
||||
@@ -513,4 +513,13 @@ def resource_catalog_targets() -> str:
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
if __name__ == "__main__":
|
||||
mcp.run(transport="stdio")
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(description="OpsBridge MCP server")
|
||||
parser.add_argument("--http", action="store_true", help="Run in SSE/HTTP mode instead of stdio")
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.http:
|
||||
port = int(os.environ.get("BRIDGE_MCP_PORT", "8002"))
|
||||
mcp.run(transport="sse", host="127.0.0.1", port=port)
|
||||
else:
|
||||
mcp.run(transport="stdio")
|
||||
|
||||
18
uv.lock
generated
18
uv.lock
generated
@@ -345,7 +345,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "fastmcp"
|
||||
version = "3.1.0"
|
||||
version = "3.0.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "authlib" },
|
||||
@@ -365,14 +365,13 @@ dependencies = [
|
||||
{ name = "python-dotenv" },
|
||||
{ name = "pyyaml" },
|
||||
{ name = "rich" },
|
||||
{ name = "uncalled-for" },
|
||||
{ name = "uvicorn" },
|
||||
{ name = "watchfiles" },
|
||||
{ name = "websockets" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/0a/70/862026c4589441f86ad3108f05bfb2f781c6b322ad60a982f40b303b47d7/fastmcp-3.1.0.tar.gz", hash = "sha256:e25264794c734b9977502a51466961eeecff92a0c2f3b49c40c070993628d6d0", size = 17347083 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/11/6b/1a7ec89727797fb07ec0928e9070fa2f45e7b35718e1fe01633a34c35e45/fastmcp-3.0.2.tar.gz", hash = "sha256:6bd73b4a3bab773ee6932df5249dcbcd78ed18365ed0aeeb97bb42702a7198d7", size = 17239351 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/17/07/516f5b20d88932e5a466c2216b628e5358a71b3a9f522215607c3281de05/fastmcp-3.1.0-py3-none-any.whl", hash = "sha256:b1f73b56fd3b0cb2bd9e2a144fc650d5cc31587ed129d996db7710e464ae8010", size = 633749 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0a/5a/f410a9015cfde71adf646dab4ef2feae49f92f34f6050fcfb265eb126b30/fastmcp-3.0.2-py3-none-any.whl", hash = "sha256:f513d80d4b30b54749fe8950116b1aab843f3c293f5cb971fc8665cb48dbb028", size = 606268 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -664,7 +663,7 @@ dev = [
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "fastmcp", specifier = ">=2.0.0" },
|
||||
{ name = "fastmcp", specifier = ">=2.0.0,<3.1.0" },
|
||||
{ name = "httpx", specifier = ">=0.27" },
|
||||
{ name = "pyyaml", specifier = ">=6.0" },
|
||||
{ name = "typer", specifier = ">=0.12" },
|
||||
@@ -1297,15 +1296,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uncalled-for"
|
||||
version = "0.2.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/02/7c/b5b7d8136f872e3f13b0584e576886de0489d7213a12de6bebf29ff6ebfc/uncalled_for-0.2.0.tar.gz", hash = "sha256:b4f8fdbcec328c5a113807d653e041c5094473dd4afa7c34599ace69ccb7e69f", size = 49488 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/7f/4320d9ce3be404e6310b915c3629fe27bf1e2f438a1a7a3cb0396e32e9a9/uncalled_for-0.2.0-py3-none-any.whl", hash = "sha256:2c0bd338faff5f930918f79e7eb9ff48290df2cb05fcc0b40a7f334e55d4d85f", size = 11351 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uvicorn"
|
||||
version = "0.41.0"
|
||||
|
||||
@@ -4,11 +4,11 @@ type: workplan
|
||||
title: "Agent Usability — MCP Registration, Skill, and Worker Orientation"
|
||||
domain: custodian
|
||||
repo: ops-bridge
|
||||
status: active
|
||||
status: done
|
||||
owner: custodian
|
||||
topic_slug: custodian
|
||||
created: "2026-03-21"
|
||||
updated: "2026-03-21"
|
||||
updated: "2026-03-26"
|
||||
depends_on: OPS-WP-0001
|
||||
state_hub_workstream_id: "c195cc40-8be7-462e-be26-a7d6bda34cd5"
|
||||
---
|
||||
@@ -74,7 +74,7 @@ worker agents:
|
||||
|
||||
```task
|
||||
id: OPS-WP-0002-T01
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "27fc6fa1-6d0e-438a-b4a3-c6091931da88"
|
||||
```
|
||||
@@ -101,7 +101,7 @@ Gate: `bridge_status()` tool callable via SSE on localhost:8002 after
|
||||
|
||||
```task
|
||||
id: OPS-WP-0002-T02
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "2216457d-035e-4804-b685-18975f3c6d1f"
|
||||
```
|
||||
@@ -133,7 +133,7 @@ mcp-http`.
|
||||
|
||||
```task
|
||||
id: OPS-WP-0002-T03
|
||||
status: todo
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "4b2e39eb-4585-4e60-ab16-9e7909eced74"
|
||||
```
|
||||
@@ -178,7 +178,7 @@ identifies and recovers a manually-stopped tunnel.
|
||||
|
||||
```task
|
||||
id: OPS-WP-0002-T04
|
||||
status: todo
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "cc64bb07-ea5d-498a-8c14-bb653581efe7"
|
||||
```
|
||||
@@ -213,9 +213,9 @@ session protocol references bridge status check.
|
||||
|
||||
## Done Criteria
|
||||
|
||||
- [ ] `make mcp-http` starts the MCP server on port 8002 (SSE)
|
||||
- [ ] `bridge_status` and `bridge_check` callable as MCP tools from Claude Code
|
||||
- [ ] `ops-bridge` registered in `~/.claude.json` at user scope
|
||||
- [ ] `/bridge` skill surfaces tunnel states and recovers a stopped tunnel
|
||||
- [ ] Global CLAUDE.md has worker agent bridge protocol
|
||||
- [ ] All existing tests pass after T01 changes (`make test`)
|
||||
- [x] `make mcp-http` starts the MCP server on port 8002 (SSE)
|
||||
- [x] `bridge_status` and `bridge_check` callable as MCP tools from Claude Code
|
||||
- [x] `ops-bridge` registered in `~/.claude.json` at user scope
|
||||
- [x] `/bridge` skill surfaces tunnel states and recovers a stopped tunnel
|
||||
- [x] Global CLAUDE.md has worker agent bridge protocol
|
||||
- [x] All existing tests pass after T01 changes (`make test`)
|
||||
|
||||
Reference in New Issue
Block a user