mirror of
https://github.com/hanzoai/python-sdk.git
synced 2026-10-26 11:49:36 +00:00
hanzo-tools-browser 0.5.7: fix CdpTool — implement register() (0.5.6 was DOA)
0.5.6 shipped CdpTool inheriting BaseTool but missing the required `register()` abstract method, so any host that registered the tool crashed with `TypeError: Can't instantiate abstract class CdpTool`. The browser package never reached MCP startup, taking the whole hanzo MCP server with it. This commit adds CdpTool.register() with the cdp-specific param surface (action / method / params / tab_id / target_browser / client_id / timeout) matching the BrowserTool registration pattern. Yanking 0.5.6 from PyPI alongside this release; 0.5.7 is the canonical 0.5.x for the three-tool surface.
This commit is contained in:
@@ -21,15 +21,25 @@ Example::
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from typing import Any, Optional, Union
|
||||
from typing import Any, Annotated, Literal, Optional, Union
|
||||
|
||||
from pydantic import Field
|
||||
from mcp.server import FastMCP
|
||||
|
||||
from hanzo_tools.core import BaseTool
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
CdpAction = Annotated[
|
||||
Literal["send", "tabs", "status", "list_browsers", "claim_browser", "release_browser"],
|
||||
Field(description="CDP action"),
|
||||
]
|
||||
|
||||
|
||||
async def _dispatch_raw(
|
||||
method: str,
|
||||
params: Optional[dict] = None,
|
||||
@@ -160,6 +170,49 @@ Use `playwright` for headless Playwright automation.
|
||||
async def call(self, ctx, action: str = "send", **kwargs) -> dict[str, Any]:
|
||||
return await self.execute(action=action, **kwargs)
|
||||
|
||||
def register(self, mcp_server: FastMCP) -> None:
|
||||
"""Register the cdp tool with an MCP server."""
|
||||
tool_instance = self
|
||||
|
||||
@mcp_server.tool(name=self.name, description=self.description)
|
||||
async def cdp(
|
||||
action: CdpAction = "send",
|
||||
method: Annotated[
|
||||
Optional[str],
|
||||
Field(description="CDP method name (e.g. 'Page.navigate', 'Runtime.evaluate')"),
|
||||
] = None,
|
||||
params: Annotated[
|
||||
Optional[dict],
|
||||
Field(description="CDP method params"),
|
||||
] = None,
|
||||
tab_id: Annotated[
|
||||
Optional[Union[str, int]],
|
||||
Field(description="Target tab id (string or int)"),
|
||||
] = None,
|
||||
target_browser: Annotated[
|
||||
Optional[str],
|
||||
Field(description="Provider filter: firefox|chrome|safari|edge"),
|
||||
] = None,
|
||||
client_id: Annotated[
|
||||
Optional[str],
|
||||
Field(description="Specific extension client id"),
|
||||
] = None,
|
||||
timeout: Annotated[
|
||||
Optional[float],
|
||||
Field(description="Per-call timeout (seconds)"),
|
||||
] = None,
|
||||
) -> str:
|
||||
result = await tool_instance.execute(
|
||||
action=action,
|
||||
method=method,
|
||||
params=params,
|
||||
tab_id=tab_id,
|
||||
target_browser=target_browser,
|
||||
client_id=client_id,
|
||||
timeout=timeout,
|
||||
)
|
||||
return json.dumps(result, indent=2, default=str)
|
||||
|
||||
async def execute(
|
||||
self,
|
||||
action: str = "send",
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "hanzo-tools-browser"
|
||||
version = "0.5.6"
|
||||
version = "0.5.7"
|
||||
description = "Browser automation tools with ZAP-native extension routing — Python MCP hosts the ZAP server on an OS-assigned port and advertises via mDNS (HIP-0069). No node bridge, no port pool, no lockfile."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
|
||||
Reference in New Issue
Block a user