Files
doc-forge/docforge/servers/mcp_server.py
Vishesh 'ironeagle' Bangotra 582b6809a0 docs: bring docforge docstrings and wiki to GSDFC standard
- fix GSDFC spec contradictions in __init__ docstring (parenthesized types, fenced-block rule) and sync generated README
- rewrite docstrings across loaders, models, nav, servers, renderers, cli; sync .pyi stubs
- add pydoclint (google style) gate to dev extras and pyproject config
- fix mcp nav resources doc:// -> docs://
- refresh docs/lib and docs/mcp, drop stale docforge/ duplicate group
- update wiki pages and add GSDFC + MCP guides under 05_development
2026-09-12 13:12:51 +05:30

153 lines
4.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
# Summary
MCP server implementation.
This module defines the `MCPServer` class, which serves pre-generated
documentation bundles through the Model Context Protocol (MCP).
---
Notes:
- The served bundle is generated offline by `MCPRenderer`.
- Missing resources are reported as structured error dictionaries rather
than raising exceptions.
- The server exposes read-only resources and a single health-check tool.
---
"""
from __future__ import annotations
import json
from pathlib import Path
from typing import Any, Literal
from mcp.server.fastmcp import FastMCP
class MCPServer:
"""
MCP server for serving a pre-generated documentation bundle.
The server exposes documentation resources and diagnostic tools through
MCP endpoints backed by JSON files generated by the MCP renderer.
Attributes:
mcp_root (Path):
Directory containing the generated MCP documentation bundle.
app (FastMCP):
Underlying FastMCP application instance that registers resources
and tools.
"""
def __init__(self, mcp_root: Path, name: str) -> None:
"""
Initialize the MCP server.
Args:
mcp_root (Path):
Directory containing the generated MCP documentation bundle
(for example `index.json`, `nav.json`, and `modules/`).
name (str):
Identifier used for the MCP server instance.
"""
self.mcp_root = mcp_root
self.app = FastMCP(name)
self._register_resources()
self._register_tools()
# ------------------------------------------------------------------
# Internal helpers
# ------------------------------------------------------------------
def _read_json(self, path: Path) -> Any:
"""
Load and parse a JSON file.
If the file does not exist, a structured error response is returned
instead of raising an exception.
Args:
path (Path):
Path to the JSON file to read.
Returns:
Any:
Parsed JSON data if the file exists, otherwise an error dictionary
describing the missing resource.
"""
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:
"""
Register MCP resource endpoints.
The server exposes documentation resources through the following
endpoints:
- `docs://index` Project metadata
- `docs://nav` Navigation structure
- `docs://modules/{module}` Individual module documentation
"""
@self.app.resource("docs://index")
def index():
return self._read_json(self.mcp_root / "index.json")
@self.app.resource("docs://nav")
def nav():
return self._read_json(self.mcp_root / "nav.json")
@self.app.resource("docs://modules/{module}")
def module(module: str):
return self._read_json(self.mcp_root / "modules" / f"{module}.json")
# ------------------------------------------------------------------
# MCP tools
# ------------------------------------------------------------------
def _register_tools(self) -> None:
"""
Register optional MCP diagnostic tools.
These tools provide lightweight endpoints useful for verifying that
the MCP server is operational.
"""
@self.app.tool()
def ping() -> str:
"""Return a simple health check response."""
return "pong"
# ------------------------------------------------------------------
# Server lifecycle
# ------------------------------------------------------------------
def run(
self,
transport: Literal["stdio", "sse", "streamable-http"] = "streamable-http",
) -> None:
"""
Start the MCP server.
Args:
transport (Literal["stdio", "sse", "streamable-http"]):
Transport mechanism used by the MCP server. Supported options
include `stdio`, `sse`, and `streamable-http`.
"""
self.app.run(transport=transport)