Skip to main content

Webscope

A small MCP server (stdio, JSON-RPC 2.0, Python standard library only) that gives a coding agent short answers about a project: grouped search hits, one symbol instead of a whole file, and the output of the project's own read-only scripts, trimmed to head and tail. The goal is fewer tokens per question.

Tool names, parameters and messages are in Spanish.

Requirements

  • Python 3.9 or newer (no third-party packages)
  • Optional: uv, to run it with uvx without cloning
  • grep on PATH (used by buscar)

Installation

  1. In your project's root, generate or create its manifest. You can autodetect the stack (Laravel, Vue/React/Frontend, Python or generic) and generate webscope.json in 1 second:

    # With webscope-mcp installed or via uvx
    webscope-mcp --init
    
    # Or using standard Python
    python3 webscope.py --init
    

    --init automatically inspects composer.json, package.json, pyproject.toml and directory structure to configure adapters and search paths (see Configuration and webscope.example.json). All adapters (db_check.php, agents, web/*.js) come packaged as internal package assets.

    To export the recorrido subagent into .agents/ or .claude/agents/ (protecting 100% of existing user agents):

    webscope-mcp --agente [directorio]
    
  2. Register the server. With Claude Code, from the project's root, pick one:

    # Claude Code con uvx (sin clonar, versión v0.2.4)
    claude mcp add --scope project webscope -- uvx --from git+https://github.com/partprogramming09/webscope@v0.2.4 webscope-mcp --manifest "$PWD/webscope.json"
    
    # Con pip
    pip install git+https://github.com/partprogramming09/webscope.git@v0.2.4
    claude mcp add --scope project webscope -- webscope-mcp --manifest "$PWD/webscope.json"
    
    # Con un clon local y Python estándar
    git clone https://github.com/partprogramming09/webscope.git ~/webscope
    claude mcp add --scope project webscope -- python3 -I ~/webscope/webscope.py --manifest "$PWD/webscope.json"
    

    --scope project writes .mcp.json so the whole team gets it; use --scope user for all your projects. Add -e WEBSCOPE_ESCRITURA=1 before -- only if a script declares escribe and you want to allow it.

  3. Start claude in the project, approve the server, and check it with /mcp: webscope should show as connected with the tools buscar, leer and correr.

Configuration in other MCP clients

You can configure Webscope in other MCP clients using uvx or standard Python:

Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "webscope": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/partprogramming09/webscope@v0.2.4",
        "webscope-mcp",
        "--manifest",
        "/absolute/path/to/your/project/webscope.json"
      ]
    }
  }
}

Cursor / VS Code / Cline (.cursor/mcp.json or .vscode/mcp.json)

{
  "mcpServers": {
    "webscope": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/partprogramming09/webscope@v0.2.4",
        "webscope-mcp",
        "--manifest",
        "${workspaceFolder}/webscope.json"
      ]
    }
  }
}

Zed (settings.json)

{
  "context_servers": {
    "webscope": {
      "command": {
        "path": "uvx",
        "args": [
          "--from",
          "git+https://github.com/partprogramming09/webscope@v0.2.4",
          "webscope-mcp",
          "--manifest",
          "/absolute/path/to/your/project/webscope.json"
        ]
      }
    }
  }
}

Instead of --manifest you can set the environment variable WEBSCOPE_MANIFEST. Without either, the server uses ./webscope.json if it exists; otherwise it serves the current folder with buscar and leer and no scripts.

Updating

If you previously installed or ran an earlier version of Webscope:

  • uvx: uv caches git repositories and tools. Clear the cache or pass --refresh:
    # Clean cached tool package
    uv cache clean webscope-mcp
    
    # Or run uvx with --refresh
    claude mcp add --scope project webscope -- uvx --refresh --from git+https://github.com/partprogramming09/webscope@v0.2.4 webscope-mcp --manifest "$PWD/webscope.json"
    
  • pip:
    pip install --upgrade --force-reinstall git+https://github.com/partprogramming09/webscope.git@v0.2.4
    
  • Git clone:
    cd ~/webscope && git pull origin main
    

Docker

docker build -t webscope .
docker run -i --rm -v "$PWD:/project:ro" -e WEBSCOPE_MANIFEST=/project/webscope.json webscope

Without WEBSCOPE_MANIFEST the image serves the bundled webscope.example.json.

Tools

Tool What it does
buscar(texto, donde?, tope?, formato?, contexto?, regex?) Case-insensitive search, literal unless regex=true (extended regex). Hits grouped by file, most-referenced files first, capped at tope lines. donde limits it to a folder or file; contexto (0-5) adds lines around each hit. formato="conciso" returns only the top 5 files with counts.
leer(archivo, simbolo?, lineas?, max_lineas?, cola?, contiene?, formato?) Returns only one function, method or class (PHP, TS, JS, Vue, Python) — or several, if simbolo is a list —, one Markdown section by heading, a line range (lineas="120-180"), or for .log/.txt/.out files the last cola lines and/or the lines containing contiene. Without simbolo or lineas it returns the file's index: headings or definitions with their line numbers.
correr(nombre?, args?, detalle?) Runs a script declared in the manifest and returns exit N plus trimmed output. Without nombre it lists the scripts; detalle="esquema" shows one script's usage. Read-only.
correr_escritura(nombre, args) Only listed when a script declares escribe. Runs a write argument; requires WEBSCOPE_ESCRITURA=1 in the server environment and is marked destructiveHint and anthropic/requiresUserInteraction.

Every answer starts with one short line saying what it is and what to do next, and is capped at tope_tokens (about 4 characters per token).

A malformed request, a non-UTF-8 script output or an unexpected error comes back as an error message; the server keeps running. buscar skips files that are not valid UTF-8 when the locale is UTF-8 (grep treats them as binary).

Security model

  • Project root only. buscar and leer resolve paths against the manifest's root and reject anything outside it.
  • Secret files are invisible. buscar and leer skip .env, .env.*, *.pem, *.key, *.p12, id_rsa*, id_ed25519*, auth.json and credentials* (templates ending in .example stay visible).
  • Fixed commands, no shell. Scripts run as a fixed argument list from the manifest. Arguments that are absolute paths or contain .. are rejected (unless the script sets acepta_barra, which allows URL-like /a/b but still not ..). Flags listed in rechaza are rejected.
  • Read-only by default. correr refuses any argument listed in a script's escribe. Those go through correr_escritura, which only exists when declared and only runs when the user sets WEBSCOPE_ESCRITURA=1.
  • Minimal environment. Scripts do not inherit the server's environment. They receive only PATH, HOME, LANG, LC_ALL, TMPDIR, the variables named in the manifest's env_permitidas, plus WEBSCOPE_RAIZ (project root) and WEBSCOPE_MANIFIESTO (manifest path).
  • Bounded output. Script output is trimmed to head and tail lines, and each response to tope_tokens.

The scripts themselves are trusted code: Webscope limits how they are called, not what they do. Only list scripts you would run yourself.

Configuration (webscope.json)

See webscope.example.json.

{
  "root": ".",
  "recorte": { "cabeza": 10, "cola": 70 },
  "tope_tokens": 5000,
  "buscar": { "dirs": ["src"], "extensiones": ["py", "ts"] },
  "env_permitidas": ["DATABASE_URL"],
  "almacenamiento": ".agents/webscope",
  "prefijo_prueba": "ZZ_E2E",
  "scripts": {
    "report": {
      "cmd": ["python3", "-I", "scripts/report.py"],
      "descripcion": "Summarises a table",
      "uso": "<table>",
      "rechaza": ["--out"],
      "escribe": ["--fix"],
      "timeout": 120
    }
  }
}
Key Meaning
root Project root, relative to the manifest's folder.
recorte Default head (cabeza) and tail (cola) lines kept from script output.
tope_tokens Maximum size of any response, in approximate tokens.
buscar.dirs, buscar.extensiones Folders and file extensions searched by default.
env_permitidas Extra environment variables passed to scripts.
almacenamiento Carpeta de almacenamiento para persistencia interna (mapa-modulos.json, flujos/, recorridos/). Por defecto autodetecta .agents/webscope/, .claude/webscope/ o .webscope/.
prefijo_prueba Prefijo para nombres y valores creados durante pruebas (por defecto ZZ_E2E).
scripts.<name>.cmd Fixed command as a list; python3 is replaced by the server's interpreter.
descripcion, uso Shown by correr() listings.
rechaza Flags that would write files; always refused.
escribe Arguments that write data; only via correr_escritura with WEBSCOPE_ESCRITURA=1.
acepta_barra Allow arguments starting with / (URL paths).
timeout, cabeza, cola Per-script overrides (e2e_chrome raises cabeza and cola so its whole JavaScript arrives in one piece).

Included scripts

The package ships ready-made scripts in webscope_adaptadores/. All adapters (db_check.php, agents, web/*.js) come packaged as internal package assets. A manifest names them with {adaptadores} in cmd (see webscope.example.json); copy the entries you need and adjust the folders.

Script What it answers Stack
vue_ts.py (mapa) Routes, views, API calls, composables and stores of a frontend module; --recorrido lists what can be clicked (actions with their v-if and permission, links, tabs with their API, form fields); --cobertura says which calls an e2e capture exercised Vue 3 + TS
laravel.py (mapa_back) Endpoint, controller, service, model and table behind a frontend module or API path Laravel
astro.py (mapa_web) File-based routes and endpoints with what they call; for one page, its components, data, client scripts, API calls and form fields with their visible (translated) label; --cobertura <capture> counts the page's /api/ calls a capture exercised Astro
e2e_chrome.py JavaScript for one javascript_tool call of Claude in Chrome (or paste it in the browser's own DevTools console): walks routes and returns per route time, rows, failed requests, console errors and UI problems, without screenshots. Las macros (__f, ayudantes de pantalla) se auto-inicializan y toleran recargas de página sin error. --llamar reuses the walk already installed in the page; --captura/--detalle record what the page sends and receives; --form installs __f to fill a form by label, press Save and read it back, plus screen helpers that replace screenshots and coordinate clicks: estado() (the screen as short text), clic(text) (click by visible text, then wait until the page settles), esperar, ir(route) (router navigation without reload) and pasos([...]) (several steps in one call). With a local receiver: --servir [port folder] starts it (reutiliza el puerto inteligentemente si ya está en marcha), --cargar [port] installs capture and __f from it, --guardar <name> [port] sends the whole capture to <folder>/<name>.txt (with one ms <ms> <method> <status> <path> line per API call; the receiver answers with the 5 slowest) and the steps __f recorded to .claude/webscope/recorridos/<name>.json, and --repetir <name> replays those steps in one call (with a fresh stamp on ZZ_E2E values) while the frontend does not change; --mapear [text ...] enumerates the routes the router registers (filters by text, e.g. crm/quotes) and walks them deep by default: routes, every tab of each screen and the first record of each :param (read-only; --superficial walks routes only) and, on save, the receiver merges a module index .claude/webscope/mapa-modulos.json (module → routes → captures and walks that cover it; --indice [text] prints a ≤25-line summary — with a captures folder it rebuilds from it, the full JSON stays in the file); --exportar <capture> <url> writes a Playwright test with the same steps; --evaluar <código o archivo> [coincidencia] permite ejecutar JavaScript directamente sobre la pestaña activa o coincidente de la ventana abierta de Google Chrome del usuario (reutilizando perfiles, cookies y sesión) sin abrir instancias duplicadas Any SPA with a router
payload_check.py Checks a capture against the FormRequest rules, the Resource and the table columns; flags keys without a rule, values outside in:, '' sent to a nullable column Laravel
limpiar_zz.py Lists, and with --borrar deletes after a backup, test rows whose code starts with ZZ_ Laravel
costo_sesion.py Cost of the latest (or a given) Claude Code session in the project: USD per model at list prices (subagents and advisor included), calls and re-read context per tool, large outputs, repeated calls, and which tool loops would have been cheaper in a subagent Claude Code
uso_agentes.py Subagent usage: turns, context, models, agents over the turn limit Claude Code
uso_webscope.py Share of file reads and searches that went through leer and buscar in sessions where Webscope was available, and the Read/sed/grep calls used instead Claude Code
estado_sesion.py Session bootstrap: replayable walk templates, mapped flows (findings/pending), module index, the test menu and the budget rules, in ≤35 lines Any project
db_check.php Data-integrity check at the database layer (SELECT only): test rows by prefix marker, column list and sample rows, from a .env; MySQL/Postgres, credentials never printed Any project with a DB

Two prompts ship with the server: sesion (the browser session starts with estado_sesion, the test menu and the budget rules; shows the menu table as a question only when the user does not name a test type) and recorrido (one-module walk).

Project-specific settings go in the manifest's proyecto section:

Key Used by Meaning
modulos payload_check Backend modules folder (default app/Modules)
prefijo_rutas e2e_chrome Prefix the app lives under, e.g. /demo, so routes work with or without it
contenedor mapa_back Docker container where php artisan route:list --json runs; empty reads the route files
sql payload_check, limpiar_zz Script that runs a read-only SQL query and prints TSV with a header
tinker limpiar_zz Script that runs a PHP file against the database (<script> <file.php> --commit)
php_db limpiar_zz PHP expression for the connection (default DB::connection())
capturas MCP resources Captures folder (the one given to --servir); its .txt files are listed as webscope://capturas/<file> next to the saved walks webscope://recorridos/<file>
almacenamiento e2e_chrome, proyecto Carpeta de persistencia interna (autodetecta .agents/webscope/, .claude/webscope/ o .webscope/)
prefijo_prueba e2e_chrome, proyecto Prefijo para nombres y registros creados durante pruebas (por defecto ZZ_E2E)

The Vue index cache and limpiar_zz backups go to ~/.cache/webscope/. The e2e_chrome receiver writes captures to the folder given to --servir (default capturas, relative to where it starts), and at each save merges the module index into <almacenamiento>/mapa-modulos.json (.agents/webscope/, .claude/webscope/ o .webscope/ por defecto; module → routes → captures and walks that cover it), so start it with the project environment like the other scripts: WEBSCOPE_RAIZ (only needed if you want the project root) and WEBSCOPE_MANIFIESTO (path of webscope.json), which --cargar/--guardar need for the route prefix. --servir does not return: start it from a shell in the background (the example manifest lists it in rechaza, so correr refuses it).

Using the scripts from a subagent

A subagent sees Webscope only if its definition lists the tools, for example in .agents/<name>.md or Claude Code's .claude/agents/<name>.md:

tools: Read, Grep, Glob, Bash, mcp__webscope__buscar, mcp__webscope__leer, mcp__webscope__correr
model: sonnet

Add mcp__webscope__correr_escritura only if the agent must run write arguments, plus the browser tools it needs.

Exporting the recorrido agent (webscope-mcp --agente)

You can export the ready-made recorrido agent automatically:

# Autodetecta .agents/ o .claude/agents/
webscope-mcp --agente

# O especificando el directorio de destino
webscope-mcp --agente [directorio]

# O directamente con Python
python3 webscope.py --agente [directorio]

Este comando exporta recorrido.md configurado con las herramientas requeridas (Read, Grep, Glob, mcp__webscope__*). Es completamente no destructivo:

  • Protección 100% de agentes existentes del usuario: si ya existe recorrido.md, jamás lo sobreescribe sin la bandera --force.
  • No modifica ni elimina ningún otro agente definido en el directorio del usuario (reviewer.md, debugger.md, etc.).

agents/recorrido.example.md es la plantilla base de agente que recorre un módulo de frontend en Chrome con mapa, e2e_chrome y limpiar_zz devolviendo un resumen de máximo 25 líneas.

One measurement (a browser walk of one module, one project, one run per condition) found:

  • With the walk in the main session, Webscope did not change the cost (+7 % and −5 % in two runs). It changed accuracy: the order of steps (mapa --recorrido), the fields that were not saved (__f.verificar) and the measured coverage.
  • The same walk in a sonnet subagent that returns a summary of at most 25 lines cost 1.05 USD instead of 6.40, with the same coverage. About 2× came from isolating the context; the rest from the sonnet price.
  • Page reads and screenshots were about 80 % of the re-read context, so the agent reads state with javascript_tool and takes screenshots only to understand an error.
  • Subagents that ran for more than about 40 turns grew their context like a main session. Give one module or one bounded task per agent, and tell it to stop at about 40 tool calls and return what is done and what is pending.

costo_sesion.py --raiz <project> and uso_agentes.py --raiz <project> measure the same in another project. The USD come from the price table at the top of costo_sesion.py (list prices, October 2026), which only lists models checked against the cost reported by claude -p (Opus 5.5, Sonnet 5.5, Fable 5.1: within 0.01 USD on three runs); any other model is shown as sin precio until it is added.

Hook: suggest Webscope

Agents often keep using Read, cat, sed -n and grep even when Webscope is available. hooks/sugerir_webscope.py is a Claude Code PostToolUse hook that, after such a call, adds one line to the model's context with the equivalent Webscope call (for example leer(archivo, lineas="120-180")). It never blocks and speaks at most 3 times per session. Add it to the project's .claude/settings.json or .claude/settings.local.json:

{"hooks": {"PostToolUse": [{"matcher": "Read|Bash", "hooks": [{"type": "command",
  "command": "python3 -I /path/to/webscope/hooks/sugerir_webscope.py"}]}]}}

uso_webscope.py measures whether it works: the share of reads and searches that go through Webscope.

Browser UI check

webscope_adaptadores/web/chequeo-ui.js is a standalone snippet for a browser automation tool (page.evaluate in Playwright, or a JavaScript tool in a browser extension). It returns only the problems on the current page: horizontal overflow, empty chips or badges, untranslated i18n keys, raw values (undefined, NaN…), overlapping text and unnamed buttons.

PLAYWRIGHT_DIR=<folder containing node_modules/playwright> node webscope_adaptadores/web/test_chequeo_ui.mjs
PLAYWRIGHT_DIR=<folder containing node_modules/playwright> PW_CHANNEL=chrome node webscope_adaptadores/web/test_form.mjs

PW_CHANNEL=chrome uses the installed Chrome when Playwright's own browser is missing.

Tests

python3 -I test_webscope.py

Out of scope

Webscope does not replace a language server or a browser automation server, does not run code written by the agent, and is not a test framework.

License

MIT

Metadata

Release files for webscope-mcp 0.2.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for webscope-mcp 0.2.4
File Size Uploaded Provenance
webscope_mcp-0.2.4.tar.gz 97.0 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for webscope-mcp 0.2.4
File Interpreter ABI Platform
webscope_mcp-0.2.4-py3-none-any.whl Python 3 none any Details

Total release size: 196.2 kB

Release files / webscope_mcp-0.2.4.tar.gz

Download URL webscope_mcp-0.2.4.tar.gz
Size 97.0 kB
Tags Source
SHA-256 checksum
How to use checksums
b22eadf74baa48c23735e01b577b25f49f4f9f17fc4b92bbb339daa94b7ad4d6
BLAKE2b-256 checksum
How to use checksums
530759ec38d4952f9f2667fb09ee853cdd9941339e11d75975cd2f05889950ee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / webscope_mcp-0.2.4-py3-none-any.whl

Download URL webscope_mcp-0.2.4-py3-none-any.whl
Size 99.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c1f051febe9b26824620a93c17204f8e469110b6966987bf81c0fdf94a3e315e
BLAKE2b-256 checksum
How to use checksums
072c1a8d762653f27151fee13212e46c8c9f9d4f32840c5dc5187c84450e384f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Security for webscope-mcp 0.2.4

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for webscope_mcp-0.2.4.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page