ie-mode-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ie-mode-mcp open the legacy sales report at http://legacy01.local/reports and show me today's total"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ie-mode-mcp
MCP Server for operating legacy web applications running in Microsoft Edge's IE mode from AI agents via MCP (Model Context Protocol).
AI Agent ──(MCP / stdio)──> ie-mode-mcp ──> BrowserManager ──> selenium-webdriver
│
IEDriverServer.exe
│
Microsoft Edge (IE Mode)
│
Legacy Web ApplicationConfigured only with Node.js 22 / TypeScript / selenium-webdriver (no HTTP Server, DB, DI, Logging Framework)
MCP Transport is stdio only
Browser session is only one, WebDriver operations are fully sequential
Does not return full HTML,
inspect_pagereturns summarized screen information for LLMNo approval flow. Operations are executed when the Tool is called.
Table of Contents
Related MCP server: Selenium MCP Server
1. Quick Start
Run the following on Windows.
git clone https://github.com/sumikof/iedriver-mcp.git
cd iedriver-mcp
npm install
npm run build
# IEDriverServer.exe のパスと、遷移を許可する Origin を指定して起動
$env:IE_MCP_DRIVER_PATH = "C:\tools\IEDriverServer.exe"
$env:IE_MCP_ALLOWED_ORIGINS = "http://legacy01.local"
node dist/index.jsIf {"level":"info","event":"started","transport":"stdio"} is output to stderr, startup is successful. Normally, do not start manually; let it auto-start from the AI Agent's MCP settings.
2. Prerequisites
Item | Description |
OS | Windows 11 / Windows 10 (logged-in interactive session) |
Node.js | 22 or higher |
Browser | Microsoft Edge (IE mode must be available) |
Driver | IEDriverServer.exe (Selenium 4.x series. 32-bit version recommended) |
Download IEDriverServer.exe from the Selenium download page and place it in any folder (e.g.,
C:\tools\). Since the 64-bit version has known limitations, Selenium officially recommends using the 32-bit version.IEDriver is affected by GUI, window focus, and native events, so use in a dedicated Windows VM or dedicated Windows session is recommended.
Configuration to run the browser on a Windows Service (Session 0) is not assumed.
MCP Server and IEDriver / Edge run in the same Windows environment.
3. Windows Pre-configuration
IEDriver is strongly affected by environment settings. Complete the manual configuration first before starting the MCP Server.
3.1 Enable Edge IE Mode
First, manually verify with Edge that the target site can be opened in IE mode. IE mode is enabled via one of the following policies (under Software\Policies\Microsoft\Edge).
Policy (Display Name) | Registry Value Name |
Configure Internet Explorer integration |
|
Configure the Enterprise Mode Site List |
|
Send all intranet sites to Internet Explorer | (Configured via Group Policy for Edge 77 and later) |
Specific configuration depends on organizational policy, so check with the Microsoft IE mode documentation and your organization's administrator. Apply the latest updates to Windows / Edge.
3.2 IEDriver Required Settings
Item | Required State | Handling in this Server |
Browser zoom | 100% | Not required because |
Protected Mode | Same setting for all zones | If not unified, an exception occurs at startup. Unify via Internet Options → Security |
IEDriverServer bitness | 32-bit recommended | — |
If the Protected Mode settings are not unified, browser_start will fail. IEDriver's introduceFlakinessByIgnoringProtectedModeSettings is not used because it makes behavior unstable.
4. Installation and Build
npm install # 依存パッケージの取得
npm run build # TypeScript を dist/ へビルドThe output is dist/index.js. After building, it can also be started with npm start (= node dist/index.js).
5. Environment Variables
Configuration files (YAML/JSON) are not used; settings are configured only via environment variables.
Environment Variable | Description | Default Value |
| Path to msedge.exe | Not specified (IEDriver auto-detects) |
| Path to IEDriverServer.exe | Not specified (searched from |
| Comma-separated origins allowed for |
|
| Default timeout for element search and waiting (ms) |
|
IE_MCP_EDGE_PATH=C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
IE_MCP_DRIVER_PATH=C:\tools\IEDriverServer.exe
IE_MCP_ALLOWED_ORIGINS=http://legacy01.local,http://legacy02.local
IE_MCP_TIMEOUT_MS=10000IE Driver 4.5.0 and later automatically detects Edge in environments without IE (Windows 11 default), so
IE_MCP_EDGE_PATHis usually unnecessary. Only specify explicitly when auto-detection fails.To prioritize operational reproducibility, it is recommended to explicitly specify
IE_MCP_DRIVER_PATH.IE_MCP_ALLOWED_ORIGINSis a simple restriction to prevent accidental operations, and is determined by exact match of Origin (scheme + host + port). Path-based restrictions are not performed.
6. Startup Methods
Manual Startup (for verification)
PowerShell:
$env:IE_MCP_DRIVER_PATH = "C:\tools\IEDriverServer.exe"
$env:IE_MCP_ALLOWED_ORIGINS = "http://legacy01.local"
node dist/index.jsCommand Prompt:
set IE_MCP_DRIVER_PATH=C:\tools\IEDriverServer.exe
set IE_MCP_ALLOWED_ORIGINS=http://legacy01.local
node dist\index.jsListens for connections from the client via stdio. Since standard input/output is used for the MCP protocol, there is no response to keyboard input in this state (normal). All logs are output to stderr. Exit with Ctrl+C (browser also closes automatically).
Note: Starting the MCP Server alone does not start the browser. The browser starts when the Agent calls
browser_start.
Normal Operation
The AI Agent (MCP client) starts this Server as a child process. Manual startup is not required. Configure as described in the next chapter.
7. Registration with AI Agent
Add the following to the MCP client's configuration file.
{
"mcpServers": {
"ie-mode": {
"command": "node",
"args": ["C:\\ie-mode-mcp\\dist\\index.js"],
"env": {
"IE_MCP_DRIVER_PATH": "C:\\tools\\IEDriverServer.exe",
"IE_MCP_EDGE_PATH": "C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe",
"IE_MCP_ALLOWED_ORIGINS": "http://legacy01.local,http://legacy02.local",
"IE_MCP_TIMEOUT_MS": "10000"
}
}
}
}Escape backslashes in paths within JSON (
C:\\...).Specify the absolute path of the built
dist/index.jsinargs.For Claude Code, it can also be registered with
claude mcp add.
claude mcp add ie-mode --env IE_MCP_DRIVER_PATH=C:\tools\IEDriverServer.exe --env IE_MCP_ALLOWED_ORIGINS=http://legacy01.local -- node C:\ie-mode-mcp\dist\index.jsAfter registration, if the client shows 10 Tools including browser_start, the connection is successful.
8. Tool Reference
There are 10 Tools exposed. Low-level WebDriver APIs (such as findElement / executeScript) are not exposed.
Tool | Input | Overview |
| None | Start Edge IE Mode. If already started, reuse existing session |
| None | Close the browser. No error even if called multiple times |
|
| Navigate after checking URL Allowlist |
|
| Return URL / title / screen text / operable elements |
|
| Wait for visible and enabled, then click |
|
| Input into input / textarea |
|
| Select an option from |
|
| Wait until condition is met |
|
| Switch to popup or another window |
| None | Return current screen as PNG (MCP image content) |
Common: Selector
{ "by": "id | name | css | xpath | linkText", "value": "searchButton" }Legacy web applications frequently use name and xpath, so they are supported.
Common: frame (iframe is one level)
All element operation Tools accept an optional frame. When specified, they switch back to defaultContent and then to the frame, and search for elements within it.
{
"frame": { "by": "name", "value": "mainFrame" },
"selector": { "by": "id", "value": "searchButton" }
}browser_start
{}{ "status": "ready", "reused": false }reused: true indicates that the existing session was used as-is. If the existing session is dead, it automatically restarts.
navigate
{ "url": "http://legacy01.local/customer" }{ "url": "http://legacy01.local/customer", "title": "顧客検索" }inspect_page
Main Tool for the Agent to understand the screen. Does not return full HTML, only returns URL / title / displayed text / operable elements (a button input textarea select iframe). Hidden elements and type="hidden" inputs are excluded.
{ "frame": { "by": "name", "value": "mainFrame" } }{
"url": "http://legacy01.local/customer",
"title": "顧客検索",
"text": "顧客検索 顧客名 支店 検索",
"elements": [
{ "tag": "input", "id": "customerName", "name": "customerName", "type": "text" },
{ "tag": "select", "id": "branch", "name": "branch", "text": "東京支店", "optionCount": 12 },
{ "tag": "button", "id": "searchButton", "text": "検索" },
{ "tag": "iframe", "name": "mainFrame" }
],
"truncated": false
}truncated: trueindicates that elements were truncated at the upper limit (300 items).If the element list includes
iframe, call again withframespecified to see its contents.
click
{ "selector": { "by": "id", "value": "searchButton" } }{ "url": "http://legacy01.local/customer", "title": "顧客検索" }Waits until visible and enabled, then clicks. click does not automatically retry (to prevent duplicate processing from re-clicking when registration/update/submission has already succeeded).
type
{
"selector": { "by": "id", "value": "customerName" },
"text": "山田太郎",
"clear": true
}If clear (default true) is true, inputs after clear(); if false, appends.
select
{
"selector": { "by": "id", "value": "branch" },
"by": "text",
"value": "東京支店"
}{ "text": "東京支店", "value": "13", "index": 2 }by is one of text / value / index (index is 0-based).
wait_for
Does not use fixed sleep, waits explicitly.
{
"type": "visible",
"selector": { "by": "id", "value": "resultTable" },
"timeoutMs": 10000
}
| Required Input | Condition |
|
| Element exists in DOM |
|
| Element is visible |
|
| Element is visible and operable |
|
| Element's text contains |
|
| Current URL contains |
|
| Title contains |
When timeoutMs is omitted, IE_MCP_TIMEOUT_MS is used.
switch_window
{ "target": "newest" }{ "index": 1 }{ "url": "http://legacy01.local/detail", "title": "顧客詳細", "index": 1, "windowCount": 2 }newest polls briefly until a new window handle appears. If not detected, switches to the last existing window.
screenshot
{}Returns a PNG image (MCP image content). Used to check layout/error screens that cannot be determined from DOM alone.
9. Usage Examples
Basic Loop
browser_start → navigate → inspect_page → click / type / select → wait_for → inspect_pageRepeat: inspect_page to understand the screen → operate → wait_for to wait for result → inspect_page again.
Example: Search for customer "Yamada Taro" and open detail screen
# | Tool | Arguments |
1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
Example: Operate inside an iframe
{"tool": "inspect_page", "args": {}}
{"tool": "inspect_page", "args": { "frame": { "by": "name", "value": "mainFrame" } }}
{"tool": "click", "args": {
"frame": { "by": "name", "value": "mainFrame" },
"selector": { "by": "id", "value": "searchButton" }
}}Specify the frame each time for each operation (because internally it resets to defaultContent and switches each time, state is not carried over).
Example: Operate a popup and return to the original window
{"tool": "click", "args": { "selector": { "by": "id", "value": "openPopup" } }}
{"tool": "switch_window", "args": { "target": "newest" }}
{"tool": "inspect_page", "args": {}}
{"tool": "switch_window", "args": { "index": 0 }}10. Errors and Troubleshooting
Errors are returned with the following code instead of Selenium's stack trace (isError: true).
{
"error": "ELEMENT_NOT_FOUND",
"message": "Element was not found: id=searchButton",
"selector": { "by": "id", "value": "searchButton" }
}Error Code | Meaning | Countermeasure |
| Browser not started | Call |
| Element/frame not found | Check actual elements with |
| Condition for | Review condition and |
| Specified window does not exist | Review |
| Navigation failed | Check URL, network, authentication |
| IEDriver/Edge terminated abnormally | Restart with |
| Origin outside Allowlist | Review |
| Invalid argument | Check Tool input specification |
| Other (including startup failure) | Check |
Recovery from DRIVER_LOST
If the browser or Driver crashes, the internal WebDriver is discarded and subsequent operations will result in BROWSER_NOT_STARTED. Automatic recovery and automatic re-execution of the last operation are not performed (to prevent side effects such as duplicate registration). The Agent should call browser_start again, check the screen state with inspect_page, and then resume operations. Since the previous operation may have already succeeded, do not re-execute registration/update operations as-is.
11. Logging
Since stdout is used by the MCP protocol, all logs are output to stderr as single-line JSON.
{"level":"info","event":"started","transport":"stdio"}
{"level":"info","tool":"navigate","url":"http://legacy01.local/customer","durationMs":842}
{"level":"info","tool":"type","selector":{"by":"id","value":"password"},"textLength":16,"durationMs":128}
{"level":"error","tool":"click","selector":{"by":"id","value":"x"},"error":"ELEMENT_NOT_FOUND","message":"Element was not found: id=x","durationMs":5012}The input string itself, cookies, authentication information, and full HTML are not recorded (type only records character count). To save to a file, redirect stderr.
node dist/index.js 2>> C:\logs\ie-mode-mcp.log12. Troubleshooting
Symptom | What to check |
| Is |
Protected mode related exceptions occur | Internet Options → Security: unify protected mode settings for all zones |
Zoom related exceptions occur | Reset Edge / IE zoom to 100% |
Edge starts but does not enter IE mode | Check IE mode policies (site list, etc.). First verify manually that IE mode can be displayed |
Operations freeze / cannot click elements | Is the window minimized or inactive? Becomes unstable when Remote Desktop is disconnected |
| Is it a screen inside a frame? (Re-acquire by specifying |
Tool not visible on Agent side | Is |
Nothing appears in standard output | Normal. Logs are output to stderr |
screenshot is effective for investigating causes. It allows you to check states that cannot be determined from DOM information alone (modals, authentication dialogs, rendering issues).
13. Development
src/
├─ index.ts MCP Server のエントリーポイント(stdio)
├─ config.ts 環境変数と stderr ログ
├─ tools.ts MCP Tool の Schema と Handler
├─ browser.ts BrowserManager(Selenium / IEDriver 操作の集約)
├─ selectors.ts Selector → Selenium の By 変換
└─ errors.ts Selenium Error → MCP Error Code 変換npm run build # tsc でビルド
npm start # node dist/index.jsMCP Tool does not directly touch Selenium; it always goes through
BrowserManager.All WebDriver operations are serialized via a Promise Chain, so even if Tools are called in parallel, only one request at a time is sent to IEDriver.
Only operations without side effects (element search, Window Handle detection) are retried.
clickand submissions are not retried.
14. Limitations
The initial implementation does not support the following:
Multiple browser sessions / Multiple users / HTTP Transport / REST API / DB / Session persistence / Automatic browser recovery / Complex Retry Policy / WebDriver Grid / General-purpose Selenium API / executeScript Tool / Multi-level iframes (only one level) / Element Cache / Metrics / Approval flow / Authentication and authorization
Available Tools
10 toolsbrowser_closeClose browserB
Close the browser session. Safe to call repeatedly.
Inputs: no named parameters.
browser_startStart Edge IE ModeA
Start Microsoft Edge in IE Mode through IEDriverServer. Only one browser session exists; calling this while a session is running returns the existing one. Also use this to recover after a DRIVER_LOST error.
Inputs: no named parameters.
clickClick elementA
Click an element after waiting for it to be visible and enabled. This operation is never retried automatically, because a repeated click may submit or register data twice.
Inputs: selector (required), frame.
inspect_pageInspect pageA
Return the current URL, title, visible page text and the operable elements (a, button, input, textarea, select, iframe). The full HTML is never returned. Pass frame to inspect the contents of an iframe listed by a previous inspect_page call.
Inputs: frame.
screenshotScreenshotB
Capture the current browser window as a PNG image.
Inputs: no named parameters.
selectSelect optionB
Choose an option of an HTML element by visible text, value or index.
Inputs: by (required), value (required), selector (required), frame.
switch_windowSwitch windowA
Switch to another browser window or popup. Use target:"newest" after an action that opens a window, or index to select a window by its zero-based position.
Inputs: index, target, timeoutMs.
typeType textA
Type text into an input or textarea. Set clear to false to append instead of replacing.
Inputs: text (required), selector (required), clear, frame.
wait_forWait for conditionA
Wait until a condition holds. present/visible/enabled/text require a selector; text/url/title require text, which is matched as a substring. Use this instead of sleeping after an action.
Inputs: type (required), text, frame, selector, +1 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 10 tools
Each tool has a clearly distinct purpose: session management (start/close), navigation, inspection, interaction (click, type, select), window switching, waiting, and screenshot. No two tools overlap in functionality.
The naming pattern is inconsistent: some tools use a 'browser_' prefix (browser_start, browser_close), while others are bare verbs (navigate, click, type) or compound snake_case (inspect_page, switch_window, wait_for). This mix of styles could cause confusion.
With 10 tools, the set is well-scoped for browser automation. It covers session lifetime, navigation, element interaction, inspection, window handling, and waiting without being bloated or too thin.
The tools cover fundamental browser actions but miss common features like back/forward navigation, JavaScript execution, alert handling, or cookie management. The set is functional for basic scenarios but has notable gaps for comprehensive automation.
Maintenance
Related MCP Connectors
Web scraping, browser automation, screenshots and AI data extraction for AI agents via MCP.
Browz hosted MCP (free public beta): let an AI app drive your own Browz browser profiles from anywhere. Connect https://mcp.gobrowz.com/mcp and sign in with your Browz account (OAuth) or an agent token. Each call is relayed to the Browz app on your computer, which must be online with Remote control on and have a hardware security chip (Mac Secure Enclave or TPM 2.0). 17 tools: profiles, tabs, navigate, snapshot, act, wait, screenshot. Cookies, downloads and stored sign-ins stay on your computer.
Governed app access for AI agents: 1,000+ apps & 12,000+ tools via Code Mode MCP.
Official Browserless MCP server: browser automation, scraping, screenshots and PDFs for AI agents.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables LLMs to drive Edge in IE mode for automating legacy IE-only web applications, supporting tasks like clicking, filling forms, and data extraction via Selenium.28MIT
- AlicenseAqualityCmaintenanceEnables AI agents and MCP clients to automate web browsers via Selenium WebDriver, supporting Chrome, Firefox, and Edge in headless or visible mode with tools for navigation, interaction, content extraction, screenshots, and scripting.2134 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables remote agents to control a local Chrome/Edge browser via MCP, supporting navigation, snapshots, clicks, typing, screenshots, and script execution.25 npmISC
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to drive real Chrome or Edge browsers through MCP, allowing them to open pages, interact with elements, inspect network activity, take screenshots, and record or replay flows as tests.7MIT