Skip to content

chore: Add tracing start/stop tools and enhance global switch management#2059

Open
KananSu wants to merge 6 commits intolynx-family:mainfrom
KananSu:p/kanan/trace_mcp_tools
Open

chore: Add tracing start/stop tools and enhance global switch management#2059
KananSu wants to merge 6 commits intolynx-family:mainfrom
KananSu:p/kanan/trace_mcp_tools

Conversation

@KananSu
Copy link

@KananSu KananSu commented Dec 26, 2025

  • Introduced StartTracing and EndTracing tools to the devtool-mcp-server, enabling trace event collection control via MCP server.
    • StartTracing: Starts trace event collection, checks and enables debug mode for Android, and provides user feedback based on result.
    • EndTracing: Stops trace event collection, reads trace data from stream, saves it to a temporary file, and returns the file path or error.
  • Registered the new tracing tools in the MCP server tool list.
  • Extended global switch management:
    • Added support for enable_debug_mode global key.
    • Ensured both enable_devtool and enable_debug_mode are enabled when connecting.
    • Updated response types and internal logic to use { message: ... } instead of { global_value: ... } for global switch responses.
  • Added offCDPEvent method for event listener cleanup.
  • Updated event map to support Tracing.tracingComplete.

Summary by CodeRabbit

  • New Features

    • Added StartTracing and EndTracing tools to begin/end trace collection and save trace files.
    • Clients now auto-enable debug mode on connect to simplify tracing.
    • Added ability to detach CDP event listeners to prevent duplicate notifications.
  • Bug Fixes

    • Improved trace error messages, timeout handling, streaming, and cleanup for more reliable tracing.
  • Documentation

    • Added a changeset documenting the new tracing tools and behavior.

✏️ Tip: You can customize this high-level summary in your review settings.

Checklist

  • Tests not required.
  • Documentation not required
  • Changeset added.

@changeset-bot
Copy link

changeset-bot bot commented Dec 26, 2025

🦋 Changeset detected

Latest commit: d120290

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@lynx-js/devtool-mcp-server Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 26, 2025

📝 Walkthrough

Walkthrough

Adds StartTracing and EndTracing tools and registers them; updates connector types and EventMap for tracing events; changes GetGlobalSwitch response shape to { message }; ensures enable_debug_mode is set on client connect; exposes offCDPEvent to remove CDP listeners. (≤50 words)

Changes

Cohort / File(s) Summary
Changeset
/.changeset/angry-insects-care.md
New minor-version changeset documenting addition of StartTracing and EndTracing tools and trace collection control via the MCP server.
Connector / Core
packages/mcp-servers/devtool-mcp-server/src/connector.ts
GetGlobalSwitch response shape changed from { global_value } to { message }; added exported TracingComplete type; extended EventMap with CDP-event-Tracing.tracingComplete; expanded GlobalKey to include enable_debug_mode; added public offCDPEvent method; ensure enable_debug_mode is enabled after client connect.
Tool Registry
packages/mcp-servers/devtool-mcp-server/src/index.ts
Imported and registered StartTracing and EndTracing under a new Tracing section in the TOOLS registry.
Tracing — Start
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
New Tracing_start tool: public input schema (clientId, JSProfileType, enableSystrace, JSProfileInterval); checks/sets Android debug switch; builds traceConfig; issues Tracing.start via CDP; maps known errors to guidance URLs; returns success or mapped errors.
Tracing — End
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
New Tracing_end tool: subscribes to Tracing.tracingComplete, streams IO.read base64 chunks into a timestamped .pftrace temp file via a stream writer, enforces an 8s timeout, cleans up CDP listeners/timers, maps certain errors, and returns the trace file path.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • colinaaa

Poem

🐇 I nibble traces, soft and light,
I chase the events from byte to byte,
Base64 crumbs in tidy rows,
I stitch a pftrace as the timeline grows,
I stop the stream — the rabbit knows.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: adding StartTracing/EndTracing tools and enhancing global switch management with enable_debug_mode support.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ffd4fef and c4b5232.

📒 Files selected for processing (2)
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with the configuration specified in tsconfig.json

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,tsx}: Follow eslint rules as configured in eslint.config.js including React and TypeScript specific rules
Follow code formatting rules specified in .dprint.jsonc and biome.jsonc

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
🧠 Learnings (3)
📓 Common learnings
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.
📚 Learning: 2025-11-06T01:19:23.670Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.

Applied to files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
📚 Learning: 2025-11-06T01:17:11.892Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/src/connector.ts:347-368
Timestamp: 2025-11-06T01:17:11.892Z
Learning: In the lynx-family/lynx-stack repository, for the devtool-mcp-server package, the getSource and getConsole methods intentionally throw errors when collectors don't exist (rather than returning empty arrays) to provide clear feedback to code agents and automation tools that something is wrong (e.g., debugger not enabled, collectors not initialized), enabling them to take corrective action.

Applied to files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🧬 Code graph analysis (1)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts (2)
packages/mcp-servers/devtool-mcp-server/src/index.ts (1)
  • defineTool (135-135)
packages/mcp-servers/devtool-mcp-server/src/McpContext.ts (1)
  • connector (20-22)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts (2)

25-41: Consider simplifying the debug mode check.

The ensureLynxConnected function already enables enable_debug_mode for connected clients. This additional check handles the edge case where debug mode was disabled after connection, but could be simplified. The current approach is defensive and provides good user feedback.


63-68: Prefer includes() over indexOf() >= 0 for readability.

Using includes() is more idiomatic in modern JavaScript/TypeScript.

🔎 Suggested fix
       if (
-        msg.indexOf('Failed to get trace controller') >= 0
-        || msg.indexOf('Not implemented:') >= 0
-        || msg.indexOf('Tracing not enabled') >= 0
-        || msg.indexOf('Failed to start tracing') >= 0
+        msg.includes('Failed to get trace controller')
+        || msg.includes('Not implemented:')
+        || msg.includes('Tracing not enabled')
+        || msg.includes('Failed to start tracing')
       ) {
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7903c9e and a01ea11.

📒 Files selected for processing (5)
  • .changeset/angry-insects-care.md
  • packages/mcp-servers/devtool-mcp-server/src/connector.ts
  • packages/mcp-servers/devtool-mcp-server/src/index.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with the configuration specified in tsconfig.json

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/index.ts
  • packages/mcp-servers/devtool-mcp-server/src/connector.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,tsx}: Follow eslint rules as configured in eslint.config.js including React and TypeScript specific rules
Follow code formatting rules specified in .dprint.jsonc and biome.jsonc

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/index.ts
  • packages/mcp-servers/devtool-mcp-server/src/connector.ts
🧠 Learnings (6)
📓 Common learnings
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/src/connector.ts:347-368
Timestamp: 2025-11-06T01:17:11.892Z
Learning: In the lynx-family/lynx-stack repository, for the devtool-mcp-server package, the getSource and getConsole methods intentionally throw errors when collectors don't exist (rather than returning empty arrays) to provide clear feedback to code agents and automation tools that something is wrong (e.g., debugger not enabled, collectors not initialized), enabling them to take corrective action.
📚 Learning: 2025-12-26T05:10:01.595Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-26T05:10:01.595Z
Learning: Use changeset tool with `pnpm changeset` to document changes before contribution

