npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@i-scope/mcp-server

v0.4.5

Published

Model Context Protocol server for iScope / Oscilloscope.exe debug & control. Lets AI agents drive a .ajs debug session — breakpoints, step, variables, evaluate — through standard MCP tools layered on top of the iScope DAP adapter.

Readme

@i-scope/mcp-server

npm version npm downloads License: MIT Node

Part of the @i-scope/debugger SDK — one of seven leaf packages aggregated by the @i-scope/debugger meta-umbrella. Most users should install the meta (npm install @i-scope/debugger), which transitively pulls this package in together with the rest of the Debugger SDK (DAP adapter, native helper, source-map / VLST / COM leaves). Install @i-scope/mcp-server directly only when you want the MCP server surface without the rest of the SDK on your top-level package.json (e.g. an MCP-only Claude Code config via npx -y @i-scope/mcp-server). Cursor / VS Code end-users should install the iScope .ajs Debugger extension from Marketplace and run iScope: Enable MCP instead of editing mcp.json by hand.

Model Context Protocol (MCP) server that lets AI agents drive a Oscilloscope.exe debug session for .ajs scripts — set breakpoints, step, read variables and call stack, evaluate watch expressions — all through standard MCP tools layered on top of the iScope DAP adapter.

Status: 22 MCP tools shipped: 16 debug_*, 4 ui_modal_* (ui_modal_list, ui_modal_click, ui_modal_fill, ui_modal_dismiss), 2 system_* (system_preflight_check, system_abi_check).

Quick start

  1. Prerequisites (Windows):

    • Oscilloscope.exe v5 installed (default install path is supported out-of-the-box; for portable installs see the oscilloscopePath launch argument).
  2. Install the MCP server. Two flavours:

    Cursor / VS Code (recommended) — install iScope .ajs Debugger (cursor --install-extension i-scope.iscope-debugger or the same with code). Command Palette → iScope: Enable MCP → confirm. That merges npx -y @i-scope/mcp-server into workspace .cursor/mcp.json (Cursor) or .vscode/mcp.json (VS Code) and leaves other servers alone. Then Developer: Reload Window in this editor (not Oscilloscope).

    Other MCP clients / no extension — no repo clone:

    npm install -g @i-scope/mcp-server
    # ...or use npx in the client's mcp.json (see step 3).

    This pulls in @i-scope/dap-adapter, @i-scope/iscope-bridge-client, and the native helper @i-scope/iscope-bridge (which bundles iScopeBridge.exe) as transitive dependencies. No ISCOPE_* environment variable required.

    Monorepo developer — full local build:

    npm install
    npm run build:packages
    npm --workspace=@i-scope/iscope-bridge run build:msbuild
  3. Configure your MCP client only if you skipped iScope: Enable MCP.

    Cursor (.cursor/mcp.json):

    {
      "mcpServers": {
        "iscope-debug": {
          "command": "npx",
          "args": ["-y", "@i-scope/mcp-server"]
        }
      }
    }

    VS Code (.vscode/mcp.json):

    {
      "servers": {
        "iscope-debug": {
          "type": "stdio",
          "command": "npx",
          "args": ["-y", "@i-scope/mcp-server"]
        }
      }
    }

    For local development from the monorepo:

    {
      "mcpServers": {
        "iscope-debug": {
          "command": "node",
          "args": ["${workspaceFolder}/packages/mcp-server/dist/src/index.js"]
        }
      }
    }

    ISCOPE_EXTENSION_PATH is optional now — set it only when you want to override the helper-binary lookup with a custom bundled root.

  4. Reload this editor (Command Palette → Developer: Reload Window in Cursor or VS Code — not Oscilloscope) and ask your AI agent:

    "Run dist/Analyzer.ajs and pause on src/index.ts:42, show me the value of signal at that point."

    The agent will use debug_launch + debug_set_breakpoints + debug_continue + debug_variables to inspect your script.

Architecture

AI Agent (Cursor / Claude Code)
  ↕ MCP JSON-RPC over stdio
@i-scope/mcp-server  (this package)
  ↕ DAP over stdio (custom DapClient → spawned server.js)
@i-scope/dap-adapter (AjsDebugSession + stdio server entry)
  ↕ JSON-RPC over stdio
@i-scope/iscope-bridge-client → @i-scope/iscope-bridge (iScopeBridge.exe)
  ↕ COM (DISPID Invoke)
Oscilloscope.exe     (JScript engine + ScopeAppDbgCtrl)

