implemented steps 1-5
This commit is contained in:
+137
-32
@@ -1,38 +1,143 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from typing import Any
|
||||
|
||||
from fastmcp import FastMCP
|
||||
|
||||
from personal_mcp.catalog.server import catalog_server
|
||||
from personal_mcp.skills.copilot_customization.server import (
|
||||
copilot_customization_server,
|
||||
from personal_mcp.catalog.server import (
|
||||
build_skill_detail_payload,
|
||||
build_skills_index_payload,
|
||||
get_pattern_by_id_payload,
|
||||
search_patterns_payload,
|
||||
)
|
||||
from personal_mcp.skills.fastapi_async_sqlalchemy_modernization.server import (
|
||||
fastapi_async_sqlalchemy_modernization_server,
|
||||
from personal_mcp.skills.document_loader import (
|
||||
DocsRegistry,
|
||||
load_docs_registry,
|
||||
read_docs_markdown_path,
|
||||
read_skill_document,
|
||||
read_skill_reference,
|
||||
)
|
||||
from personal_mcp.skills.fastapi_uv_docker.server import fastapi_uv_docker_server
|
||||
from personal_mcp.skills.new_skill.server import new_skill_server
|
||||
from personal_mcp.skills.nicegui.server import nicegui_server
|
||||
from personal_mcp.skills.nicegui_ui_customization.server import (
|
||||
nicegui_ui_customization_server,
|
||||
)
|
||||
from personal_mcp.skills.pytest_scaffolding.server import pytest_scaffolding_server
|
||||
from personal_mcp.skills.python_logging_dictconfig.server import (
|
||||
python_logging_dictconfig_server,
|
||||
)
|
||||
from personal_mcp.skills.vscode_configuration.server import vscode_configuration_server
|
||||
from personal_mcp.skills.zensical_docs.server import zensical_docs_server
|
||||
|
||||
mcp = FastMCP("personal-mcp")
|
||||
|
||||
mcp.mount(catalog_server, namespace="catalog")
|
||||
mcp.mount(copilot_customization_server, namespace="copilot_customization")
|
||||
mcp.mount(
|
||||
fastapi_async_sqlalchemy_modernization_server,
|
||||
namespace="fastapi_async_sqlalchemy_modernization",
|
||||
DOCS_ROOT = os.getenv("PERSONAL_MCP_DOCS_ROOT", "../../docs")
|
||||
REGISTRY: DocsRegistry = load_docs_registry(
|
||||
package_anchor="personal_mcp",
|
||||
docs_root=DOCS_ROOT,
|
||||
)
|
||||
mcp.mount(new_skill_server, namespace="new_skill")
|
||||
mcp.mount(nicegui_server, namespace="nicegui")
|
||||
mcp.mount(nicegui_ui_customization_server, namespace="nicegui_ui_customization")
|
||||
mcp.mount(pytest_scaffolding_server, namespace="pytest_scaffolding")
|
||||
mcp.mount(python_logging_dictconfig_server, namespace="python_logging_dictconfig")
|
||||
mcp.mount(vscode_configuration_server, namespace="vscode_configuration")
|
||||
mcp.mount(fastapi_uv_docker_server, namespace="fastapi_uv_docker")
|
||||
mcp.mount(zensical_docs_server, namespace="zensical_docs")
|
||||
|
||||
mcp = FastMCP("personal-mcp", on_duplicate="error")
|
||||
|
||||
|
||||
def _ro_annotations() -> dict[str, bool]:
|
||||
return {
|
||||
"readOnlyHint": True,
|
||||
"idempotentHint": True,
|
||||
}
|
||||
|
||||
|
||||
@mcp.resource(
|
||||
"resource://catalog/skills_index",
|
||||
mime_type="application/json",
|
||||
tags={"catalog"},
|
||||
annotations=_ro_annotations(),
|
||||
)
|
||||
def skills_index() -> dict[str, Any]:
|
||||
return build_skills_index_payload(REGISTRY)
|
||||
|
||||
|
||||
@mcp.resource(
|
||||
"resource://catalog/skills_index{?q,tag,capability,cursor,limit}",
|
||||
mime_type="application/json",
|
||||
tags={"catalog"},
|
||||
annotations=_ro_annotations(),
|
||||
)
|
||||
def skills_index_query(
|
||||
q: str | None = None,
|
||||
tag: str | None = None,
|
||||
capability: str | None = None,
|
||||
cursor: str | None = None,
|
||||
limit: int | None = None,
|
||||
) -> dict[str, Any]:
|
||||
return build_skills_index_payload(
|
||||
REGISTRY,
|
||||
query=q,
|
||||
tag=tag,
|
||||
capability=capability,
|
||||
cursor=cursor,
|
||||
limit=limit,
|
||||
)
|
||||
|
||||
|
||||
@mcp.resource(
|
||||
"resource://catalog/skills/{skill_id}",
|
||||
mime_type="application/json",
|
||||
tags={"catalog"},
|
||||
annotations=_ro_annotations(),
|
||||
)
|
||||
def skill_detail(skill_id: str) -> dict[str, Any]:
|
||||
return build_skill_detail_payload(REGISTRY, skill_id)
|
||||
|
||||
|
||||
@mcp.resource(
|
||||
"resource://skills/{skill_id}/document",
|
||||
mime_type="text/markdown",
|
||||
tags={"skill-doc"},
|
||||
annotations=_ro_annotations(),
|
||||
)
|
||||
def skill_document(skill_id: str) -> dict[str, str]:
|
||||
return read_skill_document(REGISTRY, skill_id)
|
||||
|
||||
|
||||
@mcp.resource(
|
||||
"resource://skills/{skill_id}/references/{ref_id}",
|
||||
mime_type="text/markdown",
|
||||
tags={"reference"},
|
||||
annotations=_ro_annotations(),
|
||||
)
|
||||
def skill_reference(skill_id: str, ref_id: str) -> dict[str, str]:
|
||||
return read_skill_reference(REGISTRY, skill_id=skill_id, ref_id=ref_id)
|
||||
|
||||
|
||||
@mcp.resource(
|
||||
"resource://docs/{path*}",
|
||||
mime_type="text/markdown",
|
||||
tags={"docs"},
|
||||
annotations=_ro_annotations(),
|
||||
)
|
||||
def docs_markdown(path: str) -> dict[str, str]:
|
||||
return read_docs_markdown_path(REGISTRY, path)
|
||||
|
||||
|
||||
@mcp.tool
|
||||
def search_patterns(
|
||||
query: str = "",
|
||||
tags: list[str] | None = None,
|
||||
skip: int = 0,
|
||||
limit: int = 20,
|
||||
) -> dict[str, Any]:
|
||||
"""Search normalized pattern metadata with optional tags and pagination."""
|
||||
return search_patterns_payload(
|
||||
REGISTRY,
|
||||
query=query,
|
||||
tags=tags,
|
||||
skip=skip,
|
||||
limit=limit,
|
||||
)
|
||||
|
||||
|
||||
@mcp.tool
|
||||
def get_pattern_by_id(id: str) -> dict[str, Any]:
|
||||
"""Return one normalized pattern by stable id."""
|
||||
return get_pattern_by_id_payload(REGISTRY, id)
|
||||
|
||||
|
||||
@mcp.tool
|
||||
def get_skill_document_by_id(skill_id: str) -> dict[str, Any]:
|
||||
"""Return the canonical skill document payload for a stable skill id."""
|
||||
if skill_id not in REGISTRY.skills_by_id:
|
||||
return {"found": False, "id": skill_id}
|
||||
|
||||
return {
|
||||
"found": True,
|
||||
"document": read_skill_document(REGISTRY, skill_id),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user