Headline MCP server at /mcp; remember + activity endpoints; hardened contradiction parsing
bbce9fa verified | """Probe the hosted (streamable-HTTP) ContextFirewall MCP endpoint. | |
| Usage: python scripts/mcp_http_probe.py [base_url] | |
| Connects over the real MCP protocol, lists tools, and calls a couple of them. | |
| """ | |
| from __future__ import annotations | |
| import asyncio | |
| import sys | |
| from mcp import ClientSession | |
| from mcp.client.streamable_http import streamablehttp_client | |
| BASE = (sys.argv[1] if len(sys.argv) > 1 else "http://127.0.0.1:8000").rstrip("/") | |
| URL = f"{BASE}/mcp" | |
| def _text(res) -> str: | |
| return "".join(getattr(c, "text", "") for c in res.content) | |
| async def main() -> None: | |
| async with streamablehttp_client(URL) as (read, write, _): | |
| async with ClientSession(read, write) as s: | |
| await s.initialize() | |
| tools = sorted(t.name for t in (await s.list_tools()).tools) | |
| print("TOOLS:", tools) | |
| expected = { | |
| "get_trusted_context", | |
| "audit_context", | |
| "remember", | |
| "forget_memory", | |
| "improve_rules", | |
| "list_coding_rules", | |
| } | |
| assert expected.issubset(set(tools)), f"missing tools: {expected - set(tools)}" | |
| print("PASS: all six tools exposed over streamable HTTP") | |
| r = await s.call_tool("get_trusted_context", {"task": "How do I deploy taskflow-api safely?"}) | |
| txt = _text(r) | |
| print("---- get_trusted_context (first 240) ----") | |
| print(txt[:240]) | |
| assert "ContextFirewall" in txt | |
| print("PASS: get_trusted_context returned a governed pack") | |
| r = await s.call_tool("audit_context", {"task": "How do I deploy taskflow-api safely?"}) | |
| print("---- audit_context (first 280) ----") | |
| print(_text(r)[:280]) | |
| print("PASS: audit_context returned verdicts") | |
| if __name__ == "__main__": | |
| asyncio.run(main()) | |