Each MCP tool delegates to the existing DAP adapter — no debug logic is duplicated. The session state machine (idle → launching → running ⇄ paused → terminated) lives in src/dap-driver.ts. Tool groups live under src/tools/.

Tool reference

22 tools (16 debug + 4 UI modal + 2 system diagnostics). Every tool is invokable via the standard MCP tools/call request; consult the tool descriptions inside the running server (tools/list) for the canonical schemas.

Lifecycle

| Tool | Purpose | |-----------------------|-------------------------------------------------------------------------| | debug_launch | Spawn the DAP adapter, start program under Oscilloscope. | | debug_disconnect | Tear down the session; close Oscilloscope (if we launched it). | | debug_current_state | Lock-free snapshot of session state + last-known stop info. |

Breakpoints

| Tool | Purpose | |-------------------------|----------------------------------------------------------| | debug_set_breakpoints | Replace the breakpoint set for one source file. Pass lines:[] to clear. |

Execution control

| Tool | Purpose | |---------------------|-------------------------------------------------------------------------| | debug_continue | Resume; returns the next paused/terminated transition. | | debug_step_over | Step over (same frame). | | debug_step_into | Step into the called function. | | debug_step_out | Step out of the current frame. |

Sync

| Tool | Purpose | |-------------------------|----------------------------------------------------------------------| | debug_wait_for_paused | Block until the next pause / termination (or timeout). | | debug_read_output | Cursor-paginated read of buffered Host.ReportOut + adapter logs. |

Inspection

| Tool | Purpose | |---------------------|-------------------------------------------------------------------------| | debug_stack_trace | Get the current call stack with source-map provenance per frame. | | debug_scopes | List scopes (Locals, …) for a given frame. | | debug_variables | Enumerate variables under a scope or compound variablesReference. | | debug_evaluate | Evaluate a JScript expression (watch / hover / repl). |

Composite

| Tool | Purpose | |------------------|--------------------------------------------------------------------------| | debug_snapshot | Stack + scopes + locals in one round-trip, atomically under one mutex. |

Source maps (no debug session required)

| Tool | Purpose | |------------------------|--------------------------------------------------------------------| | debug_resolve_source | Translate .ts ↔ .ajs positions for any on-disk pair. |

UI modal control (interactive AI agent)

Surface Oscilloscope's child dialogs as a programmatically driveable tree. Use these tools when a debug_continue / debug_step_* unexpectedly times out — the script is most likely blocked on a Host.Configure() form, or Oscilloscope itself is reporting a diagnostic prompt that needs dismissal.

| Tool | Purpose | |--------------------|----------------------------------------------------------------------------------------------------------| | ui_modal_list | Enumerate every visible top-level dialog owned by Oscilloscope, with child controls and a signature classification (configure / diagnostic / unknown). | | ui_modal_click | Programmatic button click (WM_COMMAND + BN_CLICKED). Standard ids: 1=IDOK, 2=IDCANCEL, 6=IDYES, 7=IDNO. | | ui_modal_fill | Set the text of a child Edit (WM_SETTEXT) or ComboBox (CB_FINDSTRINGEXACT + CB_SETCURSEL, WM_SETTEXT fallback). Returns previousText for diffing. | | ui_modal_dismiss | Explicit close — mode='close' → PostMessage(WM_CLOSE) (the X button); mode='cancel' / 'ok' → SendMessage(WM_COMMAND, IDCANCEL/IDOK). |

Safety contract enforced in C++ for every UI tool:

  • GetWindowThreadProcessId(hwnd) == oscPid — we never touch a window owned by a different process.
  • Target HWND must not be the Oscilloscope main window — we only act on its owned dialogs.
  • All synchronous calls use SendMessageTimeout(SMTO_ABORTIFHUNG, 500 ms) — a hung target STA cannot stall the helper.

AI usage pattern — Configure() form

// 1. debug_continue times out — script is likely blocked on a modal.
const list = await callTool('ui_modal_list', {});
const m = list.modals.find(m => m.signature === 'configure');
if (m) {
    // 2. Find the input + the OK button.
    const edit = m.controls.find(c => c.className === 'Edit');
    const ok   = m.controls.find(c => c.controlId === 1 /* IDOK */);
    // 3. Fill and submit.
    await callTool('ui_modal_fill',  { hwnd: m.hwnd, controlId: edit.controlId, text: '42' });
    await callTool('ui_modal_click', { hwnd: m.hwnd, controlId: ok.controlId });
    // 4. Resume — engine should now proceed past the blocked Configure() call.
}

AI usage pattern — diagnostic dismissal

