wechat-devtools

Original🇨🇳 Chinese
Translated

WeChat DevTools MCP —— Mini Program Building, Preview, Debugging and Automated Testing

6installs
Added on

NPX Install

npx skill4agent add watertian/wechat-devtools-mcp wechat-devtools

SKILL.md Content (Chinese)

View Translation Comparison →

Wechat DevTools MCP Skill (v0.9.5)

Prerequisites

Step 0: Installation and Configuration

bash
pip install uv   # Install uv if not present
uv tool install wechat-devtools-mcp --force  # Install wechat-devtools-mcp via uv
Editor Configuration:
json
{
  "mcpServers": {
    "wechat-devtools": {
      "command": "uvx",
      "args": ["wechat-devtools-mcp"],
      "env": {
        "WECHAT_DEVTOOLS_CLI": "C:\\Program Files (x86)\\Tencent\\微信web开发者工具\\cli.bat",
        "WECHAT_PROJECT_PATH": "D:\\Your\\Project\\Path"
      }
    }
  }
}
See README.md for mainstream editor configurations
[!IMPORTANT] You must manually enable the service port of the developer tools:
Settings
Security Settings
Service Port
Enable
. Failure to enable will cause all CLI operations to report
CLI_TIMEOUT
.

Step 1: Runtime Environment Check

First call
wechat_ide(action='status')
to verify all prerequisites at once.
Check ItemPreferred CommandAction on Failure
CLI Installed
status
cli_exists: true
Install the tool and configure
WECHAT_DEVTOOLS_CLI
Project Path Configured
status
project_exists: true
Configure
WECHAT_PROJECT_PATH
Logged In
is_login
logged_in: true
login(qr_format='terminal')
to scan QR code
Node.js Available
status
node_available: true
Install Node.js ≥ 8.0

Efficiency Principles

The IDE is opened only once at the start of the session, compile is executed only after code changes, and page navigation uses evaluate preferentially over navigate.
ScenarioCorrect PracticeIncorrect Practice
Testing different pages without code changes
evaluate(expression="wx.reLaunch({url:'/pages/xxx/index'}); 'ok'")
page_data
Re-open → compile
Code changed
compile
page_data
verification (compile automatically reconnects automator)
Re-open → compile
Connection disconnectedQuick recovery first (only
start
)
Directly perform full recovery

API Cheat Sheet

wechat_ide
— IDE Lifecycle

actionFunctionKey Parameters
open
Open IDE/project (automatically performs startup health check when cdp_enabled)
cdp_enabled=true
(Enable CDP port 9222, automatically collect 5s CDP logs to detect startup errors)
login
QR code login
qr_format="terminal"
is_login
Check login status
close
/
quit
Close project / Exit IDE
status
Environment diagnosis

wechat_build
— Building and Publishing

actionFunctionKey Parameters
compile
Compilation check (captures errors/warnings, automatically reconnects automator after success)
  • Note: compile_condition may be invalid for tabBar pages (overridden by app route guards), using evaluate + wx.reLaunch for navigation is more reliable
|
preview
| Generate preview QR code |
qr_format="terminal"
| |
upload
| Upload to WeChat backend |
version
(required)
,
desc?
| |
build_npm
| Build NPM dependencies (mandatory before upload) | — | |
cache_clean
| Clear cache |
clean_type="compile"
|

wechat_automator
— Automated Interaction

Prerequisite: Call
start
first to enable the automation port (only required once per session).
actionFunctionRequired Parameters
start
Enable automation port
tap
Click element
selector
input
Input text
selector
,
value
element_info
Get element details (text/size/WXML)
selector
set_data
Hot update page data (no recompilation needed)
data_json
call_method
Call page method
method
,
args_json?
call_wx
Call wx API
method
mock_wx
Mock wx API return value
method
,
result_json
evaluate
Execute JS expression (universal key for logic layer)
expression
  • Note: Declaration statements (const/let/var) are supported since v0.7.0
  • v0.9.2: Automatically invalidates old cache connections and reconnects after compile, adds 3s timeout protection for daemon health check, and 2s independent timeout for navigate currentPage polling
  • v0.9.0:底层改为持久化 Node daemon(NDJSON 协议),WS 连接按端口缓存复用,工具调用延迟 ~3ms
