Metadata-Version: 2.4
Name: webscope-mcp
Version: 0.5.0
Summary: MCP server (stdio, standard library only) that gives a coding agent short answers about a project
License-Expression: MIT
Project-URL: Repository, https://github.com/partprogramming09/webscope
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# Webscope

<!-- mcp-name: io.github.partprogramming09/webscope -->

A lightweight, token-efficient MCP server (stdio, JSON-RPC 2.0, Python standard library only). It provides coding agents with short, surgical answers: grouped search hits, isolated symbols instead of whole files, native in-browser testing on the user's open Chrome, and bounded project scripts.

Tool names, parameters, and messages are in Spanish.

---

## Quick Start

### 1. Initialize your project
Run in your project root to auto-detect your stack (Laravel, Vue/React, Astro, Python, or generic) and generate `webscope.json`:

```sh
# Via uvx (no install needed)
uvx webscope-mcp --init

# Or locally with Python
python3 webscope.py --init
```

### 2. Register with your MCP client

```sh
# Claude Code (recommended, writes project .mcp.json)
claude mcp add --scope project webscope -- uvx --from git+https://github.com/partprogramming09/webscope@v0.3.0 webscope-mcp --manifest "$PWD/webscope.json"

# With pip
pip install git+https://github.com/partprogramming09/webscope.git@v0.3.0
claude mcp add --scope project webscope -- webscope-mcp --manifest "$PWD/webscope.json"
```

Start `claude` and verify with `/mcp`: `webscope` will be connected with `search`, `read`, and `run`.

---

## Tools

| Tool | Description |
| :--- | :--- |
| `search(text, where?, limit?, format?, context?, regex?)` | Case-insensitive search grouped by file with relevance ranking. `format="concise"` returns top 5 files. Skips secrets (`.env`, `*.key`). |
| `read(file, symbol?, lines?, max_lines?, tail?, contains?, format?)` | Surgical read: extracts a single function, method, class (PHP, TS, JS, Vue, Python), Markdown section, line range, or log tail (`tail`). |
| `run(name?, args?, detail?)` | Runs a declared read-only script from the manifest. Output trimmed to head and tail limits. |
| `run_write(name, args)` | Runs scripts declared in `writes`. Requires `WEBSCOPE_WRITE=1` and interactive user confirmation. |

Every response starts with a one-line actionable guide and is capped at `token_limit` (~4 characters per token).

---

## In-Browser Testing & Chrome Connector (`e2e_chrome.py`)

Webscope includes an in-browser automation engine that replaces heavy screenshot-based tools with lightweight DOM extraction:

### Native Chrome Connector (`--evaluate`)
Operates directly on the developer's open Google Chrome window without opening clean/incognito profiles, preserving your active cookies, logins, and 2FA:

```sh
# Inspect current screen on active tab
python3 webscope_adapters/e2e_chrome.py --evaluate "window.__f.state()"

# Run on a tab matching a specific URL
python3 webscope_adapters/e2e_chrome.py --evaluate "window.__f.state()" "localhost:5173"

# Run a complete JS test flow
python3 webscope_adapters/e2e_chrome.py --evaluate test_flow.js "localhost:5173"
```

### Key Capabilities
- **Screen & Form Helpers (`__f`)**: Finds inputs by visible label, fills values, coordinates clicks with active settle wait (`calma()`), and verifies persistence.
- **Network Capture (`__e2e`)**: Intercepts `/api/` calls, latency (`ms`), and console errors without screenshots.
- **Self-Healing Across Reloads**: Injected helpers tolerate full page reloads (`window.location.reload()`) with automatic re-initialization.
- **Zero-Token Replay (`--replay <name>`)**: Replays recorded user flows in one call with 0 AI tokens.
- **Playwright Export (`--export <capture> <url>`)**: Converts recorded steps into clean `.spec.js` Playwright tests.

### The Essential Testing Contract: Full Lifecycle (CRUD + Sub-modules)
A module is **never considered tested** by merely reading a view or clicking a button. Webscope enforces a strict full-lifecycle standard:
1. **Create (C)**: Fill mandatory and conditional fields, submit, verify HTTP 200/201, and capture the generated record ID.
2. **Edit (U)**: Reopen the record, mutate fields, and verify data persistence in both UI and database.
3. **Exercise Sub-modules & Lifecycle**: Navigate sub-routes (`:id`), exercise child panels/tabs (e.g. characteristics, tariffs, pre-settlements, notes, print), and trigger state transitions (e.g. approve, reopen, duplicate).
4. **Delete & Clean (D)**: Delete the test record, confirm UI removal, and verify database clean state (`ZZ_E2E`).

