Skip to content

Conversation

narekhovhannisyan
Copy link
Collaborator

@narekhovhannisyan narekhovhannisyan commented Sep 2, 2025

Motivation

Changes

  • Change 1
  • Change 2

How to test

  • Test 1
  • Test 2

Images and GIFs

Before After
link1 link2
link3 link4
link5 link6
link7 link8
link9 link10

Summary by CodeRabbit

  • New Features

    • Automatically sets a context-aware User-Agent when running within Mailtrap MCP, improving environment detection and integration.
    • Added a configurable MCP-specific User-Agent in client settings.
  • Refactor

    • Streamlined header handling to use dynamic User-Agent selection with no impact on existing behavior outside MCP contexts.

Copy link

coderabbitai bot commented Sep 2, 2025

Walkthrough

Adds MCP_USER_AGENT to config. Introduces getDynamicUserAgent to choose a User-Agent based on runtime MCP context. MailtrapClient now uses this dynamic User-Agent in Axios headers. Minor import cleanup for SuppressionsBaseAPI.

Changes

Cohort / File(s) Summary
Config: add MCP user agent
src/config/index.ts
Adds CLIENT_SETTINGS.MCP_USER_AGENT set to "mailtrap-mcp (https://github.com/railsware/mailtrap-mcp)".
Dynamic User-Agent selection
src/lib/get-agent.ts
New module exporting getDynamicUserAgent() that detects MCP context via main module, CWD, and call stack checks and returns MCP_USER_AGENT or fallback USER_AGENT.
Client uses dynamic User-Agent + import tidy
src/lib/MailtrapClient.ts
Replaces static "User-Agent" header with getDynamicUserAgent(). Stops destructuring USER_AGENT. Consolidates SuppressionsBaseAPI import.

Sequence Diagram(s)

sequenceDiagram
    actor Caller
    participant Client as MailtrapClient
    participant Agent as getDynamicUserAgent
    participant Config as CONFIG.CLIENT_SETTINGS
    participant HTTP as Axios

    Caller->>Client: sendRequest(...)
    Client->>Agent: getDynamicUserAgent()
    Agent->>Config: read USER_AGENT, MCP_USER_AGENT
    Note over Agent,Config: Detect MCP via main module, CWD, call stack
    alt MCP context detected
        Agent-->>Client: MCP_USER_AGENT
    else Not MCP
        Agent-->>Client: USER_AGENT
    end
    Client->>HTTP: request(headers.User-Agent = value)
    HTTP-->>Client: response
    Client-->>Caller: response
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

I twitch my ears at headers’ fate,
A nimble hop to annotate—
“Who goes there?” asks the wire’s gate;
MCP or not, I’ll set it straight.
With whiskered logic, light yet keen,
I sign the calls—polite, unseen. 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dynamic-user-agent

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@narekhovhannisyan narekhovhannisyan marked this pull request as draft September 2, 2025 12:53
Copy link

@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 (5)
src/config/index.ts (1)

21-21: Option: include package version in UA for better telemetry.

Consider appending the library version (e.g., "mailtrap-mcp/1.2.3 (...)"). Implement in get-agent.ts to keep config static.

src/lib/get-agent.ts (4)

23-30: Make cwd-based detection case-insensitive.

Paths can differ in case across platforms; normalize before matching.

Apply this diff:

 function isWorkingDirectoryMCP(): boolean {
   try {
     const cwd = process.cwd();
-    return cwd.includes("mailtrap-mcp") && !cwd.includes("node_modules");
+    const lower = cwd.toLowerCase();
+    return lower.includes("mailtrap-mcp") && !lower.includes("node_modules");
   } catch {
     return false;
   }
 }

36-44: Broaden self-exclusion and normalize case in stack-based detection.

Also exclude node_modules/mailtrap-nodejs to avoid false positives when this lib is on the stack.

Apply this diff:

 function isCallStackMCP(): boolean {
-  const { stack } = new Error();
-
-  return !!(
-    stack &&
-    stack.includes("mailtrap-mcp") &&
-    !stack.includes("node_modules/mailtrap")
-  );
+  const { stack } = new Error();
+  const lower = stack?.toLowerCase();
+  return !!(
+    lower &&
+    lower.includes("mailtrap-mcp") &&
+    !/node_modules\/mailtrap(-nodejs)?/.test(lower)
+  );
 }

59-61: Allow env override and ensure robust fallback.

Let users force UA selection and guard against unexpected undefineds.

Apply this diff:

-function getDynamicUserAgent(): string {
-  return isMailtrapMCPContext() ? MCP_USER_AGENT : USER_AGENT;
-}
+function getDynamicUserAgent(): string {
+  const override = process.env.MAILTRAP_UA?.toLowerCase();
+  if (override === "mcp") return MCP_USER_AGENT;
+  if (override === "default") return USER_AGENT;
+  const ua = isMailtrapMCPContext() ? MCP_USER_AGENT : USER_AGENT;
+  return ua || "mailtrap-nodejs";
+}

59-61: Optional: add version to UA string.

If resolveJsonModule is enabled, append package version for traceability (example implementation):

// at top-level (outside selected range):
// import { version } from "../../package.json";

// inside getDynamicUserAgent():
// const base = isMailtrapMCPContext() ? MCP_USER_AGENT : USER_AGENT;
// return `${base}/${version}`;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ffeca33 and 9da5776.

📒 Files selected for processing (3)
  • src/config/index.ts (1 hunks)
  • src/lib/MailtrapClient.ts (2 hunks)
  • src/lib/get-agent.ts (1 hunks)
🔇 Additional comments (4)
src/config/index.ts (1)

21-21: LGTM: adds MCP-specific User-Agent.

Field name and value look consistent with existing config keys.

src/lib/MailtrapClient.ts (2)

9-9: LGTM: importing dynamic UA helper.


69-70: LGTM: apply dynamic User-Agent header.

Header is set once per client instance, which is appropriate.

src/lib/get-agent.ts (1)

1-63: CommonJS-only packaging detected; no ESM support found.
package.json “type” is absent (defaults to CJS), tsconfig module=commonjs, and no ESM exports fields—no changes needed.

Comment on lines +9 to +17
function isMainModuleMCP(): boolean {
const mainFile = require?.main?.filename;

return !!(
mainFile &&
mainFile.includes("mailtrap-mcp") &&
!mainFile.includes("node_modules")
);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix ESM ReferenceError risk from using require directly.

require?.main still throws in pure ESM because require is an unbound identifier. Guard with typeof require !== 'undefined' and fall back to process.argv[1].

Apply this diff:

 function isMainModuleMCP(): boolean {
-  const mainFile = require?.main?.filename;
-
-  return !!(
-    mainFile &&
-    mainFile.includes("mailtrap-mcp") &&
-    !mainFile.includes("node_modules")
-  );
+  const mainFile =
+    (typeof require !== "undefined" ? require.main?.filename : undefined) ??
+    process.argv?.[1];
+  if (!mainFile) return false;
+  const lower = mainFile.toLowerCase();
+  return lower.includes("mailtrap-mcp") && !lower.includes("node_modules");
 }
🤖 Prompt for AI Agents
In src/lib/get-agent.ts around lines 9 to 17, avoid referencing the unbound
require in pure ESM by first checking typeof require !== 'undefined' and using
require.main?.filename only when defined, otherwise fall back to
process.argv[1]; replace const mainFile = require?.main?.filename with a safe
resolution like: if typeof require !== 'undefined' and require.main use
require.main.filename else use process.argv[1], then keep the subsequent
includes checks the same to determine mailtrap-mcp presence and node_modules
exclusion.

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.

1 participant