Source code for smarter.apps.mcpserver.repositories

"""
The Smarter Project's GitHub repositories, which the Smarter Project MCP server reads.

Each :class:`ProjectRepository` is one public repository of the ``smarter-sh`` GitHub
organization. The MCP server serves each repository at its own endpoint,
``/api/v1/mcp/smarter-project/<name>/``, and all of them together at
``/api/v1/mcp/smarter-project/``. The repositories are a fixed part of the platform,
declared here rather than in a manifest, because the MCP server is an internal utility of
the platform, not a resource that accounts create.

.. note::

    **Experimental.** The MCPServer was designed and coded by Claude Code (Anthropic's
    Claude Opus 5.5), with Lawrence McDaniel as co-author. It is experimental, and will
    be documented.
"""

import posixpath
from typing import Optional

from pydantic import BaseModel, ConfigDict, Field

from smarter.common.const import SMARTER_PROJECT_DOCS_URL

GITHUB_URL = "https://github.com"
GITHUB_API_URL = "https://api.github.com"
GITHUB_CODELOAD_URL = "https://codeload.github.com"
SMARTER_PROJECT_GITHUB_ORGANIZATION = "smarter-sh"
SMARTER_PROJECT_DOCS_LATEST_URL = f"{SMARTER_PROJECT_DOCS_URL}/en/latest/"
"""The latest version of the Sphinx documentation, built from the smarter repository's docs/source."""

DOCUMENTATION_PAGE_EXTENSIONS = (".rst", ".md")
"""The extensions of Sphinx source files, which are published as html pages."""


[docs] class ProjectRepository(BaseModel): """ A public GitHub repository of The Smarter Project. **Example usage**:: repository = get_repository("smarter-cli") repository.github_url # 'https://github.com/smarter-sh/smarter-cli' repository.file_url("0123abc", "README.md", 1, 20) """ model_config = ConfigDict(frozen=True, extra="forbid") name: str = Field(description="The repository's name, which is also its endpoint's path, e.g. smarter-cli.") title: str = Field( description="What the repository contains, in a few words, e.g. 'the Smarter command-line interface'." ) description: str = Field(description="What the repository contains, and what questions it answers.") owner: str = Field(default=SMARTER_PROJECT_GITHUB_ORGANIZATION, description="The GitHub organization.") ref: str = Field(default="main", description="The branch that is indexed.") docs_root: Optional[str] = Field( default=None, description="The folder of the Sphinx documentation's source files, e.g. docs/source." ) docs_url: Optional[str] = Field( default=None, description="The url of the published Sphinx documentation that is built from docs_root." ) @property def full_name(self) -> str: """The repository's GitHub name, e.g. ``smarter-sh/smarter-cli``.""" return f"{self.owner}/{self.name}" @property def github_url(self) -> str: """The repository's GitHub url.""" return f"{GITHUB_URL}/{self.full_name}" @property def commit_api_url(self) -> str: """The GitHub api url of the latest commit of :attr:`ref`.""" return f"{GITHUB_API_URL}/repos/{self.full_name}/commits/{self.ref}"
[docs] def archive_url(self, commit_sha: str) -> str: """ Return the url of the repository's gzipped tar archive at a commit. :param commit_sha: The commit. :returns: The url. """ return f"{GITHUB_CODELOAD_URL}/{self.full_name}/tar.gz/{commit_sha}"
[docs] def file_url( self, commit_sha: Optional[str], path: str, start_line: Optional[int] = None, end_line: Optional[int] = None ) -> str: """ Return the GitHub url of a file, optionally of a range of its lines. :param commit_sha: The commit, for a permanent link. Defaults to :attr:`ref`. :param path: The file's path in the repository. :param start_line: The first line to highlight. :param end_line: The last line to highlight. :returns: The url. """ url = f"{self.github_url}/blob/{commit_sha or self.ref}/{path}" if start_line: url += f"#L{start_line}" if end_line and end_line > start_line: url += f"-L{end_line}" return url
[docs] def documentation_url(self, path: str) -> Optional[str]: """ Return the url of the published documentation page that a source file becomes. :param path: The file's path in the repository, e.g. ``docs/source/smarter-resources/smarter-mcpclient.rst``. :returns: The page's url, e.g. ``https://docs.smarter.sh/en/latest/smarter-resources/smarter-mcpclient.html``, or None if the file is not a page of the repository's published documentation. """ if not self.docs_root or not self.docs_url: return None prefix = self.docs_root.rstrip("/") + "/" stem, extension = posixpath.splitext(path) if not path.startswith(prefix) or extension.lower() not in DOCUMENTATION_PAGE_EXTENSIONS: return None return f"{self.docs_url}{stem[len(prefix):]}.html"
SMARTER_PROJECT_REPOSITORIES: tuple[ProjectRepository, ...] = ( ProjectRepository( name="smarter", title="the Smarter platform, and its documentation", description=( "The Smarter platform: its Django backend, SAM manifests and resources (LLMClients, " "Plugins, MCPClients, Guardrails, Secrets, ...), its api, its React web console, its " f"Helm chart, and the source of its documentation, {SMARTER_PROJECT_DOCS_URL}, in docs/source." ), docs_root="docs/source", docs_url=SMARTER_PROJECT_DOCS_LATEST_URL, ), ProjectRepository( name="smarter-cli", title="the Smarter command-line interface", description="The smarter command-line interface, written in Go, which applies, gets, describes and deletes manifests.", ), ProjectRepository( name="smarter-python", title="the Smarter Python SDK", description="The official Python library for the Smarter platform's api, published to PyPI as smarter-api.", ), ProjectRepository( name="smarter-nodejs", title="the Smarter Node.js SDK", description="The official Node.js library for the Smarter platform's api, written in TypeScript, published to npm as @smarter.sh/api.", ), ProjectRepository( name="smarter-golang", title="the Smarter Go SDK", description="The official Go library for the Smarter platform's api, the module github.com/smarter-sh/smarter-golang.", ), ProjectRepository( name="smarter-vscode-yaml", title="the VS Code extension for Smarter manifests", description="The VS Code extension that validates and completes Smarter yaml manifests.", ), ProjectRepository( name="smarter-infrastructure", title="the Smarter cloud infrastructure", description="The Terraform and Kubernetes code of the cloud infrastructure that the Smarter platform runs on.", ), ProjectRepository( name="smarter-chat", title="the SmarterChat React component", description="SmarterChat, the React chat component of Smarter LLMClients, published to npm.", ), ProjectRepository( name="smarter-deploy", title="the Smarter platform quick start, with Docker", description="The quick start that runs the Smarter platform on a computer with Docker Compose.", ), ) """Every repository that the MCP server reads."""
[docs] def project_repositories() -> tuple[ProjectRepository, ...]: """ Return :data:`SMARTER_PROJECT_REPOSITORIES`. Every module reads the repositories through this function, so that tests can replace them with throwaway repositories, whose indexes do not collide with the real ones. """ return SMARTER_PROJECT_REPOSITORIES
[docs] def get_repository(name: str) -> Optional[ProjectRepository]: """ Return one of :data:`SMARTER_PROJECT_REPOSITORIES`, by name. :param name: The repository's name, e.g. ``smarter-cli``. :returns: The repository, or None if there is no such repository. """ return next((repository for repository in project_repositories() if repository.name == name), None)
[docs] def repository_names() -> list[str]: """Return the names of :data:`SMARTER_PROJECT_REPOSITORIES`.""" return [repository.name for repository in project_repositories()]
__all__ = [ "SMARTER_PROJECT_REPOSITORIES", "ProjectRepository", "get_repository", "project_repositories", "repository_names", ]