---

## Configuration (`webscope.json`)

All behavior is project-contained. See [`webscope.example.json`](webscope.example.json).

```json
{
  "root": ".",
  "trim": { "head": 10, "tail": 70 },
  "token_limit": 5000,
  "storage": ".agents/webscope",
  "test_prefix": "ZZ_E2E",
  "search": { "dirs": ["src"], "extensions": ["ts", "vue", "php", "py"] },
  "allowed_env": ["DATABASE_URL"],
  "scripts": {
    "report": {
      "cmd": ["python3", "-I", "scripts/report.py"],
      "description": "Summarises a database table",
      "usage": "<table>",
      "rejects": ["--out"],
      "writes": ["--fix"],
      "timeout": 120
    }
  }
}
```

| Key | Description |
| :--- | :--- |
| `root` | Project root relative to manifest directory. |
| `extra_roots` | Folders outside `root`, relative to the manifest directory, that `search` and `read` may also read (for example a logs folder). Secret files stay blocked. |
| `token_limit` | Hard limit on response size in approximate tokens. |
| `trim` | Default head (`head`) and tail (`tail`) lines kept from script outputs. |
| `storage` | Internal storage for `module-map.json`, `flows/`, `walkthroughs/`. Autodetects `.agents/webscope/`, `.claude/webscope/`, or `.webscope/`. |
| `test_prefix` | Prefix for test entities (default `ZZ_E2E`). |
| `search.dirs`, `extensions` | Folders and extensions searched by default. |
| `allowed_env` | Environment variables passed to child scripts. |
| `scripts.<name>` | Fixed command list (`cmd`), `rejects` (blocked flags), `writes` (write flags). |

### The `project` section

Read by the included adapters; every key is optional and has a neutral default.

| Key | Used by | Description |
| :--- | :--- | :--- |
| `modules` | most adapters | Backend modules folder (`<Area>/<Module>/Routes`, `Models`, `Requests`…). Default `app/Modules`. |
| `backend`, `legacy` | `consumers`, `fields` | Backend code folder (default: parent of `modules`) and an optional folder of older code searched for the same column. |
| `frontends`, `stores` | `graph`, `changed`, `audit_types`, `simulate` | Frontend module folders (`<area>/<module>/routes/*.ts`) and an optional folder of shared stores. |
| `container`, `workdir` | `tinker`, `sql` and every database adapter | Docker container for `docker exec`, or the folder with `artisan` for a local `php artisan`. |
| `boot`, `php_db` | `tinker` | PHP (string or list of lines) that prepares the connection (it sees `$host`) and the PHP expression that returns it (default `DB::connection()`). |
| `status_columns` | `unique_indexes` | Status/soft-delete column names. |
| `tenant_tables` | `tenant_queries` | Regex of the tenant table names; the audit refuses to run without it. |
| `known_types`, `known_failures`, `fail_pattern` | `audit_types`, `triage` | Files of accepted clashes and known failures, and the regex that marks a result as failed. |
| `audit_columns`, `soft_delete_value`, `form_view`, `form_composable`, `base_url`, `path_prefix` | `simulate` | Audit columns to skip, the status value of a deleted row, form file globs, and the app URL parts of the generated spec. |
| `repos`, `spec_files` | `changed` | Repository folders to diff and the JSON spec files or globs. |

Database adapters run inside a transaction that is rolled back; only `cleanup_test_rows --delete --confirm` and `tinker --commit` (both behind `run_write`) commit.

---

## Included Adapters (`{adapters}`)

Ready-made scripts shipped in the package. Use `{adapters}` in `cmd`:

| Script | Purpose | Stack |
| :--- | :--- | :--- |
| `e2e_chrome.py` | Browser walk, form automation (`__f`), replay, and open Chrome connector (`--evaluate`). | Any SPA |
| `vue_ts.py` (`map`) | Module mapping: routes, subroutes, clickable actions, API calls, and E2E coverage. | Vue 3 + TS |
| `laravel.py` (`map_back`) | Resolves endpoint → controller → service → model → database table. | Laravel |
| `astro.py` (`map_web`) | File-based routes, components, form fields, and client scripts. | Astro |
| `db_check.php` | SELECT-only database integrity checks by prefix marker from `.env`. | MySQL / Postgres |
| `payload_check.py` | Compares captures against FormRequest rules, Resources, and columns. | Laravel |
| `cleanup_test_rows.py` | Lists and safely cleans test rows matching the test prefix. | Laravel |
| `session_cost.py` | Token and USD cost auditor per model for Claude Code sessions. | Claude Code |
| `tinker.py` | Runs PHP in `artisan tinker` inside a transaction rolled back unless `--commit` (`project.container` or `project.workdir`, `project.boot`, `project.php_db`). | Laravel |
| `sql.py` | Read-only SQL (one SELECT/SHOW/DESCRIBE/EXPLAIN/WITH) through `tinker.py`; prints TSV with a header. | Laravel |
| `fields.py` | Column sheet of a table: type, nullability, rows with a value, backend readers and writers. | Laravel |
| `consumers.py` | Who reads and who writes a column: `file:line` in the backend (and `project.legacy`). | Laravel |
| `module_graph.py (`graph`)` | Screen → frontend module → endpoints → backend module → tables (`project.frontends`, `project.stores`). | Laravel + Vue |
| `audit_types.py` | Crosses columns with FormRequest rules, Resource casts and frontend numeric conversions, with real data. | Laravel |
| `unique_indexes.py` | Unique indexes on tables with a status column and whether the backend covers each (`project.status_columns`). | Laravel |
| `tenant_queries.py` | `DB::` queries on tenant tables without an explicit connection (`project.tenant_tables`). | Laravel |
| `simulate.py` | Lists what could break in a module from request, form and schema; `--out` writes the walk spec. | Laravel |
| `snap.py` | Snapshot and diff of a query: what an on-screen action really wrote. | Laravel + Vue |
| `triage.py` | Classifies failing pieces of a run summary as known, CHANGED or NEW (`project.known_failures`). | Laravel + Vue |
| `changed.py` | Specs affected by uncommitted changes, resolved to screens (`project.repos`, `project.spec_files`). | Laravel + Vue |

---

## Subagents Integration

Webscope keeps subagents fast and lightweight (~9.3k tokens initial load vs 28.8k).

### Exporting the `walkthrough` Agent
Export the ready-made walk agent without overwriting existing agents:

```sh
# Autodetects .agents/ or .claude/agents/
webscope-mcp --agent

# Or targeting a specific folder
webscope-mcp --agent [directory]
```

- **Non-destructive**: Never overwrites existing agent files unless `--force` is passed.
- **Isolation**: Leaves all other user-defined agents untouched.

### Declaring Tools in Agents
In your `.agents/<name>.md` or `.claude/agents/<name>.md`:
```yaml
---
name: navegador
tools: Read, Grep, Glob, mcp__webscope__search, mcp__webscope__read, mcp__webscope__run
model: sonnet
effort: high
---
```

---

## Configuration in Other Clients

### Claude Desktop (`claude_desktop_config.json`)
```json
{
  "mcpServers": {
    "webscope": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/partprogramming09/webscope@v0.3.0", "webscope-mcp", "--manifest", "/absolute/path/to/webscope.json"]
    }
  }
}
```

### Cursor / VS Code / Cline (`.cursor/mcp.json` or `.vscode/mcp.json`)
```json
{
  "mcpServers": {
    "webscope": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/partprogramming09/webscope@v0.3.0", "webscope-mcp", "--manifest", "${workspaceFolder}/webscope.json"]
    }
  }
}
```

### Zed (`settings.json`)
```json
{
  "context_servers": {
    "webscope": {
      "command": {
        "path": "uvx",
        "args": ["--from", "git+https://github.com/partprogramming09/webscope@v0.3.0", "webscope-mcp", "--manifest", "/absolute/path/to/webscope.json"]
      }
    }
  }
}
```

---

## Updating

```sh
# uvx: refresh package cache
uv cache clean webscope-mcp

# pip: force reinstall
pip install --upgrade --force-reinstall git+https://github.com/partprogramming09/webscope.git@v0.3.0
```

---

## Security Model

- **Root Sandbox**: `search` and `read` resolve strictly within `root` and reject outside paths.
- **Invisible Secrets**: Automatically hides `.env*`, `*.pem`, `*.key`, `*.p12`, `id_rsa*`, `id_ed25519*`, `auth.json`, and credentials.
- **No Shell Injection**: Scripts execute as fixed argument lists without intermediate shell.
- **Read-Only Default**: Destructive arguments (`writes`) require `run_write`, `WEBSCOPE_WRITE=1`, and explicit approval.

### Recommended `.gitignore`
```gitignore
# Temporary Webscope artifacts
captures/
.webscope/captures/
```

Commit `webscope.json`, `.claude/webscope/walkthroughs/` (or `.agents/webscope/`), and `module-map.json`.

---

## Tests

```sh
python3 -I test_webscope.py
```

## License

[MIT](LICENSE)
