How mksglu/context-mode Detects the Platform and Adapter at Runtime

context-mode determines the host platform by cascading through MCP handshake data, environment variable overrides, and filesystem heuristics in detectPlatform(), then lazily instantiates the correct adapter via getAdapter() according to the mksglu/context-mode source code.

When building tools that must behave differently across Claude Code, Cursor, Gemini CLI, or VS Code Copilot, reliable runtime detection is critical. The context-mode library automates this by inspecting the execution environment with a tiered confidence system, ensuring your code activates the correct platform-specific hooks without manual configuration.

Platform Detection Strategy

The core detection logic resides in src/adapters/detect.ts. The detectPlatform() function evaluates five distinct signal sources in strict priority order, returning a DetectionSignal object containing the platform ID, confidence level ("high", "medium", or "low"), and a human-readable reason.

MCP clientInfo Handshake (Highest Confidence)

When the server receives an MCP initialization handshake, it inspects clientInfo.name. According to lines 33–44 in src/adapters/detect.ts, the function maps this value to a PlatformId using the CLIENT_NAME_TO_PLATFORM registry defined in src/adapters/client-map.ts. For example, a clientInfo.name of "cursor-vscode" resolves to the "cursor" platform with high confidence.

Environment Variable Override

Users can bypass automatic detection by setting the CONTEXT_MODE_PLATFORM environment variable. Lines 46–60 validate this value against an internal whitelist of supported platforms, returning immediately if the override is valid. This is useful for testing or running in containerized environments where standard markers may be absent.

Platform-Specific Environment Variables

If no override exists, detectPlatform() scans for high-confidence environment variables unique to each supported platform. As implemented in lines 62–126, the checks include:

  • CLAUDE_PROJECT_DIR → Indicates Claude Code
  • GEMINI_CLI → Indicates Gemini CLI
  • VSCODE_PID or VSCODE_CWD → Indicates VS Code Copilot

Each match returns a high confidence signal tied to the specific platform ID.

Configuration Directory Heuristics

When environment variables are inconclusive, the system inspects the user’s home directory for platform-specific configuration folders. Lines 128–196 check for paths such as:

  • ~/.claude/ for Claude Code
  • ~/.gemini/ for Gemini CLI
  • ~/.config/kilo/ for Kilo Code

Matches at this stage receive medium confidence, as these directories may persist after the parent application closes.

Low-Confidence Fallback

If no signals are detected, lines 212–218 default to claude-code with low confidence. This ensures the library remains functional in unknown environments while flagging that the detection is uncertain.

Adapter Resolution and Lazy Loading

Once the platform is identified, getAdapter() (lines 24–86 in src/adapters/detect.ts) handles instantiation. The function accepts an optional clientInfo argument; if provided, it passes directly to detectPlatform() to ensure the MCP handshake takes precedence.

The resolution logic uses a switch statement to perform dynamic imports. For example, when detectPlatform() returns "cursor", getAdapter() executes:

const { CursorAdapter } = await import('./cursor/index.js');
return new CursorAdapter();

This lazy-loading strategy ensures that only the code for the active platform is loaded into memory, reducing startup overhead in multi-platform deployments.

Key Source Files and Their Roles

Understanding the repository structure clarifies how detection and adaptation interact:

Practical Code Examples

Detect the platform manually to inspect confidence levels:

import { detectPlatform } from "./src/adapters/detect.js";

const signal = detectPlatform();
console.log(`Platform: ${signal.platform} (${signal.confidence})`);
// Output: Platform: cursor (high)

Obtain and initialize the correct adapter asynchronously:

import { getAdapter } from "./src/adapters/detect.js";

async function bootstrap() {
  const adapter = await getAdapter(); // Auto-detects and imports
  await adapter.initialize();         // Sets up platform-specific hooks
}
bootstrap();

When handling an MCP handshake, pass the client info to ensure priority detection:

import { getAdapter } from "./src/adapters/detect.js";

async function handleHandshake(clientInfo) {
  // clientInfo.name is checked first inside getAdapter
  const adapter = await getAdapter(clientInfo);
  return adapter;
}

Summary

  • Multi-tier detection: detectPlatform() evaluates MCP data, environment variables, and config directories in descending order of reliability.
  • Confidence scoring: Every detection returns a confidence level (high, medium, low) and explanatory reason to help diagnose unexpected behavior.
  • Lazy adapter loading: getAdapter() uses dynamic import() statements to load only the necessary platform adapter, optimizing memory usage.
  • Override support: The CONTEXT_MODE_PLATFORM environment variable allows manual platform selection for testing or edge-case environments.

Frequently Asked Questions

How does context-mode handle new or unsupported platforms?

When encountering an unknown environment, detectPlatform() falls back to claude-code with low confidence (lines 212–218). This conservative default ensures basic functionality while signaling that the detection may be inaccurate. Developers can override this behavior by setting the CONTEXT_MODE_PLATFORM environment variable to a supported platform ID.

Can I force a specific platform if auto-detection fails?

Yes. As implemented in lines 46–60 of src/adapters/detect.ts, setting CONTEXT_MODE_PLATFORM to a valid platform ID (e.g., "cursor" or "gemini") causes detectPlatform() to return that value immediately with high confidence, bypassing all heuristic checks.

What confidence level indicates trustworthy platform detection?

High confidence is returned only when detectPlatform() identifies explicit platform markers such as MCP clientInfo.name or platform-specific environment variables like CLAUDE_PROJECT_DIR. Medium confidence indicates config directory matches, while low confidence signals the Claude Code fallback. Production workflows should verify they receive high confidence before executing platform-specific logic.

How does the adapter system integrate with MCP client information?

The getAdapter() function optionally accepts a clientInfo object. When provided, it forwards this to detectPlatform(), which checks lines 33–44 to map clientInfo.name to a PlatformId via CLIENT_NAME_TO_PLATFORM in src/adapters/client-map.ts. This ensures that the MCP handshake identity always takes precedence over environmental heuristics.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →