Metadata-Version: 2.4
Name: rf-mcp
Version: 0.34.0.dev4
Summary: Robot Framework MCP Server - Natural Language Test Automation Bridge
Project-URL: Homepage, https://github.com/manykarim/rf-mcp
Project-URL: Repository, https://github.com/manykarim/rf-mcp
Project-URL: Bug Tracker, https://github.com/manykarim/rf-mcp/issues
Project-URL: Documentation, https://github.com/manykarim/rf-mcp#readme
Author: Many Kasiriha
License: Apache-2.0
License-File: LICENSE
Requires-Python: >=3.10
Requires-Dist: beautifulsoup4>=4.11.0
Requires-Dist: fastmcp>=3.0
Requires-Dist: lxml>=4.9.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: python-dotenv>=1.0.1
Requires-Dist: pyyaml>=6.0.0
Requires-Dist: robotframework>=7.0
Requires-Dist: tomlkit>=0.12.0
Provides-Extra: all
Requires-Dist: django<5.0,>=4.2; extra == 'all'
Requires-Dist: model2vec>=0.4.0; extra == 'all'
Requires-Dist: robotframework-appiumlibrary; extra == 'all'
Requires-Dist: robotframework-browser; extra == 'all'
Requires-Dist: robotframework-databaselibrary; extra == 'all'
Requires-Dist: robotframework-requests; extra == 'all'
Requires-Dist: robotframework-seleniumlibrary; extra == 'all'
Requires-Dist: sqlite-vec>=0.1.6; extra == 'all'
Requires-Dist: tiktoken>=0.7.0; extra == 'all'
Requires-Dist: uvicorn[standard]>=0.24; extra == 'all'
Provides-Extra: api
Requires-Dist: robotframework-requests; extra == 'api'
Provides-Extra: database
Requires-Dist: robotframework-databaselibrary; extra == 'database'
Provides-Extra: desktop
Requires-Dist: platynui-cli==0.13.0.dev2; (python_version >= '3.12') and extra == 'desktop'
Requires-Dist: robotframework-platynui==0.13.0.dev2; (python_version >= '3.12') and extra == 'desktop'
Provides-Extra: frontend
Requires-Dist: django<5.0,>=4.2; extra == 'frontend'
Requires-Dist: uvicorn[standard]>=0.24; extra == 'frontend'
Provides-Extra: memory
Requires-Dist: model2vec>=0.4.0; extra == 'memory'
Requires-Dist: sqlite-vec>=0.1.6; extra == 'memory'
Provides-Extra: mobile
Requires-Dist: robotframework-appiumlibrary; extra == 'mobile'
Provides-Extra: semantic
Requires-Dist: scipy>=1.10.0; extra == 'semantic'
Requires-Dist: sentence-transformers>=2.2.0; extra == 'semantic'
Provides-Extra: slim
Provides-Extra: tokens
Requires-Dist: tiktoken>=0.7.0; extra == 'tokens'
Provides-Extra: web
Requires-Dist: robotframework-browser; extra == 'web'
Requires-Dist: robotframework-seleniumlibrary; extra == 'web'
Description-Content-Type: text/markdown

# 🤖 RobotMCP - AI-Powered Test Automation Bridge

