> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dragdropdo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP clients (Claude Code, Cursor, custom)

> Connect AI assistants and applications to DragDropDo using the Model Context Protocol (MCP) over HTTPS.

# DragDropDo MCP server

The **DragDropDo MCP server** exposes the same capabilities as the [Business API](/business-api/overview)—upload, convert, compress, merge, zip, PDF password tools, and status polling—as [MCP tools](https://modelcontextprotocol.io/). Clients connect over **Streamable HTTP** (HTTPS).

## Prerequisites

* A **D3 API key** from the dashboard ([sign in](https://dragdropdo.com/auth/signin) → Account → generate API key). Same key as for `Authorization: Bearer` on `/api/v1`.
* **MCP URL:** `https://mcp.dragdropdo.com/mcp`

Send the API key on every MCP request in the **`Authorization`** header:

```http theme={null}
Authorization: Bearer <YOUR_D3_API_KEY>
```

The server validates this key the same way as REST requests (see [Authentication](/business-api/authentication)).

## Claude Code

[Claude Code](https://code.claude.com/docs) supports remote MCP servers over HTTP. Prefer **`--transport http`** (SSE is deprecated).

### CLI (recommended)

Add the server and pass your API key on the `Authorization` header:

```bash theme={null}
claude mcp add --transport http d3 https://mcp.dragdropdo.com/mcp \
  --header "Authorization: Bearer YOUR_D3_API_KEY"
```

Useful commands: `claude mcp list`, `claude mcp get d3`, `claude mcp remove d3`.

Scopes: add `--scope project` to store the entry in the project’s `.mcp.json`, or `--scope user` for your user config. See [Connect Claude Code to tools via MCP](https://code.claude.com/docs/en/mcp).

### JSON configuration

Claude Code merges MCP entries from `~/.claude.json` and, for project scope, `.mcp.json`. An HTTP server entry looks like this (structure may vary slightly by Claude Code version—use `claude mcp get <name>` after adding to see the exact shape):

```json theme={null}
{
  "mcpServers": {
    "d3": {
      "type": "http",
      "url": "https://mcp.dragdropdo.com/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_D3_API_KEY"
      }
    }
  }
}
```

You can use environment substitution in values where your tooling supports it (for example `Bearer ${D3_API_KEY}`), so secrets are not committed to git.

## Cursor

In **Cursor**, MCP servers are defined in the MCP config file (often **user**: `~/.cursor/mcp.json`, or **project** `.cursor/mcp.json` depending on your setup).

Add an entry with `url` and `headers`:

```json theme={null}
{
  "mcpServers": {
    "d3": {
      "url": "https://mcp.dragdropdo.com/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_D3_API_KEY"
      }
    }
  }
}
```

Restart Cursor or reload MCP servers so the new server is picked up. The assistant can then call DragDropDo tools (for example `initiate_upload`, `convert_file`, `poll_status`) when appropriate.

## Custom MCP clients

Use an official [Model Context Protocol](https://modelcontextprotocol.io/) client with **Streamable HTTP** to `https://mcp.dragdropdo.com/mcp`, authenticated with `Authorization: Bearer` and your API key.

The examples below initialize the session and **list tools**. Match imports and APIs to your SDK version.

<CodeGroup>
  ```ts NODE theme={null}
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

  const url = new URL("https://mcp.dragdropdo.com/mcp");
  const transport = new StreamableHTTPClientTransport(url, {
    authProvider: {
      token: async () => process.env.D3_API_KEY!,
    },
  });

  const client = new Client({ name: "my-app", version: "1.0.0" });
  await client.connect(transport);
  await client.listTools();
  // await client.callTool({ name: "supported_operation", arguments: { ext: "pdf" } });
  ```

  ```python PYTHON theme={null}
  import os
  import httpx
  from mcp import ClientSession
  from mcp.client.streamable_http import streamable_http_client

  URL = "https://mcp.dragdropdo.com/mcp"
  api_key = os.environ["D3_API_KEY"]
  headers = {"Authorization": f"Bearer {api_key}"}

  async def main():
      async with httpx.AsyncClient(headers=headers) as http_client:
          async with streamable_http_client(URL, http_client=http_client) as (read, write):
              async with ClientSession(read, write) as session:
                  await session.initialize()
                  await session.list_tools()
                  # await session.call_tool("supported_operation", {"ext": "pdf"})

  # asyncio.run(main())
  ```

  ```php PHP theme={null}
  <?php

  declare(strict_types=1);

  use Mcp\Client;
  use Mcp\Client\Transport\HttpTransport;

  $apiKey = getenv('D3_API_KEY') ?: '';

  $client = Client::builder()
      ->setClientInfo('My App', '1.0.0')
      ->build();

  $transport = new HttpTransport(
      endpoint: 'https://mcp.dragdropdo.com/mcp',
      headers: ['Authorization' => 'Bearer ' . $apiKey],
  );

  $client->connect($transport);
  $client->listTools();
  // $client->callTool(name: 'supported_operation', arguments: ['ext' => 'pdf']);
  $client->disconnect();
  ```

  ```ruby RUBY theme={null}
  # Gemfile: gem "mcp" / gem "faraday", ">= 2.0"

  require "mcp"

  http_transport = MCP::Client::HTTP.new(
    url: "https://mcp.dragdropdo.com/mcp",
    headers: {
      "Authorization" => "Bearer #{ENV.fetch('D3_API_KEY')}",
    },
  )

  client = MCP::Client.new(transport: http_transport)
  client.tools
  # client.call_tool(tool: client.tools.first, arguments: { "ext" => "pdf" })
  ```

  ```go GO theme={null}
  package main

  import (
  	"context"
  	"os"

  	"github.com/mark3labs/mcp-go/client"
  	"github.com/mark3labs/mcp-go/client/transport"
  	"github.com/mark3labs/mcp-go/mcp"
  )

  func main() {
  	ctx := context.Background()
  	key := os.Getenv("D3_API_KEY")

  	httpTransport, err := transport.NewStreamableHTTP(
  		"https://mcp.dragdropdo.com/mcp",
  		transport.WithHTTPHeaders(map[string]string{
  			"Authorization": "Bearer " + key,
  		}),
  	)
  	if err != nil {
  		panic(err)
  	}

  	c := client.NewClient(httpTransport)
  	defer c.Close()

  	if err := c.Initialize(ctx); err != nil {
  		panic(err)
  	}
  	if _, err := c.ListTools(ctx, mcp.ListToolsRequest{}); err != nil {
  		panic(err)
  	}
  	// c.CallTool(ctx, mcp.CallToolRequest{ ... })
  }
  ```

  ```java JAVA theme={null}
  import io.modelcontextprotocol.sdk.client.McpClient;
  import io.modelcontextprotocol.sdk.client.McpSyncClient;
  import io.modelcontextprotocol.sdk.client.transport.HttpClientStreamableHttpTransport;
  import io.modelcontextprotocol.sdk.spec.McpTransport;

  // io.modelcontextprotocol.sdk:mcp — use your BOM or version from https://java.sdk.modelcontextprotocol.io/

  String apiKey = System.getenv("D3_API_KEY");
  McpTransport transport = HttpClientStreamableHttpTransport.builder("https://mcp.dragdropdo.com")
      .endpoint("/mcp")
      .requestCustomizer(req -> req.header("Authorization", "Bearer " + apiKey))
      .build();

  McpSyncClient client = McpClient.sync(transport).build();
  client.initialize();
  client.listTools();
  // client.callTool(new CallToolRequest("supported_operation", Map.of("ext", "pdf")));
  client.closeGracefully();
  ```
</CodeGroup>

**SDK references:** [TypeScript](https://github.com/modelcontextprotocol/typescript-sdk), [Python](https://github.com/modelcontextprotocol/python-sdk), [PHP `mcp/sdk`](https://github.com/modelcontextprotocol/php-sdk), [Ruby `mcp` gem](https://github.com/modelcontextprotocol/ruby-sdk), [Go `mark3labs/mcp-go`](https://github.com/mark3labs/mcp-go), [Java `io.modelcontextprotocol.sdk:mcp`](https://java.sdk.modelcontextprotocol.io/latest/).

## Available tools (summary)

Typical tool names include: `initiate_upload`, `complete_upload`, `supported_operation`, `convert_file`, `compress_file`, `merge_files`, `zip_files`, `lock_pdf`, `unlock_pdf`, `reset_pdf_password`, `get_status`, `poll_status`, `get_download_link`. The server also sends **instructions** describing the upload and operation workflow. Use **`list_tools`** from your client after connecting to see the canonical list and schemas for your session.

## Related documentation

* [Business API overview](/business-api/overview) — REST surface parallel to MCP tools
* [Authentication](/business-api/authentication) — API key usage and security
* [Quickstart](/quickstart) — upload and operation flow with REST examples
