# Understanding the MDXP JSON-RPC 2.0 Protocol in Motrix

> Explore the MDXP JSON-RPC 2.0 protocol for standardized communication across Motrix desktop, CLI, browser extensions, and servers. Learn how this stable API enhances interaction.

- Repository: [Dr_rOot/Motrix](https://github.com/agalwood/Motrix)
- Tags: deep-dive
- Published: 2026-08-19

---

**MDXP (Motrix Download eXchange Protocol) is a JSON-RPC 2.0-based wire protocol that enables standardized communication between the Motrix desktop application, CLI tools, browser extensions, and headless servers through a single, version-stable API.**

The **MDXP JSON-RPC 2.0 protocol** serves as the communication backbone for the [agalwood/Motrix](https://github.com/agalwood/Motrix) download manager, unifying how different components exchange download commands, task status updates, and error information across multiple transport layers.

## What is the MDXP JSON-RPC 2.0 Protocol?

MDXP defines a **strict contract** for remote procedure calls within the Motrix ecosystem. Unlike ad-hoc IPC mechanisms, the protocol specifies exact method names, request/response schemas, and error codes that every component must follow.

According to the Motrix source code, the protocol enforces **JSON-RPC 2.0 compliance** on all messages, requiring each payload to include standard fields like `jsonrpc: "2.0"`, `method`, `params`, and `id`. Motrix-specific extensions include custom error codes defined in the `@motrix/mdxp` package, such as `ErrorCodes.CapabilityNotSupported` and `ErrorCodes.InvalidParams`.

## How Motrix Implements MDXP

The implementation centers on a centralized dispatcher that validates every request against **Zod schemas** before execution, ensuring type safety across language boundaries.

### Core Dispatcher Architecture

The `MdxpDispatcher` class in [`src/core/bridge/mdxp-dispatcher.ts`](https://github.com/agalwood/Motrix/blob/main/src/core/bridge/mdxp-dispatcher.ts) acts as the central registry for all JSON-RPC method handlers. When a request arrives, the dispatcher validates the payload against the registered Zod schema exactly once, then invokes the handler with typed arguments and a `MdxpSessionContext` object.

This architecture guarantees that **CLI tools, browser extensions, and internal UI processes** all consume the same validated API surface. The dispatcher handles both synchronous returns and asynchronous errors, serializing responses back into standard JSON-RPC 2.0 format.

### Transport Layers

Motrix exposes the MDXP protocol through three primary transports:

- **HTTP POST endpoint** (`POST /mdxp`): Used by the CLI (`@motrix/cli`) for unary requests and the headless server for remote pairing flows (`/mdxp/pair/*`)
- **WebSocket connections** (`ws://<host>:<port>/mdxp`): Enables real-time bidirectional communication for browser extensions at the default port **16801**
- **In-process connections**: Internal UI components use the same dispatcher without network overhead, maintaining architectural consistency

The [`src/core/bridge/web-socket-bridge-server.ts`](https://github.com/agalwood/Motrix/blob/main/src/core/bridge/web-socket-bridge-server.ts) file implements the WebSocket transport, forwarding incoming JSON-RPC messages to the dispatcher and returning serialized responses.

## Using the MDXP Protocol

Developers interact with MDXP through the `@motrix/mdxp` package, which provides connection factories and type definitions.

### Creating a Client Connection

The `createMdxpConnection` function establishes a communication channel with the Motrix desktop application:

```typescript
import { createMdxpConnection } from '@motrix/mdxp'

const mdxp = createMdxpConnection({
  endpoint: 'http://127.0.0.1:16801', // default MDXP bridge port
  token: process.env.MOTRIX_MDXP_TOKEN, // optional for remote LAN access
})

// Submit a new download task
await mdxp.call('download/submit', {
  uri: 'https://example.com/file.iso',
  saveDir: '/Users/me/Downloads',
})

// Retrieve current tasks
const tasks = await mdxp.call('task/list', {})
console.log(tasks)

```

*Source:* [`src/core/bridge/__tests__/unary-mdxp.test.ts`](https://github.com/agalwood/Motrix/blob/main/src/core/bridge/__tests__/unary-mdxp.test.ts) demonstrates this pattern for JSON-RPC-over-HTTP clients.

### Registering Method Handlers

Server-side components register handlers using the dispatcher's type-safe registration API:

```typescript
import { MdxpDispatcher } from './mdxp-dispatcher'
import { DownloadSubmitParamsSchema } from '@motrix/mdxp'

const dispatcher = new MdxpDispatcher()

dispatcher.register(
  'download/submit',
  DownloadSubmitParamsSchema,
  async (params, ctx) => {
    // params is fully typed and validated by Zod
    const taskId = await ctx.downloadManager.submit(params)
    return { taskId }
  }
)

```

*Source:* [`src/core/bridge/mdxp-dispatcher.ts`](https://github.com/agalwood/Motrix/blob/main/src/core/bridge/mdxp-dispatcher.ts) contains the core implementation of this registration system.

### WebSocket Bridge Implementation

The WebSocket server wraps the dispatcher to handle persistent connections:

```typescript
import { WebSocket } from 'ws'

ws.on('message', async (msg: string) => {
  const response = await this.dispatcher.handleMessage(msg)
  ws.send(JSON.stringify(response))
})

```

*Source:* [`src/core/bridge/web-socket-bridge-server.ts`](https://github.com/agalwood/Motrix/blob/main/src/core/bridge/web-socket-bridge-server.ts) shows how raw WebSocket messages convert to JSON-RPC responses.

## Key Components and File Structure

| File Path | Responsibility |
|-----------|----------------|
| [`src/core/bridge/mdxp-dispatcher.ts`](https://github.com/agalwood/Motrix/blob/main/src/core/bridge/mdxp-dispatcher.ts) | Central registry for method validation and dispatch using Zod schemas |
| [`src/core/bridge/web-socket-bridge-server.ts`](https://github.com/agalwood/Motrix/blob/main/src/core/bridge/web-socket-bridge-server.ts) | WebSocket transport layer for browser extensions and remote agents |
| [`src/main/bridge/index.ts`](https://github.com/agalwood/Motrix/blob/main/src/main/bridge/index.ts) | Entry point that initializes the MDXP bridge and binds HTTP/WS servers |
| [`src/core/bridge/__tests__/mdxp-dispatcher.test.ts`](https://github.com/agalwood/Motrix/blob/main/src/core/bridge/__tests__/mdxp-dispatcher.test.ts) | Unit tests verifying schema validation, error codes, and method routing |

These files collectively ensure that the **MDXP JSON-RPC 2.0 protocol** operates as a single source of truth across the entire Motrix ecosystem.

## Summary

- **MDXP** is a JSON-RPC 2.0 protocol that standardizes communication between Motrix components
- The `MdxpDispatcher` in [`src/core/bridge/mdxp-dispatcher.ts`](https://github.com/agalwood/Motrix/blob/main/src/core/bridge/mdxp-dispatcher.ts) validates all requests using Zod schemas before execution
- Three transport layers—HTTP POST, WebSocket, and in-process—expose the same API surface
- The `@motrix/mdxp` package provides TypeScript types and connection factories for client implementations
- Default communication occurs on **port 16801** with optional token-based authentication for remote access

## Frequently Asked Questions

### What transport mechanisms does the MDXP protocol support?

The MDXP JSON-RPC 2.0 protocol supports HTTP POST requests for unary calls, WebSocket connections for real-time streaming, and in-process communication for internal UI components. The HTTP endpoint at `/mdxp` handles CLI requests, while WebSocket connections at `/mdxp` serve browser extensions, all unified through the same dispatcher logic in [`src/core/bridge/mdxp-dispatcher.ts`](https://github.com/agalwood/Motrix/blob/main/src/core/bridge/mdxp-dispatcher.ts).

### How does Motrix ensure type safety in MDXP messages?

Motrix uses **Zod schemas** generated in the `@motrix/mdxp` package to validate every incoming JSON-RPC request. The `MdxpDispatcher` validates payloads against schemas like `DownloadSubmitParamsSchema` before handlers receive typed arguments, preventing runtime errors and ensuring that method signatures remain consistent across the desktop app, CLI, and extensions.

### Can external applications communicate with Motrix using MDXP?

Yes, external applications can communicate with Motrix by connecting to the MDXP bridge endpoint at `ws://localhost:16801/mdxp` or `http://localhost:16801/mdxp`. For remote access over LAN, applications must provide an authentication token via the `MOTRIX_MDXP_TOKEN` environment variable or request headers. The headless server also exposes pairing endpoints at `/mdxp/pair/*` for device-code flows.

### Where are MDXP error codes defined in the Motrix codebase?

MDXP-specific error codes such as `ErrorCodes.CapabilityNotSupported` and `ErrorCodes.InvalidParams` are defined in the `@motrix/mdxp` package, which bundles the protocol's Zod schemas and TypeScript types. These error codes follow the JSON-RPC 2.0 specification while extending it with Motrix-specific failure states for download operations and capability mismatches.