From 35b3af97a2f23cf27b307a9c7c9e3ae385df873f Mon Sep 17 00:00:00 2001 From: Till Tomczak Date: Fri, 7 Aug 2026 18:39:24 +0200 Subject: [PATCH] chore: make this repo self-contained MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split out of the agent repository into its own project. The two commits that introduced and reworked the extension are preserved. The extension could not build on its own: prebuild called `python ../../tools/generate_tool_defs.py`, and the 31 tool schemas lived outside the tree — in a directory that was under no version control at all. - tools/schema/*.json and tools/generate_tool_defs.py now live here. They describe browser tools, so they belong with the extension. - The generator writes TypeScript into this repo and, when the agent repo is checked out next to it, the Python tool definitions there as well. The presence check looks for agent/tools.py: checking only for the directory was useless — it is almost always true, and the generator then wrote into an arbitrary neighbouring folder (verified, then fixed). - Added .gitignore: dist/, node_modules/, and *.token — the MCP bridge token is a runtime secret. Verified: `npm run build` from a clean checkout with and without the agent repo present; tsc reports no errors. Co-Authored-By: Claude Opus 5 --- .gitignore | 13 +++ package.json | 4 +- tools/generate_tool_defs.py | 128 ++++++++++++++++++++++++ tools/schema/browser_batch.json | 37 +++++++ tools/schema/browser_click.json | 22 ++++ tools/schema/browser_computer.json | 88 ++++++++++++++++ tools/schema/browser_drag.json | 22 ++++ tools/schema/browser_execute_js.json | 17 ++++ tools/schema/browser_file_upload.json | 28 ++++++ tools/schema/browser_find.json | 21 ++++ tools/schema/browser_form_input.json | 25 +++++ tools/schema/browser_get_page_info.json | 9 ++ tools/schema/browser_get_text.json | 18 ++++ tools/schema/browser_go_back.json | 9 ++ tools/schema/browser_go_forward.json | 9 ++ tools/schema/browser_highlight.json | 25 +++++ tools/schema/browser_hover.json | 18 ++++ tools/schema/browser_key.json | 30 ++++++ tools/schema/browser_navigate.json | 21 ++++ tools/schema/browser_read_console.json | 29 ++++++ tools/schema/browser_read_network.json | 26 +++++ tools/schema/browser_read_page.json | 30 ++++++ tools/schema/browser_reload.json | 9 ++ tools/schema/browser_resize_window.json | 18 ++++ tools/schema/browser_screenshot.json | 18 ++++ tools/schema/browser_scroll.json | 31 ++++++ tools/schema/browser_select.json | 25 +++++ tools/schema/browser_tabs_close.json | 17 ++++ tools/schema/browser_tabs_create.json | 17 ++++ tools/schema/browser_tabs_list.json | 9 ++ tools/schema/browser_tabs_select.json | 17 ++++ tools/schema/browser_type.json | 17 ++++ tools/schema/browser_wait.json | 22 ++++ tools/schema/browser_zoom.json | 17 ++++ 34 files changed, 844 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 tools/generate_tool_defs.py create mode 100644 tools/schema/browser_batch.json create mode 100644 tools/schema/browser_click.json create mode 100644 tools/schema/browser_computer.json create mode 100644 tools/schema/browser_drag.json create mode 100644 tools/schema/browser_execute_js.json create mode 100644 tools/schema/browser_file_upload.json create mode 100644 tools/schema/browser_find.json create mode 100644 tools/schema/browser_form_input.json create mode 100644 tools/schema/browser_get_page_info.json create mode 100644 tools/schema/browser_get_text.json create mode 100644 tools/schema/browser_go_back.json create mode 100644 tools/schema/browser_go_forward.json create mode 100644 tools/schema/browser_highlight.json create mode 100644 tools/schema/browser_hover.json create mode 100644 tools/schema/browser_key.json create mode 100644 tools/schema/browser_navigate.json create mode 100644 tools/schema/browser_read_console.json create mode 100644 tools/schema/browser_read_network.json create mode 100644 tools/schema/browser_read_page.json create mode 100644 tools/schema/browser_reload.json create mode 100644 tools/schema/browser_resize_window.json create mode 100644 tools/schema/browser_screenshot.json create mode 100644 tools/schema/browser_scroll.json create mode 100644 tools/schema/browser_select.json create mode 100644 tools/schema/browser_tabs_close.json create mode 100644 tools/schema/browser_tabs_create.json create mode 100644 tools/schema/browser_tabs_list.json create mode 100644 tools/schema/browser_tabs_select.json create mode 100644 tools/schema/browser_type.json create mode 100644 tools/schema/browser_wait.json create mode 100644 tools/schema/browser_zoom.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6f1c68b --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +# Build-Ergebnis — wird aus src/ erzeugt +dist/ + +# Abhängigkeiten +node_modules/ + +# Laufzeit-Secrets: das MCP-Bridge-Token gehört nie ins Repo +.token +*.token + +# Python-Nebenprodukte des Schema-Generators +__pycache__/ +*.pyc diff --git a/package.json b/package.json index ff61f4d..6f3df8d 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,8 @@ "private": true, "description": "Nexus Browser Agent – MCP-fähige Chrome/Brave Extension mit Nexus-Gateway-Backend", "scripts": { - "generate": "python ../../tools/generate_tool_defs.py", - "prebuild": "python ../../tools/generate_tool_defs.py", + "generate": "python tools/generate_tool_defs.py", + "prebuild": "python tools/generate_tool_defs.py", "build": "node esbuild.config.mjs", "watch": "node esbuild.config.mjs --watch", "typecheck": "tsc --noEmit", diff --git a/tools/generate_tool_defs.py b/tools/generate_tool_defs.py new file mode 100644 index 0000000..28aa090 --- /dev/null +++ b/tools/generate_tool_defs.py @@ -0,0 +1,128 @@ +"""Generator: tools/schema/*.json → Python ToolSpecs + TypeScript types. + +Liest alle JSON-Dateien aus tools/schema/, erzeugt: +1. agent/browser_tool_defs.py — Liste von Bedrock-toolSpec-Dicts für den Broker +2. extension/src/shared/tool-schemas.generated.ts — TypeScript-Typen + Registry + +Aufruf: + python tools/generate_tool_defs.py + +Im esbuild-Step der Extension als Pre-Build verdrahtet (package.json "prebuild"). +""" +import json +import os +from pathlib import Path + +SCHEMA_DIR = Path(__file__).parent / "schema" + +#: Wurzel dieses Repos (tools/ liegt direkt darunter). +_ROOT = Path(__file__).parent.parent + +#: TypeScript-Ziel — immer vorhanden, dies ist das eigene Repo. +TS_OUTPUT = _ROOT / "src" / "shared" / "tool-schemas.generated.ts" + +#: Python-Ziel im NACHBAR-Repo (agent/). Die Schemata beschreiben Browser-Tools +#: und gehoeren damit zur Extension; der Python-Broker konsumiert nur das +#: Erzeugnis, das dort eingecheckt ist. Liegen die Repos nicht nebeneinander, +#: wird der Python-Teil uebersprungen statt abzubrechen — die Extension muss +#: allein baubar bleiben. +PY_OUTPUT = _ROOT.parent / "browser_tool_defs.py" + + +def load_schemas() -> list[dict]: + schemas = [] + for f in sorted(SCHEMA_DIR.glob("*.json")): + with open(f, encoding="utf-8") as fh: + schemas.append(json.load(fh)) + return schemas + + +def generate_python(schemas: list[dict]) -> str: + lines = [ + '"""Auto-generated browser tool definitions for the Bedrock Converse API.', + '', + 'DO NOT EDIT — generated by tools/generate_tool_defs.py from tools/schema/*.json.', + '"""', + '', + 'BROWSER_TOOL_SPECS: list[dict] = [', + ] + for s in schemas: + spec = { + "toolSpec": { + "name": s["name"], + "description": s["description"], + "inputSchema": {"json": s["inputSchema"]}, + } + } + lines.append(f" {json.dumps(spec, ensure_ascii=False)},") + lines.append("]") + lines.append("") + lines.append("# Mapping: tool name -> requires_confirmation flag") + lines.append("BROWSER_TOOL_CONFIRMATION: dict[str, bool] = {") + for s in schemas: + lines.append(f' "{s["name"]}": {str(s.get("requires_confirmation", False))},') + lines.append("}") + lines.append("") + lines.append(f"BROWSER_TOOL_NAMES: list[str] = {json.dumps([s['name'] for s in schemas])}") + lines.append("") + return "\n".join(lines) + + +def generate_typescript(schemas: list[dict]) -> str: + lines = [ + "/**", + " * Auto-generated browser tool schemas and types.", + " * DO NOT EDIT — generated by tools/generate_tool_defs.py from tools/schema/*.json.", + " */", + "", + "export interface BrowserToolSchema {", + " name: string;", + " description: string;", + " requires_confirmation: boolean;", + " inputSchema: Record;", + "}", + "", + "export const BROWSER_TOOL_SCHEMAS: BrowserToolSchema[] = [", + ] + for s in schemas: + lines.append(f" {json.dumps(s, ensure_ascii=False)},") + lines.append("];") + lines.append("") + lines.append("export const BROWSER_TOOL_NAMES = [") + for s in schemas: + lines.append(f' "{s["name"]}",') + lines.append("] as const;") + lines.append("") + lines.append("export type BrowserToolName = typeof BROWSER_TOOL_NAMES[number];") + lines.append("") + lines.append("export const REQUIRES_CONFIRMATION: Record = {") + for s in schemas: + lines.append(f' "{s["name"]}": {str(s.get("requires_confirmation", False)).lower()},') + lines.append("};") + lines.append("") + return "\n".join(lines) + + +def main(): + schemas = load_schemas() + print(f"Loaded {len(schemas)} tool schemas from {SCHEMA_DIR}") + + py_code = generate_python(schemas) + # NICHT nur auf das Verzeichnis pruefen — das existiert fast immer und der + # Generator schrieb dann in ein beliebiges Nachbarverzeichnis (gemessen). + # Der Marker macht daraus eine echte Aussage: liegt hier das Agenten-Repo? + if (PY_OUTPUT.parent / "tools.py").is_file(): + PY_OUTPUT.write_text(py_code, encoding="utf-8") + print(f"Generated Python: {PY_OUTPUT} ({len(py_code)} bytes)") + else: + print(f"Skipped Python output: {PY_OUTPUT.parent} not found " + f"(agent repo not checked out next to this one)") + + ts_code = generate_typescript(schemas) + TS_OUTPUT.parent.mkdir(parents=True, exist_ok=True) + TS_OUTPUT.write_text(ts_code, encoding="utf-8") + print(f"Generated TypeScript: {TS_OUTPUT} ({len(ts_code)} bytes)") + + +if __name__ == "__main__": + main() diff --git a/tools/schema/browser_batch.json b/tools/schema/browser_batch.json new file mode 100644 index 0000000..a488eb8 --- /dev/null +++ b/tools/schema/browser_batch.json @@ -0,0 +1,37 @@ +{ + "name": "browser_batch", + "description": "Runs several browser tools in one call, in order, returning all results. Saves one model round-trip per step — the dominant cost of form filling and navigation. Use when the whole sequence is known in advance. Do NOT use when a later step depends on what an earlier one returns.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "actions": { + "type": "array", + "description": "Steps in order: [{name, input}, ...].", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of the browser tool to run, e.g. 'browser_click', 'browser_type', 'browser_computer'. Must be one of the available browser tools, and not 'browser_batch'." + }, + "input": { + "type": "object", + "description": "Argument object for that tool — exactly what you would pass in a single call. Omit or use {} for tools without arguments." + } + }, + "required": [ + "name" + ] + } + }, + "stopOnError": { + "type": "boolean", + "description": "Stop at the first failing step (default true)." + } + }, + "required": [ + "actions" + ] + } +} diff --git a/tools/schema/browser_click.json b/tools/schema/browser_click.json new file mode 100644 index 0000000..b25e46b --- /dev/null +++ b/tools/schema/browser_click.json @@ -0,0 +1,22 @@ +{ + "name": "browser_click", + "description": "Click an element addressed by ref_id or CSS selector.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "selector": { + "type": "string", + "description": "CSS selector of the element to click, e.g. 'button[type=submit]' or '#login'." + }, + "ref_id": { + "type": "string", + "description": "Stable ref_id from browser_read_page or browser_find." + }, + "trusted": { + "type": "boolean", + "description": "Force real CDP events for this one call even if the extension is configured for synthetic…" + } + } + } +} diff --git a/tools/schema/browser_computer.json b/tools/schema/browser_computer.json new file mode 100644 index 0000000..09536da --- /dev/null +++ b/tools/schema/browser_computer.json @@ -0,0 +1,88 @@ +{ + "name": "browser_computer", + "description": "Operates mouse and keyboard at pixel coordinates via CDP (isTrusted events). Workflow: action='screenshot' first, read coordinates off that image, then act. Use only for canvas, maps, drag&drop and anything that ignores selectors — for normal HTML browser_find + browser_click are cheaper and more reliable.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "action": { + "type": "string", + "enum": [ + "screenshot", + "mouse_move", + "left_click", + "right_click", + "middle_click", + "double_click", + "triple_click", + "left_click_drag", + "left_mouse_down", + "left_mouse_up", + "scroll", + "type", + "key", + "hold_key", + "wait", + "cursor_position" + ], + "description": "What to do. Pixel coordinates come from a screenshot." + }, + "coordinate": { + "type": "array", + "items": { + "type": "integer" + }, + "minItems": 2, + "maxItems": 2, + "description": "[x, y] in screenshot pixels." + }, + "start_coordinate": { + "type": "array", + "items": { + "type": "integer" + }, + "minItems": 2, + "maxItems": 2, + "description": "[x, y] where a drag begins." + }, + "text": { + "type": "string", + "description": "Text to type, or key name for key presses (e.g. 'Return', 'ctrl+a')." + }, + "scroll_direction": { + "type": "string", + "enum": [ + "up", + "down", + "left", + "right" + ], + "description": "up | down | left | right" + }, + "scroll_amount": { + "type": "integer", + "description": "Number of wheel clicks." + }, + "duration": { + "type": "number", + "description": "Seconds to hold or wait." + }, + "modifiers": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "ctrl", + "alt", + "shift", + "meta" + ] + }, + "description": "Held modifier keys, e.g. ['ctrl','shift']." + } + }, + "required": [ + "action" + ] + } +} diff --git a/tools/schema/browser_drag.json b/tools/schema/browser_drag.json new file mode 100644 index 0000000..a5d174a --- /dev/null +++ b/tools/schema/browser_drag.json @@ -0,0 +1,22 @@ +{ + "name": "browser_drag", + "description": "Drag one element onto another with the real mouse: press the left button over the centre of the source, move to the centre of the target in several intermediate steps, and release there.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "sourceSelector": { + "type": "string", + "description": "CSS selector of the element to pick up. The drag starts at its centre." + }, + "targetSelector": { + "type": "string", + "description": "CSS selector of the drop target. The button is released at its centre." + } + }, + "required": [ + "sourceSelector", + "targetSelector" + ] + } +} diff --git a/tools/schema/browser_execute_js.json b/tools/schema/browser_execute_js.json new file mode 100644 index 0000000..8cc6b1d --- /dev/null +++ b/tools/schema/browser_execute_js.json @@ -0,0 +1,17 @@ +{ + "name": "browser_execute_js", + "description": "Run JavaScript in the page's MAIN world and return the result. Same realm as the site's own scripts, so you can reach the application's window globals — frameworks, state stores, config objects, jQuery, data layers — which an isolated content script cannot see.", + "requires_confirmation": true, + "inputSchema": { + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "JavaScript source to evaluate in the page. The last expression's value is returned, e.g." + } + }, + "required": [ + "code" + ] + } +} diff --git a/tools/schema/browser_file_upload.json b/tools/schema/browser_file_upload.json new file mode 100644 index 0000000..b36868a --- /dev/null +++ b/tools/schema/browser_file_upload.json @@ -0,0 +1,28 @@ +{ + "name": "browser_file_upload", + "description": "Attaches local files to an via CDP, as if picked in the OS dialog, and fires a change event. Paths must be absolute on the machine running the browser. Never try to open the native file dialog by clicking — it cannot be operated.", + "requires_confirmation": true, + "inputSchema": { + "type": "object", + "properties": { + "selector": { + "type": "string", + "description": "CSS selector of the file input." + }, + "ref_id": { + "type": "string", + "description": "ref_id of the file input. Preferred." + }, + "files": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Absolute paths on the browser machine." + } + }, + "required": [ + "files" + ] + } +} diff --git a/tools/schema/browser_find.json b/tools/schema/browser_find.json new file mode 100644 index 0000000..87ea8a6 --- /dev/null +++ b/tools/schema/browser_find.json @@ -0,0 +1,21 @@ +{ + "name": "browser_find", + "description": "Finds elements by plain-language description instead of a CSS selector. Matches label text, accessible name, placeholder, aria-label, title, role and type, ranked by fit. Returns ref_id (for browser_click/type/select), role, text, tag and coordinates. Start here instead of reading the whole page.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "What you are looking for, in plain language." + }, + "limit": { + "type": "integer", + "description": "Maximum number of candidates (default 5)." + } + }, + "required": [ + "query" + ] + } +} diff --git a/tools/schema/browser_form_input.json b/tools/schema/browser_form_input.json new file mode 100644 index 0000000..402d50b --- /dev/null +++ b/tools/schema/browser_form_input.json @@ -0,0 +1,25 @@ +{ + "name": "browser_form_input", + "description": "Fill a form field: handles input, textarea, select, checkbox, radio. For select elements, matches by value or visible text.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "selector": { + "type": "string", + "description": "CSS selector of the form element" + }, + "ref_id": { + "type": "string", + "description": "Stable ref_id from read_page" + }, + "value": { + "type": "string", + "description": "Value to set (for select: option value or text; for checkbox/radio: 'true'/'false')" + } + }, + "required": [ + "value" + ] + } +} diff --git a/tools/schema/browser_get_page_info.json b/tools/schema/browser_get_page_info.json new file mode 100644 index 0000000..d85b8b9 --- /dev/null +++ b/tools/schema/browser_get_page_info.json @@ -0,0 +1,9 @@ +{ + "name": "browser_get_page_info", + "description": "Get current page URL, title, viewport dimensions, scroll position, and document height.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": {} + } +} diff --git a/tools/schema/browser_get_text.json b/tools/schema/browser_get_text.json new file mode 100644 index 0000000..f3bced7 --- /dev/null +++ b/tools/schema/browser_get_text.json @@ -0,0 +1,18 @@ +{ + "name": "browser_get_text", + "description": "Get the text content of the page or a specific element (Readability-style extraction).", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "selector": { + "type": "string", + "description": "CSS selector (default: body)" + }, + "maxLength": { + "type": "number", + "description": "Max characters to return (default 8000)" + } + } + } +} diff --git a/tools/schema/browser_go_back.json b/tools/schema/browser_go_back.json new file mode 100644 index 0000000..61dd72d --- /dev/null +++ b/tools/schema/browser_go_back.json @@ -0,0 +1,9 @@ +{ + "name": "browser_go_back", + "description": "Navigate back in the active tab's history.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": {} + } +} diff --git a/tools/schema/browser_go_forward.json b/tools/schema/browser_go_forward.json new file mode 100644 index 0000000..2955729 --- /dev/null +++ b/tools/schema/browser_go_forward.json @@ -0,0 +1,9 @@ +{ + "name": "browser_go_forward", + "description": "Navigate forward in the active tab's history.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": {} + } +} diff --git a/tools/schema/browser_highlight.json b/tools/schema/browser_highlight.json new file mode 100644 index 0000000..9f1de1a --- /dev/null +++ b/tools/schema/browser_highlight.json @@ -0,0 +1,25 @@ +{ + "name": "browser_highlight", + "description": "Visually highlight an element on the page (for debugging/demonstration).", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "selector": { + "type": "string", + "description": "CSS selector of the element to highlight" + }, + "color": { + "type": "string", + "description": "Outline color (default '#ff6b35')" + }, + "duration": { + "type": "number", + "description": "Highlight duration in ms (default 3000)" + } + }, + "required": [ + "selector" + ] + } +} diff --git a/tools/schema/browser_hover.json b/tools/schema/browser_hover.json new file mode 100644 index 0000000..c81a869 --- /dev/null +++ b/tools/schema/browser_hover.json @@ -0,0 +1,18 @@ +{ + "name": "browser_hover", + "description": "Move the real mouse pointer onto an element and leave it there.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "selector": { + "type": "string", + "description": "CSS selector of the element to hover, e.g. 'nav .menu-item:first-child'." + }, + "ref_id": { + "type": "string", + "description": "Stable ref_id from browser_read_page or browser_find." + } + } + } +} diff --git a/tools/schema/browser_key.json b/tools/schema/browser_key.json new file mode 100644 index 0000000..d265f6c --- /dev/null +++ b/tools/schema/browser_key.json @@ -0,0 +1,30 @@ +{ + "name": "browser_key", + "description": "Press a single key, optionally with modifiers, as a real keystroke through the DevTools Protocol — trusted keydown/keyup with the correct key code, so keyboard shortcuts, form submission via Enter and focus traversal via Tab all behave as they would for a human.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "key": { + "type": "string", + "description": "Key name in DOM KeyboardEvent.key notation, e.g." + }, + "modifiers": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "ctrl", + "alt", + "shift", + "meta" + ] + }, + "description": "Modifier keys held while the key is pressed, e.g." + } + }, + "required": [ + "key" + ] + } +} diff --git a/tools/schema/browser_navigate.json b/tools/schema/browser_navigate.json new file mode 100644 index 0000000..ec90a83 --- /dev/null +++ b/tools/schema/browser_navigate.json @@ -0,0 +1,21 @@ +{ + "name": "browser_navigate", + "description": "Navigate the active tab to a URL, or open a URL in a new tab.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "url": { + "type": "string", + "description": "Target URL to navigate to" + }, + "newTab": { + "type": "boolean", + "description": "If true, open in a new tab instead of the active one" + } + }, + "required": [ + "url" + ] + } +} diff --git a/tools/schema/browser_read_console.json b/tools/schema/browser_read_console.json new file mode 100644 index 0000000..200d7f5 --- /dev/null +++ b/tools/schema/browser_read_console.json @@ -0,0 +1,29 @@ +{ + "name": "browser_read_console", + "description": "Read captured console logs (log, warn, error, info) from the active page.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "clear": { + "type": "boolean", + "description": "Clear the log buffer after reading (default false)" + }, + "level": { + "type": "string", + "enum": [ + "all", + "log", + "warn", + "error", + "info" + ], + "description": "Filter by log level (default 'all')" + }, + "limit": { + "type": "number", + "description": "Max entries to return (default 50)" + } + } + } +} diff --git a/tools/schema/browser_read_network.json b/tools/schema/browser_read_network.json new file mode 100644 index 0000000..02a07db --- /dev/null +++ b/tools/schema/browser_read_network.json @@ -0,0 +1,26 @@ +{ + "name": "browser_read_network", + "description": "Read the network requests the active page has made. Captured live through the DevTools Protocol — the same data the Network tab of DevTools shows: URL, HTTP method, status code, resource type, timing and size.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "filter": { + "type": "string", + "description": "Only return requests whose URL contains this substring, e.g. '/api/' or 'graphql'." + }, + "method": { + "type": "string", + "description": "Only return requests with this HTTP method, e.g. 'GET', 'POST', 'PUT', 'DELETE'." + }, + "limit": { + "type": "integer", + "description": "Maximum number of entries to return, most recent first (default 50)." + }, + "includeBody": { + "type": "boolean", + "description": "Include the response body of matching requests (default false)." + } + } + } +} diff --git a/tools/schema/browser_read_page.json b/tools/schema/browser_read_page.json new file mode 100644 index 0000000..9a781a2 --- /dev/null +++ b/tools/schema/browser_read_page.json @@ -0,0 +1,30 @@ +{ + "name": "browser_read_page", + "description": "Reads the accessibility tree of the page: a compact view of what is on screen and interactive. Cheaper and more precise than a screenshot for normal HTML. Every interactive node carries a ref_id — pass it to browser_click/type/select instead of guessing a selector. Fields report label, role and editable.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "viewportOnly": { + "type": "boolean", + "description": "Only what is currently visible (default true)." + }, + "maxDepth": { + "type": "number", + "description": "Maximum nesting depth." + }, + "maxTokens": { + "type": "number", + "description": "Budget; the tree is cut off when reached." + }, + "includeHidden": { + "type": "boolean", + "description": "Include invisible elements (default false)." + }, + "selector": { + "type": "string", + "description": "Read only this subtree, e.g. a compose form." + } + } + } +} diff --git a/tools/schema/browser_reload.json b/tools/schema/browser_reload.json new file mode 100644 index 0000000..7b0adc2 --- /dev/null +++ b/tools/schema/browser_reload.json @@ -0,0 +1,9 @@ +{ + "name": "browser_reload", + "description": "Reload the current page in the active tab.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": {} + } +} diff --git a/tools/schema/browser_resize_window.json b/tools/schema/browser_resize_window.json new file mode 100644 index 0000000..db4efa1 --- /dev/null +++ b/tools/schema/browser_resize_window.json @@ -0,0 +1,18 @@ +{ + "name": "browser_resize_window", + "description": "Resize the browser window holding the active tab. Changes the viewport, so every pixel coordinate from earlier screenshots becomes invalid — take a fresh screenshot afterwards.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "width": { + "type": "integer", + "description": "Window width in pixels, e.g. 1280 for a desktop layout or 390 to force a mobile layout." + }, + "height": { + "type": "integer", + "description": "Window height in pixels, e.g. 900. Omit to keep the current height." + } + } + } +} diff --git a/tools/schema/browser_screenshot.json b/tools/schema/browser_screenshot.json new file mode 100644 index 0000000..884dee1 --- /dev/null +++ b/tools/schema/browser_screenshot.json @@ -0,0 +1,18 @@ +{ + "name": "browser_screenshot", + "description": "Captures a JPEG of the page as an image you can look at. Read pixel coordinates off it for browser_computer; origin (0,0) is top-left, x grows right, y grows down. Viewport only by default — exactly the area browser_computer can reach. Expensive in tokens: prefer browser_read_page for normal HTML.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "fullPage": { + "type": "boolean", + "description": "Whole page instead of the viewport. Coordinates then no longer match browser_computer." + }, + "maxWidth": { + "type": "integer", + "description": "Scale down to this width in pixels." + } + } + } +} diff --git a/tools/schema/browser_scroll.json b/tools/schema/browser_scroll.json new file mode 100644 index 0000000..b23842f --- /dev/null +++ b/tools/schema/browser_scroll.json @@ -0,0 +1,31 @@ +{ + "name": "browser_scroll", + "description": "Scroll the page, or a specific scrollable element, by a pixel amount.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "direction": { + "type": "string", + "enum": [ + "up", + "down", + "left", + "right" + ], + "description": "Scroll direction." + }, + "amount": { + "type": "number", + "description": "Pixels to scroll (default 500)." + }, + "selector": { + "type": "string", + "description": "CSS selector of the scrollable element (default: the page itself)." + } + }, + "required": [ + "direction" + ] + } +} diff --git a/tools/schema/browser_select.json b/tools/schema/browser_select.json new file mode 100644 index 0000000..7a9fcd8 --- /dev/null +++ b/tools/schema/browser_select.json @@ -0,0 +1,25 @@ +{ + "name": "browser_select", + "description": "Select an option in a element" + }, + "ref_id": { + "type": "string", + "description": "Stable ref_id from read_page" + }, + "value": { + "type": "string", + "description": "Option value or visible text to select" + } + }, + "required": [ + "value" + ] + } +} diff --git a/tools/schema/browser_tabs_close.json b/tools/schema/browser_tabs_close.json new file mode 100644 index 0000000..53c56cb --- /dev/null +++ b/tools/schema/browser_tabs_close.json @@ -0,0 +1,17 @@ +{ + "name": "browser_tabs_close", + "description": "Close a tab by its ID. Get IDs from browser_tabs_list. Use it to tidy up tabs you opened while working; closing a tab does not affect the pages themselves.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "tabId": { + "type": "number", + "description": "The ID of the tab to close, as reported by browser_tabs_list." + } + }, + "required": [ + "tabId" + ] + } +} diff --git a/tools/schema/browser_tabs_create.json b/tools/schema/browser_tabs_create.json new file mode 100644 index 0000000..ee5f9a7 --- /dev/null +++ b/tools/schema/browser_tabs_create.json @@ -0,0 +1,17 @@ +{ + "name": "browser_tabs_create", + "description": "Open a new tab with the given URL.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "url": { + "type": "string", + "description": "URL to open in the new tab" + } + }, + "required": [ + "url" + ] + } +} diff --git a/tools/schema/browser_tabs_list.json b/tools/schema/browser_tabs_list.json new file mode 100644 index 0000000..3bbb99c --- /dev/null +++ b/tools/schema/browser_tabs_list.json @@ -0,0 +1,9 @@ +{ + "name": "browser_tabs_list", + "description": "List all open browser tabs with their IDs, titles, URLs, and active state.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": {} + } +} diff --git a/tools/schema/browser_tabs_select.json b/tools/schema/browser_tabs_select.json new file mode 100644 index 0000000..fe53440 --- /dev/null +++ b/tools/schema/browser_tabs_select.json @@ -0,0 +1,17 @@ +{ + "name": "browser_tabs_select", + "description": "Switch to a tab by its ID (makes it the active tab).", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "tabId": { + "type": "number", + "description": "The tab ID to activate" + } + }, + "required": [ + "tabId" + ] + } +} diff --git a/tools/schema/browser_type.json b/tools/schema/browser_type.json new file mode 100644 index 0000000..be282d6 --- /dev/null +++ b/tools/schema/browser_type.json @@ -0,0 +1,17 @@ +{ + "name": "browser_type", + "description": "Types text into an input, textarea or contenteditable as real CDP keystrokes, so masks, validation and framework state react as for a human. A target is REQUIRED (ref_id or selector) — without one the text would land in whatever happens to be focused, which in forms is usually the wrong field. The result reports typed_into (where the text actually went) and sets target_mismatch=true if that is not the element you asked for.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "selector": { "type": "string", "description": "CSS selector of the field." }, + "ref_id": { "type": "string", "description": "ref_id from browser_find or browser_read_page. Preferred; wins over selector." }, + "text": { "type": "string", "description": "Text to type, character by character." }, + "clear": { "type": "boolean", "description": "Clear the field first (default true)." }, + "submit": { "type": "boolean", "description": "Press Enter afterwards (default false). Submits most forms." }, + "use_focus": { "type": "boolean", "description": "Type into the focused element without a target. Only when you set that focus yourself and mean it." } + }, + "required": ["text"] + } +} diff --git a/tools/schema/browser_wait.json b/tools/schema/browser_wait.json new file mode 100644 index 0000000..88d71a5 --- /dev/null +++ b/tools/schema/browser_wait.json @@ -0,0 +1,22 @@ +{ + "name": "browser_wait", + "description": "Wait for an element to appear or a timeout to elapse.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "selector": { + "type": "string", + "description": "CSS selector to wait for (if omitted, just waits for timeout)" + }, + "timeout": { + "type": "number", + "description": "Max milliseconds to wait (default 5000)" + }, + "visible": { + "type": "boolean", + "description": "Wait until element is visible, not just present (default true)" + } + } + } +} diff --git a/tools/schema/browser_zoom.json b/tools/schema/browser_zoom.json new file mode 100644 index 0000000..2251f49 --- /dev/null +++ b/tools/schema/browser_zoom.json @@ -0,0 +1,17 @@ +{ + "name": "browser_zoom", + "description": "Set the zoom level of the active tab.", + "requires_confirmation": false, + "inputSchema": { + "type": "object", + "properties": { + "level": { + "type": "number", + "description": "Zoom factor (1.0 = 100%, 1.5 = 150%, 0.5 = 50%)" + } + }, + "required": [ + "level" + ] + } +}