Skip to main content
Glama

inxt-agent

CI

Agent access to your Internxt Drive from pi, hermes, Claude, or any MCP client. End-to-end encrypted transfers, a stable JSON CLI contract, and an 18-tool MCP server — with no desktop app, no official CLI, and no rclone.

Features

  • Browser login, zero secrets handled — you authorize once in your browser (password and 2FA never leave it); the agent receives only the web-issued session handover.

  • Headless-friendly — works on VPS machines with no browser: paste-back mode or an SSH tunnel for a fully automatic flow.

  • End-to-end encrypted transfers — streaming uploads (multipart, presigned S3) and downloads with AES-256-CTR; key derivation is byte-identical to Internxt's web client and was verified byte-for-byte against a real account.

  • Agent-native contract — one JSON object on stdout, structured errors on stderr with stable codes, stable exit codes, destructive operations double-gated.

  • 18 MCP tools, any harness — pi, [CC], Codex, OpenCode, OpenClaw, DeepSeek Harness, Gemini, Cursor, Windsurf, VS Code, or anything that speaks MCP — annotated (readOnlyHint / destructiveHint), with confirm: true required for anything irreversible.

  • Resilient by default — single-flight token rotation on 401, SDK backoff on rate limits, cursor pagination, TTL-cached path resolution.

Related MCP server: Proton Drive CLI MCP

Why not rclone or the official CLI?

Internxt's legacy login (email + password, used by rclone and internxt login-legacy) is tier-gated: the API answers 402 — "This user current tier does not allow CLI access" on CLI-surface endpoints. The web surface has no such gate — it is what drive.internxt.com uses. inxt-agent speaks only that surface, so it works with any tier the web app works with, and never performs the legacy password login at all.

Requirements

  • Node.js >= 22.13

  • An Internxt account (any tier the web app works with)

Quick start

npm install && npm run build
node dist/cli/index.js login          # authorize once in your browser
node dist/cli/index.js ls --json      # list your Drive

Credentials persist at ~/.config/inxt-agent/credentials.json (mode 0600, inside a 0700 directory, atomic writes). status shows them redacted.

Authentication

Browser (same machine)

login starts a local callback server and opens the Internxt login page (universal-link flow). Approve once; the session is persisted and tokens are rotated automatically afterwards.

Headless A — paste-back (no tunnel needed)

inxt-agent login --remote
# 1. Open the printed URL on ANY machine with a browser and log in.
# 2. The browser "fails to connect" (127.0.0.1:1 refused) — that is expected.
# 3. Copy the FULL URL from the address bar and paste it into the prompt.

The pasted URL carries the credential set: it is read from stdin only (never argv), never echoed, never logged, and the mnemonic is validated before any network call.

Headless B — SSH tunnel (fully automatic)

inxt-agent login --port 49152
# On YOUR machine:   ssh -L 49152:127.0.0.1:49152 user@vps
# Then open the printed URL in the local browser: the redirect reaches the VPS
# callback server through the tunnel and the login completes by itself.

CLI

One JSON object on stdout (with --json); errors go to stderr as one JSON object with a stable error.code. Exit codes are stable: 0 ok · 2 auth · 4 not-found/exists · 5 invalid-argument · 6 quota · 7 rate-limited · 8 network · 9 aborted · 10 crypto · 11 local permissions · 12 confirmation-required · 13 server.

inxt-agent status                       # session + quota (redacted)
inxt-agent ls [path]                    # list a folder / stat a file
inxt-agent search <term>                # server-side fuzzy search
inxt-agent quota
inxt-agent mkdir <path>                 # recursive, like mkdir -p
inxt-agent cp <local> <remote> [--yes]  # upload (--yes overwrites via trash)
inxt-agent get <remote> <local>         # download + decrypt
inxt-agent mv <src> <dest>              # move and/or rename
inxt-agent rename <path> <name>
inxt-agent rm <path> --yes              # to trash (recoverable)
inxt-agent trash [restore <name> --yes]
inxt-agent purge <name> --yes           # permanent (IRREVERSIBLE)
inxt-agent emptytrash --yes             # permanent (IRREVERSIBLE)
inxt-agent logout

Example:

$ inxt-agent ls Reports --json
{"path":"Reports","items":[
  {"kind":"folder","name":"2025","uuid":"…","updatedAt":"2026-01-12T10:00:00.000Z"},
  {"kind":"file","name":"q3.pdf","uuid":"…","size":48213,"updatedAt":"2026-02-03T09:30:00.000Z"}
]}

Use it from any agent

One stdio MCP server (inxt, 18 tools) and one JSON CLI. Print the exact config for your harness — no docs reading required:

node dist/cli/index.js setup --list                  # supported harnesses
node dist/cli/index.js setup --client codex --json   # ready-to-paste config + target path
node dist/cli/index.js setup --generic --json        # harness-agnostic descriptor

Harness

One-liner

pi

pi mcp add inxt -- node /abs/inxt-agent-mcp.cjs

[CC]

claude mcp add --scope project inxt -- node /abs/inxt-agent-mcp.cjs

Codex CLI

[mcp_servers.inxt] in ~/.codex/config.toml

OpenCode

mcp.inxt in opencode.json (command is an array)

OpenClaw

openclaw mcp add inxt --command node --arg /abs/inxt-agent-mcp.cjs

DeepSeek Harness

@deepseek-ai/dsh-mcp-client entry in cordis.patch.yml

Gemini CLI · Cursor · Windsurf

mcpServers.inxt in their settings file

VS Code

servers.inxt in .vscode/mcp.json

anything else

spawn node /abs/inxt-agent-mcp.cjs, speak MCP over stdio

Full matrix and per-harness notes: docs/clients.md. Machine-readable manifest for tooling: docs/clients.json. Repo conventions for agents: AGENTS.md.

Irreversible tools are annotated destructiveHint: true and require confirm: true. Token expiry is handled automatically (one refresh + retry); a dead session surfaces as AUTH_EXPIRED.

How it works

src/core/       config, error taxonomy, credential store, auth
                (universal-link + headless paste-back + single-flight refresh),
                drive repo (cursor pagination, TTL cache, path resolution)
src/transfer/   E2EE engine: streaming uploads, downloads
                (bridge getDownloadLinks -> S3 shards -> AES-256-CTR),
                key derivation replicated from Internxt's web client
src/cli/        JSON contract + stable exit codes
src/mcp/        stdio MCP server (official SDK)

Only web-surface endpoints are used (/users/refresh, /folders/v2/*, /storage/trash/*, /fuzzy/*, /users/usage) — never the tier-gated CLI surface.

Development

npm test                        # 48 unit tests on fake HTTP servers
bash scripts/e2e-sandbox.sh     # E2E round-trip against a REAL account,
                                # inside a disposable sandbox folder (leaves it clean)

Security notes

  • Credentials live locally at 0600 (0700 dir); writes are atomic; loads self-check permissions and fail closed on anything laxer.

  • Nothing secret is ever printed: status redacts, errors sanitize token-shaped strings, the headless paste is consumed from stdin without echo.

  • Destructive operations are double-gated: CLI --yes / MCP confirm:true, plus destructive annotations for MCP clients.

  • The account's mnemonic never leaves the machine; only file ciphertext travels, and keys are derived locally per file.

Disclaimer

This is an independent, unofficial tool. Not affiliated with, endorsed by, or sponsored by Internxt. "Internxt" is a trademark of its respective owner, used here solely for identification.

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Manage Proton Drive from Claude, Codex, VS Code/Copilot, and any MCP client through Proton's official CLI. Authentication and encrypted Drive behavior stay with Proton's tooling.
    66 npm
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables agents to list, read, write, create, move, delete files and folders, create public share links, and search filenames in a single Nextcloud account via WebDAV and OCS, using app-password credentials from environment variables.
    9
    MIT