Skip to main content
Glama

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 Application
  • Configured 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_page returns summarized screen information for LLM

  • No approval flow. Operations are executed when the Tool is called.


Table of Contents

  1. Quick Start

  2. Prerequisites

  3. Windows Pre-configuration

  4. Installation and Build

  5. Environment Variables

  6. Startup Methods

  7. Registration with AI Agent

  8. Tool Reference

  9. Usage Examples

  10. Errors and Troubleshooting

  11. Logging

  12. Troubleshooting


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.js

If {"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

InternetExplorerIntegrationLevel

Configure the Enterprise Mode Site List

InternetExplorerIntegrationSiteList

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 ignoreZoomSetting(true) is set, but 100% recommended

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

IE_MCP_EDGE_PATH

Path to msedge.exe

Not specified (IEDriver auto-detects)

IE_MCP_DRIVER_PATH

Path to IEDriverServer.exe

Not specified (searched from PATH)

IE_MCP_ALLOWED_ORIGINS

Comma-separated origins allowed for navigate. * for unlimited

*

IE_MCP_TIMEOUT_MS

Default timeout for element search and waiting (ms)

10000

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=10000
  • IE Driver 4.5.0 and later automatically detects Edge in environments without IE (Windows 11 default), so IE_MCP_EDGE_PATH is 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_ORIGINS is 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.js

Command Prompt:

set IE_MCP_DRIVER_PATH=C:\tools\IEDriverServer.exe
set IE_MCP_ALLOWED_ORIGINS=http://legacy01.local
node dist\index.js

Listens 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.js in args.

  • 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.js

After 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

browser_start

None

Start Edge IE Mode. If already started, reuse existing session

browser_close

None

Close the browser. No error even if called multiple times

navigate

url

Navigate after checking URL Allowlist

inspect_page

frame?

Return URL / title / screen text / operable elements

click

selector, frame?

Wait for visible and enabled, then click

type

selector, frame?, text, clear?

Input into input / textarea

select

selector, frame?, by, value

Select an option from <select>

wait_for

type, selector?, frame?, text?, timeoutMs?

Wait until condition is met

switch_window

target:"newest" / index, timeoutMs?

Switch to popup or another window

screenshot

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: true indicates that elements were truncated at the upper limit (300 items).

  • If the element list includes iframe, call again with frame specified 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
}

type

Required Input

Condition

present

selector

Element exists in DOM

visible

selector

Element is visible

enabled

selector

Element is visible and operable

text

selector, text

Element's text contains text

url

text

Current URL contains text

title

text

Title contains text

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_page

Repeat: 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

browser_start

{}

2

navigate

{ "url": "http://legacy01.local/customer" }

3

inspect_page

{}

4

type

{ "selector": { "by": "id", "value": "customerName" }, "text": "山田太郎" }

5

select

{ "selector": { "by": "id", "value": "branch" }, "by": "text", "value": "東京支店" }

6

click

{ "selector": { "by": "id", "value": "searchButton" } }

7

wait_for

{ "type": "visible", "selector": { "by": "id", "value": "resultTable" } }

8

inspect_page

{}

9

click

{ "selector": { "by": "linkText", "value": "山田太郎" } }

10

wait_for

{ "type": "title", "text": "顧客詳細" }

11

inspect_page

{}

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

Browser not started

Call browser_start

ELEMENT_NOT_FOUND

Element/frame not found

Check actual elements with inspect_page and review Selector

TIMEOUT

Condition for wait_for not met

Review condition and timeoutMs. Screen may differ from expected.

WINDOW_NOT_FOUND

Specified window does not exist

Review switch_window's index

NAVIGATION_FAILED

Navigation failed

Check URL, network, authentication

DRIVER_LOST

IEDriver/Edge terminated abnormally

Restart with browser_start (see below)

URL_NOT_ALLOWED

Origin outside Allowlist

Review IE_MCP_ALLOWED_ORIGINS

INVALID_ARGUMENT

Invalid argument

Check Tool input specification

INTERNAL_ERROR

Other (including startup failure)

Check message and stderr logs

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.log

12. Troubleshooting

Symptom

What to check

browser_start becomes INTERNAL_ERROR

Is IE_MCP_DRIVER_PATH correct? Can IEDriverServer.exe be started alone?

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

inspect_page elements are empty

Is it a screen inside a frame? (Re-acquire by specifying frame). Check the actual screen with screenshot

Tool not visible on Agent side

Is dist/index.js specified with an absolute path? Has npm run build been executed?

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.js
  • MCP 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. click and 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

-
license - not tested
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • Live browser debugging for AI assistants — DOM, console, network via MCP.

  • Screenshot, diff, audit and sitemap-capture any web page — 5 MCP tools for AI agents.

  • A paid remote MCP for AI agent browser MCP session, built to return verdicts, receipts, usage logs,

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sumikof/iedriver-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server