|
page_stack
| Get page stack | — | |
page_data
| Get current page data |
expected_path?
(poll to verify page path) | |
system_info
| Get runtime system information | — | |
storage
| Read local cache |
key?
(empty = list all) |

wechat_inspector
— Log Collection

actionFunctionKey Parameters
console
Collect console logs and JS exceptions
duration=10
,
log_type="all"
cdp
Collect underlying logs via CDP protocol (WXML/rendering layer)
duration=10
,
detail_level="concise"
,
max_logs=50
CDP Prerequisite: Open the project with
cdp_enabled=true
and ensure port 9222 is available.

wechat_screenshot
— Screenshot

  • output_path
    (optional): Screenshot save path. Leave blank to automatically save to the
    screenshots/
    folder under the project directory
  • full_page
    (default
    true
    ): Set to
    false
    to capture only the current viewport
  • scroll_top
    (optional): Position to scroll to before taking the screenshot (logical pixels), use with
    full_page=false
  • page_path
    (optional): Ensure being on the specified page before taking the screenshot, automatically navigate if current page does not match
  • Prerequisite: Call
    wechat_automator(action='start')
    first
  • Note: Do not take screenshots actively, only call when explicitly requested by the user or visual confirmation is needed for troubleshooting
  • Limitation: Pages using
    scroll-view
    component cannot be stitched into long screenshots (automator SDK limitation), only the current viewport is captured
  • Limitation: Screenshots may not capture fixed/absolute overlays (pop-ups, masks), rely on
    page_data
    instead
  • Path Convention: Recommended to use
    <project>/screenshots/
    or explicit absolute path. Avoid writing to
    .claude/image-cache/
    — this is the user image cache directory for Claude Code, mixing MCP screenshots will cause mutual contamination

wechat_navigate
— Navigate and Collect Logs

  • page_path
    (required): e.g.
    pages/index/index
  • wait_ms
    : Wait time in milliseconds, recommended 3000
  • clear_logs
    : Whether to filter historical CDP logs, default
    true
  • check_data
    : Whether to check for empty page_data after navigation, default
    true
  • detail_level
    :
    concise
    (only errors+warnings) or
    full
  • Added in v0.8.0: Automatically detects TabBar pages and uses
    switchTab
    instead of
    reLaunch
    , returns
    navigation_method
    field
  • Prerequisite: Requires
    automator start
    +
    cdp_enabled=true

wechat_file
— File Reading

actionFunctionRequired Parameters
project_info
Get complete project information (app.json + directory structure)
list_pages
Get all page list (including file integrity check)
read_page
Read page source code (wxml/wxss/js/json)
page_path
read_file
Read any single file (max 800 lines)
file_path
Cloud Function and Cloud Database Management: This MCP no longer provides
wechat_cloud
tools since v0.9.5. Please use CloudBase MCP instead (with
manageFunctions
/
readNoSqlDatabaseContent
/
writeNoSqlDatabaseContent
etc.), which has no IDE dependency and covers more features.

SOP Standard Operating Procedures

SOP A: Initialization (Mandatory for New Environments)

wechat_ide(action='status')                         # Diagnose environment
wechat_ide(action='is_login')                       # Check login status
  ↳ Not logged in: wechat_ide(action='login', qr_format='terminal')
wechat_ide(action='open', cdp_enabled=True)         # Launch IDE + CDP 9222 + automatic health check
  ↳ Returns success=false + startup_errors → Fatal error during mini program startup, must fix before proceeding
  ↳ Returns success=true → Startup normal, proceed to next steps
  ↳ Transient errors may occur during IDE cold start (simulator not found / subPackages of undefined), which is normal, ignore and continue to execute compile to refresh
wechat_automator(action='start')                    # Launch daemon + enable automation port 9420
wechat_file(action='project_info')                  # [Optional] Confirm project structure
wechat_build(action='cache_clean', clean_type='all')     # Clear all cache
wechat_build(action='compile')                            # Compile to establish clean CDP baseline (automatically reconnects automator)
wechat_automator(action='page_data')                # Verify connection availability
  ↳ ⚠ Check if AppID is undefined in the output
  ↳ If undefined → project_path may point to a subdirectory instead of the project root
  ↳ Cloud development project root directory contains project.config.json, miniprogram/ and cloudfunctions/
  ↳ Correct: project_path="D:/MyProject"  Wrong: project_path="D:/MyProject/miniprogram"
