Information about a tool. Lightweight adapter over chuk-tool-processor's ToolMetadata for MCP-CLI UI/display purposes.
| 117 | # Tool-related models (converted to Pydantic) |
| 118 | # ────────────────────────────────────────────────────────────────────────────── |
| 119 | class ToolInfo(BaseModel): |
| 120 | """ |
| 121 | Information about a tool. |
| 122 | |
| 123 | Lightweight adapter over chuk-tool-processor's ToolMetadata for MCP-CLI UI/display purposes. |
| 124 | """ |
| 125 | |
| 126 | name: str |
| 127 | namespace: str |
| 128 | description: str | None = None |
| 129 | parameters: dict[str, Any] | None = None |
| 130 | is_async: bool = False |
| 131 | tags: list[str] = Field(default_factory=list) |
| 132 | supports_streaming: bool = False |
| 133 | meta: ToolMeta | None = None |
| 134 | |
| 135 | model_config = {"frozen": False, "arbitrary_types_allowed": True} |
| 136 | |
| 137 | @property |
| 138 | def has_app_ui(self) -> bool: |
| 139 | """Check if this tool has an MCP Apps interactive UI.""" |
| 140 | return self.meta is not None and self.meta.ui is not None |
| 141 | |
| 142 | @property |
| 143 | def app_resource_uri(self) -> str | None: |
| 144 | """Get the UI resource URI if available.""" |
| 145 | if self.meta and self.meta.ui: |
| 146 | return self.meta.ui.resourceUri |
| 147 | return None |
| 148 | |
| 149 | @property |
| 150 | def app_view_url(self) -> str | None: |
| 151 | """Get the direct view URL if available (fallback for resourceUri).""" |
| 152 | if self.meta and self.meta.ui: |
| 153 | return self.meta.ui.viewUrl |
| 154 | return None |
| 155 | |
| 156 | @property |
| 157 | def fully_qualified_name(self) -> str: |
| 158 | """Get the fully qualified tool name (namespace.name).""" |
| 159 | return f"{self.namespace}.{self.name}" if self.namespace else self.name |
| 160 | |
| 161 | @property |
| 162 | def display_name(self) -> str: |
| 163 | """Get a user-friendly display name.""" |
| 164 | return self.name |
| 165 | |
| 166 | @property |
| 167 | def has_parameters(self) -> bool: |
| 168 | """Check if the tool has parameters defined.""" |
| 169 | return bool(self.parameters and self.parameters.get("properties")) |
| 170 | |
| 171 | @property |
| 172 | def required_parameters(self) -> list[str]: |
| 173 | """Get list of required parameter names.""" |
| 174 | if not self.parameters: |
| 175 | return [] |
| 176 | required = self.parameters.get("required", []) |
no outgoing calls