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

> Discover how mksglu/context-mode cleverly detects your platform and adapter at runtime using handshake data, env vars, and filesystem heuristics. Explore the source code now.

- Repository: [Mert Köseoğlu/context-mode](https://github.com/mksglu/context-mode)
- Tags: how-to-guide
- Published: 2026-04-24

---

**`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`](https://github.com/mksglu/context-mode/blob/main/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`](https://github.com/mksglu/context-mode/blob/main/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`](https://github.com/mksglu/context-mode/blob/main/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`](https://github.com/mksglu/context-mode/blob/main/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:

```typescript
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:

- **[`src/adapters/detect.ts`](https://github.com/mksglu/context-mode/blob/main/src/adapters/detect.ts)** – Contains `detectPlatform()` for environment inspection and `getAdapter()` for dynamic module loading.
- **[`src/adapters/client-map.ts`](https://github.com/mksglu/context-mode/blob/main/src/adapters/client-map.ts)** – Maintains the `CLIENT_NAME_TO_PLATFORM` mapping that links MCP client identifiers to internal platform IDs.
- **[`src/runtime.ts`](https://github.com/mksglu/context-mode/blob/main/src/runtime.ts)** – Detects available language runtimes (Bun, Node, Python) to construct execution commands specific to the platform.
- **Platform adapter modules** (e.g., [`src/adapters/cursor/index.ts`](https://github.com/mksglu/context-mode/blob/main/src/adapters/cursor/index.ts), [`src/adapters/claude-code/index.ts`](https://github.com/mksglu/context-mode/blob/main/src/adapters/claude-code/index.ts)) – Implement platform-specific hooks loaded on demand by `getAdapter()`.

## Practical Code Examples

Detect the platform manually to inspect confidence levels:

```typescript
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:

```typescript
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:

```typescript
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`](https://github.com/mksglu/context-mode/blob/main/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`](https://github.com/mksglu/context-mode/blob/main/src/adapters/client-map.ts). This ensures that the MCP handshake identity always takes precedence over environmental heuristics.