# Directus MCP Server A Model Context Protocol (MCP) server that provides comprehensive tools for managing Directus schema and content. This server enables AI assistants and other MCP clients to interact with Directus instances programmatically. ## Installation ### From npm (once published) ```bash npm install -g directus-mcp-server ``` ### From source ```bash git clone https://github.com/yourusername/directus-mcp.git cd directus-mcp npm install npm run build ``` ## Features - **Schema Management**: Create, read, update, and delete collections, fields, and relations - **Content Management**: Full CRUD operations on items with advanced querying - **Type Safety**: Built with TypeScript and Zod validation - **Official SDK**: Uses the official `@directus/sdk` for reliable API interactions - **Flexible Authentication**: Supports both static tokens and email/password authentication ## Installation ```bash npm install ``` ## Configuration Create a `.env` file in the root directory with your Directus configuration: ```env # Directus Instance URL DIRECTUS_URL=https://your-directus-instance.com # Authentication - Use either token OR email/password DIRECTUS_TOKEN=your_static_token_here # Alternative: Email/Password authentication # DIRECTUS_EMAIL=admin@example.com # DIRECTUS_PASSWORD=your_password ``` ### Authentication Options 1. **Static Token** (Recommended for production): - Generate a static token in Directus Admin App - Set `DIRECTUS_TOKEN` environment variable 2. **Email/Password**: - Use for development or when static tokens aren't available - Set `DIRECTUS_EMAIL` and `DIRECTUS_PASSWORD` environment variables ### Toolset Configuration The Directus MCP server organizes tools into logical toolsets, similar to GitHub's MCP implementation. This allows you to control which tools are exposed to the MCP client. **Available Toolsets:** - `default` - Contains collections, fields, relations, and content tools (default behavior when no toolset is specified) - `collections` - Collection management tools (list, get, create, update, delete collections) - `fields` - Field management tools (list, create, update, delete fields) - `relations` - Relation management tools (list, create, delete relations) - `schema` - Schema snapshot and diff tools (get snapshot, get diff, apply diff) - NOT included in default toolset - `content` - Content management tools (items CRUD operations) - `flow` - Flow management tools (workflow automation) - NOT included in default toolset - `dashboards` - Dashboard and panel management tools (list, get, create, update, delete dashboards and panels) - NOT included in default toolset - `all` - All available tools regardless of toolset membership **Default Behavior:** When `MCP_TOOLSETS` is not set or empty, only tools in the `default` toolset are exposed. The `default` toolset contains collections, fields, relations, and content tools, but **not** schema, flow, or dashboard tools. Schema, flow, and dashboard tools must be explicitly requested by including `schema`, `flow`, or `dashboards` in the `MCP_TOOLSETS` environment variable. **Configuration:** Set the `MCP_TOOLSETS` environment variable to a comma-separated list of toolsets: ```env # Expose only collections tools MCP_TOOLSETS=collections # Expose only schema snapshot/diff tools MCP_TOOLSETS=schema # Expose collections and fields tools MCP_TOOLSETS=collections,fields # Expose only dashboard and panel tools MCP_TOOLSETS=dashboards # Expose all schema-related toolsets MCP_TOOLSETS=collections,fields,relations,schema # Expose all toolsets (includes flow and dashboard tools) MCP_TOOLSETS=default,flow,dashboards # OR MCP_TOOLSETS=collections,fields,relations,schema,content,flow,dashboards # OR simply use 'all' to expose everything MCP_TOOLSETS=all ``` **Examples:** ```json { "mcpServers": { "directus-schema": { "command": "node", "args": ["/path/to/directus-mcp/dist/index.js"], "env": { "DIRECTUS_URL": "https://your-directus-instance.com", "DIRECTUS_TOKEN": "your_token", "MCP_TOOLSETS": "schema" } }, "directus-content": { "command": "node", "args": ["/path/to/directus-mcp/dist/index.js"], "env": { "DIRECTUS_URL": "https://your-directus-instance.com", "DIRECTUS_TOKEN": "your_token", "MCP_TOOLSETS": "content" } } } } ``` **Notes:** - Toolset names are case-insensitive - Invalid toolset names are ignored (with a warning) - If all requested toolsets are invalid, the server defaults to the `default` toolset - Collections, fields, relations, and content tools belong to both `default` and their specific toolset - Schema, flow, and dashboard tools belong ONLY to their respective toolsets (not in `default`) ## Building ```bash npm run build ``` ## Usage ### Running the Server ```bash npm start ``` Or use the built binary: ```bash node dist/index.js ``` ### MCP Client Configuration Add to your MCP client configuration (e.g., Claude Desktop, Cline): **Option 1: Using npx (recommended - no installation needed):** ```json { "mcpServers": { "directus": { "command": "npx", "args": ["-y", "directus-mcp-server"], "env": { "DIRECTUS_URL": "https://your-directus-instance.com", "DIRECTUS_TOKEN": "your_static_token_here", "MCP_TOOLSETS": "default" } } } } ``` **Option 2: Using global installation:** ```json { "mcpServers": { "directus": { "command": "directus-mcp", "env": { "DIRECTUS_URL": "https://your-directus-instance.com", "DIRECTUS_TOKEN": "your_static_token_here", "MCP_TOOLSETS": "default" } } } } ``` **Option 3: Using local source:** ```json { "mcpServers": { "directus": { "command": "node", "args": ["/absolute/path/to/directus-mcp/dist/index.js"], "env": { "DIRECTUS_URL": "https://your-directus-instance.com", "DIRECTUS_TOKEN": "your_static_token_here", "MCP_TOOLSETS": "default" } } } } ``` ## Available Tools ### Schema Management Tools #### `list_collections` List all collections in the Directus instance. **Parameters**: None **Example**: ```json {} ``` #### `get_collection` Get detailed information about a specific collection. **Parameters**: - `collection` (string): Collection name **Example**: ```json { "collection": "articles" } ``` #### `create_collection` Create a new collection (database table) with optional fields. This automatically creates a proper database table, not just a folder. **Parameters**: - `collection` (string): Collection name - `meta` (object, optional): Collection metadata (icon, note, singleton, etc.) - `schema` (object, optional): Database schema configuration (automatically set if not provided) - `fields` (array, optional): Initial fields to create **Example**: ```json { "collection": "articles", "meta": { "icon": "article", "note": "Blog articles collection" }, "fields": [ { "field": "id", "type": "integer", "schema": { "is_primary_key": true, "has_auto_increment": true } }, { "field": "title", "type": "string", "meta": { "required": true } }, { "field": "status", "type": "string", "meta": { "interface": "select-dropdown", "options": { "choices": [ {"text": "Draft", "value": "draft"}, {"text": "Published", "value": "published"} ] } } } ] } ``` #### `update_collection` Update collection metadata. **Parameters**: - `collection` (string): Collection name - `meta` (object): Metadata to update **Example**: ```json { "collection": "articles", "meta": { "icon": "article", "note": "Updated description" } } ``` #### `delete_collection` Delete a collection and all its data. **Parameters**: - `collection` (string): Collection name **Example**: ```json { "collection": "articles" } ``` #### `list_fields` List all fields in a collection. **Parameters**: - `collection` (string): Collection name **Example**: ```json { "collection": "articles" } ``` #### `create_field` Add a new field to a collection. **Parameters**: - `collection` (string): Collection name - `field` (string): Field name - `type` (string): Field type (string, integer, text, boolean, json, uuid, timestamp, etc.) - `meta` (object, optional): Field metadata - `schema` (object, optional): Database schema configuration **Example**: ```json { "collection": "articles", "field": "author", "type": "uuid", "meta": { "interface": "select-dropdown-m2o", "required": true, "special": ["m2o"] } } ``` #### `update_field` Update field properties. **Parameters**: - `collection` (string): Collection name - `field` (string): Field name - `type` (string, optional): Field type - `meta` (object, optional): Metadata to update - `schema` (object, optional): Schema to update **Example**: ```json { "collection": "articles", "field": "title", "meta": { "note": "Article title (required)" } } ``` #### `delete_field` Remove a field from a collection. **Parameters**: - `collection` (string): Collection name - `field` (string): Field name **Example**: ```json { "collection": "articles", "field": "old_field" } ``` #### `list_relations` List all relations in the Directus instance. **Parameters**: None **Example**: ```json {} ``` #### `create_relation` Create a relation between collections. **Parameters**: - `collection` (string): Many collection (with foreign key) - `field` (string): Field name in many collection - `related_collection` (string, optional): One collection - `meta` (object, optional): Relation metadata - `schema` (object, optional): Database relation configuration **Example (Many-to-One)**: ```json { "collection": "articles", "field": "author", "related_collection": "users", "schema": { "on_delete": "SET NULL" } } ``` **Example (One-to-Many)**: ```json { "collection": "articles", "field": "author", "related_collection": "users", "meta": { "one_field": "articles" } } ``` #### `delete_relation` Delete a relation. **Parameters**: - `collection` (string): Collection name - `field` (string): Field name **Example**: ```json { "collection": "articles", "field": "author" } ``` ### Content Management Tools #### `query_items` Query items with filtering, sorting, and pagination. **Parameters**: - `collection` (string): Collection name - `fields` (array, optional): Fields to return - `filter` (object, optional): Filter criteria - `search` (string, optional): Search query - `sort` (array, optional): Sort fields (prefix with `-` for descending) - `limit` (number, optional): Maximum items to return - `offset` (number, optional): Items to skip - `page` (number, optional): Page number - `aggregate` (object, optional): Aggregation functions - `groupBy` (array, optional): Group by fields - `deep` (object, optional): Deep relational queries **Filter Operators**: `_eq`, `_neq`, `_lt`, `_lte`, `_gt`, `_gte`, `_in`, `_nin`, `_null`, `_nnull`, `_contains`, `_ncontains`, `_starts_with`, `_nstarts_with`, `_ends_with`, `_nends_with`, `_between`, `_nbetween` **Example**: ```json { "collection": "articles", "filter": { "status": {"_eq": "published"}, "date_created": {"_gte": "2024-01-01"} }, "sort": ["-date_created"], "limit": 10 } ``` #### `get_item` Get a single item by ID. **Parameters**: - `collection` (string): Collection name - `id` (string|number): Item ID - `fields` (array, optional): Fields to return - `deep` (object, optional): Deep relational queries **Example**: ```json { "collection": "articles", "id": 1, "fields": ["id", "title", "status", "author.first_name"] } ``` #### `create_item` Create a new item. **Parameters**: - `collection` (string): Collection name - `data` (object): Item data **Example**: ```json { "collection": "articles", "data": { "title": "My New Article", "status": "draft", "body": "Article content here...", "author": "user-uuid-here" } } ``` #### `update_item` Update an existing item. **Parameters**: - `collection` (string): Collection name - `id` (string|number): Item ID - `data` (object): Fields to update **Example**: ```json { "collection": "articles", "id": 1, "data": { "status": "published" } } ``` #### `delete_item` Delete an item. **Parameters**: - `collection` (string): Collection name - `id` (string|number): Item ID **Example**: ```json { "collection": "articles", "id": 1 } ``` #### `bulk_create_items` Create multiple items at once. **Parameters**: - `collection` (string): Collection name - `items` (array): Array of item data objects **Example**: ```json { "collection": "articles", "items": [ {"title": "Article 1", "status": "draft"}, {"title": "Article 2", "status": "draft"} ] } ``` #### `bulk_update_items` Update multiple items at once. **Parameters**: - `collection` (string): Collection name - `items` (array): Array of items with id and fields to update **Example**: ```json { "collection": "articles", "items": [ {"id": 1, "status": "published"}, {"id": 2, "status": "published"} ] } ``` #### `bulk_delete_items` Delete multiple items at once. **Parameters**: - `collection` (string): Collection name - `ids` (array): Array of item IDs **Example**: ```json { "collection": "articles", "ids": [1, 2, 3] } ``` ## Common Use Cases ### Setting up a new content model 1. Create a collection with `create_collection` 2. Add fields with `create_field` 3. Create relations with `create_relation` 4. Start adding content with `create_item` ### Querying content with relations ```json { "collection": "articles", "fields": ["*", "author.first_name", "author.last_name"], "filter": {"status": {"_eq": "published"}}, "sort": ["-date_created"], "limit": 10 } ``` ### Bulk operations Use `bulk_create_items`, `bulk_update_items`, or `bulk_delete_items` for efficient batch operations. ## Development ```bash # Watch mode for development npm run dev # Build for production npm run build ``` ## Tool Authoring This project provides utilities to streamline MCP tool development and reduce code duplication: ### Tool Helpers Use `createTool` for tools that return data, and `createActionTool` for tools that perform actions: ```typescript import { createTool, createActionTool } from './tools/tool-helpers.js'; // Data-returning tool const myTool = createTool({ name: 'my_tool', description: 'Description of what the tool does', inputSchema: MySchema, toolsets: ['default', 'my-category'], handler: async (client, args) => client.someMethod(args) }); // Action tool (returns success message) const myActionTool = createActionTool({ name: 'delete_something', description: 'Delete something', inputSchema: DeleteSchema, toolsets: ['default'], handler: async (client, args) => client.deleteMethod(args.id), successMessage: (args) => `Successfully deleted item ${args.id}` }); ``` ### Shared Validators Common Zod schemas are available in `src/tools/validators.ts`: - `CollectionNameSchema` - For collection names - `ItemIdSchema` - For item IDs (string | number) - `FieldsSchema` - For field arrays - `FilterSchema` - For Directus filter objects - Query parameter schemas (`SortSchema`, `LimitSchema`, etc.) - Flow-related schemas (`FlowTriggerSchema`, `FlowStatusSchema`, etc.) Example usage: ```typescript import { CollectionNameSchema, ItemIdSchema } from './tools/validators.js'; const MyToolSchema = z.object({ collection: CollectionNameSchema, id: ItemIdSchema, // ... other fields }); ``` ### Directus Client Resource Factory The client uses a resource factory pattern for consistent CRUD operations. When adding new Directus resources, define them in the client constructor using `createResourceMethods()`. ## Error Handling All tools include error handling and will return descriptive error messages for: - Authentication failures - Invalid parameters - API errors - Network issues - Validation errors ## License MIT ## Contributing Contributions are welcome! Please feel free to submit a Pull Request.