Source code for ralph.mcp.tools.names

"""Canonical Ralph MCP tool naming helpers."""

from __future__ import annotations

from enum import StrEnum
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from collections.abc import Sequence

RALPH_MCP_SERVER_NAME = "ralph"


[docs] class RalphToolName(StrEnum): """Canonical names for all Ralph MCP tools.""" READ_FILE = "read_file" WRITE_FILE = "write_file" LIST_DIRECTORY = "list_directory" LIST_DIRECTORY_RECURSIVE = "list_directory_recursive" DIRECTORY_TREE = "directory_tree" SEARCH_FILES = "search_files" READ_MULTIPLE_FILES = "read_multiple_files" STAT_PATH = "stat_path" LIST_ALLOWED_ROOTS = "list_allowed_roots" GREP_FILES = "grep_files" EDIT_FILE = "edit_file" APPEND_FILE = "append_file" CREATE_DIRECTORY = "create_directory" MOVE_FILE = "move_file" COPY_FILE = "copy_file" DELETE_PATH = "delete_path" GIT_STATUS = "git_status" GIT_DIFF = "git_diff" GIT_LOG = "git_log" GIT_SHOW = "git_show" EXEC = "exec" SUBMIT_ARTIFACT = "ralph_submit_artifact" SUBMIT_PLAN_SECTION = "ralph_submit_plan_section" INSERT_PLAN_STEP = "ralph_insert_plan_step" REPLACE_PLAN_STEP = "ralph_replace_plan_step" REMOVE_PLAN_STEP = "ralph_remove_plan_step" FINALIZE_PLAN = "ralph_finalize_plan" GET_PLAN_DRAFT = "ralph_get_plan_draft" DISCARD_PLAN_DRAFT = "ralph_discard_plan_draft" REPORT_PROGRESS = "report_progress" DECLARE_COMPLETE = "declare_complete" COORDINATE = "coordinate" READ_ENV = "read_env" WEB_SEARCH = "web_search" VISIT_URL = "visit_url" READ_IMAGE = "read_image" READ_MEDIA = "read_media"
[docs] def with_prefix(self, *, tool_name_prefix: str = "") -> str: """Return the tool name with an optional prefix applied.""" return f"{tool_name_prefix}{self}" if tool_name_prefix else self.value
[docs] def as_claude_alias(self, *, server_name: str = RALPH_MCP_SERVER_NAME) -> str: """Return the Claude MCP tool alias in the form mcp__<server>__<tool>.""" return f"mcp__{server_name}__{self}"
[docs] def prompt_aliases(self, *, tool_name_prefix: str = "") -> tuple[str, ...]: """Return the full set of prompt-facing alias names for this tool.""" primary = self.with_prefix(tool_name_prefix=tool_name_prefix) if primary == self.value: return (self.value,) return (primary, self.value)
[docs] def prompt_reference(self, *, tool_name_prefix: str = "") -> str: """Return a human-readable reference string for prompts.""" aliases = self.prompt_aliases(tool_name_prefix=tool_name_prefix) if len(aliases) == 1: return f"`{aliases[0]}`" return f"`{aliases[0]}` or bare `{aliases[1]}`"
READ_FILE_TOOL = RalphToolName.READ_FILE WRITE_FILE_TOOL = RalphToolName.WRITE_FILE LIST_DIRECTORY_TOOL = RalphToolName.LIST_DIRECTORY LIST_DIRECTORY_RECURSIVE_TOOL = RalphToolName.LIST_DIRECTORY_RECURSIVE DIRECTORY_TREE_TOOL = RalphToolName.DIRECTORY_TREE SEARCH_FILES_TOOL = RalphToolName.SEARCH_FILES READ_MULTIPLE_FILES_TOOL = RalphToolName.READ_MULTIPLE_FILES STAT_PATH_TOOL = RalphToolName.STAT_PATH LIST_ALLOWED_ROOTS_TOOL = RalphToolName.LIST_ALLOWED_ROOTS GREP_FILES_TOOL = RalphToolName.GREP_FILES EDIT_FILE_TOOL = RalphToolName.EDIT_FILE APPEND_FILE_TOOL = RalphToolName.APPEND_FILE CREATE_DIRECTORY_TOOL = RalphToolName.CREATE_DIRECTORY MOVE_FILE_TOOL = RalphToolName.MOVE_FILE COPY_FILE_TOOL = RalphToolName.COPY_FILE DELETE_PATH_TOOL = RalphToolName.DELETE_PATH GIT_STATUS_TOOL = RalphToolName.GIT_STATUS GIT_DIFF_TOOL = RalphToolName.GIT_DIFF GIT_LOG_TOOL = RalphToolName.GIT_LOG GIT_SHOW_TOOL = RalphToolName.GIT_SHOW EXEC_TOOL = RalphToolName.EXEC SUBMIT_ARTIFACT_TOOL = RalphToolName.SUBMIT_ARTIFACT SUBMIT_PLAN_SECTION_TOOL = RalphToolName.SUBMIT_PLAN_SECTION INSERT_PLAN_STEP_TOOL = RalphToolName.INSERT_PLAN_STEP REPLACE_PLAN_STEP_TOOL = RalphToolName.REPLACE_PLAN_STEP REMOVE_PLAN_STEP_TOOL = RalphToolName.REMOVE_PLAN_STEP FINALIZE_PLAN_TOOL = RalphToolName.FINALIZE_PLAN GET_PLAN_DRAFT_TOOL = RalphToolName.GET_PLAN_DRAFT DISCARD_PLAN_DRAFT_TOOL = RalphToolName.DISCARD_PLAN_DRAFT REPORT_PROGRESS_TOOL = RalphToolName.REPORT_PROGRESS DECLARE_COMPLETE_TOOL = RalphToolName.DECLARE_COMPLETE COORDINATE_TOOL = RalphToolName.COORDINATE READ_ENV_TOOL = RalphToolName.READ_ENV WEB_SEARCH_TOOL = RalphToolName.WEB_SEARCH VISIT_URL_TOOL = RalphToolName.VISIT_URL READ_IMAGE_TOOL = RalphToolName.READ_IMAGE READ_MEDIA_TOOL = RalphToolName.READ_MEDIA WORKSPACE_READ_TOOLS: tuple[str, ...] = ( READ_FILE_TOOL, LIST_DIRECTORY_TOOL, LIST_DIRECTORY_RECURSIVE_TOOL, DIRECTORY_TREE_TOOL, SEARCH_FILES_TOOL, READ_MULTIPLE_FILES_TOOL, STAT_PATH_TOOL, LIST_ALLOWED_ROOTS_TOOL, GREP_FILES_TOOL, ) WORKSPACE_EDIT_TOOLS: tuple[str, ...] = ( EDIT_FILE_TOOL, APPEND_FILE_TOOL, CREATE_DIRECTORY_TOOL, MOVE_FILE_TOOL, COPY_FILE_TOOL, ) WORKSPACE_DELETE_TOOLS: tuple[str, ...] = (DELETE_PATH_TOOL,) GIT_STATUS_READ_TOOLS: tuple[str, ...] = (GIT_STATUS_TOOL, GIT_LOG_TOOL, GIT_SHOW_TOOL) GIT_DIFF_READ_TOOLS: tuple[str, ...] = (GIT_DIFF_TOOL,) TRACKED_WRITE_TOOLS: tuple[str, ...] = (WRITE_FILE_TOOL,) PROCESS_EXEC_TOOLS: tuple[str, ...] = (EXEC_TOOL,) ARTIFACT_SUBMIT_TOOLS: tuple[str, ...] = (SUBMIT_ARTIFACT_TOOL, DECLARE_COMPLETE_TOOL) ARTIFACT_COORDINATE_TOOLS: tuple[str, ...] = (COORDINATE_TOOL,) ARTIFACT_TOOLS: tuple[str, ...] = (*ARTIFACT_SUBMIT_TOOLS, *ARTIFACT_COORDINATE_TOOLS) PLAN_DRAFT_READ_TOOLS: tuple[str, ...] = (GET_PLAN_DRAFT_TOOL,) PLAN_DRAFT_WRITE_TOOLS: tuple[str, ...] = ( COORDINATE_TOOL, SUBMIT_PLAN_SECTION_TOOL, INSERT_PLAN_STEP_TOOL, REPLACE_PLAN_STEP_TOOL, REMOVE_PLAN_STEP_TOOL, FINALIZE_PLAN_TOOL, DISCARD_PLAN_DRAFT_TOOL, ) PLANNING_DRAFT_TOOLS: tuple[str, ...] = (*PLAN_DRAFT_READ_TOOLS, *PLAN_DRAFT_WRITE_TOOLS) PROGRESS_TOOLS: tuple[str, ...] = (REPORT_PROGRESS_TOOL,) ENV_READ_TOOLS: tuple[str, ...] = (READ_ENV_TOOL,) WEB_SEARCH_TOOLS: tuple[str, ...] = (WEB_SEARCH_TOOL,) WEB_VISIT_TOOLS: tuple[str, ...] = (VISIT_URL_TOOL,) MEDIA_READ_TOOLS: tuple[str, ...] = (READ_IMAGE_TOOL, READ_MEDIA_TOOL) ALL_RALPH_TOOLS: tuple[str, ...] = ( *WORKSPACE_READ_TOOLS, *WORKSPACE_EDIT_TOOLS, *WORKSPACE_DELETE_TOOLS, *GIT_STATUS_READ_TOOLS, *GIT_DIFF_READ_TOOLS, *TRACKED_WRITE_TOOLS, *PROCESS_EXEC_TOOLS, *ARTIFACT_TOOLS, *PLANNING_DRAFT_TOOLS, *PROGRESS_TOOLS, *ENV_READ_TOOLS, *WEB_SEARCH_TOOLS, *WEB_VISIT_TOOLS, ) # Authoritative source: https://opencode.ai/config.json schema PermissionConfig keys # Setting each to false physically removes the tool (unlike permission which is allow-by-default). OPENCODE_NATIVE_TOOLS_TO_DISABLE: tuple[str, ...] = ( "bash", "codesearch", "edit", "glob", "grep", "list", "lsp", "patch", "question", "read", "skill", "task", "todowrite", "webfetch", "websearch", "write", ) # Authoritative source: https://developers.openai.com/codex/config-reference # apply_patch and core editing primitives are NOT disableable — documented limitation. CODEX_NATIVE_FEATURES_TO_DISABLE: tuple[tuple[str, str], ...] = ( ("features.shell_tool", "false"), ("features.multi_agent", "false"), ("features.undo", "false"), ("features.apps", "false"), ("web_search", '"disabled"'), ) def _coerce_tool_name(tool_name: str | RalphToolName) -> RalphToolName | None: if isinstance(tool_name, RalphToolName): return tool_name try: return RalphToolName(tool_name) except ValueError: return None
[docs] def prefix_tool_name(tool_name: str | RalphToolName, *, tool_name_prefix: str = "") -> str: """Return the tool name with an optional prefix applied.""" coerced = _coerce_tool_name(tool_name) if coerced is not None: return coerced.with_prefix(tool_name_prefix=tool_name_prefix) return f"{tool_name_prefix}{tool_name}" if tool_name_prefix else tool_name
[docs] def prefix_tool_names( tool_names: Sequence[str | RalphToolName], *, tool_name_prefix: str = "", ) -> list[str]: """Apply the given prefix to each tool name in the sequence.""" return [ prefix_tool_name(tool_name, tool_name_prefix=tool_name_prefix) for tool_name in tool_names ]
[docs] def claude_tool_name( tool_name: str | RalphToolName, *, server_name: str = RALPH_MCP_SERVER_NAME ) -> str: """Return the Claude MCP alias for a tool name (`mcp__<server>__<tool>`).""" # Claude exposes every MCP tool as `mcp__<server>__<tool>`. This helper is the # canonical alias builder used by prompts/tests so transport-specific naming does # not drift from the runtime CLI wiring. coerced = _coerce_tool_name(tool_name) if coerced is not None: return coerced.as_claude_alias(server_name=server_name) return f"mcp__{server_name}__{tool_name}"
[docs] def claude_tool_name_prefix(*, server_name: str = RALPH_MCP_SERVER_NAME) -> str: """Return the `mcp__<server>__` prefix string used by Claude for MCP tools.""" return f"mcp__{server_name}__"
[docs] def custom_proxy_tool_name(server_name: str, tool_name: str) -> str: """Return the stable proxy alias for a Ralph custom MCP server tool.""" return f"ralph_custom__{server_name}__{tool_name}"
[docs] def upstream_proxy_tool_name(server_name: str, tool_name: str) -> str: """Return the stable proxy alias for an agent-native upstream MCP server tool.""" return f"ralph_upstream__{server_name}__{tool_name}"
[docs] def proxied_mcp_tool_name( server_name: str, tool_name: str, *, origin: str, ) -> str: """Return the stable proxy alias for a proxied MCP server tool.""" if origin == "custom": return custom_proxy_tool_name(server_name, tool_name) return upstream_proxy_tool_name(server_name, tool_name)