74 lines
2.4 KiB
Python
74 lines
2.4 KiB
Python
from __future__ import annotations
|
|
|
|
from fastmcp import FastMCP
|
|
from fastmcp.server.transforms import PromptsAsTools
|
|
from fastmcp.server.transforms import ResourcesAsTools
|
|
from mcp_types import Icon
|
|
|
|
from .prompts.provider import prompt_lifespan
|
|
from .registry.load import get_docs_registry
|
|
from .registry.load import read_docs_markdown_path
|
|
from .skills import skill_lifespan
|
|
|
|
_SERVER_INSTRUCTIONS = """Personal development guidance exposed as native MCP resources and prompts.
|
|
|
|
Use prompts for parameterized workflows; tool-only agents can discover and render them with
|
|
list_prompts and get_prompt. For task-specific guidance, browse native skill resources, select one
|
|
skill://<name>/SKILL.md resource, and read its manifest only when supporting detail is needed.
|
|
"""
|
|
_SERVER_ICON = Icon(
|
|
src=(
|
|
"data:image/svg+xml;base64,"
|
|
"PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+"
|
|
"PHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iOCIgZmlsbD0iIzE2N0Q4RCIvPjxwYXRoIGQ9"
|
|
"Ik0xOCAxNmgyMGw4IDh2MjRIMTh6IiBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lk"
|
|
"dGg9IjQiLz48cGF0aCBkPSJNMzggMTZ2MTBoOE0yNSAzM2gxNE0yNSA0MGgxNCIgZmlsbD0ibm9uZSIg"
|
|
"c3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSI0Ii8+PC9zdmc+"
|
|
),
|
|
mime_type="image/svg+xml",
|
|
sizes=["64x64"],
|
|
)
|
|
|
|
|
|
def run_stdio() -> None:
|
|
"""Create the MCP server and expose it over stdio"""
|
|
create_mcp().run()
|
|
|
|
|
|
def create_mcp() -> FastMCP:
|
|
mcp = FastMCP(
|
|
"personal-mcp",
|
|
instructions=_SERVER_INSTRUCTIONS,
|
|
icons=[_SERVER_ICON],
|
|
on_duplicate="error",
|
|
lifespan=skill_lifespan | prompt_lifespan,
|
|
)
|
|
|
|
registry = get_docs_registry()
|
|
|
|
@mcp.resource(
|
|
"resource://docs/{path*}",
|
|
name="docs_markdown",
|
|
title="Documentation Markdown",
|
|
description="Read a packaged documentation page by its path relative to the docs root.",
|
|
mime_type="text/markdown",
|
|
tags={"docs"},
|
|
annotations={
|
|
"readOnlyHint": True,
|
|
"idempotentHint": True,
|
|
"openWorldHint": False,
|
|
},
|
|
)
|
|
def docs_markdown(path: str) -> dict[str, str]:
|
|
return read_docs_markdown_path(registry, path)
|
|
|
|
# Bridges tool-only clients that cannot browse native resources or prompts directly.
|
|
mcp.add_transform(ResourcesAsTools(mcp))
|
|
mcp.add_transform(PromptsAsTools(mcp))
|
|
|
|
return mcp
|
|
|
|
|
|
if __name__ == "__main__":
|
|
run_stdio()
|