project_path Rule: Must point to the root directory containing
project.config.json
. For cloud development projects,
miniprogram/
is a subdirectory and cannot be used as project_path.

SOP A-2: Recompile After Code Changes (No Need to Re-open IDE)

wechat_build(action='compile')                      # Compile (automatically reconnects automator)
wechat_automator(action='page_data')                # Verify connection availability
No need to re-open IDE or perform cache_clean. Only execute after modifying mini program source code.

Standard Page Navigation Methods

ScenarioMethod
Normal page
evaluate(expression="wx.navigateTo({url:'<path>'}); 'ok'")
TabBar page
wechat_navigate(page_path='<tabBar path>')
automatically uses switchTab
Force reset
evaluate(expression="wx.reLaunch({url:'<path>'}); 'ok'")
After navigationVerify
path
matches expectation via
page_data

SOP B: UI Debugging (Data/Layout Issues)

wechat_file(action='list_pages')                           # ⓪ Before first navigation, get list of valid page paths
  ↳ TabBar page paths are usually pages/xxx/index (not pages/xxx/xxx)
wechat_navigate(page_path='pages/xxx/index', wait_ms=3000) # ① Navigate + CDP logs
wechat_automator(action='page_data')                       # ② Check data status
  ↳ ⚠ Must verify that data.path === expected page_path
  ↳ If not matching → Page navigation failed or redirected (see page_data notes)
  ↳ Data exception: set_data(data_json='{"key":"val"}') to hot update and verify
  ↳ Confirm element: element_info(selector='.target')
  ↳ Only when requested by user or visual confirmation is needed: wechat_screenshot()  # Default saves to project screenshots/

SOP C: Troubleshooting (Errors/White Screen/JS Exceptions)

wechat_automator(action='page_data')                       # ① Preferred: Directly check page data
  ↳ Key fields are null/empty → Data not loaded or parameter error
  ↳ Data normal → Proceed to step ④ to confirm it's not a data issue
wechat_automator(action='evaluate', expression='wx.cloud.callFunction({name:"xxx",data:{...}})')
                                                            # ② Directly call API to get complete return value
  ↳ Must use this step when encountering [object Object] to get complete JSON
wechat_inspector(action='cdp', duration=5, detail_level='concise')
                                                            # ③ CDP auxiliary reference
  ⚠ CDP error count may include historical cache, rely on page_data instead
wechat_build(action='compile')                              # ④ Capture compilation errors
  ↳ Check wxml_errors field; ⚠ Compilation errors like Chinese quotes "" cannot be captured by the tool

SOP D: Full Page Inspection (Regression/Pre-release Acceptance)

wechat_build(action='cache_clean', clean_type='all')    # Establish clean CDP baseline
wechat_build(action='compile')
  ↳ ⚠ Check if AppID is undefined
wechat_file(action='list_pages')                        # Get page list, confirm valid paths
# Execute sequentially for each page (parallel execution is prohibited):
wechat_navigate(page_path=page, wait_ms=3000)           # Navigate + CDP logs
wechat_automator(action='page_data')                    # Core verification: Key fields are not null/empty
  ↳ ⚠ Must verify that data.path === expected page_path
  ↳ If not matching → Page navigation failed or redirected, mark as exception
  ↳ Fields normal and path matching → ✅ Page passed
  ↳ Fields empty → ⚠ Mark as exception, use evaluate for further diagnosis
  ↳ Only take supplementary screenshots when page_data is abnormal
# Summary: Output report sorted by page_data results

SOP E: Mock Integration Testing (Payment/Permissions/Devices)

wechat_automator(action='mock_wx', method='requestPayment', result_json='{"errMsg":"requestPayment:ok"}')
wechat_automator(action='mock_wx', method='getUserProfile',  result_json='{"userInfo":{"nickName":"Test User"}}')
wechat_automator(action='mock_wx', method='getLocation',     result_json='{"latitude":23.099,"longitude":113.324}')
wechat_automator(action='tap', selector='.pay-btn')         # Trigger interaction
wechat_automator(action='page_data')                        # Verify data changes
Mock is only valid for the current session, needs to be reset after restarting IDE.

SOP F: Network Debugging and UI Adaptation

