Source code for ralph.mcp.tools.bridge._tool_metadata
"""ToolMetadata dataclass."""
from __future__ import annotations
from dataclasses import dataclass
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from ralph.mcp.tools.bridge._tool_definition import ToolDefinition
[docs]
@dataclass(frozen=True)
class ToolMetadata:
"""Ralph-side metadata paired with a :class:`ToolDefinition` for registration.
Where :class:`ToolDefinition` is the public agent-facing shape, a
:class:`ToolMetadata` carries the Ralph-only annotations the bridge and
authorization layer need to *use* the tool safely:
- the capability an agent must hold before the dispatcher will
forward a call,
- whether the tool mutates workspace state (driving access-mode
enforcement), and
- whether the tool accepts multimodal (image or audio) payloads.
The dataclass is frozen and stored in the bridge's tool registry; every
invocation consults ``required_capability`` against the agent's
declared capabilities to decide whether to accept or reject the call.
Attributes:
definition: The agent-facing :class:`ToolDefinition` advertised by
``tools/list``. Carries the public name, description, and JSON
schema; :class:`ToolMetadata` adds the Ralph-side annotations.
required_capability: Name of the capability a calling agent must
hold (e.g. ``"write_files"``, ``"submit_artifact"``). The
bridge uses this to gate calls: an agent without the
capability sees ``PermissionDenied`` instead of a dispatch.
The default-deny invariant in :mod:`ralph.mcp` documents the
policy that every Ralph-managed tool must declare one.
is_mutating: ``True`` when the tool can change workspace or
artifact-store state, ``False`` for strictly read-only tools.
``None`` is treated as conservative (``True``) so an unknown
tool is assumed to mutate until the registration proves
otherwise. The bridge uses this flag together with
:func:`ralph.mcp.protocol.startup.access_mode_for_drain` to
decide whether a read-only session can still call the tool.
is_multimodal: ``True`` when the tool accepts binary content
(images, audio) alongside its text schema. The bridge surfaces
multimodal tools through a different ``callTool`` content
shape and tags them so agents can discover them via the
metadata flag.
Invariants:
- ``required_capability`` must be a non-empty capability name
recognized by :mod:`ralph.mcp.capabilities`; unknown
capabilities cause the dispatcher to reject every call.
- The combination of ``is_mutating=False`` and
``required_capability`` granting write access is allowed but
downgrades the runtime access mode on a read-only session.
- :class:`ToolMetadata` is constructed once, at registry build
time, and is then immutable for the lifetime of the bridge.
"""
definition: ToolDefinition
required_capability: str
is_mutating: bool | None = None
is_multimodal: bool = False