const list = await callTool('ui_modal_list', {});
const diag = list.modals.find(m => m.signature === 'diagnostic');
if (diag) {
    // Read diag.title, take action, then dismiss with Enter/Esc.
    await callTool('ui_modal_dismiss', { hwnd: diag.hwnd, mode: 'ok' });
}

These tools work without an active debug session (Oscilloscope only needs to be running) and are safe to mix with an active DAP session — COM lets multiple clients attach to Oscilloscope. ui_modal_* is the path for interactive control.

System diagnostics

Verify host machine prerequisites before (or after a failure during) any debug session. Read-only / idempotent — safe to call without Oscilloscope running.

| Tool | Purpose | |--------------------------|---------------------------------------------------------------------------------------------------------| | system_preflight_check | Verify that Windows Script Debugger (Machine Debug Manager, pdm.dll) is installed and that Oscilloscope's COM classes are registered. Returns a structured verdict (ok / script-debugger-not-registered / script-debugger-file-missing), per-check details, and human-readable hints + a download URL. Read-only / idempotent; safe to call before any debug session and without Oscilloscope running. AI agents should call this proactively when a launch fails or a user reports "BP ignored". | | system_abi_check | Probe iScopeBridge.exe wire ABI via protocol/version (no COM). Compares helper abi semver to @i-scope/iscope-bridge-client. Optional policy (strict default). Call when mixing npm versions or after swapping a custom helper binary — before debug_launch if you see ProtocolVersionMismatchError. |

Wire contract: preflight response shape is exported from @i-scope/com-protocol-types as PreflightCheckResponse.

AI usage pattern — preflight before launch

const r = await callTool('system_preflight_check', {});
if (!r.ok) {
    // Surface r.userHints + r.downloadUrl to the user.
    // Distinguish: r.verdict === 'script-debugger-not-registered' → install MDM
    //              r.verdict === 'script-debugger-file-missing'   → repair install
    //              r.oscilloscope.comRegistered === false         → Oscilloscope itself is not installed
}

Frame source-map provenance

Every frame in debug_stack_trace / debug_snapshot carries a sourceOrigin field:

  • mapped — source is .ts because the adapter resolved the bundler's source map.
  • unmapped-fallback — launch was .ts but the .ajs.map had a gap for this line; source is the raw .ajs so you don't act on stale TS coordinates.
  • generated — launch was directly against .ajs / .apn / .aps.

Tool namespaces

| Prefix | What it drives | Shipped | |--------------|-----------------------------------------------------|---------| | debug_* | Debug session: launch, breakpoints, step, stack, variables, evaluate, snapshot, source maps | 16 | | ui_modal_* | Native modal dialogs owned by Oscilloscope | 4 | | system_* | Host preflight and helper wire-ABI check | 2 |

Source maps

Pass .ts paths to program and source. When a source map sits next to the generated .ajs, frames and breakpoints come back in .ts space.

Testing

Three integration tests (drive the server through the official @modelcontextprotocol/sdk client over stdio) plus one unit-test suite for the pure driver internals:

# Unit tests — no Oscilloscope, no DAP child. Covers Mutex, output-
# buffer pagination, classifyFrame with reverse source-map lookup.
npm --workspace=@i-scope/mcp-server run test:unit

# Integration: pure source-map translation. No Oscilloscope.
npm --workspace=iscope-debugger run test:mcp-sourcemaps

# Integration: full launch → read output → disconnect cycle.
# Requires Oscilloscope.exe + a .mwf.
npm --workspace=iscope-debugger run test:mcp

# Integration: snapshot equivalence — asserts debug_snapshot returns
# the same payload as the headless inspect.cjs harness on the VLST
# fixture. Requires Oscilloscope + .mwf.
npm --workspace=iscope-debugger run test:mcp-snapshot

Related packages

This package is one of seven leaves of the @i-scope/debugger SDK meta-umbrella. The full family:

| Package | Role | |---------|------| | @i-scope/debugger | meta — one-install entry point for the whole SDK | | @i-scope/mcp-server (you are here) | MCP server for AI agents (22 tools: 16 debug + 4 UI modal + 2 system) | | @i-scope/dap-adapter | DAP server (AjsDebugSession) — embeddable + stdio | | @i-scope/iscope-bridge-client | Node JSON-RPC client to the native helper | | @i-scope/iscope-bridge | Win32 native helper binary (iScopeBridge.exe) | | @i-scope/source-map-bridge | TS ↔ AJS source-map manager | | @i-scope/vlst-parser | Parser for VLST locals/Watch blobs | | @i-scope/com-protocol-types | TS-mirror of COM DISPID / event constants |

License

MIT. See LICENSE.