72 lines
1.8 KiB
Python
72 lines
1.8 KiB
Python
"""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()
|