① Network and API Debugging
# Intercept requests (logic layer injection)
evaluate(expression='var o=wx.request; wx.request=function(p){console.log(p.url);return o.apply(wx,arguments)}')
# Simulate timeout
mock_wx(method='request', result_json='{"errMsg":"request:fail timeout"}')
② UI Adaptation Testing
mock_wx(method='getSystemInfo', result_json='{"theme":"dark"}')               # Dark mode adaptation
mock_wx(method='getSystemInfo', result_json='{"platform":"mac","windowWidth":1024}')  # iPad/PC adaptation
system_info()                                              # Record windowWidth/Height

SOP G: Subpage Testing (Pages Requiring Query Parameters)

wechat_file(action='read_page', page_path='pages/xxx/xxx')  # ① Check onLoad method
  ↳ Confirm query parameter names (such as id / matchId) from options parameter
wechat_navigate(page_path='pages/xxx/xxx?correct_param_name=value', wait_ms=3000)  # ② Navigate
wechat_automator(action='page_data')                          # ③ Verify data
  ↳ Key fields not empty → ✅
  ↳ Most fields are null → Parameter name may be incorrect, go back to ①

SOP I: Cross-page Data Consistency Verification

Applicable scenario: Verify whether the same data is displayed consistently across different pages (such as points, user status, level, etc.)
wechat_file(action='list_pages')                         # ① Get page list
# Define common fields to verify (such as points, phone_bound, level)
# ② Collect data page by page (execute sequentially, parallel execution is prohibited):
wechat_navigate(page_path=page, wait_ms=3000)
wechat_automator(action='page_data')
  ↳ Verify that data.path === expected page (mark and skip if navigation failed)
  ↳ Extract values of common fields, record to comparison table
# ③ Compare values of fields with the same name across pages
  ↳ Values consistent → ✅ Field passed
  ↳ Values inconsistent → ⚠ Mark as exception, use evaluate to directly call API for comparison
  ↳ When subpage data is abnormal, check if independent data acquisition link is used

SOP J: Parallel Data Comparison Between Mini Program and Management Backend

Applicable scenario: Verify consistency between mini program frontend data and management backend data
# Architecture:
#   Management Backend → Playwright MCP (browser port)
#   Mini Program   → WeChat DevTools MCP (automator port 9420)
#   They use different ports and can run in parallel

# ① Extract data from both ends respectively (can be parallel)
#   Agent A: Operate management backend via Playwright, extract data
#   Agent B: Operate mini program via WeChat MCP, extract page_data
# ② Perform data comparison in main process (serial)
Port Exclusivity Rule: The automator port 9420 is exclusive, only one Agent can operate WeChat MCP at the same time. Playwright and WeChat MCP can be used simultaneously (different ports).

CDP Log Strategy

concise → Only errors + warnings (saves tokens, preferred)
  ↓ When summary.errors > 0
full    → Complete logs + source location → wechat_file(action='read_file', file_path=source)
ScenarioRecommended Parameters
Quick diagnosis
duration=5, detail_level='concise', max_logs=20
In-depth troubleshooting
duration=10, detail_level='full', max_logs=100
Page inspection
duration=3, detail_level='concise', max_logs=30
Important: CDP error count may include accumulated historical logs across pages.
clear_logs=true
(default) in v0.4.0 filters historical logs based on timestamp, but it is still recommended to use
page_data
as the final verification standard.

CDP Log Noise Filtering

The following log sources are internal noise of the developer tools and do not represent application errors, should be excluded when judging:
source PrefixDescriptionHandling
devtools://devtools/
Assertions/warnings from the developer tool itselfIgnore
ide:///extensions/
Reminders injected by IDE extensionsTreat differently
The following message patterns are framework-level reminders, not application errors:
message PatternDescription
console.assert
Internal assertions of devtools
SharedArrayBufferIssue
Browser engine warning
getSystemInfo API prompt
Deprecated API migration reminder
wx.saveFile will be deprecated
/
wx.removeSavedFile will be deprecated
Framework API deprecation warning
[Component] property "xxx" received type-uncompatible value
Component property type mismatch warning
Judgment Principle: The errors/warnings count in CDP may be inflated by the above noise, leading to misjudgment. Always use the actual data returned by
page_data
as the final verification standard.

