Skip to main content
Glama
dropbox-mcp

dropbox-mcp

dropbox-mcp

A Model Context Protocol server that gives an LLM agent read/write access to a Dropbox account — personal or Business/Team — over the Dropbox API v2.

The problem

Dropbox's own desktop client solves file syncing. It does not solve giving an AI agent controlled access to an account it doesn't have a local copy of. An agent that can only see synced folders can't search a 2 TB team archive, can't mint a share link, and can't read a file it was never given.

This server closes that gap. It talks to the Dropbox HTTP API directly, so it works against the whole account without syncing a single byte to disk, and it exposes that access as a fixed set of MCP tools rather than a raw HTTP client — the agent gets dropbox_search, not fetch.

Related MCP server: Dropbox MCP Server

Architecture

Four tool modules (files, search, sharing, account) register themselves against a single McpServer speaking MCP over stdio. Every module funnels through one HTTP client that owns the two things the Dropbox API makes annoying: the OAuth token lifecycle and the team-space namespace. Modules can be disabled individually at startup via DROPBOX_DISABLED_MODULES, so a deployment that shouldn't be able to create public share links simply doesn't register that module — the capability is absent, not merely discouraged.

  MCP host (Claude, etc.)
          | stdio (JSON-RPC)
  +-------v--------------------------------------+
  |  index.ts   module registry / stdio transport|
  +-------+--------------------------------------+
          |
  +-------v-------+ +--------+ +---------+ +---------+
  |  tools/files  | | search | | sharing | | account |
  +-------+-------+ +---+----+ +----+----+ +----+----+
          |             |           |           |
          +------+------+-----------+-----------+
                 |
        +--------v-----------------------------------+
        |  client.ts                                 |
        |   - refresh-token -> access-token cache     |
        |   - 401 retry with a forced refresh         |
        |   - Dropbox-API-Path-Root resolution        |
        |   - ASCII-safe Dropbox-API-Arg encoding     |
        +--------+-----------------------------------+
                 |
      RPC api.dropboxapi.com   Content content.dropboxapi.com

Two endpoint families, deliberately kept as separate functions: RPC endpoints are JSON-in/JSON-out, while Content endpoints put their arguments in an HTTP header and use the body for file bytes. Collapsing them into one generic request() would have meant a parameter that silently changes where the arguments go, so they stay apart.

The genuinely hard part

On a Dropbox Business team, the API defaults to the member's home namespace. Every team folder — which is where the actual shared work lives — sits in the team's root namespace instead and is simply invisible. list_folder on "" returns the member's private files and nothing else, with no error and no hint that most of the account is missing. It looks like a permissions problem and isn't one.

The fix is to send a Dropbox-API-Path-Root header pointing at the team root namespace, whose id you get from users/get_current_account. That introduces a recursion trap: the generic RPC helper attaches the path-root header to every call, so having it resolve the namespace by calling get_current_account through itself means the header resolution calls the header resolution forever. resolveRootNamespaceId() therefore issues a deliberately bare fetch that bypasses the helper, and the result is memoised so the extra round trip happens once per process (src/client.ts).

A smaller version of the same class of bug: Content endpoints pass their arguments in Dropbox-API-Arg, and HTTP headers are ASCII. Any file with an accented character or an emoji in its name throws inside fetch rather than returning an API error. apiArg() escapes every non-ASCII code point to \uXXXX before the header is built.

What I'd do differently

  1. No tests. This was built and verified by hand against a live account. The token-refresh path, the 401 retry, and the chunked upload boundary conditions are exactly the code that should have been driven by tests with a mocked transport — they're the parts that fail rarely and expensively.

  2. The path-root cache is per-process and never invalidated. Fine for a stdio server that a host restarts freely; wrong for anything long-lived where a user could be moved between teams.

  3. dropbox_delete is exposed with no confirmation affordance. Dropbox's own retention makes it recoverable, but a destructive tool should signal that in its schema rather than relying on the host to ask.

  4. Errors are shaped into strings. Returning a structured error code alongside the message would let an agent branch on "rate limited" versus "not found" without parsing prose.

Setup

Requires Node 20+ (developed on 24) and a Dropbox account.

1. Create a Dropbox app

  1. Go to https://www.dropbox.com/developers/apps and choose Create app.

  2. Pick Scoped access and Full Dropbox access.

  3. On Permissions, enable account_info.read, files.metadata.read, files.metadata.write, files.content.read, files.content.write, sharing.read, sharing.write, then Submit.

  4. On Settings, copy the App key and App secret.

2. Build and authorise

git clone <this-repo>
cd dropbox-mcp
npm install
npm run build

cp .env.example .env      # fill in DROPBOX_APP_KEY and DROPBOX_APP_SECRET
npm run auth              # prints DROPBOX_REFRESH_TOKEN — paste it into .env

npm run auth prints a consent URL, takes the code you paste back, and exchanges it for a refresh token. The server trades that for short-lived access tokens on its own from then on.

3. Register with an MCP host