Applied to files:

  • .changeset/angry-insects-care.md
📚 Learning: 2025-09-12T09:43:04.847Z
Learnt from: gaoachao
Repo: lynx-family/lynx-stack PR: 1736
File: .changeset/spotty-experts-smoke.md:1-3
Timestamp: 2025-09-12T09:43:04.847Z
Learning: In the lynx-family/lynx-stack repository, empty changeset files (containing only `---\n\n---`) are used for internal changes that modify src/** files but don't require meaningful release notes, such as private package changes or testing-only modifications. This satisfies CI requirements without generating user-facing release notes.

Applied to files:

  • .changeset/angry-insects-care.md
📚 Learning: 2025-07-22T09:23:07.797Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1330
File: .changeset/olive-animals-attend.md:1-3
Timestamp: 2025-07-22T09:23:07.797Z
Learning: In the lynx-family/lynx-stack repository, changesets are only required for meaningful changes to end-users such as bugfixes and features. Internal/development changes like chores, refactoring, or removing debug info do not need changeset entries.

Applied to files:

  • .changeset/angry-insects-care.md
📚 Learning: 2025-11-06T01:19:23.670Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.

Applied to files:

  • .changeset/angry-insects-care.md
  • packages/mcp-servers/devtool-mcp-server/src/index.ts
  • packages/mcp-servers/devtool-mcp-server/src/connector.ts
📚 Learning: 2025-11-06T01:17:11.892Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/src/connector.ts:347-368
Timestamp: 2025-11-06T01:17:11.892Z
Learning: In the lynx-family/lynx-stack repository, for the devtool-mcp-server package, the getSource and getConsole methods intentionally throw errors when collectors don't exist (rather than returning empty arrays) to provide clear feedback to code agents and automation tools that something is wrong (e.g., debugger not enabled, collectors not initialized), enabling them to take corrective action.

Applied to files:

  • .changeset/angry-insects-care.md
  • packages/mcp-servers/devtool-mcp-server/src/index.ts
🔇 Additional comments (13)
.changeset/angry-insects-care.md (1)

1-5: LGTM!

The changeset correctly documents the new tracing tools as a minor version bump, which is appropriate for a feature addition.

packages/mcp-servers/devtool-mcp-server/src/connector.ts (5)

87-93: LGTM!

The TracingComplete type and updated EventMap entries correctly support the new tracing events and maintain backward compatibility with the existing global switch response format.


113-119: LGTM!

The Tracing.tracingComplete event entry follows the established pattern for CDP events and correctly uses the TracingComplete type.


149-156: LGTM!

The resolution logic correctly accesses result?.message to match the updated response payload structure.


467-477: LGTM!

The offCDPEvent method correctly mirrors the onCDPEvent signature and enables proper cleanup of event listeners, which is essential for the tracing workflow.


511-522: LGTM!

The enable_debug_mode handling follows the established pattern for enable_devtool, ensuring debug mode is enabled automatically when clients connect.

packages/mcp-servers/devtool-mcp-server/src/index.ts (2)

41-42: LGTM!

The imports for the new tracing tools follow the established pattern.


88-92: LGTM!

The new tracing tools are properly registered in the TOOLS array with a clear section comment, following the existing organizational pattern.

packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts (1)

13-21: LGTM!

Tool definition follows the established pattern with appropriate naming, description, and annotations.

packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (4)

1-15: LGTM!

Imports and type definition are appropriate for the file I/O operations required by this tool.


17-35: LGTM!

Tool definition and the sendIOReadMessage helper are well-structured with an appropriate chunk size.


61-84: LGTM!

The writeDataToFile function properly handles stream events and ensures the write stream is closed correctly.


91-133: LGTM on the async flow logic.

The event handling flow is well-structured: register listener → send CDP message → wait for completion. The finally block ensures proper cleanup, and client ID filtering prevents cross-client interference.

@KananSu KananSu force-pushed the p/kanan/trace_mcp_tools branch from a01ea11 to 3517d4e Compare December 26, 2025 07:26
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts (1)

62-67: Consider using includes() instead of indexOf() for readability.

Modern JavaScript/TypeScript style prefers includes() for substring checks as it's more readable and returns a boolean directly.

🔎 Suggested refactor
     if (
-      msg.indexOf('Failed to get trace controller') >= 0
-      || msg.indexOf('Not implemented:') >= 0
-      || msg.indexOf('Tracing not enabled') >= 0
-      || msg.indexOf('Failed to start tracing') >= 0
+      msg.includes('Failed to get trace controller')
+      || msg.includes('Not implemented:')
+      || msg.includes('Tracing not enabled')
+      || msg.includes('Failed to start tracing')
     ) {
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (1)

55-78: Consider handling write stream backpressure.

writeStream.write() returns false when the internal buffer is full, indicating the caller should wait for the 'drain' event before writing more data. For large trace files, ignoring this could lead to increased memory usage.

🔎 Suggested approach using pipeline

For a simpler and more robust solution, consider using stream.Readable.from() with pipeline():

import { pipeline } from 'node:stream/promises';
import { Readable } from 'node:stream';

const writeDataToFile = async (
  dataChunks: Buffer[],
  filePath: string,
): Promise<void> => {
  const readable = Readable.from(dataChunks);
  const writeStream = fs.createWriteStream(filePath);
  await pipeline(readable, writeStream);
};
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a01ea11 and 3517d4e.

📒 Files selected for processing (5)
  • .changeset/angry-insects-care.md
  • packages/mcp-servers/devtool-mcp-server/src/connector.ts
  • packages/mcp-servers/devtool-mcp-server/src/index.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • .changeset/angry-insects-care.md
  • packages/mcp-servers/devtool-mcp-server/src/index.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with the configuration specified in tsconfig.json

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/connector.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,tsx}: Follow eslint rules as configured in eslint.config.js including React and TypeScript specific rules
Follow code formatting rules specified in .dprint.jsonc and biome.jsonc

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/connector.ts
🧠 Learnings (3)
📓 Common learnings
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.
📚 Learning: 2025-11-06T01:17:11.892Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/src/connector.ts:347-368
Timestamp: 2025-11-06T01:17:11.892Z
Learning: In the lynx-family/lynx-stack repository, for the devtool-mcp-server package, the getSource and getConsole methods intentionally throw errors when collectors don't exist (rather than returning empty arrays) to provide clear feedback to code agents and automation tools that something is wrong (e.g., debugger not enabled, collectors not initialized), enabling them to take corrective action.

Applied to files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
📚 Learning: 2025-11-06T01:19:23.670Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.

Applied to files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/connector.ts
🧬 Code graph analysis (3)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts (2)
packages/mcp-servers/devtool-mcp-server/src/index.ts (1)
  • defineTool (135-135)
packages/mcp-servers/devtool-mcp-server/src/McpContext.ts (1)
  • connector (20-22)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (4)
packages/mcp-servers/devtool-mcp-server/src/index.ts (1)
  • defineTool (135-135)
packages/mcp-servers/devtool-mcp-server/src/McpContext.ts (1)
  • connector (20-22)
packages/mcp-servers/devtool-mcp-server/src/connector.ts (1)
  • TracingComplete (87-89)
packages/mcp-servers/devtool-mcp-server/src/schema/index.ts (1)
  • clientId (6-10)
packages/mcp-servers/devtool-mcp-server/src/connector.ts (2)
packages/mcp-servers/devtool-mcp-server/src/schema/index.ts (2)
  • clientId (6-10)
  • sessionId (22-26)
packages/mcp-servers/devtool-mcp-server/src/McpContext.ts (1)
  • connector (20-22)
🔇 Additional comments (16)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts (4)

1-11: LGTM!

The imports and type definition are appropriate. The TracingStartResponse type correctly models the CDP error response structure.


22-41: LGTM!

The Android-specific debug mode handling logic is well-structured. The flow correctly:

  1. Checks if the client is Android
  2. Gets the current enable_debug_mode state
  3. Enables it if not already enabled
  4. Returns early with a restart prompt (since the mode change requires an app restart)

This aligns with the learning that the devtool-mcp-server intentionally provides clear feedback for corrective action.


42-49: Previous concern addressed - trace config is now valid.

The excludedCategories: ['*'] has been removed, resolving the contradictory configuration. The config now correctly uses only includedCategories: ['*'] to capture all trace categories.


62-70: Previous concern addressed - URL is now platform-agnostic.

The documentation URL no longer includes the ?platform=ios query parameter, making it appropriate for all platforms.

packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (5)

1-15: LGTM!

The imports are appropriate for the file operations and CDP integration. The IOReadResponse type correctly models the expected CDP response for IO.read.


36-53: LGTM!

The readStreamData function correctly implements chunked reading with EOF detection. The error handling for missing data is appropriate.


79-92: Previous concerns addressed - ordering is now correct.

The Promise.withResolvers() call is now correctly placed before the setTimeout, so resolve is in scope when the timer fires. The timeout handler also now removes the event listener before resolving.

However, note that the timeout handler calls offCDPEvent directly (line 85) while the cleanup function also clears the timer (line 91). For consistency and to ensure clearTimeout(timer) is called in the timeout path (though technically unnecessary since the timer already fired), you could call cleanup() instead:

     const timer = setTimeout(() => {
       response.appendLines(
         'Loading trace data timeout, please try again later!',
       );
-      connector.offCDPEvent('Tracing.tracingComplete', handleTraceComplete);
+      cleanup();
       resolve();
     }, 8000);

This is a minor consistency improvement.


93-125: LGTM!

The handleTraceComplete event handler correctly:

  1. Filters by clientId to handle only relevant events
  2. Reads the stream data and writes to a temp file
  3. Provides informative success/error messages
  4. Calls cleanup() and resolve() in the finally block to ensure proper resource cleanup

127-135: LGTM!

The event registration and CDP message sending are correctly ordered - the listener is registered before sending Tracing.end to ensure the completion event is not missed.

packages/mcp-servers/devtool-mcp-server/src/connector.ts (7)

87-89: LGTM!

The TracingComplete type is correctly defined and exported, matching the expected CDP Tracing.tracingComplete event payload structure with a stream handle.


113-119: LGTM!

The CDP-event-Tracing.tracingComplete event is correctly added to the EventMap with the appropriate tuple type signature, consistent with other CDP events in the map.


121-121: LGTM!

The GlobalKey type is correctly extended to include 'enable_debug_mode', which aligns with the new tracing functionality requirements.


146-157: LGTM!

The getGlobalSwitch method correctly handles the updated response format by checking for result?.message when the result is an object. The boolean resolution logic handles both string 'true' and boolean true values appropriately.


467-477: LGTM!

The offCDPEvent method correctly mirrors the onCDPEvent method signature and implementation, providing proper event listener cleanup capability needed by the EndTracing tool.


511-522: LGTM!

The enable_debug_mode handling follows the same pattern as enable_devtool, maintaining consistency. The sequential get/set approach is appropriate for ensuring each switch is properly configured before proceeding.


52-56: Type change from global_value to message in GetGlobalSwitchResponse is correct.

The GetGlobalSwitchResponse type has been updated to use message instead of global_value. This change is consistent throughout the codebase—line 152 correctly reads result?.message, and the remaining global_value references are for the distinct SetGlobalSwitchResponse type, which appropriately uses global_value. No inconsistencies found.

@KananSu KananSu changed the title chore: Add tracing start/stop tools and enhance global switch managem… chore: Add tracing start/stop tools and enhance global switch management Dec 26, 2025
@KananSu KananSu force-pushed the p/kanan/trace_mcp_tools branch from 6a96033 to 9d98767 Compare December 29, 2025 02:32
…ent**

- Introduced `StartTracing` and `EndTracing` tools to the devtool-mcp-server, enabling trace event collection control via MCP server.
  - `StartTracing`: Starts trace event collection, checks and enables debug mode for Android, and provides user feedback based on result.
  - `EndTracing`: Stops trace event collection, reads trace data from stream, saves it to a temporary file, and returns the file path or error.
- Registered the new tracing tools in the MCP server tool list.
- Extended global switch management:
  - Added support for `enable_debug_mode` global key.
  - Ensured both `enable_devtool` and `enable_debug_mode` are enabled when connecting.
  - Updated response types and internal logic to use `{ message: ... }` instead of `{ global_value: ... }` for global switch responses.
- Added `offCDPEvent` method for event listener cleanup.
- Updated event map to support `Tracing.tracingComplete`.
@KananSu KananSu force-pushed the p/kanan/trace_mcp_tools branch from 9d98767 to f16f391 Compare December 29, 2025 02:35
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (2)

72-76: Consider handling write stream backpressure.

The current implementation writes all chunks synchronously without checking the return value of writeStream.write(). If the write buffer fills up, this could cause increased memory usage. For trace files that may be large, consider handling backpressure by waiting for the 'drain' event when write() returns false.

🔎 Optional fix with backpressure handling
-        for (const chunk of dataChunks) {
-          writeStream.write(chunk);
-        }
-
-        writeStream.end();
+        const writeNext = (index: number) => {
+          while (index < dataChunks.length) {
+            const ok = writeStream.write(dataChunks[index]);
+            index++;
+            if (!ok) {
+              writeStream.once('drain', () => writeNext(index));
+              return;
+            }
+          }
+          writeStream.end();
+        };
+        writeNext(0);

102-104: Consider validating data.stream before use.

The data.stream is accessed directly without checking if it's defined. If the CDP event delivers a TracingComplete payload without a valid stream property, this will cause a runtime error that may produce an unclear message.

🔎 Suggested validation
       try {
         const stream = data.stream;
+        if (stream === undefined || stream === null) {
+          throw new Error('TracingComplete event missing stream handle');
+        }
         const dataChunks = await readStreamData(stream);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3517d4e and 9d98767.

📒 Files selected for processing (5)
  • .changeset/angry-insects-care.md
  • packages/mcp-servers/devtool-mcp-server/src/connector.ts
  • packages/mcp-servers/devtool-mcp-server/src/index.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • .changeset/angry-insects-care.md
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with the configuration specified in tsconfig.json

Files:

  • packages/mcp-servers/devtool-mcp-server/src/index.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/connector.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,tsx}: Follow eslint rules as configured in eslint.config.js including React and TypeScript specific rules
Follow code formatting rules specified in .dprint.jsonc and biome.jsonc

Files:

  • packages/mcp-servers/devtool-mcp-server/src/index.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/connector.ts
🧠 Learnings (3)
📓 Common learnings
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.
📚 Learning: 2025-11-06T01:19:23.670Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.

Applied to files:

  • packages/mcp-servers/devtool-mcp-server/src/index.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/connector.ts
📚 Learning: 2025-11-06T01:17:11.892Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/src/connector.ts:347-368
Timestamp: 2025-11-06T01:17:11.892Z
Learning: In the lynx-family/lynx-stack repository, for the devtool-mcp-server package, the getSource and getConsole methods intentionally throw errors when collectors don't exist (rather than returning empty arrays) to provide clear feedback to code agents and automation tools that something is wrong (e.g., debugger not enabled, collectors not initialized), enabling them to take corrective action.

Applied to files:

  • packages/mcp-servers/devtool-mcp-server/src/index.ts
  • packages/mcp-servers/devtool-mcp-server/src/connector.ts
🧬 Code graph analysis (1)
packages/mcp-servers/devtool-mcp-server/src/connector.ts (2)
packages/mcp-servers/devtool-mcp-server/src/schema/index.ts (2)
  • clientId (6-10)
  • sessionId (22-26)
packages/mcp-servers/devtool-mcp-server/src/McpContext.ts (1)
  • connector (20-22)
🔇 Additional comments (13)
packages/mcp-servers/devtool-mcp-server/src/index.ts (2)

41-42: LGTM!

The imports for StartTracing and EndTracing follow the existing import conventions and path structure.


88-91: LGTM!

The new Tracing section is well-organized and follows the existing pattern of grouping tools by domain (CSS, Debugger, Device, DOM, etc.). The registration order is consistent with the import order.

packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (4)

1-15: LGTM!

License header, imports, and type definition are appropriate. The IOReadResponse type correctly models the CDP IO.read response structure.


36-53: LGTM!

The readStreamData function correctly handles streaming with EOF detection and throws a descriptive error when data is unavailable, aligning with the pattern of providing clear feedback to automation tools. Based on learnings, this intentional error throwing is the expected behavior.


79-92: LGTM!

The Promise.withResolvers is correctly placed before the timer creation (addressing the previous review concern). The timeout handler properly removes the event listener before resolving, and the cleanup function is correctly structured for use in the event handler's finally block.


127-135: LGTM!

The implementation correctly registers the event listener before sending the Tracing.end CDP message, ensuring the completion event won't be missed. The promise-based flow properly coordinates the async event handling.

packages/mcp-servers/devtool-mcp-server/src/connector.ts (7)

52-56: LGTM!

The GetGlobalSwitchResponse type correctly accommodates the new response format where data can be a primitive (string | boolean) or an object with a message field. This aligns with the updated handling logic in getGlobalSwitch.


87-89: LGTM!

The TracingComplete type is appropriately minimal, exporting just the stream handle needed by the EndTracing tool.


113-118: LGTM!

The CDP-event-Tracing.tracingComplete event entry follows the established pattern of other CDP events in the EventMap, with appropriate typing for error, payload, clientId, and sessionId.


121-121: LGTM!

The GlobalKey union type is appropriately expanded to include 'enable_debug_mode', enabling type-safe usage of the new global switch throughout the codebase.


149-156: LGTM!

The updated handler correctly accesses result?.message instead of the previous global_value, and properly handles both string ('true') and boolean (true) representations of the value.


467-477: LGTM!

The offCDPEvent method is a well-designed mirror of onCDPEvent, providing proper event listener cleanup capability. This is essential for the timeout handling in EndTracing to prevent memory leaks.


511-522: LGTM!

The enable_debug_mode handling follows the same established pattern as enable_devtool and is correctly placed in the client connection flow. The optional chaining on connector provides safety in edge cases.

@KananSu KananSu requested a review from colinaaa December 29, 2025 03:10
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (1)

53-78: Consider handling write stream backpressure for large traces.

writeStream.write(chunk) at line 68 doesn't check the return value. When the internal buffer is full, write() returns false, and you should wait for the 'drain' event before writing more data. For very large traces, this could cause memory buildup.

🔎 Suggested improvement with backpressure handling
         const readAndWrite = async () => {
           let hasEnd = false;

           while (!hasEnd) {
             try {
               const message = await sendIOReadMessage(stream);

               if (!message.data) {
                 reject(
                   new Error('Failed to read trace data: no data available'),
                 );
                 return;
               }

               const chunk = Buffer.from(message.data, 'base64');
-              writeStream.write(chunk);
+              const canContinue = writeStream.write(chunk);
+              if (!canContinue) {
+                await new Promise<void>((r) => writeStream.once('drain', r));
+              }
               hasEnd = message.eof;
             } catch (error) {
               writeStream.destroy();
               reject(error);
               return;
             }
           }

           writeStream.end();
         };
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f16f391 and 41df9bd.

📒 Files selected for processing (2)
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with the configuration specified in tsconfig.json

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,tsx}: Follow eslint rules as configured in eslint.config.js including React and TypeScript specific rules
Follow code formatting rules specified in .dprint.jsonc and biome.jsonc

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.
📚 Learning: 2025-11-06T01:19:23.670Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.

Applied to files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
🔇 Additional comments (5)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (5)

1-15: LGTM!

Imports are well-organized using the node: prefix for built-in modules, and the local IOReadResponse type is appropriately scoped.


17-25: LGTM!

Tool definition follows the established pattern with appropriate metadata and annotations.


83-96: LGTM!

The Promise.withResolvers pattern is correctly used, and the timeout handler properly cleans up the CDP event listener before resolving. The cleanup function provides comprehensive resource cleanup for the success path.


97-128: LGTM!

The handler correctly filters by clientId, uses a try/catch/finally pattern for robust error handling, and ensures cleanup always occurs. The temp file naming with timestamp is appropriate.


130-137: LGTM!

The event registration before sending Tracing.end ensures no race condition. The returned promise correctly awaits either the completion event or timeout.

@KananSu KananSu force-pushed the p/kanan/trace_mcp_tools branch from 41df9bd to 1362602 Compare December 29, 2025 05:13
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (1)

28-35: Critical: Stream handle type should be string, not number.

The Chrome DevTools Protocol specifies IO.StreamHandle as a string type. Using number here creates a type mismatch with the CDP specification. This issue affects both the function parameter and the upstream TracingComplete.stream type definition in connector.ts (lines 86-88).

🔎 Proposed fix

Update the parameter type:

-    const sendIOReadMessage = (stream: number): Promise<IOReadResponse> => {
+    const sendIOReadMessage = (stream: string): Promise<IOReadResponse> => {
       return connector.sendCDPMessage<IOReadResponse>(
         params.clientId,
         -1,
         'IO.read',
         { handle: stream, size: 1024 * 1024 },
       );
     };

Also update TracingComplete in packages/mcp-servers/devtool-mcp-server/src/connector.ts:

export type TracingComplete = {
  stream: string;
};

Run this script to verify all usages of TracingComplete.stream:

#!/bin/bash
# Find all references to TracingComplete and stream usage
rg -n "TracingComplete|\.stream" packages/mcp-servers/devtool-mcp-server/src/ -C 2
🧹 Nitpick comments (2)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (2)

36-82: Consider using streaming API instead of buffering.

The current implementation reads trace data in chunks and buffers them through memory before writing to disk. As suggested in previous review, using the Web Streams API (ReadableStream with pipeTo) would be more memory-efficient for potentially large trace files.

🔎 Proposed streaming implementation (based on previous feedback)

Replace the current buffering approach with:

const readStreamDataToFile = async (
  stream: string, // Note: also fix type to string
  filePath: string,
): Promise<void> => {
  const sourceStream = new ReadableStream<Uint8Array>({
    async pull(controller) {
      try {
        const message = await sendIOReadMessage(stream);

        if (message.data) {
          controller.enqueue(Buffer.from(message.data, 'base64'));
        }

        if (message.eof) {
          controller.close();
        }
      } catch (err) {
        controller.error(err);
      }
    },
  });

  const fileWritable = Writable.toWeb(fs.createWriteStream(filePath));
  await sourceStream.pipeTo(fileWritable);
};

You'll need to import Writable from node:stream:

import { Writable } from 'node:stream';

Based on learnings, this approach was previously suggested by colinaaa.


107-107: Add validation for stream handle.

While the type issue needs to be fixed separately, consider adding validation to ensure the stream handle exists before attempting to read from it.

🔎 Suggested validation
       try {
         const stream = data.stream;
+        
+        if (!stream) {
+          throw new Error('No stream handle provided in tracing complete event');
+        }

         const tempDir = os.tmpdir();
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 41df9bd and 1362602.

📒 Files selected for processing (2)
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with the configuration specified in tsconfig.json

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,tsx}: Follow eslint rules as configured in eslint.config.js including React and TypeScript specific rules
Follow code formatting rules specified in .dprint.jsonc and biome.jsonc

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.
📚 Learning: 2025-11-06T01:19:23.670Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.

Applied to files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
🧬 Code graph analysis (1)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (3)
packages/mcp-servers/devtool-mcp-server/src/index.ts (1)
  • defineTool (135-135)
packages/mcp-servers/devtool-mcp-server/src/connector.ts (1)
  • TracingComplete (87-89)
packages/mcp-servers/devtool-mcp-server/src/schema/index.ts (1)
  • clientId (6-10)
🔇 Additional comments (2)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (2)

83-96: LGTM: Promise ordering and cleanup logic are correct.

The previously reported issues have been properly addressed:

  • Promise.withResolvers is now called before the timeout (line 83 before line 85)
  • The timeout handler correctly calls cleanup before resolving (line 89)
  • The cleanup function properly removes the event listener and clears the timer

130-137: LGTM: Event handling flow is correct.

The event listener is properly registered before sending the Tracing.end command, ensuring no race condition. The promise-based return allows proper async handling of the trace completion.

@KananSu KananSu force-pushed the p/kanan/trace_mcp_tools branch from 1362602 to c1b943c Compare December 29, 2025 06:48
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts (1)

72-80: URL hardcoded to iOS platform despite Android check.

The handler explicitly checks for Android clients (line 35), but the error message at line 79 always links to the iOS documentation (?platform=ios). This is inconsistent and misleading for Android users.

🔎 Suggested fix
     if (
       msg.includes('Failed to get trace controller')
       || msg.includes('Not implemented:')
       || msg.includes('Tracing not enabled')
       || msg.includes('Failed to start tracing')
     ) {
+      const platform = client?.info.query.os === 'Android' ? 'android' : 'ios';
       throw new Error(
-        'Tracing functionality is not supported in the current version. Please integrate the Lynx development version (with -dev suffix) to enable tracing. For more information, visit: https://lynxjs.org/en/guide/start/integrate-lynx-dev-version.html?platform=ios',
+        `Tracing functionality is not supported in the current version. Please integrate the Lynx development version (with -dev suffix) to enable tracing. For more information, visit: https://lynxjs.org/en/guide/start/integrate-lynx-dev-version.html?platform=${platform}`,
       );
     } else {
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (1)

29-29: Critical: Stream handle type mismatch with CDP protocol specification.

According to the Chrome DevTools Protocol specification, IO.StreamHandle is a string type, not number. Both sendIOReadMessage (line 29) and readStreamDataToFile (line 38) incorrectly declare the stream parameter as number. Additionally, the TracingComplete type imported from connector.ts (line 7) defines stream: number, which should be updated to stream: string to match the CDP specification.

🔎 Suggested fix

Update the type signatures in this file:

-    const sendIOReadMessage = (stream: number): Promise<IOReadResponse> => {
+    const sendIOReadMessage = (stream: string): Promise<IOReadResponse> => {
       return connector.sendCDPMessage<IOReadResponse>(
     const readStreamDataToFile = async (
-      stream: number,
+      stream: string,
       filePath: string,
     ): Promise<void> => {

Also update TracingComplete in packages/mcp-servers/devtool-mcp-server/src/connector.ts:

 export type TracingComplete = {
-  stream: number;
+  stream: string;
 };

Also applies to: 38-38

🧹 Nitpick comments (1)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (1)

66-72: Use cleanup() function for consistency.

The timeout handler manually calls connector.offCDPEvent (line 70) and resolve() (line 71), but doesn't use the cleanup() function defined at lines 74-77. For better maintainability and consistency with the success path (which calls cleanup() at line 106), consider refactoring to use cleanup() here as well.

🔎 Suggested fix
     const timer = setTimeout(() => {
       response.appendLines(
         'Loading trace data timeout, please try again later!',
       );
-      connector.offCDPEvent('Tracing.tracingComplete', handleTraceComplete);
+      cleanup();
       resolve();
     }, 8000);

Note: clearTimeout(timer) inside cleanup() will be a no-op when called from within the timeout callback, but this improves code consistency.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1362602 and c1b943c.

📒 Files selected for processing (2)
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with the configuration specified in tsconfig.json

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,tsx}: Follow eslint rules as configured in eslint.config.js including React and TypeScript specific rules
Follow code formatting rules specified in .dprint.jsonc and biome.jsonc

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🧠 Learnings (3)
📓 Common learnings
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.
📚 Learning: 2025-11-06T01:19:23.670Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.

Applied to files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
📚 Learning: 2025-11-06T01:17:11.892Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/src/connector.ts:347-368
Timestamp: 2025-11-06T01:17:11.892Z
Learning: In the lynx-family/lynx-stack repository, for the devtool-mcp-server package, the getSource and getConsole methods intentionally throw errors when collectors don't exist (rather than returning empty arrays) to provide clear feedback to code agents and automation tools that something is wrong (e.g., debugger not enabled, collectors not initialized), enabling them to take corrective action.

Applied to files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🧬 Code graph analysis (2)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (3)
packages/mcp-servers/devtool-mcp-server/src/McpContext.ts (1)
  • connector (20-22)
packages/mcp-servers/devtool-mcp-server/src/connector.ts (1)
  • TracingComplete (87-89)
packages/mcp-servers/devtool-mcp-server/src/schema/index.ts (1)
  • clientId (6-10)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts (2)
packages/mcp-servers/devtool-mcp-server/src/index.ts (1)
  • defineTool (135-135)
packages/mcp-servers/devtool-mcp-server/src/McpContext.ts (1)
  • connector (20-22)
🔇 Additional comments (7)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts (3)

14-28: LGTM! Well-designed tool schema with clear parameter descriptions.

The tool definition includes sensible defaults for JSProfileType ('quickjs'), enableSystrace (true), and JSProfileInterval (100ms), with helpful descriptions for each parameter.


32-50: LGTM! Proper handling of Android debug mode prerequisite.

The code correctly checks and enables enable_debug_mode for Android clients before starting tracing, with a clear error message prompting the user to restart the app.


51-59: LGTM! Trace configuration is now correct.

The contradictory configuration issue (having both includedCategories: ['*'] and excludedCategories: ['*']) has been resolved. The current configuration correctly traces all categories with sensible defaults for buffer size (200KB) and compression enabled.

packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (4)

18-26: LGTM! Clean tool definition.

The EndTracing tool is properly defined with a minimal schema (only clientId required) and appropriate annotations.


37-63: LGTM! Excellent streaming implementation.

The code correctly implements streaming using ReadableStream with a pull controller and pipes data directly to the file without caching in memory. This addresses the past review concern about memory efficiency and follows modern Node.js streaming patterns.


78-109: LGTM! Robust event handler with proper cleanup.

The handleTraceComplete callback correctly filters events by clientId, handles both success and error cases, and ensures cleanup is performed in the finally block. The try-catch-finally pattern provides comprehensive error handling.


111-119: LGTM! Clean async coordination.

The main handler logic properly registers the event listener before sending the Tracing.end command and returns a promise that resolves when either the trace completes or the timeout fires. The async flow is well-structured.

@KananSu KananSu force-pushed the p/kanan/trace_mcp_tools branch from c1b943c to b1bf6ed Compare December 29, 2025 09:21
Comment on lines +67 to +69
response.appendLines(
'Loading trace data timeout, please try again later!',
);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (1)

29-45: Fix stream handle type: should be string, not number.

According to the Chrome DevTools Protocol specification, IO.StreamHandle is a string type. The current implementation incorrectly uses number for the stream parameter in both sendIOReadMessage (line 29) and sendIOCloseMessage (line 38). This type mismatch could cause runtime issues when the CDP returns a string handle.

🔎 Fix the stream parameter type
-    const sendIOReadMessage = (stream: number): Promise<IOReadResponse> => {
+    const sendIOReadMessage = (stream: string): Promise<IOReadResponse> => {
       return connector.sendCDPMessage<IOReadResponse>(
         params.clientId,
         -1,
         'IO.read',
         { handle: stream, size: 1024 * 1024 },
       );
     };
 
-    const sendIOCloseMessage = (stream: number): Promise<IOReadResponse> => {
+    const sendIOCloseMessage = (stream: string): Promise<IOReadResponse> => {
       return connector.sendCDPMessage<IOReadResponse>(
         params.clientId,
         -1,
         'IO.close',
         { handle: stream },
       );
     };

Note: You'll also need to update the readStreamDataToFile parameter type at line 47 and the TracingComplete.stream type in connector.ts (line 88 based on past comments) to maintain type consistency across the codebase.

🧹 Nitpick comments (1)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (1)

81-96: Consider adding a comment to clarify the unhandled rejection suppression.

The promise.catch(() => { void 0; }) pattern at lines 82-83 is intentionally used to prevent Node's unhandledRejection warnings (as noted in commit messages). While functionally correct, a brief comment explaining this intent would improve code clarity for future maintainers.

🔎 Suggested comment
     const { promise, resolve, reject } = Promise.withResolvers<void>();
+    // Attach a no-op catch handler to mark the promise as handled and prevent
+    // Node's unhandledRejection warnings. Actual errors are handled via settle().
     promise.catch(() => {
       void 0;
     });
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b1bf6ed and a2f29ab.

📒 Files selected for processing (2)
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with the configuration specified in tsconfig.json

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,tsx}: Follow eslint rules as configured in eslint.config.js including React and TypeScript specific rules
Follow code formatting rules specified in .dprint.jsonc and biome.jsonc

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
🧠 Learnings (3)
📓 Common learnings
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.
📚 Learning: 2025-11-06T01:17:11.892Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/src/connector.ts:347-368
Timestamp: 2025-11-06T01:17:11.892Z
Learning: In the lynx-family/lynx-stack repository, for the devtool-mcp-server package, the getSource and getConsole methods intentionally throw errors when collectors don't exist (rather than returning empty arrays) to provide clear feedback to code agents and automation tools that something is wrong (e.g., debugger not enabled, collectors not initialized), enabling them to take corrective action.

Applied to files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
📚 Learning: 2025-11-06T01:19:23.670Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.

Applied to files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
🔇 Additional comments (9)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts (4)

1-12: LGTM!

Imports and type definitions are properly structured.


14-31: LGTM!

Tool schema is well-defined with appropriate defaults and helpful descriptions for each parameter.


32-50: LGTM!

Android debug mode check is correctly implemented. The tool properly enables the flag and provides clear feedback that the app needs to be restarted.


51-87: LGTM!

Trace configuration and error handling are well-implemented. The config correctly includes all categories without contradictory exclusions, and error messages provide helpful guidance with documentation links.

packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (5)

1-16: LGTM!

Imports and type definitions are properly structured for streaming I/O operations.


18-26: LGTM!

Tool definition is appropriately minimal for stopping trace collection.


46-80: LGTM!

Streaming implementation is well-designed. The code properly reads trace data in chunks, decodes base64, streams to a file, and ensures the IO stream is closed in the finally block even if errors occur.


98-106: LGTM!

Timeout and cleanup logic is correctly implemented. The event listener is properly removed before settling the promise on timeout.


107-147: LGTM!

Event handler and execution flow are well-structured. The code properly handles both success and error cases, ensures cleanup in all paths, and correctly filters events by clientId.

@KananSu KananSu requested a review from colinaaa December 30, 2025 08:47
- Add sendIOCloseMessage helper to send IO.close for trace streams
- Wrap sourceStream.pipeTo in try/finally to always close the CDP IO handle
- Replace resolve-only promise with settle helper using resolve / reject and isSettled
- Change trace loading timeout to reject with a friendly error instead of resolving
- Route Tracing.tracingComplete success/failure paths through settle to avoid double-settle and surface errors
- Attach a no-op promise.catch(() => {}) to mark the internal promise as handled for Node’s unhandledRejection detection, without affecting the await /catch flow in index.ts
@KananSu KananSu force-pushed the p/kanan/trace_mcp_tools branch from a2f29ab to 563395d Compare December 30, 2025 09:09
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (1)

29-47: Stream handle type should be string, not number.

Per CDP specification, IO.StreamHandle is a string type. The stream parameter in sendIOReadMessage, sendIOCloseMessage, and readStreamDataToFile should be typed as string to match the protocol and the TracingComplete.stream type (which should also be string in connector.ts).

🔎 Suggested fix
-    const sendIOReadMessage = (stream: number): Promise<IOReadResponse> => {
+    const sendIOReadMessage = (stream: string): Promise<IOReadResponse> => {
       return connector.sendCDPMessage<IOReadResponse>(
         params.clientId,
         -1,
         'IO.read',
         { handle: stream, size: 1024 * 1024 },
       );
     };

-    const sendIOCloseMessage = (stream: number): Promise<IOReadResponse> => {
+    const sendIOCloseMessage = (stream: string): Promise<void> => {
       return connector.sendCDPMessage<IOReadResponse>(
         params.clientId,
         -1,
         'IO.close',
         { handle: stream },
       );
     };
     const readStreamDataToFile = async (
-      stream: number,
+      stream: string,
       filePath: string,
     ): Promise<void> => {

Also update TracingComplete.stream type in connector.ts from number to string.

#!/bin/bash
# Check TracingComplete type definition in connector.ts
rg -n "TracingComplete" packages/mcp-servers/devtool-mcp-server/src/connector.ts -A 5
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts (1)

51-60: Contradictory trace configuration: both include and exclude all categories.

The config specifies both includedCategories: ['*'] and excludedCategories: ['*']. Per CDP semantics, exclusions typically take precedence, which could result in no categories being traced.

If the intent is to trace all categories, remove excludedCategories. If specific categories should be traced, replace the wildcards with explicit category lists.

🔎 Suggested fix to trace all categories
     const config = {
       recordMode: 'recordContinuously',
       includedCategories: ['*'],
-      excludedCategories: ['*'],
       enableSystrace: params.enableSystrace,
       bufferSize: 200 * 1024,
       JSProfileInterval: params.JSProfileInterval,
       JSProfileType: params.JSProfileType,
       enableCompress: true,
     };
Chrome DevTools Protocol Tracing.start includedCategories excludedCategories wildcard precedence
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a2f29ab and 563395d.

📒 Files selected for processing (2)
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with the configuration specified in tsconfig.json

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,tsx}: Follow eslint rules as configured in eslint.config.js including React and TypeScript specific rules
Follow code formatting rules specified in .dprint.jsonc and biome.jsonc

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
🧠 Learnings (3)
📓 Common learnings
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.
📚 Learning: 2025-11-06T01:17:11.892Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/src/connector.ts:347-368
Timestamp: 2025-11-06T01:17:11.892Z
Learning: In the lynx-family/lynx-stack repository, for the devtool-mcp-server package, the getSource and getConsole methods intentionally throw errors when collectors don't exist (rather than returning empty arrays) to provide clear feedback to code agents and automation tools that something is wrong (e.g., debugger not enabled, collectors not initialized), enabling them to take corrective action.

Applied to files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
📚 Learning: 2025-11-06T01:19:23.670Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.

Applied to files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
🧬 Code graph analysis (1)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts (2)
packages/mcp-servers/devtool-mcp-server/src/index.ts (1)
  • defineTool (135-135)
packages/mcp-servers/devtool-mcp-server/src/McpContext.ts (1)
  • connector (20-22)
🔇 Additional comments (7)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (4)

81-96: Well-structured settle pattern to prevent double-resolution.

The use of Promise.withResolvers with an isSettled guard and the no-op catch handler to prevent unhandled rejection warnings is a clean approach. The settle function correctly routes to reject or resolve based on error presence.


98-106: Timeout and cleanup logic is correct.

The timeout handler properly removes the event listener before settling with an error, and the cleanup function correctly clears both the listener and the timer. This addresses previous review concerns about potential memory leaks.


107-138: Handler logic is well-structured with proper error propagation.

The handleTraceComplete handler correctly:

  • Filters by clientId to handle only relevant events
  • Uses try/catch/finally for proper error handling
  • Calls cleanup in finally block to ensure resources are released
  • Routes errors through the settle helper for proper rejection

71-79: Good use of try/finally for IO cleanup.

The sendIOCloseMessage call in the finally block ensures the CDP IO handle is closed even if pipeTo fails. Silently catching the close error is acceptable since it's cleanup code.

packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts (3)

14-28: Schema definition is well-structured with sensible defaults.

The tool schema exposes useful configuration options (JSProfileType, enableSystrace, JSProfileInterval) with appropriate defaults and clear descriptions. The use of Zod for schema validation is consistent with other tools.


35-49: Android debug mode handling is appropriate.

The logic correctly checks and enables enable_debug_mode for Android clients before tracing, and throws a clear error message prompting app restart when the mode needs to be enabled.


70-87: Error handling properly maps CDP errors to user-friendly messages.

The error handling:

  • Uses String.prototype.includes for message matching (as suggested in past reviews)
  • Throws errors instead of appending to response (as suggested)
  • Maps specific CDP error patterns to helpful guidance with a documentation link
  • Falls back to including the original error message for unexpected errors

@KananSu KananSu force-pushed the p/kanan/trace_mcp_tools branch 2 times, most recently from a024c37 to 74047ac Compare December 30, 2025 18:40
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts (1)

54-63: Contradictory trace configuration still present despite previous fix.

Lines 56-57 still have both includedCategories: ['*'] and excludedCategories: ['*'], which is contradictory. According to Chrome DevTools Protocol semantics, exclusions take precedence, so this configuration will trace no categories and render tracing non-functional.

A previous review comment indicated this was "Addressed in commit 3517d4e", but the issue persists in the current code.

🔎 Proposed fix

To trace all categories, remove the excludedCategories line:

     const config = {
       recordMode: 'recordContinuously',
       includedCategories: ['*'],
-      excludedCategories: ['*'],
       enableSystrace: params.enableSystrace,
       bufferSize: 200 * 1024,
       JSProfileInterval: params.JSProfileInterval,
       JSProfileType: params.JSProfileType,
       enableCompress: true,
     };

Alternatively, if you need to trace only specific categories, replace includedCategories with an explicit list and keep excludedCategories: ['*'].

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6b66fbc and a024c37.

📒 Files selected for processing (2)
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with the configuration specified in tsconfig.json

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,tsx}: Follow eslint rules as configured in eslint.config.js including React and TypeScript specific rules
Follow code formatting rules specified in .dprint.jsonc and biome.jsonc

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🧠 Learnings (3)
📓 Common learnings
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.
📚 Learning: 2025-11-06T01:17:11.892Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/src/connector.ts:347-368
Timestamp: 2025-11-06T01:17:11.892Z
Learning: In the lynx-family/lynx-stack repository, for the devtool-mcp-server package, the getSource and getConsole methods intentionally throw errors when collectors don't exist (rather than returning empty arrays) to provide clear feedback to code agents and automation tools that something is wrong (e.g., debugger not enabled, collectors not initialized), enabling them to take corrective action.

Applied to files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
📚 Learning: 2025-11-06T01:19:23.670Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.

Applied to files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🧬 Code graph analysis (1)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts (2)
packages/mcp-servers/devtool-mcp-server/src/index.ts (1)
  • defineTool (135-135)
packages/mcp-servers/devtool-mcp-server/src/McpContext.ts (1)
  • connector (20-22)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (2)

29-36: Fix stream handle type: should be string, not number.

The parameter type stream: number contradicts the Chrome DevTools Protocol specification, which defines IO.StreamHandle as a string type. Update this parameter and all related usages (including sendIOCloseMessage, readStreamDataToFile, and the TracingComplete.stream type in connector.ts) to string.


38-45: Return type should be Promise<void>, not Promise<IOReadResponse>.

The IO.close CDP method returns no payload. The function signature should return Promise<void> instead of Promise<IOReadResponse>.

🔎 Suggested fix
-    const sendIOCloseMessage = (stream: number): Promise<IOReadResponse> => {
-      return connector.sendCDPMessage<IOReadResponse>(
+    const sendIOCloseMessage = (stream: string): Promise<void> => {
+      return connector.sendCDPMessage<void>(
         params.clientId,
         -1,
         'IO.close',
         { handle: stream },
       );
     };
🧹 Nitpick comments (1)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (1)

83-86: Consider calling cleanup() in timeout handler for consistency.

The timeout handler removes the event listener but doesn't call clearTimeout(timer). While not strictly necessary (since the timeout has already fired), calling cleanup() would be more consistent and make the cleanup logic centralized.

🔎 Suggested refactor
     const timer = setTimeout(() => {
-      connector.offCDPEvent('Tracing.tracingComplete', handleTraceComplete);
+      cleanup();
       reject(new Error('Loading trace data timeout, please try again later!'));
     }, 8000);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a024c37 and 74047ac.

📒 Files selected for processing (2)
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with the configuration specified in tsconfig.json

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,tsx}: Follow eslint rules as configured in eslint.config.js including React and TypeScript specific rules
Follow code formatting rules specified in .dprint.jsonc and biome.jsonc

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.
📚 Learning: 2025-11-06T01:19:23.670Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.

Applied to files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
🧬 Code graph analysis (1)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (3)
packages/mcp-servers/devtool-mcp-server/src/McpContext.ts (1)
  • connector (20-22)
packages/mcp-servers/devtool-mcp-server/src/connector.ts (1)
  • TracingComplete (87-89)
packages/mcp-servers/devtool-mcp-server/src/schema/index.ts (1)
  • clientId (6-10)
🔇 Additional comments (2)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (2)

46-80: Good use of streaming API.

The implementation correctly uses ReadableStream and pipeTo to stream trace data directly to the file system, avoiding memory accumulation. The finally block ensures the IO stream is closed even if an error occurs during the write.


92-148: Well-structured error handling and resource cleanup.

The event handler correctly validates the clientId, manages the streaming trace file write, and ensures cleanup happens in all code paths. The specific error message rewrapping for unsupported versions and unstarted tracing provides helpful user feedback.

@KananSu KananSu force-pushed the p/kanan/trace_mcp_tools branch from 74047ac to 89be0ef Compare December 31, 2025 01:03
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (2)

29-36: Fix stream handle type: should be string, not number.

The Chrome DevTools Protocol specifies IO.StreamHandle as a string type. The current implementation incorrectly uses number for the stream parameter. This type mismatch affects this function, sendIOCloseMessage, readStreamDataToFile, and the TracingComplete.stream type definition in connector.ts (line 87).

🔎 Proposed fix
-    const sendIOReadMessage = (stream: number): Promise<IOReadResponse> => {
+    const sendIOReadMessage = (stream: string): Promise<IOReadResponse> => {
       return connector.sendCDPMessage<IOReadResponse>(
         params.clientId,
         -1,
         'IO.read',
         { handle: stream, size: 1024 * 1024 },
       );
     };

Also update:

  • sendIOCloseMessage parameter (line 38)
  • readStreamDataToFile parameter (line 47)
  • TracingComplete.stream type in connector.ts (line 87)

Based on past review comments and CDP protocol specification.


38-45: Fix return type: IO.close returns Promise<void>, not Promise<IOReadResponse>.

The CDP IO.close method doesn't return a response payload with data or eof fields. The return type should be Promise<void>.

🔎 Proposed fix
-    const sendIOCloseMessage = (stream: number): Promise<IOReadResponse> => {
-      return connector.sendCDPMessage<IOReadResponse>(
+    const sendIOCloseMessage = (stream: string): Promise<void> => {
+      return connector.sendCDPMessage<void>(
         params.clientId,
         -1,
         'IO.close',
         { handle: stream },
       );
     };

Based on past review comments.

🧹 Nitpick comments (2)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (2)

74-78: Consider logging IO.close errors for observability.

The IO.close error is silently swallowed in the finally block. While this is acceptable for cleanup, consider logging the error for debugging purposes.

🔎 Suggested improvement
       } finally {
         try {
           await sendIOCloseMessage(stream);
-        } catch {
-          void 0;
+        } catch (err) {
+          // Ignore close errors during cleanup, but could log for debugging
+          // console.error('Failed to close IO stream:', err);
         }
       }

83-86: Consider calling cleanup() in the timeout handler for consistency.

The timeout handler removes the event listener and rejects, but doesn't call cleanup() which would also clear the timer. While clearing an already-fired timer is redundant, calling cleanup() would make the error path consistent with the success path.

🔎 Suggested improvement
     const timer = setTimeout(() => {
-      connector.offCDPEvent('Tracing.tracingComplete', handleTraceComplete);
+      cleanup();
       reject(new Error('Loading trace data timeout, please try again later!'));
     }, 8000);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 74047ac and 89be0ef.

📒 Files selected for processing (2)
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/StartTracing.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with the configuration specified in tsconfig.json

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,tsx}: Follow eslint rules as configured in eslint.config.js including React and TypeScript specific rules
Follow code formatting rules specified in .dprint.jsonc and biome.jsonc

Files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.
📚 Learning: 2025-11-06T01:19:23.670Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.

Applied to files:

  • packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts
🧬 Code graph analysis (1)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (3)
packages/mcp-servers/devtool-mcp-server/src/McpContext.ts (1)
  • connector (20-22)
packages/mcp-servers/devtool-mcp-server/src/connector.ts (1)
  • TracingComplete (87-89)
packages/mcp-servers/devtool-mcp-server/src/schema/index.ts (1)
  • clientId (6-10)
🔇 Additional comments (2)
packages/mcp-servers/devtool-mcp-server/src/tools/Tracing/EndTracing.ts (2)

92-119: LGTM: Clean async event handler with proper cleanup.

The handler correctly filters by clientId, streams trace data to a file, provides user feedback, and ensures cleanup in the finally block. Error handling properly rejects the promise as suggested in past reviews.


121-150: LGTM: Robust error handling with helpful user feedback.

The CDP message handling properly cleans up on error and maps specific CDP error messages to user-friendly guidance. The promise-based control flow correctly rejects on failures and resolves on success.

@KananSu KananSu force-pushed the p/kanan/trace_mcp_tools branch 2 times, most recently from 46e9fab to ffd4fef Compare January 5, 2026 07:59
…ls to prevent hanging on device disconnection

Add timeout mechanisms to StartTracing and EndTracing to handle cases where
sendCDPMessage doesn't return due to device disconnection or USB communication
blockage. This ensures tool handlers return within 8 seconds instead of hanging
indefinitely, improving system stability and user experience.
@KananSu KananSu force-pushed the p/kanan/trace_mcp_tools branch from ffd4fef to c4b5232 Compare January 5, 2026 08:03
@KananSu KananSu requested a review from colinaaa January 6, 2026 09:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants