# directus-mcp-server [Health: Active]

**Category:** 💻 Developer Tools  
**Repository:** https://github.com/staminna/mcp-server-claude  
**GitHub Stars:** 0  
**npm Downloads (last month):** 117  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/directus-mcp-server

## Description
Enhanced MCP server for Directus 12.3 with TypeScript, WebSocket, and full API coverage

## Tools
Capabilities this server exposes over MCP:

- **list_collections** — List all collections in Directus
- **get_collection_schema** — Get schema for a specific collection
- **get_collection_items** — Get items from a collection with filtering
- **create_collection** — Create a new collection
- **delete_collection** — Delete a collection (requires `confirm`)
- **create_item** — Create a new item in a collection
- **update_item** — Update an existing item, optionally into a draft `version
- **delete_items** — Delete items by `ids` or by `query` (see note below)
- **bulk_operations** — Execute bulk create, update, delete
- **create_field** — Create a new field in a collection
- **update_field** — Update an existing field
- **delete_field** — Delete a field from a collection
- **create_relationship** — Create relationships (O2O, O2M, M2O, M2M, M2A)
- **analyze_collection_schema** — Analyze schema with relationship mapping
- **validate_collection_schema** — Validate schema and relationships
- **analyze_relationships** — Analyze relationships across collections
- **get_schema_snapshot** — Read a full or partial snapshot of the data model
- **diff_schema** — Compare a snapshot against the live schema (`merge` or `mirror`). Directus drops request bodies over ~96 KB, so pass a partial snapshot from `get_schema_snapshot` with `include_collections` on any sizeable data model — see `DIRECTUS_V12_BREAKING_CHANGES.md
- **apply_schema** — Apply a diff (requires `confirm`)
- **get_flows** — Get all flows with optional filtering
- **get_flow** — Get a specific flow by ID
- **create_flow** — Create a new automation flow
- **update_flow** — Update an existing flow
- **delete_flow** — Delete a flow
- **trigger_flow** — Manually trigger a flow
- **get_operations** — Get flow operations
- **get_users** — Get all users with filtering
- **get_user** — Get a specific user by ID
- **get_files** — Get files with filtering and pagination
- **import_data** — Import CSV/JSON into one collection, or several at once
- **diagnose_collection_access** — Diagnose collection access issues
- **refresh_collection_cache** — Refresh collection cache
- **validate_collection_creation** — Validate newly created collections
- **search_tools** — Find the tools matching a task description

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `npx` (confidence: high):

```json
"mcpServers": {
  "directus-mcp-server": {
    "command": "npx",
    "args": ["-y","@staminna/directus-mcp-server"]
  }
}
```

## Documentation & README

# @staminna/directus-mcp-server

MCP server for Directus 12 — items, collections, files, flows, users, and schema tools. TypeScript, typed throughout.

[![npm version](https://badge.fury.io/js/%40staminna%2Fdirectus-mcp-server.svg)](https://www.npmjs.com/package/@staminna/directus-mcp-server)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![CI](https://github.com/staminna/mcp-server-claude/actions/workflows/ci.yml/badge.svg)](https://github.com/staminna/mcp-server-claude/actions/workflows/ci.yml)
[![mcp-server-claude MCP server](https://glama.ai/mcp/servers/staminna/mcp-server-claude/badges/score.svg)](https://glama.ai/mcp/servers/staminna/mcp-server-claude)

[![mcp-server-claude MCP server](https://glama.ai/mcp/servers/staminna/mcp-server-claude/badges/card.svg)](https://glama.ai/mcp/servers/staminna/mcp-server-claude)

### Test Coverage

| Statements | Branches | Functions | Lines |
|------------|----------|-----------|-------|
| ![Statements](https://img.shields.io/badge/statements-98.65%25-brightgreen.svg?style=flat) | ![Branches](https://img.shields.io/badge/branches-98.04%25-brightgreen.svg?style=flat) | ![Functions](https://img.shields.io/badge/functions-97.3%25-brightgreen.svg?style=flat) | ![Lines](https://img.shields.io/badge/lines-98.64%25-brightgreen.svg?style=flat) |

Coverage badges are generated from `coverage/coverage-summary.json` by `npm run badges` (no external service required). Run `npm run test:coverage` first.

## Features

- 🔐 **Full Authentication** - Token-based authentication with Directus
- 📦 **Collection Management** - CRUD operations for collections and items
- 📁 **File Operations** - Upload, download, and manage files
- 🔄 **Flow Management** - Create, update, trigger, and manage Directus Flows
- 👥 **User Management** - User CRUD and role management
- 🔍 **Schema Tools** - Analyze and validate collection schemas
- 🩺 **Diagnostics** - Collection access diagnostics and troubleshooting

## Installation

### Via npm (Recommended)

```bash
npm install -g @staminna/directus-mcp-server
```

### From Source

```bash
git clone https://github.com/staminna/mcp-server-claude.git
cd mcp-server-claude
npm install
npm run build
```

## Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `DIRECTUS_URL` | Yes | Your Directus instance URL (e.g., `http://localhost:8065`) |
| `DIRECTUS_TOKEN` | Yes | Static API token with appropriate permissions |
| `DIRECTUS_PROMPTS_COLLECTION_ENABLED` | No | Enable AI prompts collection (`true`/`false`) |
| `DIRECTUS_PROMPTS_COLLECTION` | No | Collection name for AI prompts (default: `ai_prompts`) |
| `DIRECTUS_RESOURCES_ENABLED` | No | Enable resources feature (`true`/`false`) |
| `DIRECTUS_RESOURCES_EXCLUDE_SYSTEM` | No | Exclude system collections from resources (`true`/`false`) |
| `NODE_ENV` | No | Environment mode (`development`/`production`) |
| `DIRECTUS_TIMEOUT` | No | Request timeout in ms (default: `30000`) |
| `DIRECTUS_RETRIES` | No | Retry attempts for network errors, 5xx and 429 (default: `3`) |
| `DIRECTUS_RETRY_DELAY` | No | Base backoff delay in ms (default: `1000`) |
| `DIRECTUS_MAX_RETRY_DELAY` | No | Backoff ceiling in ms (default: `10000`) |
| `DIRECTUS_IMPORT_MAX_FILE_SIZE` | No | Client-side import size ceiling in bytes, mirroring the Directus `IMPORT_MAX_FILE_SIZE` (default: 50 MB) |
| `LOG_LEVEL` | No | `DEBUG`/`INFO`/`WARN`/`ERROR` (default: `INFO`). Logs go to stderr; stdout is reserved for MCP |

### TLS / client certificates

Set these when the Directus instance uses a private CA or requires a client
certificate. Each of `CA`/`CERT`/`KEY`/`PFX` accepts either a file path or the
PEM/DER content itself.

| Variable | Description |
|----------|-------------|
| `DIRECTUS_HTTPS_CA` | Certificate authority |
| `DIRECTUS_HTTPS_CERT` | Client certificate |
| `DIRECTUS_HTTPS_KEY` | Client private key |
| `DIRECTUS_HTTPS_PFX` | PKCS#12 bundle (alternative to cert/key) |
| `DIRECTUS_HTTPS_PASSPHRASE` | Passphrase for the key or PFX |
| `DIRECTUS_HTTPS_REJECT_UNAUTHORIZED` | `false` to accept self-signed certificates |
| `DIRECTUS_HTTPS_SERVERNAME` | SNI server name override |

---

## Authentication — no OAuth required

This server uses a **static Directus access token** (`DIRECTUS_TOKEN`) and runs over **stdio transport**. OAuth is *not* required, by design:

- The MCP specification only defines OAuth 2.1 authorization for **HTTP-based transports**. For stdio servers the spec says implementations *"SHOULD NOT"* use it and should instead retrieve credentials from the environment — exactly what this server does.
- **Directus 12 fully supports static access tokens.** The OAuth 2.1 support Directus added (mid-2026) applies to its own built-in *remote* MCP endpoint and is optional; there are no breaking changes to token authentication in Directus 12 (see `DIRECTUS_V12_BREAKING_CHANGES.md`).
- OAuth only becomes relevant if you expose an MCP server **remotely over HTTP** (Streamable HTTP/SSE). As a local stdio subprocess of Claude Desktop, Claude Code, Cursor, etc., this server needs only the env token.

Generate the token in Directus under **User Settings → Token** (use a dedicated user with least-privilege role for production).

### Using with a Claude subscription (Max/Pro) — no API key needed

MCP servers do not consume Anthropic API tokens themselves; only the AI client's model calls do. If you use this server inside **Claude Code or Claude Desktop with a Claude Max (or Pro) subscription**, the model usage is covered by the subscription — you do **not** need an Anthropic API key. An API key is only required when driving Claude programmatically via the Claude API (e.g. the remote MCP connector).

---

## IDE Configuration

### 🟣 Cursor

1. Open Cursor Settings: `Cmd+,` (macOS) or `Ctrl+,` (Windows/Linux)
2. Search for **"MCP"** or navigate to **Features → MCP Servers**
3. Click **"Edit in settings.json"**
4. Add the following configuration:

```json
{
  "mcpServers": {
    "directus": {
      "command": "npx",
      "args": [
        "-y",
        "@staminna/directus-mcp-server"
      ],
      "env": {
        "DIRECTUS_URL": "http://localhost:8065",
        "DIRECTUS_TOKEN": "your-directus-token-here"
      }
    }
  }
}
```

**Or if installed locally:**

```json
{
  "mcpServers": {
    "directus": {
      "command": "node",
      "args": [
        "/path/to/mcp-server-claude/dist/index.js"
      ],
      "env": {
        "DIRECTUS_URL": "http://localhost:8065",
        "DIRECTUS_TOKEN": "your-directus-token-here"
      }
    }
  }
}
```

5. Save the file and restart Cursor

---

### 🌊 Windsurf

1. Open Windsurf Settings: `Cmd+,` (macOS) or `Ctrl+,` (Windows/Linux)
2. Search for **"MCP Servers"**
3. Click **"Edit in settings.json"**
4. Add the following configuration:

```json
{
  "mcpServers": {
    "directus": {
      "command": "npx",
      "args": [
        "-y",
        "@staminna/directus-mcp-server"
      ],
      "env": {
        "DIRECTUS_URL": "http://localhost:8065",
        "DIRECTUS_TOKEN": "your-directus-token-here",
        "DIRECTUS_PROMPTS_COLLECTION_ENABLED": "true",
        "DIRECTUS_PROMPTS_COLLECTION": "ai_prompts",
        "DIRECTUS_RESOURCES_ENABLED": "true",
        "DIRECTUS_RESOURCES_EXCLUDE_SYSTEM": "true",
        "NODE_ENV": "production"
      }
    }
  }
}
```

**Or if installed locally:**

```json
{
  "mcpServers": {
    "directus": {
      "command": "node",
      "args": [
        "/path/to/mcp-server-claude/dist/index.js"
      ],
      "env": {
        "DIRECTUS_URL": "http://localhost:8065",
        "DIRECTUS_TOKEN": "your-directus-token-here"
      }
    }
  }
}
```

5. Save the file
6. **Quit Windsurf completely** (`Cmd+Q` or `Ctrl+Q`)
7. Reopen Windsurf and wait ~10 seconds for MCP to initialize

---

### 🤖 Claude Desktop

1. Locate your Claude Desktop config file:
   - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
   - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
   - **Linux**: `~/.config/Claude/claude_desktop_config.json`

2. Create or edit the config file:

```json
{
  "mcpServers": {
    "directus": {
      "command": "npx",
      "args": [
        "-y",
        "@staminna/directus-mcp-server"
      ],
      "env": {
        "DIRECTUS_URL": "http://localhost:8065",
        "DIRECTUS_TOKEN": "your-directus-token-here"
      }
    }
  }
}
```

**Or if installed locally:**

```json
{
  "mcpServers": {
    "directus": {
      "command": "node",
      "args": [
        "/path/to/mcp-server-claude/dist/index.js"
      ],
      "env": {
        "DIRECTUS_URL": "http://localhost:8065",
        "DIRECTUS_TOKEN": "your-directus-token-here"
      }
    }
  }
}
```

3. Save the file and restart Claude Desktop

---

### 🔮 Claude.ai (Web with MCP)

For Claude.ai web interface with MCP support:

1. Navigate to Claude.ai settings
2. Find the MCP configuration section
3. Add a new MCP server with:

```json
{
  "name": "directus",
  "command": "npx",
  "args": ["-y", "@staminna/directus-mcp-server"],
  "env": {
    "DIRECTUS_URL": "http://localhost:8065",
    "DIRECTUS_TOKEN": "your-directus-token-here"
  }
}
```

> **Note**: Claude.ai MCP support may require a Pro subscription and specific browser extensions.

---

## Available Tools

### Collection Management
| Tool | Description |
|------|-------------|
| `list_collections` | List all collections in Directus |
| `get_collection_schema` | Get schema for a specific collection |
| `get_collection_items` | Get items from a collection with filtering |
| `create_collection` | Create a new collection |
| `delete_collection` | Delete a collection (requires `confirm`) |
| `create_item` | Create a new item in a collection |
| `update_item` | Update an existing item, optionally into a draft `version` |
| `delete_items` | Delete items by `ids` or by `query` (see note below) |
| `bulk_operations` | Execute bulk create, update, delete |

### Schema & Fields
| Tool | Description |
|------|-------------|
| `create_field` | Create a new field in a collection |
| `update_field` | Update an existing field |
| `delete_field` | Delete a field from a collection |
| `create_relationship` | Create relationships (O2O, O2M, M2O, M2M, M2A) |
| `analyze_collection_schema` | Analyze schema with relationship mapping |
| `validate_collection_schema` | Validate schema and relationships |
| `analyze_relationships` | Analyze relationships across collections |
| `get_schema_snapshot` | Read a full or partial snapshot of the data model |
| `diff_schema` | Compare a snapshot against the live schema (`merge` or `mirror`). Directus drops request bodies over ~96 KB, so pass a partial snapshot from `get_schema_snapshot` with `include_collections` on any sizeable data model — see `DIRECTUS_V12_BREAKING_CHANGES.md` |
| `apply_schema` | Apply a diff (requires `confirm`) |

### Flow Management
| Tool | Description |
|------|-------------|
| `get_flows` | Get all flows with optional filtering |
| `get_flow` | Get a specific flow by ID |
| `create_flow` | Create a new automation flow |
| `update_flow` | Update an existing flow |
| `delete_flow` | Delete a flow |
| `trigger_flow` | Manually trigger a flow |
| `get_operations` | Get flow operations |

### User Management
| Tool | Description |
|------|-------------|
| `get_users` | Get all users with filtering |
| `get_user` | Get a specific user by ID |

### File Management
| Tool | Description |
|------|-------------|
| `get_files` | Get files with filtering and pagination |
| `import_data` | Import CSV/JSON into one collection, or several at once |

### Diagnostics
| Tool | Description |
|------|-------------|
| `diagnose_collection_access` | Diagnose collection access issues |
| `refresh_collection_cache` | Refresh collection cache |
| `validate_collection_creation` | Validate newly created collections |

### Discovery
| Tool | Description |
|------|-------------|
| `search_tools` | Find the tools matching a task description |

### Tool safety annotations

Every tool carries MCP annotations so a client can tell reads from writes before
calling: 17 are `readOnlyHint: true`, 6 are explicitly `destructiveHint: false`
(additive — creates), and 11 are `destructiveHint: true` (deletes, overwriting
updates, `apply_schema`, `import_data`, `trigger_flow`).

Note that `destructiveHint` **defaults to true** in the MCP spec, which is why
the additive tools set it to `false` rather than omitting it.

### Deleting items safely

Following Directus 12.3.0, `delete_items` never falls back to deleting
everything:

- `ids: [...]` deletes those items.
- `query: {...}` deletes everything the query matches.
- Passing both is rejected.
- Passing neither deletes nothing and issues no request.

To delete every item in a collection, ask for it explicitly:

```json
{ "collection": "articles", "query": { "limit": -1 }, "confirm": true }
```

---

## Usage Examples

Once configured, you can interact with Directus through your AI assistant:

```
"List all collections in my Directus instance"

"Create a new collection called 'blog_posts' with title, content, and published fields"

"Get all items from the 'products' collection where status is 'published'"

"Create a new flow that triggers on item creation in the 'orders' collection"

"Analyze the schema of the 'users' collection including relationships"
```

---

## Troubleshooting

### MCP Server Not Connecting

1. **Verify Directus is running**: Ensure your Directus instance is accessible at the configured URL
2. **Check token permissions**: The API token needs appropriate permissions for the operations you want to perform
3. **Restart IDE**: After changing MCP configuration, fully restart your IDE
4. **Check logs**: Look for MCP-related errors in your IDE's developer console

### Permission Errors

Ensure your Directus token has the required permissions:
- Admin token for full access
- Or configure specific role permissions for collections you need to access

### Connection Timeout

If using a remote Directus instance:
- Verify the URL is correct and accessible
- Check firewall/network settings
- Ensure CORS is properly configured on Directus

---

## Development

```bash
# Install dependencies
npm install

# Build
npm run build

# Watch mode
npm run dev

# Run server
npm start

# Type check
npm run typecheck

# Lint
npm run lint
```

### Testing

The project ships unit, integration and end-to-end suites (vitest). Coverage thresholds (95% statements/lines/functions/branches) are enforced — the test run fails below them.

```bash
# Unit + integration tests
npm test

# With coverage report (coverage/ — text, html, lcov, json-summary)
npm run test:coverage

# End-to-end: builds, then spawns the real server over stdio against a mock Directus
npm run test:e2e

# Everything
npm run test:all

# Refresh the README coverage badges from the last coverage run
npm run badges
```

### Live verification against a real Directus

`tests/live/demo.mjs` drives all 34 tools against a real instance over stdio. It is
deliberately outside `npm test` — it needs a credential and a reachable server, so it
is a manual gate rather than a CI one.

```bash
# Read-only + guard phases (touches nothing)
ENV_FILE=.env.mdbaudio npm run test:live

# Also create, mutate and drop a scratch mcp_demo_<stamp> collection
ENV_FILE=.env.mdbaudio npm run test:live -- --write

# Additionally exercise apply_schema, confined to that scratch collection
ENV_FILE=.env.mdbaudio npm run test:live -- --write --apply-schema
```

Credentials are read from `ENV_FILE` (default `.env.mdbaudio`) so they never pass through
shell history. Results are reported per tool as pass / refused-by-instance / fail, keeping
"this server is broken" separate from "this instance declined". `--apply-schema` diffs in
**merge** mode, which yields a strictly additive diff, so it can only re-create the scratch
collection — it cannot drop anything that already existed. Cleanup runs even when an
earlier phase fails.

The e2e suite uses the official MCP SDK client (`StdioClientTransport`) to spawn `dist/index.js` as a subprocess, talking to an in-process mock Directus on an ephemeral port — no real Directus instance or network access needed.

---

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

---

## License

MIT © [Jorge Domingues Nunes](https://github.com/staminna)

---

## Links

- [npm Package](https://www.npmjs.com/package/@staminna/directus-mcp-server)
- [GitHub Repository](https://github.com/staminna/mcp-server-claude)
- [Directus Documentation](https://docs.directus.io/)
- [MCP Protocol Specification](https://modelcontextprotocol.io/)

