Files
nadlan-mcp/run_http_server.py
T
chaim 5e9963f51b Add: Web UI (React 19 + Vite + shadcn/ui) + FastAPI REST layer
Adds a self-contained web interface that wraps the MCP tools so end users
don't need to issue MCP commands. Single Docker container serves:

  /              → React SPA (RTL Hebrew, Heebo font, shadcn/ui components)
  /api/*         → FastAPI REST endpoints used by the SPA
  /api/docs      → OpenAPI / Swagger
  /mcp           → existing FastMCP streamable-http endpoint
  /health        → liveness probe

REST endpoints (in nadlan_mcp/web_app.py):
  GET  /api/search/address?q=...  — autocomplete + best-effort gush/חלקה
                                    via Govmap PARCEL_ALL layer
  POST /api/search/deals          — Govmap deals around an address
  POST /api/search/appraisals     — Decisive-appraiser search (gov.il)
  GET  /api/appraisals/pdf?url=.. — Stream PDFs through this server,
                                    carrying the upstream x-client-id
                                    header (a normal browser fetch fails)

UI flow:
  - Address search → resolves gush/חלקה → shows BOTH deals (Govmap) AND
    appraiser decisions (gov.il) for the same parcel side-by-side in tabs.
  - Block+plot search → goes straight to appraisals.
  - Appraiser-name search → all decisions by that appraiser.

Stack chosen for RTL-first usability and longevity: React 19, Vite 6,
TypeScript, Tailwind, shadcn/ui (Radix primitives), TanStack Query,
Lucide icons. ~295KB gzipped JS, no SSR overhead.

Multi-stage Dockerfile: Node 22 builds web/ in stage 1, Python 3.13
runtime serves the dist + the FastAPI app in stage 2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 12:35:08 +00:00

51 lines
1.4 KiB
Python

#!/usr/bin/env python3
"""
HTTP Server Entry Point for Nadlan-MCP.
Serves three things on a single port:
/ → React SPA (search & browse Israeli real estate data)
/api/... → REST endpoints used by the SPA (also documented at /api/docs)
/mcp → FastMCP streamable-http endpoint (for LLM clients)
For local Claude Desktop integration, use run_fastmcp_server.py (stdio).
"""
import logging
import os
import sys
import uvicorn
from nadlan_mcp.web_app import create_app
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
)
logger = logging.getLogger(__name__)
# Module-level app for ASGI servers (uvicorn web_app:app, gunicorn, etc.).
app = create_app()
def main() -> None:
port = int(os.environ.get("PORT", 8000))
host = "0.0.0.0"
logger.info("=" * 60)
logger.info("Starting Nadlan-MCP HTTP Server")
logger.info("=" * 60)
logger.info(f" UI: http://{host}:{port}/")
logger.info(f" API docs: http://{host}:{port}/api/docs")
logger.info(f" MCP: http://{host}:{port}/mcp")
logger.info(f" Health: http://{host}:{port}/health")
logger.info("=" * 60)
try:
uvicorn.run(app, host=host, port=port, log_level="info")
except Exception as e:
logger.error(f"Failed to start HTTP server: {e}", exc_info=True)
sys.exit(1)
if __name__ == "__main__":
main()