refactor: serve MCP bundles under <name>/mcp with nginx guard; rename core->mcp_server

- collect.py: copy repo MCP bundles to ROOT/<name>/mcp (instead of ROOT/mcp/<name>); add nginx location guard to deny /<name>/mcp/
- config.py: bundle roots now point to <repo>/mcp and standards/mcp for static bundles
- Rename core.py -> mcp_server.py and update imports in main.py and registry.py
- Dockerfile: per-repo MCP COPYs under /app/<name>/mcp, drop blog copy; add ports 8008/8009 in .drone.yml
- Restore standards/mcp/libraries.json from git for registry server
This commit is contained in:
2026-10-11 23:37:46 +05:30
parent c5619bc5e8
commit 9929f05334
194 changed files with 166 additions and 83 deletions

View File

@@ -74,6 +74,8 @@ steps:
-p 8005:8005 \
-p 8006:8006 \
-p 8007:8007 \
-p 8008:8008 \
-p 8009:8009 \
--restart always \
aetos/docs:latest

View File

@@ -25,7 +25,7 @@ RUN pip install --no-cache-dir uv && \
uv pip install --system -r requirements.txt
# --- application files -----------------------------------------------------
COPY main.py core.py config.py registry.py collect.py config.yml ./
COPY main.py mcp_server.py config.py registry.py collect.py config.yml ./
COPY nginx.conf /etc/nginx/conf.d/default.conf
RUN rm -f /etc/nginx/sites-enabled/default

View File

@@ -256,6 +256,10 @@ NGINX_TEMPLATE = r"""server {{
root /usr/share/nginx/html;
index index.html lib/index.html api/index.html;
location ~ ^/[^/]+/mcp/ {{
deny all;
}}
location / {{
try_files $uri $uri/ /index.html;
}}
@@ -316,7 +320,7 @@ def collect(config: dict, dry_run: bool = False) -> list[str]:
if not src.is_dir():
errors.append(f"{name}: mcp bundle missing ({src})")
continue
dst = ROOT / MCP_DIR / name
dst = ROOT / name / MCP_DIR
copied.append(f" mcp {name} {dst.relative_to(ROOT)}/")
if not dry_run:
_copy_dir(src, dst)

View File

@@ -39,7 +39,7 @@ class ServiceConfig:
"""Return every MCP server: one per repo that declares a bundle, plus
the hand-authored static servers (for example the standards registry)."""
servers: dict[str, MCPBundle] = {
r.name: MCPBundle(root=Path("mcp") / r.name, name=r.mcp_server, port=r.mcp_port)
r.name: MCPBundle(root=Path(r.name) / "mcp", name=r.mcp_server, port=r.mcp_port)
for r in self.repos
if r.mcp_port is not None
}

View File

@@ -15,7 +15,7 @@ from http.server import BaseHTTPRequestHandler, HTTPServer
from pathlib import Path
from config import MCPBundle, load_config
from core import MCPServer
from mcp_server import MCPServer
from registry import StandardsMCPServer
APP_ROOT = Path(__file__).resolve().parent

View File

@@ -1,78 +0,0 @@
{
"project": "standards",
"note": "Machine-readable library registry. Mirrors standards_src/wiki/13_library_registry.md. Query with the find_library MCP tool.",
"libraries": [
{
"name": "DAG Pipe",
"import": "dagpipe",
"purpose": "Deterministic state-transformation DAG engine.",
"use_instead_of": "hand-rolled orchestration, topological ordering, immutable state propagation",
"capabilities": ["pipeline", "orchestration", "dag", "graph", "engine", "state", "node"],
"mcp": { "server": "dagpipe", "port": 8006 }
},
{
"name": "Hexa",
"import": "hexa",
"purpose": "Declarative dependency injection and composition-root tooling.",
"use_instead_of": "manual wiring, hand-written factories, manual composition roots",
"capabilities": ["di", "dependency-injection", "composition", "wiring", "ports"],
"mcp": { "server": "hexa", "port": null, "note": "bundle exists; port not yet assigned" }
},
{
"name": "Mongo Ops",
"import": "mongo_ops",
"purpose": "Async MongoDB repositories, caching, population and transactions.",
"use_instead_of": "raw Motor CRUD, connection lifecycle, generic repository code",
"capabilities": ["mongo", "mongodb", "database", "repository", "crud", "cache", "transactions"],
"mcp": { "server": "mongo_ops", "port": 8007 }
},
{
"name": "Omniread",
"import": "omniread",
"purpose": "Format-agnostic content acquisition and parsing (HTML, PDF, CSV, XLSX).",
"use_instead_of": "custom scrapers and parsers for HTML/PDF/CSV/XLSX",
"capabilities": ["ingestion", "parse", "pdf", "csv", "xlsx", "html", "scrape", "fetch"],
"mcp": { "server": "omniread", "port": 8003 }
},
{
"name": "OpenAPI First",
"import": "openapi_first",
"purpose": "Spec-first FastAPI bootstrap, client, and codegen.",
"use_instead_of": "decorator routers and hand-written API clients",
"capabilities": ["openapi", "http", "api", "routing", "fastapi", "client", "codegen", "spec"],
"mcp": { "server": "openapi_first", "port": 8004 }
},
{
"name": "Mail Intake",
"import": "mail_intake",
"purpose": "Provider-agnostic read-only email ingestion.",
"use_instead_of": "Gmail OAuth and MIME parsing implemented by hand",
"capabilities": ["email", "mail", "gmail", "ingestion", "imap", "mime", "oauth"],
"mcp": { "server": "mail_intake", "port": 8002 }
},
{
"name": "Py JWT",
"import": "jwtlib",
"purpose": "JWT authentication primitives (register, login, introspect).",
"use_instead_of": "password hashing and token issuance/verification written by hand",
"capabilities": ["auth", "jwt", "token", "login", "password", "introspect", "security"],
"mcp": { "server": "jwtlib", "port": 8005 }
},
{
"name": "Doc Forge",
"import": "docforge",
"purpose": "Docstring compiler that renders documentation for humans (MkDocs) and machines (MCP).",
"use_instead_of": "custom documentation generators",
"capabilities": ["docs", "documentation", "mkdocs", "mcp", "docstrings", "gsdfc"],
"mcp": { "server": "docforge", "port": 8001 }
},
{
"name": "Auth Server",
"import": "auth-server",
"purpose": "Central identity service (register/login/me/introspect).",
"use_instead_of": "building authentication endpoints yourself",
"capabilities": ["auth", "identity", "service", "register", "login", "introspect"],
"mcp": { "server": null, "port": null, "note": "service; no MCP bundle" }
}
]
}

View File

@@ -5,6 +5,10 @@ server {
root /usr/share/nginx/html;
index index.html lib/index.html api/index.html;
location ~ ^/[^/]+/mcp/ {
deny all;
}
location / {
try_files $uri $uri/ /index.html;
}

Some files were not shown because too many files have changed in this diff Show More