This Skill provides complete instructions for third-party AI Agents on how to use webmcp-cli via Model Context Protocol (MCP) to interact with browser pages.
When to use
- When you need to interact with a web page (click elements, fill out forms, scroll the page).
- When you need to read the current DOM structure and identify interactive elements.
- When operating on pages that have domain-specific tools injected (for example, the Excalidraw drawing tool).
Installation
The user environment usually already has the webmcp-cli tool installed. Only perform the following installation when the shell terminal indicates that the tool cannot be found:
npm install -g @opentiny/webmcp-cli
Commands
1. Manage browser tabs webmcp-cli tabs
All subcommands are as follows:
webmcp-cli tabs open https://excalidraw.com # 打开新网页
webmcp-cli tabs close <tabid> # 关闭指定标签页
webmcp-cli tabs switch <tabid> # 切换到指定标签页
webmcp-cli tabs back # 当前标签页后退
webmcp-cli tabs back <tabid> # 指定标签页后退
webmcp-cli tabs forward # 当前标签页前进
webmcp-cli tabs forward <tabid> # 指定标签页前进
2. Query the current browser state webmcp-cli state
It returns the current browser'snavigation metadata(url, title, activeTabid, webmcpTools, all open tabs), and is the only way to confirm which tools are available on the current page (webmcpTools).
Note:
statedoes not return page DOM content (there is nocontentfield). When you need to obtain interactive elements or page information state, explicitly callpage-agent-tool'sbrowserStateorsearchTreeaction.
webmcp-cli state
webmcp-cli state -t <targetId> # target a specific tab by its real Chrome target ID
Example output:
{
"url": "https://www.baidu.com/",
"title": "百度一下,你就知道",
"activeTabid": "2EA73ED323E46E5E108D4E46DA4E4AA7",
"webmcpTools": [{ "name": "page-agent-tool" }, { "name": "baidu_search" }],
"tabs": [
{ "tabid": "2EA73ED323E46E5E108D4E46DA4E4AA7", "title": "百度一下,你就知道", "url": "https://www.baidu.com/" }
]
}
In the return value, the tabs property value is the information for all tabs currently open in the browser; the other properties are the URL, title, and list of injected MCP tools for the currently active page (webmcpTools)。
tabidis the real Chrome target ID(UUID). Together with-t, you can specify a particular tab.
webmcpToolsIf the array of values for system-overviewcontains a tool forsystem-overviewand it has not been called under this domain in the current conversation round, then you must immediately execute it once. The tool's return value can guide subsequent operations, for example it will contain the website's模块 & 路由 & 页面工具 &使用规范and so on.
webmcp-cli run system-overview '{}'
When state must be called
| Timing | Must state be called first state |
Description |
|---|---|---|
Before executing tabs open before |
No | tabs open is the only command that can be executed directly without first calling state the command to execute directly in the case of |
After executing tabs after |
Yes | After a new page loads and tools are injected, you must use state to obtain the new page's webmcpTools |
Before executing run before |
Yes | You must first use state to confirm the tool list, then use browserState or searchTree to obtain the page's interactive elements |
Between consecutive multiple run between |
Depends on the situation | Only if you need to reconfirm the tool list or the current page do you need to call stateagain; to only obtain DOM changes, directly use the page-agent-tool -related action |
Recommended workflow:
- Open the page: use the
tabs opencommand to navigate to the target URL. - Confirm the state: use
stateGet navigation metadata, confirm whetherwebmcpToolshas finished injecting. - Get page information: this is interacting with the pagethe most critical step! Since
statedoes not contain DOM content, you must usepage-agent-toolto get the page's interactive elements.Please think independently based on the actual situation and choose the retrieval method:- Method A (on-demand search): if you clearly know the characteristics of the element you are looking for (for example, the "Login" button),prioritize using
searchTreeto save a large amount of context tokens.webmcp-cli run page-agent-tool '{"action": "searchTree", "query": "登录"}' - Method B (full retrieval): if you need a comprehensive understanding of the page structure, or do not know what specific elements are on the page, please use
browserStateto capture the complete accessibility tree.webmcp-cli run page-agent-tool '{"action": "browserState", "responseMode": "full"}'
- Method A (on-demand search): if you clearly know the characteristics of the element you are looking for (for example, the "Login" button),prioritize using
- Execute interaction: after obtaining the element index returned by the previous step (
index), then executeclick、filland other specific operations.
When executing the page-agent-tool operation (click, fill, scroll, etc.),you must determine the element based on the element index returned by browserState or searchTree The returned element index identifies the element index, and never reuse an outdated guessed index.
3. Execute tools on the page webmcp-cli run <tool-name> '<json-args>'
Execute the MCP tool on the current active page, json-args must be escaped in advance into valid CLI parameters.
Invocation specification
This tool can run in multiple terminals, but prioritize using the bash shell to run it.
When passing the json-args parameter in different terminals, please strictly follow the rules below:
- bash terminal: wrap with single quotes
json-args, eg. '{"action": "fill", "index": 0, "text": "your humorous and witty technical title"}' - cmd terminal: wrap with double quotes
json-args, and the double quotes inside need to be escaped, eg. "{"action": "fill", "index": 0, "text":"your humorous and witty technical title"}" - powershell terminal: wrap with single quotes
json-args, and the double quotes inside need to be escaped, eg. `{"action": "fill", "index": 0, "text":"your humorous and witty technical title"}'
When encountering a console error: executing run command: 参数不是有效的 JSON, be sure to check whetherjson-args the format of the parameter complies with the rules above.
3.1 page-agent-tool
It is a tool for automating web page operations. It exists on every page and can be called directly. It supports the following actions (action):
browserState、searchTree、click、fill、select、scroll、executeJavascript。
In addition, this tool accepts the configuration parameter responseMode, which is used to control the form of the page state returned after the operation:
diff(default): returns only the incremental DOM diff since the last state, greatly saving tokens.full: returns the complete semantic ARIA YAML tree in the current viewport.both: returns both the full tree and the incremental diff.
After executing operations such as click、fill、select、scroll , the tool will automatically use the specified responseMode(default diff) to return the latest page state,there is no need to manually call browserState。
Example:
# 1. 首次获取全量页面状态
webmcp-cli run page-agent-tool '{"action": "browserState", "responseMode": "full"}'
# 2. 点击索引为 18 的元素,自动返回 diff
webmcp-cli run page-agent-tool '{"action": "click", "index": 18}'
# 3. 填充文本框
webmcp-cli run page-agent-tool '{"action": "fill", "index": 13, "text": "Hello"}'
# 4. 选择下拉框选项
webmcp-cli run page-agent-tool '{"action": "select", "index": 7, "value": "option_value"}'
# 5. 滚动页面,同时获取全量与增量
webmcp-cli run page-agent-tool '{"action": "scroll", "down": true, "numPages": 1, "responseMode": "both"}'
# 6. 执行 JavaScript
webmcp-cli run page-agent-tool '{"action": "executeJavascript", "script": "document.title"}'
# 7. 对指定标签页操作
webmcp-cli run page-agent-tool '{"action": "browserState"}' -t <targetId>
3.1.1 Browser State: page accessibility tree format description
browserState Returns the semantic YAML accessibility tree of the current page, in the following format:
- region:
- main:
- button #9 [cursor=pointer] "产品文档"
- button #47 [selected] [cursor=pointer] "40元/月 2核CPU 2GB内存"
- radio #53 [checked] [cursor=pointer] "自动生成密码"
- button #74 [cursor=pointer] "立即购买"
- generic #6 [cf-uba="serviceList..Flexus云服务"] "Flexus云服务"
Node format:- role #N [token1] [token2] "accessible name"
| Field | Description |
|---|---|
role |
ARIA semantic role (button / link / radio / heading / listitem / generic, etc.) |
#N |
Unique action index of the interactive element,Only nodes with #N can be operated on, and when operating, pass N as the index parameter |
[token] |
Optional token: status marker ([checked] [selected] [disabled] [cursor=pointer]) or custom attribute ([cf-uba="..."]) |
"accessible name" |
Semantic name of the element,wrapped in double quotes(computed from aria-label / aria-labelledby / innerText, etc.); this field is omitted for nodes without a name |
| Indentation | indicates the parent-child relationship |
⚠️ After each operation, the
#Nindex is reassigned; do not reuse old indexes.
3.1.2 Browser State Diff: Incremental diff format description
After performing an interactive operation, the tool returns an incremental diff (Diff) by default to reduce token consumption:
- button #9 "产品文档"
+ button #9 "产品文档 (已点击)"
Or when the page structure changes, the diff of added or removed nodes is shown. Prioritize reading the Diff to quickly confirm whether the operation took effect; only when the Diff is insufficient to support the next decision, explicitly call browserState(full)。
3.1.3 searchTree: Precisely search the accessibility tree by keyword (preferred)
This is completely consistent with the strategy of industry AI editors (Cursor / Windsurf)of reading files on demand— search precisely first, then fetch the full amount on demand, minimizing the tokens sent to the model.
Decision process (please follow strictly):
已知要找的元素类型或名称?
↓ 是
→ 先用 searchTree 搜索
↓ 找到了?
是 → 直接使用命中的 #N 索引操作
否 → 再用 browserState(full) 获取全量树兜底
↓ 否(完全不知道页面有什么)
→ 用 browserState(full) 获取完整树
Supported search dimensions (all perform substring matching on the same query string):
| Search target | Example query | Description |
|---|---|---|
| By role type | button / link / heading / textbox |
Find nodes with a specific role |
| By element name | 提交 / 下一步 / 立即购买 |
Find nodes whose accessible name contains that text |
| By status | checked / disabled / expanded |
Find nodes with a specific status |
| By ref index | #5 |
Precisely locate a known ref |
Parameters:
query(required): search keywordcontextLines(optional, default 2): number of context lines to keep before and after each matching linemaxMatches(optional, default 20): maximum number of groups to return, to prevent too many results
Example:
webmcp-cli run page-agent-tool '{"action": "searchTree", "query": "button"}'
webmcp-cli run page-agent-tool '{"action": "searchTree", "query": "提交", "contextLines": 3}'
webmcp-cli run page-agent-tool '{"action": "searchTree", "query": "checked"}'
webmcp-cli run page-agent-tool '{"action": "searchTree", "query": "#42", "contextLines": 1}'
Example output:
无障碍树搜索结果 — 关键词: "button" | 总行数: 182 | 命中: 4 行 | 返回分组: 1
── 分组 1(第 159–171 行)──
159 | - generic #132 [cursor=pointer]
160 | - link #133 [cursor=pointer]
>>> 161 | - button #134 [cursor=pointer] "立即购买"
162 | - link #135 [cursor=pointer] "计费说明"
>>> 165 | - button #138 [cursor=pointer] "立即购买"
提示:如需操作命中元素,使用其 #N 索引;如需查看完整树,请使用 browserState。
>>> The marked lines are matching lines, and the rest are context. After getting #N , pass it directly to click / fill and other actions.
3.1.4 Four principles for obtaining page state
- Precisely search by keyword (highest priority): When the element type or name to find is known,prefer using
searchTree, which reduces token consumption by 80%+ compared with the full tree. - Fetch the full amount for the first time: When first entering the page, when the page undergoes a major refresh, or when
searchTreecannot find the required information, callbrowserStateand specifyresponseModeasfullorboth。 - Incremental first: After executing
click、fill、select、scrolloperations, the tool by default automatically returnsdiffincremental information; prioritize reading these Diffs to quickly confirm whether the operation took effect. - Fetch the full data on demand: If the incremental Diff is insufficient to support the next operation, or you need to find a
#Nnode that is not in the Diff, andsearchTreealso cannot locate it, then explicitly callbrowserStateto fetch the complete tree.
3.1.5 Browser Rules (Operation Constraints)
When using page-agent-tool to interact with web pages, strictly follow these rules:
- Only interact with elements that have a
#Nindex, passing N as theindexparameter, and only use indexes that explicitly appear in the tree. - After each operation,
#Nindexes are reassigned, do not use old indexes. - After the operation, analyze the returned Diff to determine whether you need to interact with newly appeared elements (such as selecting an option from a dropdown list).
- By default, only listvisible viewportelements; if the element you need to interact with is off-screen, first use the
scrolloperation to scroll. You can use thenumPagesparameter to control the scroll amount (0.5 = half a page, 2.0 = two pages). - If aCAPTCHAappears, inform the user that it cannot be solved automatically and ask the user to handle it manually before continuing.
- If the expected element is missing, try scrolling or navigating back.
- Do not repeat the same operation more than 3 times, unless there is a clear change in conditions.
- If the operation is interrupted after filling text into an input box (such as a dropdown suggestion popping up), it means the page state has changed, and you need to handle the newly appeared elements first.
- If
<user_request>contains specific filter conditions (product type, price, location, etc.), prioritize applying filters to improve efficiency. - If you fill text into an input box, you may need to press Enter, click the search button, or select from a dropdown list to complete the operation.
- Do not attempt to log in without credentials。
3.1.6 Capability (Capability Boundaries)
page-agent-toolOnly handle single-page applications, do not leave the current page.- Do not click
target="_blank"links(they will open in a new window); if you need to open a new page, usewebmcp-cli tabs open。 - Task failure is acceptable:
- The user's request may be infeasible, inappropriate, or missing necessary information—in this case, inform the user and explain the reason.
- Web pages may have bugs; when blocked, promptly inform the user of the problem with the current page.
- Repeated back-and-forth operations may cause side effects—it is better to end in failure than to blindly retry a complex process。
- If you do not have sufficient knowledge about the current web page or task,you must ask the user to provide specific instructions and detailed steps。
3.1.7 Task Completion Rules (Task End Conditions)
You must end the task in the following situations:
- The user's request has been fully completed.
- You feel confused or cannot solve the request; or the request is unclear or contains inappropriate content.
- Absolutely cannot continue (e.g., missing necessary permissions, blocked by CAPTCHA, target element does not exist).
3.2 Domain-Specific Tools
When webmcp-cli tabs open navigates to a specific domain, or when usingwebmcp-cli state to query the browser, dedicated tools for that domain are automatically injected to implement specialized functionality for the current domain.
Please check webmcp-cli state in the output of webmcpTools to confirm the available tools for the webpage.
| Domain to inject | Injected tools | When to read the sub-Skill |
|---|---|---|
excalidraw.com |
excalidraw_execute_command |
When the current page URL contains excalidraw.com and you need to draw or manipulate canvas elements, please read domains/excalidraw.md。 |
juejin.cn |
create_article, publish_current_draft, get_article_info |
When you need to publish an article on the Juejin platform, please read domains/publish-article-in-juejin.md。Note: Before calling publish_current_draft you must first generate an article summary strictly within 50-100 characters , otherwise the tool will directly error out and stop publishing! |
www.baidu.com |
baidu_search, baidu_get_results |
No sub-Skill needed; the tool's description already explains its purpose. |
my.oschina.net/ |
create_article, get_article_info, publish_current_draft |
When you need to publish an article on the Open Source China platform, please read domains/publish-article-in-oschina.md。Note: Before calling publish_current_draft you must first get_article_info and generate a 50~200 characters summary. |
xiaohongshu.com |
xhs_get_note_detail, xhs_get_feed, xhs_search_notes |
No sub-Skill needed; the tool's description already explains its purpose. |
creator.xiaohongshu.com |
xhs_publish_note |
No sub-Skill needed; the tool's description already explains its purpose. |
editor.csdn.net |
create_article, get_article_info, publish_current_draft |
When you need to publish an article on the CSDN platform, please read domains/publish-article-in-csdn.md。Note: Before calling publish_current_draft you must first get_article_info and generate a within 100 characters summary. |
segmentfault.com |
create_article, get_article_info, publish_current_draft, segmentfault_publish_article |
When you need to publish an article on the SegmentFault platform, please read domains/publish-article-in-segmentfault.md。 The recommended Juejin-style three-step process; for advanced scenarios, use segmentfault_publish_article。 |
Within their respective domains, the corresponding webpage tools can be called:
# 在excalidraw网页中,获取画布元素
webmcp-cli run excalidraw_execute_command '{"eventName": "getSceneElements"}'
# 在掘金上发布新文章
webmcp-cli run create_article '{"title": "文章标题", "content": "文章的正文的base64编码"}'
# 在 CSDN 上填写并发布(须先 get_article_info 推断分类/标签/摘要)
webmcp-cli run create_article '{"title": "文章标题", "content": "@base64file:./article.md"}'
webmcp-cli run get_article_info
webmcp-cli run publish_current_draft '{"category":"前端","tags":["Vue.js","JavaScript"],"summary":"100字以内的文章摘要..."}'
# 在开源中国上填写并发布
webmcp-cli run create_article '{"title": "文章标题", "content": "@base64file:./article.md"}'
webmcp-cli run publish_current_draft '{"category":"开源资讯","tags":["Vue.js","AI"],"summary":"50~200字的文章摘要..."}'
# 搜索小红书笔记(自动触发滚动加载)
webmcp-cli run xhs_search_notes '{"keyword": "AI Agent", "limit": 10}'
# 小红书发布图文笔记
webmcp-cli run xhs_publish_note '{"title": "第一条笔记", "content": "内容极其精彩...", "images": [{"name": "1.jpg", "mimeType": "image/jpeg", "base64": "..."}]}'
# 思否平台:掘金风格三步流程(推荐)
webmcp-cli run create_article '{"title": "你的文章标题", "content": "@base64file:./article.md"}'
webmcp-cli run get_article_info
webmcp-cli run publish_current_draft '{"category": "前端", "tags": ["前端", "AI", "WebMCP"]}'
# 思否高级流程(导航→过引导→填内容→保存草稿)
webmcp-cli run segmentfault_publish_article '{
"action": "publish_full_flow",
"title": "你的文章标题",
"content": "# 正文\n\n文章内容...",
"category": "前端",
"tags": ["前端", "AI", "WebMCP"],
"type": "original",
"scope": "personal",
"copyright": true,
"scheduled_time": "2026-07-01T10:00:00+08:00"
}'
# 思否分步操作(精细控制)
webmcp-cli run segmentfault_publish_article '{"action": "set_title", "title": "文章标题"}'
webmcp-cli run segmentfault_publish_article '{"action": "set_scheduled_publish", "scheduled_time": "2026-07-01T10:00:00+08:00"}'
webmcp-cli run segmentfault_publish_article '{"action": "publish", "confirm": true}'
When to read domains/excalidraw.md
If the following any condition is met, please read domains/excalidraw.md:
- The user requests that you draw a diagram, flowchart, architecture diagram, or any visualization on Excalidraw.
- The current page URL is
excalidraw.com, andwebmcpToolscontainsexcalidraw_execute_command。 - You need to add, update, delete, or query elements on the Excalidraw canvas.
Core constraints
- searchTree first: When the target element type or name is known,you must prioritize using
searchTreerather than directly pulling the full tree. This is fully consistent with the industry's AI editor strategy of reading files on demand—search and locate first, and fall back to the full tree only if not found. - state first: Except for
tabs open, before executing any other command you must first callwebmcp-cli state;tabs openand after that you must also callstateonce more. Never guess element indices or the tool list—stateis the only entry point for querying the browser's complete state. - Valid JSON: Wrap JSON parameters in single quotes:
'{"action": ...}'。 - Tab targeting: Use the UUID format
statefrom the output oftabid, together with-tto specify the tab.tabs open/tabs switchreturned bytabidshould be reused in all subsequentruncommands;statewill also return the current operation page'sactiveTabid。 - Domain tools: If domain-specific tools exist, they should take priority over
page-agent-tool— they are more reliable for interactions with that domain. - Call the web tool: strictly according to the terminal type, pass in the corresponding
json-argsparameter