[![Python](https://img.shields.io/badge/python-3.10+-blue.svg)](https://python.org)
[![Robot Framework](https://img.shields.io/badge/robot%20framework-7.0+-green.svg)](https://robotframework.org)
[![FastMCP](https://img.shields.io/badge/fastmcp-3.0+-orange.svg)](https://github.com/jlowin/fastmcp)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)

**Plain English in, real Robot Framework tests out — with an AI agent doing the typing.**

RobotMCP (`rf-mcp`) is a Model Context Protocol (MCP) server that hands your coding
agent the keys to Robot Framework. The agent discovers keywords, runs steps *live*
against Browser, Selenium, Appium, Requests, a database, or the desktop, sees what
actually happens, and — once the steps pass — writes you a clean `.robot` suite.
No guessed locators, no hallucinated keywords, no "works on my machine". Built on
Robot Framework: open source, and always evolving.

> **New to rf-mcp?** Jump to **[Getting Started](docs/GETTING_STARTED.md)**. Want the
> full picture? See the **[MCP tool reference](docs/MCP_TOOLS.md)**,
> **[configuration](docs/CONFIGURATION.md)**, and **[worked examples](docs/EXAMPLES.md)**.

**📺 Video Tutorial**

[![RobotMCP Tutorial](https://img.youtube.com/vi/CBXGEn8jRtU/0.jpg)](https://www.youtube.com/watch?v=CBXGEn8jRtU)

**Intro**

https://github.com/user-attachments/assets/ad89064f-cab3-4ae6-a4c4-5e8c241301a1

---

## ✨ Quick Start

Three commands and a sentence. That's the whole setup.

### 1️⃣ Install it as a tool

```bash
# Everything (Browser, Selenium, Appium, Requests, Database)
uv tool install "rf-mcp[all]"

# ...or just what you need — API testing is pure Python, nothing else to do:
uv tool install "rf-mcp[api]"
```

This puts a `robotmcp` command on your PATH. Extras decide which test libraries come
along — see the [extras table](#-install-as-a-tool--wire-it-into-your-coding-agent).

### 2️⃣ Wire it into your coding agent

```bash
robotmcp init            # detects libraries, prints the MCP config to paste
robotmcp install         # registers rf-mcp into the agents it finds
```

`robotmcp install` writes the right MCP config for **Claude Code, Codex, GitHub
Copilot, opencode, Gemini CLI, Kilo Code, goose, and Cursor** — each in its own
format, without touching your other servers. Prefer to do it by hand? Every agent
accepts:

```json
{ "mcpServers": { "robotmcp": { "command": "robotmcp" } } }
```

<details>
<summary>Legacy / manual config (running from a checkout, HTTP transport)</summary>

```json
{
  "servers": {
    "robotmcp": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "-m", "robotmcp.server"],
      "env": { "UV_COMPILE_BYTECODE": "1" }
    }
  }
}
```

> `UV_COMPILE_BYTECODE=1` precompiles the dependency tree at install time. Without
> it, the **first** server launch after an install/upgrade pays several seconds of
> `.pyc` compilation before the MCP handshake completes (some clients time out and
> show the server as unavailable). It is a one-time, install-time cost.

#### HTTP

Start the MCP server with HTTP transport:

```bash
uv run -m robotmcp.server --transport http --host 127.0.0.1 --port 8000
```

Then configure your AI agent:

```json
{
  "servers": {
    "robotmcp": {
      "type": "http",
      "url": "http://localhost:8000/mcp"
    }
  }
}
```

#### Claude Code

```bash
claude mcp add rf-mcp -- uvx rf-mcp
```

</details>

### 3️⃣ Start testing — just ask

```
Use #robotmcp to create a TestSuite and execute it step wise.
Create a test for https://www.saucedemo.com/ that:
- Logs in to https://www.saucedemo.com/ with valid credentials
- Adds two items to cart
- Completes checkout process
- Verifies success message

Use Selenium Library.
Execute the test suite stepwise and build the final version afterwards.
```

**That's it.** rf-mcp walks the agent through discovery, live execution, and suite
generation — you just describe the test.

---

## 📚 Documentation

| Guide | What's inside |
|-------|---------------|
| **[Getting Started](docs/GETTING_STARTED.md)** | Install, wire into your agent, run your first test |
| **[MCP Tool Reference](docs/MCP_TOOLS.md)** | Every tool rf-mcp exposes to the agent — parameters, returns, when to reach for it |
| **[Configuration](docs/CONFIGURATION.md)** | Every `ROBOTMCP_*` environment variable and CLI flag |
| **[Examples](docs/EXAMPLES.md)** | Copy-pasteable web / API / mobile / desktop / BDD / data-driven walkthroughs |
| **[Library Plugins](docs/library-plugin-authoring.md)** | Teach rf-mcp about your own Robot Framework libraries |
| **[Instruction Templates](docs/INSTRUCTION_TEMPLATES_GUIDE.md)** | Steer the agent's behavior per project |

---

## 🛠️ Installation & Setup

https://github.com/user-attachments/assets/8448cb70-6fb3-4f04-9742-a8a8453a9c7f

### Prerequisites

- Python 3.10+
- Robot Framework 7.0+
- FastMCP 2.8+ (compatible with both 2.x and 3.x)

`rf-mcp` comes with minimal dependencies by default. To use specific libraries (e.g., Browser, Selenium, Appium), install the corresponding extras or libraries separately.

### Method 1: UV Installation (Recommended)

```bash
# Install with uv pip wrapper
uv venv   # create a virtual environment
uv pip install rf-mcp

# Feature bundles (install what you need)
uv pip install rf-mcp[web]       # Browser Library + SeleniumLibrary
uv pip install rf-mcp[mobile]    # AppiumLibrary
uv pip install rf-mcp[api]       # RequestsLibrary
uv pip install rf-mcp[database]  # DatabaseLibrary
uv pip install --pre rf-mcp[desktop]  # PlatynUI new-core (Rust) native desktop — Python 3.12+, prerelease
uv pip install rf-mcp[frontend]  # Django-based web frontend dashboard
uv pip install rf-mcp[memory]    # Persistent semantic memory (sqlite-vec + model2vec)
uv pip install rf-mcp[semantic]  # Sentence-transformers for find_keywords embedding ranking
uv pip install rf-mcp[all]       # All optional Robot Framework libraries (desktop is separate — prerelease/3.12+)

# Alternatively, add to an existing uv project
uv init
# Add rf-mcp to project dependencies and sync
uv add rf-mcp[all]
uv sync

# Browser Library still needs Playwright browsers
uv run rfbrowser init
```

### Method 2 PyPI Installation

```bash
# Install RobotMCP core (minimal dependencies)
pip install rf-mcp

# Feature bundles (install what you need)
pip install rf-mcp[web]       # Browser Library + SeleniumLibrary
pip install rf-mcp[mobile]    # AppiumLibrary
pip install rf-mcp[api]       # RequestsLibrary
pip install rf-mcp[database]  # DatabaseLibrary
pip install rf-mcp[frontend]  # Django-based web frontend dashboard
pip install rf-mcp[memory]    # Persistent semantic memory (sqlite-vec + model2vec)
pip install rf-mcp[semantic]  # Sentence-transformers for find_keywords embedding ranking
pip install rf-mcp[all]       # All optional Robot Framework libraries

# Browser Library still needs Playwright browsers
rfbrowser init
# or
python -m Browser.entry install
```

Prefer installing individual Robot Framework libraries instead?
Just install `rf-mcp` and add your desired libraries manually.

### Method 3: Development Installation

```bash
# Clone repository
git clone https://github.com/manykarim/rf-mcp.git
cd rf-mcp

# Install with uv (recommended)
uv sync
# Include optional extras & dev tooling
uv sync --all-extras --dev

# Or with pip
pip install -e .
```

### Method 4: Docker Installation

RobotMCP provides pre-built Docker images for both headless and VNC-enabled environments.

#### Headless Image (Recommended for CI/CD)

```bash
# Pull from GitHub Container Registry
docker pull ghcr.io/manykarim/rf-mcp:latest

# Run with HTTP transport and frontend
docker run -p 8000:8000 -p 8001:8001 ghcr.io/manykarim/rf-mcp:latest

# Or run interactively with STDIO
docker run -it --rm ghcr.io/manykarim/rf-mcp:latest uv run robotmcp
```

**Included browsers:** Chromium, Firefox ESR, Playwright browsers (Chromium, Firefox, WebKit)

#### VNC Image (For Visual Debugging)

The VNC image includes a full X11 desktop accessible via VNC or noVNC web interface:

```bash
# Pull VNC image
docker pull ghcr.io/manykarim/rf-mcp-vnc:latest

# Run with all ports exposed
docker run -p 8000:8000 -p 8001:8001 -p 5900:5900 -p 6080:6080 ghcr.io/manykarim/rf-mcp-vnc:latest
```

**Access points:**
| Port | Service |
|------|---------|
| 8000 | MCP HTTP transport |
| 8001 | Frontend dashboard |
| 5900 | VNC (use any VNC client) |
| 6080 | noVNC web interface (http://localhost:6080/vnc.html) |

#### Building Docker Images Locally

```bash
# Build headless image
docker build -f docker/Dockerfile -t robotmcp .

# Build VNC image
docker build -f docker/Dockerfile.vnc -t robotmcp-vnc .
```

#### Using Docker with VS Code MCP

**STDIO mode:**
```json
{
  "servers": {
    "robotmcp": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "ghcr.io/manykarim/rf-mcp:latest", "uv", "run", "robotmcp"]
    }
  }
}
```

**HTTP mode (start container first, then connect):**
```json
{
  "servers": {
    "robotmcp": {
      "type": "http",
      "url": "http://localhost:8000/mcp"
    }
  }
}
```

### Playwright/Browsers for UI Tests

- Browser Library: run `rfbrowser init` (downloads Playwright and browsers)

### Hint: When using a venv

If you are using a virtual environment (venv) for your project, I recommend to install the `rf-mcp` package within the same venv. When starting the MCP server, make sure to use the Python interpreter from that venv.

---

## 📦 Install as a tool & wire it into your coding agent

The fastest way to use rf-mcp from a coding agent is to install it as a standalone
CLI tool and let it register itself into the agents you use.

### 1. Install

```bash
# API testing only (pure Python, nothing else to do)
uv tool install "rf-mcp[api]"

# Web + API (Selenium works with a system browser; Browser/Playwright adds one step)
uv tool install "rf-mcp[web,api]"

# Everything (Browser, Selenium, Appium, Requests, Database, …)
uv tool install "rf-mcp[all]"
```

This puts a `robotmcp` command (aliased `rf-mcp`) on your PATH. Extras control which
test libraries are available:

| Extra | Adds | Post-install |
| --- | --- | --- |
| `api` | RequestsLibrary | none |
| `web` | SeleniumLibrary + Browser | Selenium: none (Selenium Manager fetches the driver); Browser: `robotmcp init --browsers` |
| `mobile` | AppiumLibrary | Appium server (external) |
| `database` | DatabaseLibrary | a DB driver |
| `all` | all of the above | as above |

### 2. Prepare & diagnose

```bash
robotmcp init            # reports libraries, prints the MCP config to paste
robotmcp init --browsers # also initializes the Playwright browser (needs Node.js)
robotmcp doctor          # read-only health: version, libraries, browser, Node
robotmcp --version
```

`robotmcp init` runs the bundled `rfbrowser init` inside rf-mcp's own environment,
so Playwright lands where the installed Browser library looks for it. It advises
(rather than fails) if the `web` extra or Node.js is missing.

### 3. Register into coding agents

```bash
robotmcp list                              # supported agents + what's detected/registered
robotmcp install                           # interactive: registers into detected agents
robotmcp install --agents claude-code,codex,gemini
robotmcp install --agents all --scope user
robotmcp install --dry-run                 # show the plan, write nothing
robotmcp uninstall                         # safe, reversible removal
```

Supported agents (each written in its own file/format, other MCP servers preserved):
**Claude Code, OpenAI Codex, GitHub Copilot, opencode, Gemini CLI, Kilo Code, goose,
Cursor** (plus `pi`, listed as *planned* until its config convention is confirmed).

**Scope.** Installs default to `--scope project` (writes into the current project,
e.g. `./.mcp.json`) where the agent supports it; use `--scope user` for a global
(home-directory) install. goose only supports user scope.

**Safe & reversible.** Every change is recorded in a hash-tracked manifest
(`~/.local/state/robotmcp/install-manifest.json`). `robotmcp uninstall` removes only
entries that are unchanged since install — if you edited an rf-mcp entry by hand it
is left in place and reported, and unrelated servers are never touched. Use
`--dry-run` on either command to preview.

**Manual fallback.** If you prefer to edit config yourself, add:

```json
{ "mcpServers": { "robotmcp": { "command": "robotmcp" } } }
```

---

## 🔌 Library Plugins

Extend RobotMCP with custom libraries via the plugin system. Two discovery modes are available:

- **Entry points** (`robotmcp.library_plugins`) for packaged plugins.
- **Manifest files** (JSON) under `.robotmcp/plugins/` for workspace overrides.

See the [Library Plugin Authoring Guide](docs/library-plugin-authoring.md) for detailed instructions and explore the sample plugin in [`examples/plugins/sample_plugin`](examples/plugins/sample_plugin/) to get started quickly.

---

## 🖥️ Frontend Dashboard

RobotMCP ships with an optional Django-based dashboard that mirrors active sessions, keywords, and tool activity.

![RobotMCP Frontend Dashboard](media/frontend.png)

1. **Install frontend extras**
   ```bash
   pip install rf-mcp[frontend]
   ```
2. **Start the MCP server with the frontend enabled**
   ```bash
   uv run -m robotmcp.server --with-frontend
   ```
   - Default URL: <http://127.0.0.1:8001/>
   - Quick toggles: `--frontend-host`, `--frontend-port`, `--frontend-base-path`
   - Environment equivalents: `ROBOTMCP_ENABLE_FRONTEND=1`, `ROBOTMCP_FRONTEND_HOST`, `ROBOTMCP_FRONTEND_PORT`, `ROBOTMCP_FRONTEND_BASE_PATH`, `ROBOTMCP_FRONTEND_DEBUG`
3. **Connect your MCP client** (Cline, Claude Desktop, etc.) to the same server process—the dashboard automatically streams events once the session is active.

To disable the dashboard for a given run, either omit the flag or pass `--without-frontend`.

---

## 📋 Instruction Templates

RobotMCP sends server-level instructions to LLMs via the MCP `initialize` response, guiding them to discover keywords before executing them. This significantly reduces failed tool calls and wasted tokens, especially for smaller LLMs.

### Configuration

Three environment variables control instruction behavior:

| Variable | Values | Default |
|----------|--------|---------|
| `ROBOTMCP_INSTRUCTIONS` | `off` / `default` / `custom` | `default` |
| `ROBOTMCP_INSTRUCTIONS_TEMPLATE` | `minimal` / `standard` / `detailed` / `browser-focused` / `api-focused` | `standard` |
| `ROBOTMCP_INSTRUCTIONS_FILE` | Path to `.txt` or `.md` file | *(none, required when mode=custom)* |
| `ROBOTMCP_LOG_LEVEL` | `DEBUG` / `INFO` / `WARNING` / `ERROR` — stderr log verbosity | `WARNING` |
| `ROBOTMCP_MCP_LOG_NOTIFICATIONS` | set to `1` to also forward logs to the client as MCP `notifications/message` (structured, level-tagged) | *(off)* |

> **Output & logging.** The MCP stdio channel (stdout) carries only JSON-RPC; all
> logs and a one-line readiness banner go to stderr. Logging defaults to `WARNING`
> so the client is not flooded — set `ROBOTMCP_LOG_LEVEL=INFO`/`DEBUG` to
> troubleshoot. Logging never blocks execution (it is drained on a background
> thread with drop-on-overflow), and fd 1 is never redirected out from under the
> transport.

### Built-in Templates

| Template | ~Tokens | Best For |
|----------|---------|----------|
| `minimal` | ~40 | Capable LLMs (Claude Opus, GPT-4) — brief reminder only |
| `standard` | ~400 | Mid-range LLMs (Claude Sonnet, GPT-4o) — balanced workflow guide |
| `detailed` | ~600 | Smaller LLMs (Claude Haiku, GPT-4o-mini) — step-by-step with examples |
| `browser-focused` | ~350 | Web-only testing scenarios |
| `api-focused` | ~300 | API-only testing scenarios |

### Example

```json
{
  "servers": {
    "robotmcp": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "-m", "robotmcp.server"],
      "env": {
        "ROBOTMCP_INSTRUCTIONS": "default",
        "ROBOTMCP_INSTRUCTIONS_TEMPLATE": "detailed"
      }
    }
  }
}
```

### Custom Instructions

Set `ROBOTMCP_INSTRUCTIONS=custom` and provide a file via `ROBOTMCP_INSTRUCTIONS_FILE`. Custom files support `{available_tools}` placeholder substitution. Allowed extensions: `.txt`, `.md`, `.instruction`, `.instructions`. If the file is missing or fails validation, the server falls back to the `standard` template automatically.

See [docs/INSTRUCTION_TEMPLATES_GUIDE.md](docs/INSTRUCTION_TEMPLATES_GUIDE.md) for the full guide.

---

## 🪝 Debug Attach Bridge

https://github.com/user-attachments/assets/8d87cd6e-c32e-4481-9f37-48b83f69f72f

RobotMCP ships with `robotmcp.attach.McpAttach`, a lightweight Robot Framework library that exposes the live `ExecutionContext` over a localhost HTTP bridge. When you debug a suite from VS Code (RobotCode) or another IDE, the bridge lets RobotMCP reuse the in-process variables, imports, and keyword search order instead of creating a separate context.

### MCP Server Setup

Example configuration with passed environment variables for Debug Bridge

#### Using UV

```json
{
  "servers": {
    "RobotMCP": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "src/robotmcp/server.py"],
      "env": {
        "ROBOTMCP_ATTACH_HOST": "127.0.0.1",
        "ROBOTMCP_ATTACH_PORT": "7317",
        "ROBOTMCP_ATTACH_TOKEN": "change-me",
        "ROBOTMCP_ATTACH_DEFAULT": "auto"
      }
    }
  }
}
```

#### Using Docker

```json
{
  "servers": {
    "RobotMCP": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "ghcr.io/manykarim/rf-mcp:latest", "uv", "run", "robotmcp"],
      "env": {
        "ROBOTMCP_ATTACH_HOST": "127.0.0.1",
        "ROBOTMCP_ATTACH_PORT": "7317",
        "ROBOTMCP_ATTACH_TOKEN": "change-me",
        "ROBOTMCP_ATTACH_DEFAULT": "auto"
      }
    }
  }
}
```

### Robot Framework setup

Import the library and start the serve loop inside the suite that you are debugging:

```robotframework
*** Settings ***
Library    robotmcp.attach.McpAttach    token=${DEBUG_TOKEN}

*** Variables ***
${DEBUG_TOKEN}    change-me

*** Test Cases ***
Serve From Debugger
    MCP Serve    port=7317    token=${DEBUG_TOKEN}    mode=blocking    poll_ms=100
    [Teardown]    MCP Stop
```

- `MCP Serve    port=7317    token=${TOKEN}    mode=blocking|step    poll_ms=100` — starts the HTTP server (if not running) and processes bridge commands. Use `mode=step` during keyword body execution to process exactly one queued request.
- `MCP Stop` — signals the serve loop to exit (used from the suite or remotely via RobotMCP `attach_stop_bridge`).
- `MCP Process Once` — processes a single pending request and returns immediately; useful when the suite polls between test actions.
- `MCP Start` — alias for `MCP Serve` for backwards compatibility.

The bridge binds to `127.0.0.1` by default and expects clients to send the shared token in the `X-MCP-Token` header.

### Configure RobotMCP to attach

Start `robotmcp.server` with attach routing by providing the bridge connection details via environment variables (token must match the suite):

```bash
export ROBOTMCP_ATTACH_HOST=127.0.0.1
export ROBOTMCP_ATTACH_PORT=7317          # optional, defaults to 7317
export ROBOTMCP_ATTACH_TOKEN=change-me    # optional, defaults to 'change-me'
export ROBOTMCP_ATTACH_DEFAULT=auto       # auto|force|off (auto routes when reachable)
export ROBOTMCP_ATTACH_STRICT=0           # set to 1/true to fail when bridge is unreachable
uv run python -m robotmcp.server
```

When `ROBOTMCP_ATTACH_HOST` is set, `execute_step(..., use_context=true)` and other context-aware tools first try to run inside the live debug session. Use the new MCP tools to manage the bridge from any agent:

- `attach_status` — reports configuration, reachability, and diagnostics from the bridge (`/diagnostics`).
- `attach_stop_bridge` — sends a `/stop` command, which in turn triggers `MCP Stop` in the debugged suite.

---

## 🎪 Example Workflows

### 🌐 Web Application Testing (BDD)

**Prompt:**

```
Use RobotMCP to create a test suite and execute it step wise.
It shall:

- Open https://demoshop.makrocode.de/
- Add item to cart
- Assert item was added to cart
- Add another item to cart
- Assert another item was added to cart
- Checkout
- Assert checkout was successful

Execute step by step and build final test suite afterwards
Create in BDD style and use Keywords with embedded arguments when applicable
```

**Result:** BDD-style Robot Framework test suite with Given/When/Then keywords, embedded arguments, and extracted variables.

### 🌐 Web Application Testing (Data-Driven)

**Prompt:**

```
Use RobotMCP to create a test suite and execute it step wise.
It shall:

- Open https://saucedemo.com
- Login with different user/password combinations
- Assert message or login

Execute step by step and build final test suite afterwards
Create in datadriven style and add multiple test rows with different scenarios
Use Test Template setting in suite
```

**Result:** Data-driven Robot Framework test suite with `Test Template` and parameterized rows for each login scenario.

### 📱 Mobile App Testing

**Prompt:**

```
Use RobotMCP to create a TestSuite and execute it step wise.
It shall:
- Launch app from tests/appium/SauceLabs.apk
- Perform login flow
- Add products to cart
- Complete purchase

Appium server is running at http://localhost:4723
Execute the test suite stepwise and build the final version afterwards.
```

**Result:** Mobile test suite with AppiumLibrary keywords and device capabilities.

### 🔌 API Testing

**Prompt:**

```
Read the Restful Booker API documentation at https://restful-booker.herokuapp.com.
Use RobotMCP to create a TestSuite and execute it step wise.
It shall:

- Create a new booking
- Authenticate as admin
- Update the booking
- Delete the booking
- Verify each response

Execute the test suite stepwise and build the final version afterwards.
```

**Result:** API test suite using RequestsLibrary with proper error handling.

### 🧪 XML/Database Testing

**Prompt:**

```
Create a xml file with books and authors.
Use RobotMCP to create a TestSuite and execute it step wise.
It shall:
- Parse XML structure
- Validate specific nodes and attributes
- Assert content values
- Check XML schema compliance

Execute the test suite stepwise and build the final version afterwards.
```

**Result:** XML processing test using Robot Framework's XML library.

---

## 🔍 MCP Tools Overview

RobotMCP provides a comprehensive toolset organized by function. Highlights:

### Planning & Orchestration

- `analyze_scenario` – Convert natural language to structured test intent and spawn sessions.
- `recommend_libraries` – Suggest libraries (`mode="direct"`, `"sampling_prompt"`, or `"merge_samples"`). Includes confidence filtering, negation support ("not using Selenium"), and conflict prevention (Browser and SeleniumLibrary are never recommended together).
- `manage_library_plugins` – List, reload, or diagnose library plugins from a single endpoint.

### Session & Execution

- `manage_session` – Initialize sessions, import resources/libraries, set variables, manage multi-test suites, or switch tool profiles via `action`. Key actions include `init`, `import_library`, `set_variable`, `start_test`, `end_test`, `list_tests`, `set_suite_setup`, `set_suite_teardown`, `set_tool_profile`.
- `execute_step` – Execute keywords or `mode="evaluate"` expressions with optional `assign_to` and `timeout_ms`. Includes automatic timeout tuning by keyword type and element pre-validation for faster error feedback.
- `execute_flow` – Build `if`/`for_each`/`try` control structures using RF context-first execution.
- `execute_batch` – Execute multiple keywords in a single MCP call with variable chaining (`${STEP_N}` references), automatic recovery on failure, and configurable failure policies (`stop`, `retry`, `recover`). Reduces N tool round-trips to 1.
- `resume_batch` – Resume a failed batch from its failure point, optionally inserting fix steps before retrying.
- `intent_action` – Library-agnostic intent execution (e.g. `intent="click"`, `target="text=Login"`). Resolves to the correct keyword/locator for the session's active library. Supports 8 intents: `navigate`, `click`, `fill`, `hover`, `select`, `assert_visible`, `extract_text`, `wait_for`.

### Discovery & Documentation

- `find_keywords` – Unified keyword discovery (`strategy="semantic"`, `"pattern"`, `"catalog"`, or `"session"`).
- `get_keyword_info` – Retrieve keyword/library documentation or parse argument signatures (`mode="keyword"|"library"|"session"|"parse"`).

### Observability & Diagnostics

- `get_session_state` – Aggregate session insight (`summary`, `variables`, `page_source`, `application_state`, `validation`, `libraries`, `rf_context`). Supports `detail_level="minimal"|"standard"|"full"` for controlling response verbosity.
- `check_library_availability` – Verify availability/install guidance for specific libraries (always includes `success`).
- `set_library_search_order` – Control keyword resolution precedence.
- `manage_attach` – Inspect or stop the attach bridge.

### Suite Lifecycle

- `build_test_suite` – Generate Robot Framework test files from validated steps. Supports multi-test suites with per-test tags, setup, and teardown. Use `bdd_style=True` for Given/When/Then output.
- `run_test_suite` – Validate (`mode="dry"`) or execute (`mode="full"`) suites.

### Locator Guidance

- `get_locator_guidance` – Consolidated Browser/Selenium/Appium selector guidance with structured output. Also serves non-locator topics: `library="requests"` (API request/response cookbook) and `library="visual"` (visual-validation cookbook — see below).
- `visual_check` – Capture the current screen/page to disk and, on explicit opt-in, return the image for multimodal inspection (see [Visual validation](#-visual-validation-multimodal)).

### Visual validation (multimodal)

Some checks are impossible from the DOM / ARIA tree alone — text baked into a
`<canvas>` or an image, layout/overlap, an element visually obscured by an
overlay, color/state, charts, or transient UI states. When the coding agent's
model is multimodal, a screenshot closes that gap. RobotMCP exposes this
**pull-not-push** so it stays token-cheap by default:

- **Default (cheap, ~no extra tokens):** every successful screenshot step
  advertises an absolute `screenshot_path` plus a one-line `visual_hint` in its
  response. No image bytes are sent. A multimodal agent that can read files
  opens the path on demand; a text-only agent simply ignores it. The run never
  depends on the model being multimodal.
- **Guidance topic:** `get_locator_guidance(library="visual")` (aliases:
  `screenshot`, `vision`, `image`) returns a cookbook — the vision-only case
  categories, the **dual read-back** pattern (prefer `Get Text` when a node
  exposes the value; use a screenshot to *confirm*; go screenshot-primary only
  when no node exposes it), and the caveats.
- **Opt-in image escape hatch:** the `visual_check` tool. By default it returns
  `{screenshot_path, size, mode, visual_hint}` — **text only**. It returns an
  actual image content block **only** when called with `return_image=true`
  *and* `ROBOTMCP_SCREENSHOT_MODE` is `image` or `auto`. A missing/failed
  capture degrades to the evidence-missing hint and never raises.

**`ROBOTMCP_SCREENSHOT_MODE`** (default `file`):

| Value   | Behavior |
| ------- | -------- |
| `file`  | Always path-only; `return_image=true` is ignored. Safe default for text-only deployments. |
| `image` | Honor `return_image=true` and return the image block. |
| `auto`  | Same as `image` where supported, else falls back to path-only. |

**Caveats:** each attached image costs roughly 800 tokens, so keep it on-demand;
prefer `Get Text` for exact text/number assertions that live in the DOM;
screenshots may capture PII; and pixel comparisons are not deterministic across
renderers — use vision for *gestalt* validation, not byte-exact diffs.

### Memory (optional, requires `rf-mcp[memory]`)

- `recall_step` – Recall previously successful step sequences for a test scenario.
- `recall_fix` – Recall known fixes for an error message from past sessions.
- `recall_locator` – Recall working locator strategies for a UI element.
- `store_knowledge` – Store domain knowledge for future recall.
- `get_memory_status` – Check memory availability and collection statistics.

---

## 🧪 BDD & Data-Driven Test Generation

### BDD Style (Given/When/Then)

**Prompt:**

```
Use RobotMCP to create a test suite and execute it step wise.
It shall:

- Open https://demoshop.makrocode.de/
- Add item to cart
- Assert item was added to cart
- Add another item to cart
- Assert another item was added to cart
- Checkout
- Assert checkout was successful

Execute step by step and build final test suite afterwards
Create in BDD style and use Keywords with embedded arguments when applicable
```

**Result:** RobotMCP executes each step, inspects the DOM between actions, and generates a BDD-style suite with Given/When/Then keywords:

```robotframework
*** Test Cases ***
Demoshop BDD Purchase Workflow
    Given the demoshop is open
    When the user adds the first product to cart
    Then the cart should contain 1 item
    When the user adds the second product to cart
    Then the cart should contain 2 items
    When the user proceeds to checkout
    And the user fills in the checkout form
    And the user places the order
    Then the order confirmation should be displayed

*** Keywords ***
the demoshop is open
    New Browser    chromium
    New Context
    New Page    ${DEMOSHOP_URL}

the user adds the first product to cart
    Click    ${FIRST_PRODUCT_BUTTON}
```

During stepwise execution, use `bdd_group` and `bdd_intent` on `execute_step` to control how steps are grouped into behavioral keywords. Call `build_test_suite(bdd_style=True)` at the end.

### Data-Driven Templates

**Prompt:**

```
Use RobotMCP to create a test suite and execute it step wise.
It shall:

- Open https://saucedemo.com
- Login with different user/password combinations
- Assert message or login

Execute step by step and build final test suite afterwards
Create in datadriven style and add multiple test rows with different scenarios
Use Test Template setting in suite
```

**Result:** RobotMCP builds a parameterized suite using `Test Template` with named data rows:

```robotframework
*** Settings ***
Library         Browser
Test Template   Verify Login

*** Test Cases ***          USERNAME            PASSWORD        EXPECTED
Valid User                  standard_user       secret_sauce    Products
Locked Out User             locked_out_user     secret_sauce    locked out
Invalid Password            standard_user       wrong_pass      Username and password do not match
```

Use `manage_session(action="start_test", template="Verify Login")` to set the template keyword, then `manage_session(action="add_data_row", test_name="Valid User", args=["standard_user", "secret_sauce", "Products"])` to add each row.

---

## 🧠 Small LLM Optimization

RobotMCP includes optimizations for small and medium-sized LLMs (8K-32K context windows) that reduce token overhead and improve tool call accuracy.

### Dynamic Tool Profiles

Control which tools are visible to the LLM based on the workflow phase. Smaller models see fewer, more compact tools:

```
manage_session(action="set_tool_profile", tool_profile="browser_exec")
```

Profiles: `browser_exec`, `api_exec`, `discovery`, `minimal_exec`, `full`. Reduces tool description overhead from ~7,000 to ~1,000 tokens. Can also be set via the `ROBOTMCP_TOOL_PROFILE` environment variable.

### Response Verbosity

Control response detail level to reduce token consumption. Available on most tools via the `detail_level` parameter:

- `minimal` – Essential output only (60-80% token reduction)
- `standard` – Balanced output (default)
- `full` – Complete detailed output

Set a default via `ROBOTMCP_OUTPUT_VERBOSITY=compact|standard|verbose`.

### Delta State Responses

`get_session_state` supports incremental responses that only return sections that changed since the last call:

```
# First call returns full state (version 1):
get_session_state(session_id="...", sections=["variables", "page_source"])

# Subsequent calls return only what changed:
get_session_state(session_id="...", mode="delta", since_version=1)
```

In `mode="auto"` (the default), the server automatically returns delta responses when a previous version exists. This reduces token usage by 50-80% for multi-step workflows where only variables or page content change between steps.

### Artifact Externalization

Large outputs (HTML page source, execution logs, stack traces) are automatically externalized into fetchable artifacts instead of being inlined in the response:

```
# Response includes artifact_id instead of full content:
{"result": "...", "artifact_id": "abc123", "artifact_hint": "Full page source available via fetch_artifact"}

# Fetch when needed:
fetch_artifact(artifact_id="abc123")
```

This keeps tool responses compact while preserving access to full output on demand.

### Intent Action

The `intent_action` tool provides a library-agnostic entry point for common test actions. Instead of requiring the LLM to know library-specific keyword names and locator syntax, it expresses intent:

```
intent_action(intent="click", target="text=Login", session_id="...")
intent_action(intent="fill", target="#username", value="testuser", session_id="...")
```

The server resolves intent + target to the correct keyword and locator format for the session's active library (Browser, SeleniumLibrary, or AppiumLibrary).

#### Navigate Fallback

When `intent_action(intent="navigate")` fails because no browser or page is open, the server automatically opens the browser/page and retries:
- **Browser Library**: executes `New Browser` + `New Page` (or just `New Page` if browser exists)
- **SeleniumLibrary**: executes `Open Browser about:blank chrome`

The response includes `fallback_applied: true` and `fallback_steps` count. Saves 2-4 tool calls per session.

### Batch Execution

The `execute_batch` tool executes multiple keywords in a single MCP call, reducing N round-trips to 1. Steps can reference results from earlier steps via `${STEP_N}` variables:

```
execute_batch(session_id="...", steps=[
    {"keyword": "Go To", "args": ["https://example.com"]},
    {"keyword": "Get Title", "assign_to": "title"},
    {"keyword": "Should Be Equal", "args": ["${STEP_2}", "Example Domain"]}
], on_failure="recover")
```

If a step fails, `resume_batch` lets you insert fix steps and retry from the failure point.

### Strict Mode Hints

When a Browser Library keyword fails because the selector matches multiple elements (Playwright strict mode), the error response includes a hint suggesting `>> nth=0` (zero-based index) or `>> visible=true` selector chains, with concrete examples using the actual keyword name and element count.

### Type-Constrained Parameters

All action/mode/strategy parameters use `Literal` types, producing `enum` constraints in the JSON Schema. This eliminates hallucinated values (e.g., `action="setup"` instead of `action="init"`). All values accept case-insensitive input.

### Automatic Parameter Coercion

Common small LLM mistakes are corrected server-side:
- JSON-stringified arrays (`"[\"Browser\"]"`) are parsed to native arrays
- Comma-separated strings (`"Browser,BuiltIn"`) are split into lists
- Deprecated keywords (`GET`) are mapped to current equivalents (`GET On Session`)

### Instruction Templates

Configurable server-level instructions guide LLMs to follow the "discover-then-act" pattern. Choose a template sized for your LLM's capability — from `minimal` (~40 tokens) for Claude Opus to `detailed` (~600 tokens) for Claude Haiku. See [Instruction Templates](#-instruction-templates) above.

---

## 🧠 Persistent Semantic Memory

RobotMCP can learn from past sessions and recall successful patterns, locators, and error fixes — reducing trial-and-error for repeated testing scenarios.

### How It Works

Memory is powered by **sqlite-vec** (vector search) and **model2vec** (256-dimensional embeddings). When enabled, the server:

1. **Stores** successful step sequences, working locators, and error→fix mappings after each tool call
2. **Recalls** relevant memories and injects them as hints into tool responses (e.g., `execute_step` failures include previous fixes, `get_session_state` includes previously successful step patterns)
3. **Learns** across sessions — the warm database persists between server restarts

### Installation

```bash
pip install rf-mcp[memory]
# or
uv pip install rf-mcp[memory]
```

### Configuration

Enable via environment variables:

```json
{
  "servers": {
    "robotmcp": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "-m", "robotmcp.server"],
      "env": {
        "ROBOTMCP_MEMORY_ENABLED": "true",
        "ROBOTMCP_MEMORY_DB_PATH": "./memory.db"
      }
    }
  }
}
```

### Memory MCP Tools

When memory is enabled, five additional tools become available:

| Tool | Description |
|------|-------------|
| `recall_step` | Recall previously successful step sequences. Call **before** building new test steps to reuse proven patterns. |
| `recall_fix` | Recall known fixes for an error. Call **immediately** when `execute_step` fails before retrying. |
| `recall_locator` | Recall working locators for a UI element. Call **before** DOM inspection for familiar elements. |
| `store_knowledge` | Store domain knowledge (e.g., site structure, auth flows) for future recall. |
| `get_memory_status` | Check memory availability and statistics at session start. |

### Response Augmentation

Memory hints are automatically injected into existing tool responses — no LLM cooperation required:

- **`execute_step` failures**: Previous fixes and working locators are included in the error response
- **`get_session_state`**: Previously successful step patterns for the scenario are included
- **`analyze_scenario`**: Recalled step sequences from past sessions are suggested

All memory lookups have a 50ms timeout to avoid impacting response latency.

### Benchmark Results

Tested across 8 scenarios (72 opencode invocations, 3 iterations each) with `qwen/qwen3-coder`:

| Scenario Type | Best Result | Memory Recall Rate |
|---|---|---|
| Complex web flows (checkout) | **-23% calls, -22% tokens** | 3/3 iterations |
| Exploration-heavy browsing | -44% calls on best iteration | 3/3 iterations |
| API error recovery | -3% calls ±3% (tightest CI) | 3/3 iterations |

Memory benefits are strongest for **complex, multi-step scenarios** where past locators and step sequences reduce exploratory tool calls.

---

## ⚙️ Environment Variables Reference

### Core Configuration

| Variable | Values | Default | Description |
|----------|--------|---------|-------------|
| `ROBOTMCP_INSTRUCTIONS` | `off` / `default` / `custom` | `default` | Instruction mode |
| `ROBOTMCP_INSTRUCTIONS_TEMPLATE` | `minimal` / `standard` / `detailed` / `browser-focused` / `api-focused` | `standard` | Template selection (default mode only) |
| `ROBOTMCP_INSTRUCTIONS_FILE` | File path | *(none)* | Custom instructions file (custom mode only) |
| `ROBOTMCP_TOOL_PROFILE` | `browser_exec` / `api_exec` / `discovery` / `minimal_exec` / `full` | *(auto)* | Default tool profile |
| `ROBOTMCP_OUTPUT_VERBOSITY` | `compact` / `standard` / `verbose` | `standard` | Response detail level |
| `ROBOTMCP_USE_SAMPLING` | `true` / `1` / `yes` | *(disabled)* | Enable LLM-powered scenario analysis |
| `ROBOTMCP_OUTPUT_MODE` | `auto` / `full` / `delta` | `auto` | Default `get_session_state` response mode |
| `ROBOTMCP_PRE_VALIDATION` | `0` / `1` | `1` | Enable element pre-validation before actions |
| `ROBOTMCP_STARTUP_CLEANUP` | `auto` / `on` / `off` | `auto` | Session cleanup on server start |

### Persistent Memory

| Variable | Values | Default | Description |
|----------|--------|---------|-------------|
| `ROBOTMCP_MEMORY_ENABLED` | `true` / `1` / `yes` | *(disabled)* | Enable persistent semantic memory |
| `ROBOTMCP_MEMORY_DB_PATH` | file path | `./robotmcp_memory.db` | SQLite database path for memory storage |
| `ROBOTMCP_MEMORY_MODEL` | model name | `potion-base-8M` | Embedding model for similarity search |

### Debug Attach Bridge

| Variable | Values | Default | Description |
|----------|--------|---------|-------------|
| `ROBOTMCP_ATTACH_HOST` | hostname/IP | *(none)* | Attach bridge host (enables attach mode) |
| `ROBOTMCP_ATTACH_PORT` | integer | `7317` | Attach bridge port |
| `ROBOTMCP_ATTACH_TOKEN` | string | `change-me` | Shared auth token |
| `ROBOTMCP_ATTACH_DEFAULT` | `auto` / `force` / `off` | `auto` | Attach routing mode |
| `ROBOTMCP_ATTACH_STRICT` | `0` / `1` | `0` | Fail if bridge unreachable |

### Frontend Dashboard

| Variable | Values | Default | Description |
|----------|--------|---------|-------------|
| `ROBOTMCP_ENABLE_FRONTEND` | `0` / `1` | `0` | Enable dashboard |
| `ROBOTMCP_FRONTEND_HOST` | hostname/IP | `localhost` | Dashboard host |
| `ROBOTMCP_FRONTEND_PORT` | integer | `8001` | Dashboard port |
| `ROBOTMCP_FRONTEND_BASE_PATH` | URL path | `/` | URL base path prefix |
| `ROBOTMCP_FRONTEND_DEBUG` | `0` / `1` | `1` | Django debug mode |

---

## 🤝 Contributing

We welcome contributions! Here's how to get started:

1. **Fork** the repository
2. **Clone** your fork locally
3. **Install** development dependencies: `uv sync`
4. **Create** a feature branch
5. **Add** comprehensive tests for new functionality
6. **Run** tests: `uv run pytest tests/`
7. **Submit** a pull request

## 📝 Changelog

- [**v0.31.1**](docs/RELEASE_NOTES_v0.31.0.md) – Packaging cleanup (exclude tests/examples from sdist)
- [**v0.31.0**](docs/RELEASE_NOTES_v0.31.0.md) – BDD/data-driven generation, namespace architecture fixes, persistent memory, 71-88% token reduction
- [v0.30.1](docs/RELEASE_NOTES_v0.30.1.md) – FastMCP 3.x compatibility layer
- [v0.30.0](docs/RELEASE_NOTES_v0.30.0.md) – Small LLM optimization (tool profiles, intent action, response optimization, type constraints)
- [v0.29.0](docs/RELEASE_NOTES_v0.29.0.md) – Instruction templates, multi-test sessions, batch execution, smart timeouts

## 📄 License

Apache 2.0 License - see [LICENSE](LICENSE) file for details.

---

**⭐ Star us on GitHub if RobotMCP helps your test automation journey!**

Made with ❤️ for the Robot Framework and AI automation community.
