"""Offline smoke test for the CrossBeam MCP Space (no API key / network needed).""" import base64, json, sys, fitz import engine as eng import mcp_server as mcpsrv from jurisdiction import list_jurisdictions, load_jurisdiction_file P = F = 0 def ok(c, m): global P, F print((" PASS " if c else " FAIL ") + m); P += c; F += (not c) def pdf(t): d = fitz.open(); d.new_page().insert_text((50, 50), t); return d.tobytes() print("\n[1] Jurisdictions & knowledge") ch = list_jurisdictions(".") real = [s for s in ch if not s.startswith("_") and s != "default"] ok(len(real) >= 1, f"configs: {real}") skills, loose = eng.load_knowledge(".") tracks = eng.discover_tracks(skills) ok(len(tracks) >= 1, f"tracks: {list(tracks)}") print("\n[2] MCP tool surface") import asyncio tools = asyncio.new_event_loop().run_until_complete(mcpsrv.mcp.list_tools()) names = [t.name for t in tools] expected = {"list_municipalities", "list_review_tracks", "list_knowledge", "review_plan_set", "analyze_corrections_letter", "generate_checklist"} ok(expected.issubset(set(names)), f"all 6 tools registered: {names}") print("\n[3] Keyless discovery tools") mun = mcpsrv.list_municipalities() ok(len(mun["municipalities"]) >= 1, f"municipalities: {[m['slug'] for m in mun['municipalities']]}") ok("tracks" in mcpsrv.list_review_tracks() and "providers" in mcpsrv.list_review_tracks(), "tracks + providers listed") ok(len(mcpsrv.list_knowledge()["manifest"]) > 50, "knowledge manifest") print("\n[4] Missing-key handling") ok("error" in mcpsrv.review_plan_set(pdf_base64="", api_key=""), "review errors clearly") ok("error" in mcpsrv.analyze_corrections_letter(letter_base64="", api_key=""), "corrections errors clearly") print("\n[5] End-to-end through MCP (mocked LLM)") eng.llm_call = lambda *a, **k: json.dumps({"submission_check": {"detected_project": "suite", "matches_declared_scope": True, "note": "ok"}, "findings": [{"id": "F-01", "category": "safety-codes", "severity": "must-fix", "description": "x", "citation": "9.5.3.1."}], "summary": {"verdict": "revisions required", "must_fix": 1, "clarify": 0, "advisory": 0}}) slug = [m["slug"] for m in mun["municipalities"]][0] r = mcpsrv.review_plan_set(pdf_base64=base64.b64encode(pdf("A1 suite")).decode(), api_key="k", municipality=slug, application_number="DP-TEST", site_address="1 TEST WY NE", applicant="TEST APPLICANT", community="TEST COMMUNITY", land_use_district="Residential - Test District", use_type="Discretionary", planning_contact="TEST REVIEWER") ok(r.get("result", {}).get("summary", {}).get("must_fix") == 1, "review returns findings via MCP") ok("report_markdown" in r and len(r["report_markdown"]) > 50, "report rendered via MCP") city = r.get("city_review_letter_markdown", "") ok("# Detailed Review 1 – Development Permit" in city, "City DR title rendered") ok("DP-TEST" in city and "TEST COMMUNITY" in city and "Discretionary" in city, "municipal header metadata rendered") ok("## Bylaw Discrepancies" in city and "## Prior to Decision Requirements" in city, "City DR core sections rendered") ok("## Building/Safety Codes" not in city, "building-code stream excluded from City DP conditions") ok("**(A)** Request cancellation" in city and "**(C)** Amend the application" in city, "City response options rendered") backyard = {"submission_check": {"detected_project": "New: Backyard Suite", "matches_declared_scope": True}, "findings": [], "summary": {}} eng._reconcile_calgary_backyard_checks( backyard, load_jurisdiction_file("jurisdictions/calgary.yaml"), {"label": "secondary/backyard suite"}) ok(len(backyard.get("mandatory_checks", [])) == 7, "all mandatory Calgary backyard-suite checks reconciled") ok(all(f.get("severity") == "clarify" for f in backyard.get("findings", [])), "missing mandatory checks become clarifications, not invented violations") eng.llm_call = lambda *a, **k: json.dumps({"letter_meta": {"permit_number": "X"}, "corrections": [{"id": "C-01", "city_item": "i", "category": "land-use", "governing_rule": "s.1", "governing_rule_source": "knowledge", "interpretation": "y", "resolution_options": ["z"], "needs_from_applicant": "w", "confidence": "high"}], "summary": {"total_items": 1, "by_category": {}, "notes": ""}}) c = mcpsrv.analyze_corrections_letter(letter_base64=base64.b64encode(pdf("Detailed Review")).decode(), api_key="k", municipality=slug) ok("[APPLICANT:" in c["draft_response_letter_markdown"], "draft letter keeps APPLICANT placeholders") print(f"\n{'='*44}\n {P} passed, {F} failed\n{'='*44}") sys.exit(1 if F else 0)