MCP server, позволяющий ИИ-агентам тестировать веб-приложения через чтение баз данных, управление браузером Chrome и анализ исходного кода проекта.
Также известен как partprogramming09/webscope, webscope-mcp
- Звёзды
- 0
- Инструменты
- 6
- Загрузки, 30 дней
- —
- Последняя версия
- 0.6.0
- Последний коммит
- 12 нояб. 2026 г.
- Лицензия
- MIT
Что такое Webscope MCP?
Webscope — это MCP server. MCP server, позволяющий ИИ-агентам тестировать веб-приложения через чтение баз данных, управление браузером Chrome и анализ исходного кода проекта. Он предоставляет 6 инструментов, например query, page, check.
Сводка сгенерирована из README проекта
О Webscope MCP server
Webscope позволяет тестировать веб-приложения, подключая ИИ-агентов к базам данных, браузерам и исходному коду. Это дает разработчикам возможность проверять, что действия пользователя в браузере Chrome корректно обновляют базу данных MySQL или SQLite, избавляя агента от необходимости гадать или тратить лишние токены. Сервер предоставляет структурированные текстовые ответы с ограничением объема, чтобы взаимодействие оставалось эффективным и целенаправленным.
Пользователи разворачивают сервер локально с помощью бинарного файла Go и подключают его к MCP-клиенту, например Claude Code. Для работы требуются определенные переменные окружения, такие как WEBSCOPE_DB_URL для доступа к базе данных, WEBSCOPE_APP_URL для целевого браузера, а также пути к исходному коду бэкенда и фронтенда. Система работает с базой данных в режиме только для чтения, гарантируя, что любые изменения данных происходят только через собственный пользовательский интерфейс приложения.
Сервер работает через четыре основных инструмента: query для выполнения SQL-запросов на чтение, page для управления Chrome, check для сравнения данных на экране с записями в базе данных и code для анализа структуры и логики проекта. Он особенно эффективен при миграции устаревших PHP-модулей на современные стеки Laravel и Vue путем сравнения старого и нового поведения.
Что вы можете с ним делать
- 1Проверка целостности базы данных после отправки формыПопросите агента заполнить веб-форму и подтвердить, соответствуют ли данные, сохраненные в базе данных, тем, что были отправлены с экрана.
- 2Аудит удобства использования и доступности веб-экрановЗапросите аудит конкретного экрана, чтобы найти нерендеренный текст или элементы управления, перекрытые другими объектами.
- 3Сравнение идентичности устаревшего и современного приложенийПроверьте, отправляет и получает ли заново переписанный модуль те же поля данных, что и оригинальная устаревшая версия.
- 4Анализ потребителей кода бэкендаОпределите, какие части кода бэкенда отвечают за чтение или запись в конкретный столбец базы данных.
- 5Симуляция серверных ошибок для тестированияПринудительно вызовите ошибку HTTP 500 на веб-странице, чтобы проверить, как пользовательский интерфейс обрабатывает сбои на стороне сервера.
Взято из README проекта. Каждый вариант использования проверен на соответствие цитате из него.
Как установить Webscope MCP
Форматы проверены 10 ноя 2026Установка Webscope MCP в Claude Code
$ claude mcp add webscope -- uvx webscope-mcpУстановка Webscope MCP в Cursor
~/.cursor/mcp.json
{
"mcpServers": {
"webscope": {
"command": "uvx",
"args": [
"webscope-mcp"
]
}
}
}Установка Webscope MCP в VS Code
.vscode/mcp.json
{
"servers": {
"webscope": {
"type": "stdio",
"command": "uvx",
"args": [
"webscope-mcp"
]
}
}
}Установка Webscope MCP в Claude Desktop
claude_desktop_config.json
{
"mcpServers": {
"webscope": {
"command": "uvx",
"args": [
"webscope-mcp"
]
}
}
}Установка Webscope MCP в Codex
~/.codex/config.toml
[mcp_servers.webscope] command = "uvx" args = ["webscope-mcp"]
Установка Webscope MCP в Gemini CLI
~/.gemini/settings.json
{
"mcpServers": {
"webscope": {
"command": "uvx",
"args": [
"webscope-mcp"
]
}
}
}Инструменты Webscope MCP 6
Определено из READMEquerypagecheckcodestatepayloads
| query | — | |
| page | — | |
| check | — | |
| code | — | |
| state | — | |
| payloads | — |
Автоматические проверки
Запущено 14 нояб. 2026 г.Полный отчёт →Прошло наши автоматизированные проверки. Это не аудит безопасности: изучите код и предоставьте серверу минимально необходимый доступ. Как работают проверки
- Связанный и доступный исходный репозиторийpartprogramming09/webscope is public and reachablegithub.com/partprogramming09/webscope ↗Пройдено
- Пакет указывает этот репозиторий как источникwebscope-mcp names partprogramming09/webscope as sourcepypi.org/project/webscope-mcp/ ↗Пройдено
- Происхождение сборки (аттестация Sigstore)Sigstore attestation for webscope-mcppypi.org/project/webscope-mcp/ ↗Пройдено
- Open source лицензия (OSI)MITspdx.org/licenses/MIT.html ↗Пройдено
- Коммит или релиз за последний годLast commit or release 2026-11-12github.com/partprogramming09/webscope ↗Пройдено
- OpenSSF ScorecardНе проверялось
- Имя пакета не похоже на популярный пакетNo popular package one edit away from webscope-mcpПройдено
- Нет критических уязвимостей в пакете и зависимостях1 resolved dependencies checked; no critical advisoryosv.dev ↗Пройдено
- Нет скрытых инструкций для модели6 tool descriptions and the README read; no override phrases, credential paths or hidden charactersПройдено
- Деструктивные инструменты помеченыNo tool named like delete, drop or execПройдено
- Удалённый endpoint отвечает на MCP handshakeНе проверялось
README
Открыть на GitHubwebscope
An MCP server that lets an AI agent test a web application and understand its data and code while spending very few tokens. It reads your database, looks at and drives a screen in your Chrome, checks that what a screen sent is what ended up saved, and reads the project's code. One Go binary, four tools, and it never writes to your database.
What it is for
When you ask an agent to «test the quotes screen», the expensive part is not thinking: it is reading. Whole pages of HTML, hundreds of table rows, the output of a grep over a backend. webscope answers with short, capped, structured text instead, so the agent can do the whole round (look at the screen, fill it, save, see what was stored, see what else changed) in a handful of calls.
It was built against a real Laravel + Vue application and its older PHP version, and works on any web app and any MySQL or SQLite database. Some pieces are tied to a stack: map, map_back, flows and cases to Laravel routes and Vue modules, and legacy to legacy PHP with the SQL inside the file and jQuery calls; the rest is generic.
What you can ask your agent
With the server registered, ask in plain words:
- «How many rows does
quoteshave, and which columns are always empty?» (query,code fields) - «Who reads or writes the column
statusofquotesin the backend?» (code consumers) - «Open the quotes screen, fill the form with test data, save it, and tell me if what the screen sent is what was stored.» (
page,check) - «What did saving that quote really write? List every row it touched, child tables included.» (
code snap,snap_diff) - «Make the quotes list answer a 500 and tell me what the screen shows.» (
page simulate) - «Audit this screen: text that was not rendered, controls covered by something, fields nobody can name.» (
page audit) - «What does the old screen send when I press Search?» (
page payloads, also on legacy pages that use jQuery) - «Does the new screen send and receive the same fields as the old one?» (
page parity {req_a, req_b}) - «Compare the old and the new version of this screen.» (
page shapeon each, thenpage parity) - «Which endpoint, controller and table does this screen use?» (
code map_back) - «What are the flows and user stories of this module?» (
code flows; you write the stories from it and confirm them) - «What should I test in this module, and does the migration keep what the legacy did?» (
code cases, then the chain in «Migrating a module» below) - «Which unit tests pin what the legacy did?» (step 7 of
code help {topic: "migration"})
The four tools
| Tool | In one line | It needs |
|---|---|---|
query |
One read-only SQL statement; the answer is a short table. | WEBSCOPE_DB_URL |
page |
Read, fill and click a screen in your Chrome, see the requests it sent, force an HTTP error, audit it, and compare an old screen and a new one. | Claude in Chrome and WEBSCOPE_APP_URL |
check |
For one saved row: what the screen sent, what the database stored, what the screen read back. Only the differences. | page and the database |
code |
The sheet of a table, who uses a column, the routes and calls of a screen, what an action changed, the flows and test cases of a module, and what a legacy PHP module calls and writes. | WEBSCOPE_BACKEND, WEBSCOPE_FRONT, WEBSCOPE_LEGACY |
A typical session, in the order that works best (docs/usage.md has the contract of each tool):
code fieldsandquery: learn the table and its current counts.code maporcode map_back: learn which endpoints and tables the screen touches.code snap: keep the table as it is before the action.page:load,state,fill,click.check: compare the saved row with what was sent and read back.code snap_diff: see every row the action wrote.- Clean up through the screen, never through the database.
Requirements
- Go 1.27.3 or newer, to build it (
go.mod). - An MCP client. The quick start below uses Claude Code.
- For
query,checkandcode fields: a MySQL or SQLite database. - For
pageandcheck: Google Chrome with the Claude in Chrome extension and a tab open on the app you test. - For
code: the source folders of the app (a Laravel backend and a Vue front formap,map_back,flowsandcases).
Quick start (Claude Code)
go build -o webscope . # Go 1.27.3 or newer (go.mod)
claude mcp add webscope \
-e WEBSCOPE_DB_URL='mysql://user:pass@127.0.0.1:3306/dbname' \
-e WEBSCOPE_APP_URL='http://localhost:5173' \
-e WEBSCOPE_BACKEND='/path/to/backend' \
-e WEBSCOPE_FRONT='/path/to/front' \
-- /absolute/path/to/webscope
Only WEBSCOPE_DB_URL is needed to start (query). The others switch on the rest:
WEBSCOPE_APP_URL: the address of the tab to test, exactly as the browser writes it (scheme, host and port).pageneeds it, and it needs the Claude in Chrome extension. When the old and the new app answer on different addresses, list them separated by commas (http://localhost:8088,http://demo.localhost:5173): the helper then works in a tab of any of them and the requests of all of them are kept together.WEBSCOPE_BACKEND: the folder with the project's PHP.codeuses it.WEBSCOPE_FRONT: the folder of the Vue front (itssrc/modulesis read if it exists).code mapandmap_backuse it.WEBSCOPE_LEGACY: the folder of the legacy PHP (the one that holds the module folders, for examplepublic_html).code legacyreads it; it never leaves it, follows no link and opens no.env*.WEBSCOPE_TENANT_QUERY: a tenant lookup other than Hyn Tenancy's (see below).WEBSCOPE_DOWNLOADS: the folder Chrome saves files to, forpage download(default~/Downloads).WEBSCOPE_LOG: the backend log (for example PHP's error log): when a request ends with status 0 or 5xx,click,pressandpayloadsadd the error lines written to it since that click or key began (up to 3, 200 characters each, as the log wrote them: they can hold data). The helper notes where the file ends before each click or key, so it needs no clock and no timestamp format.
After changing a variable, or after rebuilding, reconnect with /mcp: the connected client keeps talking to the old process. To check it works, ask the agent for query with SELECT 1 and for page(help).
What it guarantees
- It never writes to the database.
queryis read-only twice (a statement check, and a read-only session);check,codeandsnaponly read. - Writes happen only through the screen, with your approval, on rows prefixed
ZZ_. Cleaning up is done through the screen too. - Answers are small and say what they left out: 50 rows (at most 500), 200 characters per cell, 8000 bytes per answer. The list of tools the agent has to load stays under 1800 bytes (a test checks it).
pageis local: a server on127.0.0.1with a random port and token, which answers only the origin of your app.- No guessing:
checktakes the field-to-column map from you, and every answer ofcodethat comes from searching text says it is an estimate. - With customer data, ask for the schema and for counts, not for rows.
- The tool reports, the model decides: webscope only labels facts it can check and never blocks an action. How to report a test honestly (verified apart from not verified, an interceptor said on the first line, a download counts only if the file is on disk) is in docs/usage.md.
Things worth taking advantage of
- Tenants.
tenantonquery,checkandcode fieldsruns in another database, found in the central one (Hyn Tenancy by default). - Right addresses.
page open {path}goes to a router path fromcode mapthrough the app's own Vue Router (which adds the tenant prefix) and refuses a path no route owns, naming the similar ones, so a screen is never reached by a typed URL. - Errors on demand.
page simulate {match, status}makes the next requests to a URL answer an HTTP error, so you see what the screen does with a 500 without breaking anything. - What did the action really write?
snapbefore andsnap_diffafter show only what changed, child rows included. - Old pages too. The helper sees
fetchandXMLHttpRequest, including pages that replace the constructor (the legacy PHP pages of the app that motivated this); a legacy link reloads the page, so runpage(load)again after each one. - A review of a screen without a reference.
page auditlists unrendered text, covered controls, unlabeled fields, repeated labels and unnamed buttons; it is a hint, not a verdict. - A list of what has been found.
docs/patterns.mdrecords the findings met while testing screens, each with how to recognize it, what to do and how far it was verified.docs/module-testing.mdis the procedure for testing a whole module.
Migrating a module from a legacy system, start to end
The case this was extended for: a module that exists in an old system and was rebuilt, and you want to know what the new one lacks, adds or changes. It takes two origins (WEBSCOPE_APP_URL=http://old:8088,http://new:5173), the legacy folder (WEBSCOPE_LEGACY) and two tabs of Chrome with the session started. Everything below reads; the only writes are one test row per system through the screen, prefixed ZZ_, and only with your approval.
| Step | Ask the agent | What it runs | What comes back |
|---|---|---|---|
| 1. What the module does | «Give me the flows and user stories of crm/quotes» |
code flows |
Screens and actions with their conditions and permissions, then endpoints, controllers and tables, as evidence; the stories are written from it and you confirm them |
| 2. What the old code touches | «What does the legacy quotes module call and write, and which tables does the new one not have?» | code legacy {path, module} |
Each legacy endpoint with its caller and tables; the tables only one side has, split into «named elsewhere in the backend» and «not named» |
| 3. Screens | «Compare the quotes list of the old and the new screen» | page shape {name, selector} on each, page parity {a, b} |
Only the fields, buttons and columns one side has |
| 4. Requests | «Does the new search send and receive what the old one did?» | the same action on both, page parity {req_a, req_b, map} |
Status and the field names only one side sends or gets, never values |
| 5. What to test | «List the test cases for this module» | code cases |
A table: happy path, permission, required field, status, HTTP error and empty list, with what runs each |
| 6. A write on both | «Create a ZZ_ quote on each system and compare what was saved» |
code snap, page fill and click, code snap_diff, code rows, query |
The rows each system wrote, their differences, and the child rows by count |
| 7. Unit tests | «Plan the unit tests that pin the old behaviour» | code help {topic: "migration"}, step 7 |
How to write each confirmed difference as a unit test, in the layer that owns the rule |
The whole chain, step by step, is code help {topic: "migration"}. A real run on a quotes module found, among other things: 21 of 22 tables «only in the legacy» were in fact used by the new backend, one database view the old code reads does not exist, the old screen was saving a number the new one had already taken (Duplicate entry … 1062), and the two systems wrote the same child rows for a new quote. CHANGELOG.md has the detail of each run and what was not checked.
Docs
docs/usage.md is the contract of each tool and the order to use them in. docs/module-testing.md is the procedure for testing a module and docs/patterns.md the list of patterns found while testing screens. CHANGELOG.md has one entry per version. To build, test or change the server, see CONTRIBUTING.md; to report a vulnerability, SECURITY.md.
Reference
The query tool
query(sql, limit?): one statement that starts with SELECT, SHOW, DESCRIBE, EXPLAIN or WITH. WEBSCOPE_DB_URL is mysql://user:password@host:port/db or sqlite:///path/file.db; percent-encode special characters in the password. The answer is TSV (header, \N for NULL, rows and cells capped).
Two layers keep it read-only: a statement check (one statement, no INTO, no /*! */ comments) and a read-only session (MySQL READ ONLY transaction, SQLite query_only). Answers stop at 50 rows (at most 500), 200 characters per cell and 8000 bytes of rows (plus a one-line footer), and say when something was left out. The statement is read under the rules of MySQL and of SQLite at once and must be one safe read under both, so a quote escaped with a backslash ('it\'s') is refused: double it ('it''s'). LOAD_FILE, GET_LOCK, PRAGMA, ATTACH and DETACH are refused too, and so are FOR UPDATE and FOR SHARE (they take locks) and a WITH that ends in DELETE, UPDATE, INSERT or REPLACE as a statement (REPLACE(...) and INSERT(...) as functions are reads). A SQLite file is opened read-only (mode=ro): a path that does not exist is an error and is not created.
With tenant (an fqdn) the query runs in that tenant's database, found in the central database of WEBSCOPE_DB_URL with Hyn Tenancy's hostnames and websites tables. WEBSCOPE_TENANT_QUERY replaces that lookup: one ?, the database name in the first column.
The page tool
page(action, args?) does not drive the browser: it returns a short JavaScript snippet and you run it with Claude in Chrome's javascript_tool; the snippet returns the screen as compact text. Set WEBSCOPE_APP_URL to the address of the tab, exactly as the browser writes it: scheme, host and port (http://localhost:5173; a tenant on a subdomain is another origin, http://demo.localhost:5173). The listener refuses every other origin, so with a different address the helper still loads and state and audit work, but payloads shows no requests; it then says that a request was refused. Restart the server after changing the variable. After a rebuild and /mcp, a page that still holds the helper of the old build answers Failed: an older helper is in this page: reload the page and run page(load) again.
page(load): one line that loads the helper. A local server on127.0.0.1(random port, random token per start, answers only the app's origin, caps what it receives) serves the helper and keeps the requests the page sends. Run it once per page load, and again after every navigation, reload or/mcp.state(a first line when the screen looks like a 404; the URL with the names of its query parameters, never their values; title, the console lines logged since the helper loaded (console.error,console.warn, uncaught errors and rejected promises, without query strings; what was logged beforeloadis not seen), headings, fields, buttons (the dialog's first, the side menu's last, up to 30, disabled ones marked(disabled)), alerts, errors, table rows),read,fill(a whole form in one call; when a name fits several fields, such as a list filter and a form field with the same label, it fills the first one (a dialog's before the page's), warns and lists the others, and an id picks one; it also chooses in Vuetifyv-selectandv-autocompletemenus, scrolling long lists, and fails with the options it saw when the one asked for is missing, in a menu or in a native<select>),clickandpress(both wait for the answer and report the requests (method, path without the query string, status, or0 (no answer)for one nobody answered), the new alerts, field errors and console errors, a URL change, or «No effect seen»; they andstatealso warn when the tab's origin is not the one inWEBSCOPE_APP_URL),simulate(the next requests to a URL answer an HTTP error, forfetchand XMLHttpRequest),audit(what the page shows wrong about itself, see below), each returns a snippet.payloads: the requests sent and their answers, answered by the tool itself; when any request failed, aProblems:line counts them (4xx, 5xx, no answer) over all the captured ones, not only the shown ones.clickandpresssayStill pending: N request(s)…when a request had not answered after about 2.5 s, instead ofNo effect seen.helplists the arguments.
fill also writes into a rich-text editor (contenteditable), found by its aria-label or id or, when it has neither, as editor. A field whose <label> is empty is named by its aria-label, placeholder, name or id. click {text} falls back to the plain element with exactly that text when no button or link has it, and when nothing matches the error lists the dialog's buttons first.
shape {name, selector?} saves what the screen offers under a name (with selector, only what is inside the first element it matches, such as the list or a dialog; a selector that matches nothing fails and saves nothing), in the local listener and in memory (field labels and kinds, buttons, table columns, tabs and headings; no values; the side menu and the top bar are left out). parity {a, b} (answered by the server, no snippet) compares two saved shapes and prints only only in a, only in b and the fields that kept their label but changed kind; names are compared ignoring case and spaces. It compares names, so it cannot say two screens behave the same. Shapes are lost when the server restarts; up to 20 are kept.
parity {req_a, req_b, map?} compares instead two captured requests, for example the same action on the old and the new screen: each spec is a method and a part of the address (POST save.php), and the latest capture that matches is used. It prints the two requests, the status if it differs, and the field names only one side sent (sent only in a) or received (got only in b); never a value. It reads JSON (nested names with a dot, a list by its first element as lines[].qty), forms (a=1&b=2, what the old jQuery pages send) and the query string of the address (a GET sends its fields there; a list index is written [], as in filters[statuses][]). The request line shows the address without its query string and how many parameters it had (?5 params), never their values; a body that was cut or that is neither says so and is not compared. map {name in a: name in b} renames the names of a first, so DESCRIPCION and notes count as the same field.
audit {selector?} lists, without any reference screen: unrendered text ({{ x }}, undefined, null, NaN, [object Object]), controls covered by another element, fields with no label (with their name, id and a short CSS path), repeated labels, and buttons or links with no name. It says so when it finds nothing, and selector limits it to a part of the screen. It is a hint to look at, not a verdict.
download proves a download with the real click: download {arm:true} notes the files in the downloads folder (WEBSCOPE_DOWNLOADS, else ~/Downloads), you make the real click in the page, and download {wait:true, seconds?} (10 s by default, at most 60) returns the new file's name, size, type by its first bytes (PK with xl/workbook.xml is xlsx, %PDF is pdf) and time, and for an xlsx the header names and the row count, never a value. Partial files (.crdownload) do not count. download {report:true} lists the files this session saw appear (name and size) so that the report can say what was left in the folder: the user decides to delete them, the server never does. If no file appears, it answers Failed: no file appeared …: an export is downloaded only if this finds the file, not because a replaced fetch or a click on a patched anchor returned the right bytes. When the page's fetch, XMLHttpRequest.send or anchor click were replaced after load, the answers of page start with an Interceptor: line (a label; nothing is refused).
verify builds the final report from evidence: verify {claim, evidence} adds a claim and answers its state, which the server decides, not the caller. evidence is a reference: capture POST /api/quotes (a request that page captured), check POST /api/quotes (the last check of that request: no differences is OBSERVADO, a difference is NO VERIFICADO, only equivalent fields (empty~, space~) is INFERIDO) or download (a file that download wait found). A query is not evidence: a count says nothing about which claim it backs. OBSERVADO means the reference exists; INFERIDO means it exists but an interceptor was seen on the page since load; NO VERIFICADO means there is no evidence or none the server can find (free text is not evidence). verify {report:true} prints the table and {clear:true} empties it. It is optional and blocks nothing.
Arguments enter the snippet as escaped JSON, never as text. Writes happen only through the screen, with your approval, on rows prefixed ZZ_. fill on a multiple menu adds the option, it does not replace the ones already chosen, and a field that depends on another needs its own call. Not covered: v-combobox, calendar-style date pickers, menus of other libraries, file uploads, an editor inside an iframe (TinyMCE), pages whose Content-Security-Policy blocks the helper (all unchecked against the real app). Tests need a Chrome (WEBSCOPE_CHROME to point at one); a missing Chrome fails them.
The check tool
check(sent, table, where, map, after?, at?, tenant?) compares three things for one saved row: what the screen sent (a request page captured, e.g. POST /api/quotes, the last one that matches), what the database stored (the row where picks, {column: value}, in a read-only transaction) and what the screen read afterwards (after, another captured request such as GET /api/quotes, and at, the path of the object inside its answer: quote, data.0). map says which column holds each sent field: {"sub_type": "SUBTIPO_OPER"}. Nothing is guessed, because the names differ on each side.
The answer is the counts (equal, empty~, different) and one line only for each field that differs, each value cut at 40 characters; a row is never shown whole. 007 is not 7; a null, an empty text and a database NULL count as empty~ (equivalent, but said so); a field missing from the sent body is (absent) and counts as different. A field that the read does not name, while sent and stored agree, is unread~: not different (the read says nothing about it) and not equal either, so it is listed apart; if sent and stored differ, it is different and the read shows (absent). A body that was cut when it was captured (page keeps 8000 characters of each, the server 16 KiB) is refused, not compared. check never writes: it reads captures and one row.
Вопросы о Webscope MCP
Как добавить Webscope MCP в Claude Code?
Выполните claude mcp add webscope -- uvx webscope-mcp в терминале. Добавьте --scope user, чтобы сервер был доступен во всех проектах.
Как добавить Webscope MCP в Cursor?
Откройте ~/.cursor/mcp.json и добавьте сервер в mcpServers, используя конфигурацию Cursor из раздела установки выше.
Какие инструменты предоставляет Webscope MCP?
Он предоставляет 6 инструментов, включая query, page, check, code, state.
Пишет ли этот сервер данные в мою базу данных?
Нет, сервер предназначен только для чтения базы данных; запись должна осуществляться только через веб-интерфейс с вашего одобрения.
Какие технологии поддерживает Webscope?
Он разработан для работы с приложениями на Laravel и Vue, а также с базами данных MySQL или SQLite.
Как сервер взаимодействует с моим браузером?
Он использует Google Chrome с расширением Claude in Chrome для чтения, заполнения полей и нажатия на элементы на экране.
Может ли он помочь с миграцией устаревшего кода?
Да, в него включены специальные инструменты для сравнения устаревших PHP-модулей с новыми, включая проверку маршрутов, таблиц и идентичности экранов.