Skip to main content
Glama
danielsimonjr

dropbox-mcp

README.md
# dropbox-mcp

An MCP (Model Context Protocol) server that exposes the Dropbox API as tools for
LLM agents. Built on the [TypeScript MCP SDK v2](https://github.com/modelcontextprotocol/typescript-sdk)
(`@modelcontextprotocol/server`) and the official [`dropbox`](https://www.npmjs.com/package/dropbox) npm SDK.

Built on `@modelcontextprotocol/server` v2. The negotiated protocol version is
`2025-11-25` (the SDK's `LATEST_PROTOCOL_VERSION`): stateless
per-request metadata, `server/discover` capability negotiation, and no session-scoped
`initialize` handshake. Legacy 2025-era MCP clients continue to work on the same stdio
transport.

Focus: **recovery and discovery on an existing Dropbox account** — restoring deleted
files, listing revisions, searching content, and force-downloading cloud-only files.
The server talks to the Dropbox *server-side* API, not the local sync folder, so it
can see and restore files that local sync has already deleted.

---

## Tools

All tool names are prefixed `dropbox_` to avoid collisions with other MCP servers.

| Tool | Behavior | Read-only |
|---|---|---|
| `dropbox_restore` | Restore the most recent server-side revision of a deleted file. | No |
| `dropbox_restore_batch` | Restore multiple files in one call; reports per-path result. | No |
| `dropbox_restore_revision` | Restore a specific revision ID (e.g., a known-good earlier version). | No |
| `dropbox_download` | Force-download a file from Dropbox to the local sync folder, bypassing Smart Sync cloud-only state. | No |
| `dropbox_upload` | Upload a single local file to Dropbox. Source defaults to the local-folder mirror of the destination path; `mode` add/overwrite. Rejects files >150 MB. | No |
| `dropbox_move` | Move or rename a file/folder server-side (no download). `autorename` to avoid collisions. | No |
| `dropbox_delete` | Delete a file or folder (goes to trash; recoverable via `dropbox_restore` for ~30 days). | No |
| `dropbox_search` | Search by filename or content across the account. Returns path, size, modified date. | Yes |
| `dropbox_list_deleted` | List deleted entries in a folder (optionally recursive). Input for restore workflows. | Yes |
| `dropbox_file_info` | Return size, modified time, revision ID, and content hash for a path. | Yes |
| `dropbox_list_revisions` | List up to 100 revisions of a file with rev ID, size, and modified time. | Yes |

**Atomic single-file ops vs. bulk sync**: these tools are for one-file or interactive operations. For syncing or sorting whole folders (10s–1000s of files), use the companion `dropbox` skill's `dbx_sync.py` (bulk, move-aware, plan→review→execute). The split: this server is the atomic + recovery layer; the skill is the orchestration layer.

---

## Installation

### Prerequisites

- [Bun](https://bun.sh) 1.4 or newer (package manager and script runner)
- Node.js 24 or newer (MCP server runtime — the shipped `bundle/index.mjs` and
  `dist/index.js` are launched with `node`)
- A Dropbox account and a [Dropbox app](https://www.dropbox.com/developers/apps)
  with `files.content.read`, `files.content.write`, and `files.metadata.read` scopes

### Install

```bash
git clone https://github.com/danielsimonjr/dropbox-mcp.git
cd dropbox-mcp
bun install
bun run build
```

The build emits `dist/index.js`, which is the entry point used below.

---

## Authentication

The server loads credentials from `~/.claude/channels/dropbox/.env` on startup,
with `process.env` taking precedence over the file (so the MCP host can override
via `.mcp.json` `env`). Create the file and paste in the template below, then
fill in your values:

```bash
mkdir -p ~/.claude/channels/dropbox
touch ~/.claude/channels/dropbox/.env
```

Template:

```ini
# --- Option A: OAuth 2 refresh token (recommended) ---
# Create an app at https://www.dropbox.com/developers/apps, enable the scopes
# files.content.read, files.content.write, files.metadata.read, then run the
# OAuth flow once to obtain a refresh token.
DROPBOX_REFRESH_TOKEN=
DROPBOX_APP_KEY=
DROPBOX_APP_SECRET=

# --- Option B: Long-lived access token (fallback) ---
# Leave blank if you are using Option A above.
DROPBOX_ACCESS_TOKEN=

# --- Optional ---
# Local Dropbox sync folder. Used by dropbox_download to write files.
# Defaults to ~/Dropbox if unset.
# DROPBOX_LOCAL_PATH=C:\Users\you\Dropbox
```

Two auth modes are supported, tried in order:

1. **OAuth 2 refresh token (recommended):** set `DROPBOX_REFRESH_TOKEN`,
   `DROPBOX_APP_KEY`, and `DROPBOX_APP_SECRET`. Access tokens are refreshed
   automatically, so credentials do not expire.
2. **Legacy long-lived access token (fallback):** set `DROPBOX_ACCESS_TOKEN` only.
   Simpler to obtain, but tokens expire after a few hours for newer apps.

---

## Running the server

### Directly (for testing)

```bash
node dist/index.js
```

The server communicates over stdio, so there is no interactive output — it waits
for MCP protocol messages on stdin. On connect it logs `"dropbox-mcp: connected
on stdio"` to stderr.

### With the MCP Inspector

```bash
npx @modelcontextprotocol/inspector node dist/index.js
```

### Registering with Claude Code

Add an entry to your `.mcp.json`:

```json
{
  "mcpServers": {
    "dropbox-mcp": {
      "type": "stdio",
      "command": "node",
      "args": ["C:/path/to/dropbox-mcp/dist/index.js"]
    }
  }
}
```

Restart Claude Code (or run `/reload-plugins`) for the registration to take effect.

---

## Examples

**Restore a file deleted by accident:**

```
Agent: dropbox_restore(path="/Projects/report-final.docx")
Result: Restored: /Projects/report-final.docx (rev: abc123, size: 45678 bytes)
```

**Find a file without knowing its exact location:**

```
Agent: dropbox_search(query="RSP consciousness paper", max_results=5)
Result: Found 3 results for 'RSP consciousness paper':
      1.25 MB  2026-02-18  /Misc/Philosophy/Beyond the Bat/paper.pdf
      0.31 MB  2026-02-10  /Misc/Philosophy/Beyond the Bat/drafts/outline.md
      ...
```

**Roll back to a specific earlier revision:**

```
Agent: dropbox_list_revisions(path="/report.docx", limit=5)
Agent: dropbox_restore_revision(path="/report.docx", rev="0123abc")
```

**Upload, move, and delete a single file:**

```
Agent: dropbox_upload(path="/Misc/notes.md", mode="overwrite")
Result: Uploaded: /Misc/notes.md (2048 bytes, mode: overwrite)

Agent: dropbox_move(from_path="/Misc/notes.md", to_path="/Misc/Archive/notes.md")
Result: Moved: /Misc/notes.md -> /Misc/Archive/notes.md

Agent: dropbox_delete(path="/Misc/Archive/old-draft.md")
Result: Deleted: /Misc/Archive/old-draft.md (recoverable via dropbox_restore for ~30 days)
```

---

## Security notes

- The `.env` file holds long-lived credentials — keep it out of version control
  (the default `.gitignore` already excludes `.env` files).
- Mutating tools (restore, download, **upload, move, delete**) change Dropbox or
  local state. Agents should confirm intent before invoking them — especially
  `dropbox_delete` on a folder (removes all contents) and `dropbox_restore_batch`.
  Deletes go to Dropbox trash and are recoverable via `dropbox_restore` for ~30 days.
- The server binds to no network ports — communication is stdio only. The only
  outbound connection is to `api.dropbox.com` over HTTPS.
- Logs go to stderr, never stdout (stdout is reserved for MCP protocol frames).

---

## Development

Bun is the package manager and script driver; Node remains the long-lived MCP
runtime (the Claude Code plugin entry still uses `node …/bundle/index.mjs`).

```bash
bun run typecheck   # tsc --noEmit
bun run test        # vitest run (full suite)
bun run build       # emit dist/
bun run bundle      # rebuild bundle/index.mjs (plugin artifact)
```

The test suite covers config loading, every output formatter, the tool handlers
(both read-only and mutating), protocol negotiation, and a smoke test asserting
`TOOLS↔HANDLERS` symmetry.

For changes to the tool surface, update both this README and `CHANGELOG.md` in the
same commit.

---

## License

MIT — see [LICENSE](LICENSE).

TDQS

A3.9/5.0

Scored across 11 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: delete, download, file info, listing deleted files/revisions, move, restore (deleted, batch, specific revision), search, and upload. No two tools overlap in functionality, and descriptions clarify any potential confusion between restore variants.

Naming Consistency4/5

Most tools follow a consistent 'dropbox_verb_noun' pattern (e.g., dropbox_delete, dropbox_search). The minor exception is 'dropbox_file_info' which uses a noun-noun form instead of verb-noun, but overall the pattern is clear and predictable.

Tool Count5/5

With 11 tools, the server is well-scoped for a file management service like Dropbox. It covers essential operations (CRUD, search, version history, restoration) without being bloated or insufficient.

Completeness4/5

The tool set covers core file operations: upload, download, delete, move, search, and version/restoration. Minor gaps exist, such as no explicit folder creation or sharing tools, but these are acceptable for a basic file management interface.

Maintenance

ActivityActive
ResponsivenessNo issues