feat: unify docs portal and MCP servers into one config-driven service
- add config.yml as single source of truth for collected repos/categories - add collect.py CLI to pull lib/api/wiki site builds and mcp bundles from source repos and regenerate nginx.conf + _index/index.html - port mcp runtime (main.py/core.py/config.py): nginx + health + FastMCP servers started from config.yml - docker: python:3.13-slim + nginx, expose 8000-8006 + 9000 (html portal) - drone: publish html (6007:9000) and MCP ports 8000-8006 - move mongo-ops docs to wiki/, add auth-server (api) and hexa (lib) - refresh lib site builds (lib/ prefix) and collect mcp bundles
This commit is contained in:
63
core.py
Normal file
63
core.py
Normal file
@@ -0,0 +1,63 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from config import MCPBundle
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
|
||||
|
||||
class MCPServer:
|
||||
"""MCP server serving a pre-built documentation bundle."""
|
||||
|
||||
def __init__(self, bundle: MCPBundle) -> None:
|
||||
self.mcp_root = bundle.root
|
||||
self.app = FastMCP(
|
||||
name=f"{bundle.name}-mcp",
|
||||
host="0.0.0.0",
|
||||
port=bundle.port,
|
||||
)
|
||||
self._register_resources()
|
||||
self._register_tools()
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def _read_json(self, path: Path) -> Any:
|
||||
if not path.exists():
|
||||
return {"error": "not_found", "path": str(path)}
|
||||
return json.loads(path.read_text(encoding="utf-8"))
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# MCP resources
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def _register_resources(self) -> None:
|
||||
@self.app.resource("doc://index")
|
||||
def index():
|
||||
return self._read_json(self.mcp_root / "index.json")
|
||||
|
||||
@self.app.resource("doc://nav")
|
||||
def nav():
|
||||
return self._read_json(self.mcp_root / "nav.json")
|
||||
|
||||
@self.app.resource("doc://modules/{module}")
|
||||
def module(module: str):
|
||||
return self._read_json(self.mcp_root / "modules" / f"{module}.json")
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# MCP tools
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def _register_tools(self) -> None:
|
||||
@self.app.tool()
|
||||
def ping() -> str:
|
||||
return "pong"
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# ASGI exposure
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
@property
|
||||
def asgi(self):
|
||||
return self.app
|
||||
Reference in New Issue
Block a user