{
  "mcpServers": {
    "dropbox": {
      "command": "node",
      "args": ["/absolute/path/to/dropbox-mcp/dist/index.js"],
      "env": {
        "DROPBOX_APP_KEY": "your-app-key",
        "DROPBOX_APP_SECRET": "your-app-secret",
        "DROPBOX_REFRESH_TOKEN": "your-refresh-token"
      }
    }
  }
}

Restart the host and ask it something like "What's my Dropbox space usage?".

To exercise the server without a host:

npm run inspect           # @modelcontextprotocol/inspector

Tools

files — dropbox_list_folder, dropbox_get_metadata, dropbox_create_folder, dropbox_move, dropbox_copy, dropbox_delete, dropbox_get_temporary_link, dropbox_read_file, dropbox_upload (auto-chunks large files through upload sessions).

search — dropbox_search across filenames and content, account-wide or scoped to a folder.

sharing — dropbox_create_shared_link, dropbox_list_shared_links, dropbox_get_shared_link_metadata, dropbox_revoke_shared_link.

account — dropbox_get_current_account, dropbox_get_space_usage.

Configuration

All configuration is environment variables; see .env.example for the full annotated list, including the namespace control (DROPBOX_PATH_ROOT), the read-size cap (DROPBOX_MAX_READ_BYTES), the upload chunk size, and the team-app impersonation headers.

Licence

MIT — see LICENSE.

Available Tools

16 tools
dropbox_copyCopyB

Copy a file or folder to a new path.

Inputs: to_path (required), from_path (required), autorename.

dropbox_create_folderCreate folderB

Create a folder at the given path.

Inputs: path (required), autorename.

dropbox_deleteDeleteA
Destructive

Delete a file or folder (and its contents). Destructive — the item moves to deleted state and can be restored from Dropbox for the retention window.

Inputs: path (required).

dropbox_get_current_accountGet current accountA
Read-only

Return the authenticated account (name, email, account id, team). Good for confirming the server is connected to the right Dropbox.

Inputs: no named parameters.

dropbox_get_metadataGet metadataA
Read-only

Get metadata (size, modified time, id, etc.) for a single file or folder.

Inputs: path (required), include_deleted.

dropbox_get_space_usageGet space usageA
Read-only

Return storage usage and allocation for the account.

Inputs: no named parameters.

dropbox_list_folderList folderA
Read-only

List the contents of a folder. Pass "" for the root. Set recursive=true to walk subfolders. If the result is truncated, call again with the returned cursor.

Inputs: path, limit, cursor, recursive.

dropbox_moveMove / renameA

Move or rename a file or folder from one path to another.

Inputs: to_path (required), from_path (required), autorename.

dropbox_read_fileRead file (text)A
Read-only

Download a file and return its contents as UTF-8 text — for referencing docs, notes, code, csv, etc. Guarded by DROPBOX_MAX_READ_BYTES (default 5 MB). For large or binary files use dropbox_get_temporary_link instead.

Inputs: path (required).

dropbox_uploadUpload fileA

Upload content to a path. Provide either text (inline UTF-8) or localPath (a file on this machine to read). Files at/under ~140 MB go in a single request; larger local files are streamed in chunks via an upload session automatically.

Inputs: path (required), mode, text, localPath, +1 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.9/5.0

    Scored across 16 tools

    Disambiguation5/5

    Each tool has a clear, non-overlapping purpose: folder operations (list, get metadata, create), file operations (move, copy, delete, upload, read, temporary link), search, shared link management (create, list, metadata, revoke), and account/space info. Even get_temporary_link vs read_file are distinct (URL vs content).

    Naming Consistency5/5

    All tools follow a consistent verb_noun pattern prefixed with 'dropbox_' (e.g., list_folder, get_metadata, create_shared_link). The verbs (list, get, create, move, copy, delete, read, upload, search, revoke) and nouns are uniform and predictable.

    Tool Count4/5

    16 tools is slightly above the ideal 3-15 range but appropriate given the comprehensive scope of Dropbox's API (folder, file, search, shared links, account). Each tool earns its place, and none seem redundant.

    Completeness4/5

    The surface covers core lifecycle operations for files and folders (create, read, update via upload/overwrite, delete, move/copy), search, and shared link management. Minor omissions like file version history or listing deleted items are acceptable gaps that agents can work around.

    Maintenance

    ActivityStale
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      B
      quality
      D
      maintenance
      Provides read access to Dropbox files with advanced search and content extraction capabilities. Supports browsing, reading, and searching within various file types including PDFs, DOCX, and text files.
      5
      -
    • F
      license
      A
      quality
      Not graded
      maintenance
      A local MCP server that enables Claude to manage Dropbox accounts through tools for file manipulation, searching, and sharing. It supports operations such as listing folders, moving files, creating shared links, and monitoring storage usage via natural language commands.
      10
      -
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables Dropbox file operations such as listing, searching, downloading, and creating folders via the Dropbox API v2 through MCP.
      108 npm
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables AI agents to manage Box files, folders, collaborations, and more via the Box API using tools for search, upload, and metadata operations.
      5 npm
      ISC