page_data Notes

  1. Must verify the path field: The returned
    data.path
    represents the current actual page. If it does not match the navigation target, it means the page navigation failed or was redirected.
  2. Common reasons for inconsistency:
    • User not logged in, page intercepts and redirects to login/welcome page
    • Cloud function call failed (AppID undefined), page falls back to homepage
    • page_path spelling error, navigate fails silently (returns success: true)
    • Conditional navigation logic exists in page onLoad
  3. Recommended Pattern:
    wechat_navigate(page_path='pages/xxx/index', wait_ms=3000)
    wechat_automator(action='page_data')
      ↳ data.path !== 'pages/xxx/index' → Page not loaded correctly
      ↳ Use page_stack to view complete page stack, locate redirection reason

Return Value Format

json
{"success": true,  "data": {...}, "message": "Operation description"}
{"success": false, "error_code": "CLI_TIMEOUT", "message": "...", "hint": "Fix hint"}
{"success": false, "error_code": "UNKNOWN_ERROR", "message": "N errors detected during mini program startup...", "hint": "...", "startup_errors": [...], "cdp_summary": {...}}
error_codeMeaningHandling
PARAM_MISSING
Required parameter missingCheck hint field
CLI_NOT_FOUND
CLI not foundCheck
WECHAT_DEVTOOLS_CLI
PROJECT_PATH_MISSING
Project path not configuredCheck
WECHAT_PROJECT_PATH
NODE_NOT_FOUND
Node.js not installedInstall Node.js ≥ 8.0
CLI_TIMEOUT
CLI execution timeoutEnable service port; restart IDE

Connection Recovery Tiers

Quick Recovery (try first):
wechat_automator(action='start')                    # Only reconnect
wechat_automator(action='page_data')                # Verify
Full Recovery (when quick fails):
wechat_ide(action='open', cdp_enabled=True)         # Re-open
wechat_automator(action='start')                    # Reconnect
wechat_build(action='compile')                      # Recompile (automatically reconnects automator)
wechat_automator(action='page_data')                # Verify

Troubleshooting Quick Reference

SymptomCauseSolution
CDP collection failed (port 9222 unresponsive)IDE not started with cdp_enabledRestart with
wechat_ide(action='open', cdp_enabled=True)
Blank screenshot / size 0automator not started or page not renderedConfirm
start
has been called; increase
wait_ms=3000
Page is not found
page_path spelled incorrectly / not registeredVerify with
wechat_file(action='list_pages')
Element is obfuscated
Element blocked or outside shadow-rootCheck WXML structure, try parent node
Cannot find context
Logic layer crashed / reloadingRetry after waiting 3s
CLI_TIMEOUT
Service port not enabled / IDE not runningEnable service port;
wechat_ide(action='open')
Element not foundNot on current page or selector wrongConfirm page with
page_stack
; verify selector with
element_info
Using AppID: undefined
project_path points to subdirectory instead of project rootChange to directory containing
project.config.json
appid missing
cloud function failed
AppID not configured or not logged inCheck project_path + login status
Connection closed
screenshot/operation failed
automator WS connection disconnected (rare under v0.9.0 daemon architecture)First perform quick recovery (only
start
page_data
); if failed, perform full recovery (see Recovery Tiers)
Failed connecting to ws://localhost:9420
automator not started or disconnectedSame as above
navigate returns success but page not navigatedpage_path does not exist or spelled incorrectlyConfirm path with
list_pages
; verify with
page_stack
page_data.path does not match navigate targetPage redirected (not logged in/parameter error/cloud function failed)Check AppID, login status, page onLoad logic
CDP errors count includes console.assertdevtools internal noiseFilter
devtools://
sources, rely on page_data
Subpage data inconsistent with main pageSubpage uses independent data acquisition linkUse
evaluate
to directly call API for comparison
Bottom navigation bar repeated in long screenshotFixed area detection failed (fixed in v0.5.0)Upgrade to latest version; feedback if still reproducible
open
returns startup_errors
Fatal error during mini program startup (page cannot be displayed)Fix code according to error details in
startup_errors
, re-open after fix
simulator not found
/
subPackages of undefined
Transient error during IDE cold start, not ready yetIgnore, continue to execute compile to refresh
compile succeeds but IDE shows red WXML errorWXML compilation errors go through IDE internal channelCheck Chinese quotes
""
, unclosed tags; check
wxml_errors
field
currentPageTimeout is not defined
Internal variable scope bug in wechat_navigate (fixed in v0.7.0)Upgrade to v0.7.0; or use evaluate + wx.reLaunch
compile_condition entry page overriddenApp route guard overrides compilation entryCompile default page, navigate with evaluate(wx.reLaunch)
switchTab ok but not switchedswitchTab not completed asynchronouslyIncrease wait_ms; v0.8.0 navigate automatically handles TabBar pages
evaluate reports
Unexpected token 'const'
v0.6.0 only supports expressions (fixed in v0.7.0)Upgrade to v0.7.0; or wrap with IIFE
Pop-ups/masks not visible in screenshotfixed/absolute overlay not in same rendering layerRely on page_data
call_method reports
page.xxx not exists
and no page info
v0.6.0 does not return path (fixed in v0.7.0)Upgrade to v0.7.0; or confirm path with page_data first
navigate to TabBar page ineffectiveTabBar pages do not support reLaunch/navigateTov0.8.0 automatically detects and uses switchTab; or manually
evaluate(wx.switchTab)
Screenshot shows wrong pagePage reset after screenshot connectionUse
page_path
parameter to ensure being on correct page before screenshot
Long screenshot of scroll-view page only shows one screenautomator SDK cannot capture internal scroll of scroll-viewKnown limitation, returns
isScrollViewPage: true
; use page-level scrolling or canvas screenshot instead

