"""Local-only MCP server over stdio.""" from __future__ import annotations import os import sys from mcp.server.fastmcp import FastMCP from mcp_server import tools def _is_local_only() -> bool: return os.environ.get("MCP_ALLOW_REMOTE", "").lower() not in {"1", "true", "yes"} def _guard_local() -> None: if not _is_local_only(): return if os.environ.get("SSH_CONNECTION"): sys.stderr.write("Remote access denied. Unset SSH_CONNECTION or set MCP_ALLOW_REMOTE.\n") sys.exit(1) mcp = FastMCP("NixOS Repo MCP", json_response=True) @mcp.tool(name="show-constitution") def show_constitution() -> dict[str, object]: """Display repository AI constitution for rule lookup.""" return tools.invoke_tool("show-constitution", {}) @mcp.tool(name="list-playbooks") def list_playbooks() -> dict[str, object]: """List available playbooks under docs/playbooks.""" return tools.invoke_tool("list-playbooks", {}) @mcp.tool(name="show-reference") def show_reference() -> dict[str, object]: """Show docs/reference/index.md for navigation guidance.""" return tools.invoke_tool("show-reference", {}) @mcp.tool(name="search-docs") def search_docs(query: str) -> dict[str, object]: """Search docs for a query string.""" return tools.invoke_tool("search-docs", {"query": query}) @mcp.tool(name="list-mcp-tasks") def list_mcp_tasks() -> dict[str, object]: """Show MCP feature task list from specs.""" return tools.invoke_tool("list-mcp-tasks", {}) @mcp.tool(name="sync-docs") def sync_docs() -> dict[str, object]: """Compare tool catalog against documented anchors.""" return tools.invoke_tool("sync-docs", {}) def main() -> None: """Run the MCP server in stdio mode.""" _guard_local() mcp.run(transport="stdio") if __name__ == "__main__": main()