Connection Disconnection Recovery Process

When screenshot or automation operation reports
Connection closed
or
ws://localhost:9420
connection failure, execute the following standard recovery process:
wechat_ide(action='open', project_path='...', cdp_enabled=true)   # ① Re-open project
wechat_automator(action='start', project_path='...')               # ② Restart automator
wechat_build(action='compile', project_path='...')                 # ③ Recompile
# ④ Retry the failed operation

Absolute Red Lines

  • ❌ Continue executing subsequent test operations after
    open
    returns
    startup_errors
    (must fix errors first)
  • ❌ Call
    preview
    /
    upload
    without confirming
    is_login: true
  • ❌ Call
    cache_clean(clean_type='all')
    on production projects
  • ❌ Execute
    eval()
    or unsafe code in
    evaluate
  • ❌ Assume running status — must rely on actual data returned by MCP interfaces
  • ❌ Retry the same failed operation more than 3 times (should switch to diagnosing root cause)
  • ❌ Use
    sleep
    hard wait in automated testing (use
    wait_ms
    or poll
    page_data
    )
  • ❌ Actively call screenshot in SOP process — only take screenshots when explicitly requested by user or visual confirmation is needed for troubleshooting
  • ❌ Directly perform full recovery when connection is disconnected (should first perform quick recovery: only
    start
    page_data
    )
  • ❌ Compile without code changes (wastes time, directly navigate with evaluate)
  • ❌ Do not verify automator connection after compile (v0.8.0 automatically reconnects, but need
    page_data
    confirmation)
  • ❌ Use
    miniprogram/
    subdirectory as project_path for cloud development projects
  • ❌ Do not verify if
    page_data.path
    matches expected page after navigate
  • ❌ Treat
    console.assert
    from
    devtools://
    source in CDP logs as application errors
  • ❌ Use
    wechat_automator
    in multiple parallel Agents (port 9420 is exclusive)
  • output_path
    of
    wechat_screenshot
    is optional, leave blank to automatically save to project
    screenshots/
    directory
  • ✅ Must call
    automator(action='start')
    before using any automation/screenshot features
  • ✅ Use
    element_info
    to confirm element exists before executing
    tap
    /
    input
  • ✅ Confirm version number has been incremented and
    build_npm
    has been executed before
    upload
  • ✅ Pay attention to
    [Violation]
    marks in CDP logs (render blocking/performance issues)
  • ✅ Check if AppID is undefined after
    compile
  • ❌ Use Chinese quotes
    ""
    or unescaped double quotes in WXML attribute values (compilation error that cannot be detected by tools)
  • ✅ Execute
    open
    start
    compile
    to restore connection after screenshot/operation failure
  • ✅ Must verify current page path via
    page_data
    or
    page_stack
    after navigate
  • ✅ Compare consistency of fields with the same name in cross-page testing