strapi_list_servers
List all Strapi servers from the configuration to manage multiple CMS instances.
Instructions
List all available Strapi servers from the configuration.
Security Policy
STRICT_USER_AUTHORIZATION_REQUIRED: No write operations without explicit user authorization. Protected operations: POST (Create), PUT (Update), DELETE (Delete), Media Upload. All write operations require userAuthorized: true parameter.
Strapi Version Support
Supports both Strapi v4 and v5 with automatic version detection.
Version Differences
v4: Numeric IDs, nested attributes under 'attributes', data wrapper in responses
v5: Document-based IDs (documentId), flat structure, direct attribute access
Common Errors
404: Using numeric ID instead of documentId, wrong plural/singular form
405: Incorrect endpoint (/article instead of /articles)
400: Missing data wrapper in request body
Best Practices
Always check schema first with strapi_get_content_types
Use documentId (not numeric id) for Strapi v5
Always use data wrapper for updates: { data: { field: value } }
Use pluralName for collection endpoints (api/articles)
Validate URLs with webtools before using them
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/index.ts:457-458 (schema)Zod schema for strapi_list_servers tool - no parameters needed (empty object).
// Schema for strapi_list_servers tool (no parameters) const ListServersSchema = z.object({}).strict(); - src/index.ts:616-622 (schema)ToolSchemas collection mapping tool name 'strapi_list_servers' to its schema.
const ToolSchemas = { strapi_list_servers: ListServersSchema, strapi_get_content_types: GetContentTypesSchema, strapi_get_components: GetComponentsSchema, strapi_rest: RestSchema, strapi_upload_media: UploadMediaSchema } as const; - src/index.ts:1142-1366 (registration)Tool registration via ListToolsRequestSchema handler - defines strapi_list_servers with name, description, and inputSchema.
server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "strapi_list_servers", description: `List all available Strapi servers from the configuration. ## Security Policy STRICT_USER_AUTHORIZATION_REQUIRED: No write operations without explicit user authorization. Protected operations: POST (Create), PUT (Update), DELETE (Delete), Media Upload. All write operations require userAuthorized: true parameter. ## Strapi Version Support Supports both Strapi v4 and v5 with automatic version detection. ### Version Differences - v4: Numeric IDs, nested attributes under 'attributes', data wrapper in responses - v5: Document-based IDs (documentId), flat structure, direct attribute access ### Common Errors - 404: Using numeric ID instead of documentId, wrong plural/singular form - 405: Incorrect endpoint (/article instead of /articles) - 400: Missing data wrapper in request body ### Best Practices 1. Always check schema first with strapi_get_content_types 2. Use documentId (not numeric id) for Strapi v5 3. Always use data wrapper for updates: { data: { field: value } } 4. Use pluralName for collection endpoints (api/articles) 5. Validate URLs with webtools before using them`, inputSchema: zodToJsonSchema(ToolSchemas.strapi_list_servers), }, { name: "strapi_get_content_types", description: `Get all content types from Strapi. Returns the complete schema of all content types. ## Initialization Steps (ALWAYS DO FIRST) 1. Get schema and analyze with this tool 2. Capture Content Types and structures 3. Remember endpoint names (pluralName/singularName) 4. Document fields and types 5. Identify relations 6. Consider required fields and validations ## Schema Conventions - singularName: Used for single item queries (e.g., "article") - pluralName: Used for collection endpoints (e.g., "articles") - collectionName: Database collection name ## Endpoint Patterns - Collection: GET /api/{pluralName} - Single: GET /api/{pluralName}/{id} - Create: POST /api/{pluralName} - Update: PUT /api/{pluralName}/{id} - Delete: DELETE /api/{pluralName}/{id}`, inputSchema: { ...zodToJsonSchema(ToolSchemas.strapi_get_content_types), properties: { ...zodToJsonSchema(ToolSchemas.strapi_get_content_types).properties, server: { ...zodToJsonSchema(ToolSchemas.strapi_get_content_types).properties.server, description: "The name of the server to connect to" } } }, }, { name: "strapi_get_components", description: "Get all components from Strapi with pagination support. Returns both component data and pagination metadata (page, pageSize, total, pageCount).", inputSchema: { ...zodToJsonSchema(ToolSchemas.strapi_get_components), properties: { ...zodToJsonSchema(ToolSchemas.strapi_get_components).properties, server: { ...zodToJsonSchema(ToolSchemas.strapi_get_components).properties.server, description: "The name of the server to connect to" }, page: { ...zodToJsonSchema(ToolSchemas.strapi_get_components).properties.page, description: "Page number (starts at 1)", default: 1 }, pageSize: { ...zodToJsonSchema(ToolSchemas.strapi_get_components).properties.pageSize, description: "Number of items per page", default: 25 } } }, }, { name: "strapi_rest", description: `Execute REST API requests against Strapi endpoints. IMPORTANT: All write operations (POST, PUT, DELETE) require explicit user authorization via the userAuthorized parameter. ## Reading Data params: { populate: ['SEO'] } // Populate a component params: { populate: { SEO: { fields: ['Title', 'seoDescription'] } } } // With field selection params: { filters: { title: { $contains: 'search' } } } // Filter results params: { sort: ['createdAt:desc'] } // Sort results params: { pagination: { page: 1, pageSize: 10 } } // Pagination ## Writing Data (REQUIRES userAuthorized: true) body: { data: { componentName: { Title: 'value' }, // Single component componentName: [{ field: 'value' }] // Repeatable component } } ## Debugging Guide - 404 Error: Check plural/singular form, use documentId not numeric id - 400 Error: Check if data wrapper is present in body - 405 Error: Check endpoint format (/articles not /article) - URL Errors: Validate URLs with webtools first - ID Problems: Use documentId for Strapi v5 ## Strapi v5 Specifics - Use documentId instead of numeric id - Direct attribute access (no nested attributes) - No data wrapper in GET responses`, inputSchema: { ...zodToJsonSchema(ToolSchemas.strapi_rest), properties: { ...zodToJsonSchema(ToolSchemas.strapi_rest).properties, server: { ...zodToJsonSchema(ToolSchemas.strapi_rest).properties.server, description: "The name of the server to connect to" }, endpoint: { ...zodToJsonSchema(ToolSchemas.strapi_rest).properties.endpoint, description: "The API endpoint (e.g., 'api/articles')" }, method: { ...zodToJsonSchema(ToolSchemas.strapi_rest).properties.method, description: "HTTP method to use", default: "GET" }, params: { ...zodToJsonSchema(ToolSchemas.strapi_rest).properties.params, description: "Optional query parameters for GET requests. For components, use populate: ['componentName'] or populate: { componentName: { fields: ['field1'] } }" }, body: { ...zodToJsonSchema(ToolSchemas.strapi_rest).properties.body, description: "Request body for POST/PUT requests. For components, use: { data: { componentName: { field: 'value' } } } for single components or { data: { componentName: [{ field: 'value' }] } } for repeatable components" }, userAuthorized: { ...zodToJsonSchema(ToolSchemas.strapi_rest).properties.userAuthorized, description: "REQUIRED for POST/PUT/DELETE operations. Client MUST obtain explicit user authorization before setting this to true.", default: false } } }, }, { name: "strapi_upload_media", description: `Upload media to Strapi's media library from a URL with format conversion, quality control, and metadata options. IMPORTANT: This is a write operation that REQUIRES explicit user authorization via the userAuthorized parameter. ## Upload Steps 1. Upload via strapi_upload_media with URL and metadata 2. Get image ID from response 3. Link to content using strapi_rest PUT request ## Linking Images to Content (Strapi v5) After upload, use PUT request to link: { "method": "PUT", "endpoint": "api/articles/{documentId}", "body": { "data": { "images": ["imageId"] } }, "userAuthorized": true }`, inputSchema: { ...zodToJsonSchema(ToolSchemas.strapi_upload_media), properties: { ...zodToJsonSchema(ToolSchemas.strapi_upload_media).properties, server: { ...zodToJsonSchema(ToolSchemas.strapi_upload_media).properties.server, description: "The name of the server to connect to" }, url: { ...zodToJsonSchema(ToolSchemas.strapi_upload_media).properties.url, description: "URL of the image to upload" }, format: { ...zodToJsonSchema(ToolSchemas.strapi_upload_media).properties.format, description: "Target format for the image. Use 'original' to keep the source format.", default: "original" }, quality: { ...zodToJsonSchema(ToolSchemas.strapi_upload_media).properties.quality, description: "Image quality (1-100). Only applies when converting formats.", default: 80 }, metadata: { type: "object", properties: { name: { type: "string", description: "Name of the file" }, caption: { type: "string", description: "Caption for the image" }, alternativeText: { type: "string", description: "Alternative text for accessibility" }, description: { type: "string", description: "Detailed description of the image" } }, additionalProperties: false }, userAuthorized: { ...zodToJsonSchema(ToolSchemas.strapi_upload_media).properties.userAuthorized, description: "REQUIRED for media upload operations. Client MUST obtain explicit user authorization before setting this to true.", default: false } } } } ], }; }); - src/index.ts:1380-1463 (handler)Main handler for strapi_list_servers in CallToolRequestSchema - lists all configured Strapi servers with version details, or shows setup instructions if no config found.
if (name === "strapi_list_servers") { // Validate input using Zod (no args for this tool) validateToolInput("strapi_list_servers", args, requestId); if (Object.keys(config).length === 0) { const exampleConfig = { "myserver": { "api_url": "http://localhost:1337", "api_key": "your-jwt-token-from-strapi-admin", "version": "5.*" } }; result = { content: [ { type: "text", text: JSON.stringify({ error: "No servers configured", help: { message: "No server configuration found. Please create a configuration file.", config_path: CONFIG_PATH, example_config: exampleConfig, setup_steps: [ "Create the .mcp directory: mkdir -p ~/.mcp", "Create the config file: touch ~/.mcp/strapi-mcp-server.config.json", "Add your server configuration using the example above", "Get your JWT token from Strapi Admin Panel > Settings > API Tokens", "Make sure the file permissions are secure: chmod 600 ~/.mcp/strapi-mcp-server.config.json" ] } }, null, 2), }, ], }; } const servers = Object.keys(config).map(serverName => { const serverConfig = config[serverName]; const version = serverConfig.version || "v4"; // Default to v4 if not specified // Extract major version from different formats: "5.*", "4.1.5", "v4", "4.*" let majorVersion: keyof StrapiVersionDifferences; if (version.includes('*')) { // Handle "5.*" or "4.*" format majorVersion = version.split('.')[0] as keyof StrapiVersionDifferences; } else if (version.startsWith('v')) { // Handle "v4" or "v5" format majorVersion = version.substring(1) as keyof StrapiVersionDifferences; } else { // Handle "4.1.5" or plain "4" format majorVersion = version.split('.')[0] as keyof StrapiVersionDifferences; } return { name: serverName, api_url: serverConfig.api_url, version: serverConfig.version, version_details: STRAPI_VERSION_DIFFERENCES[majorVersion] }; }); result = { content: [ { type: "text", text: JSON.stringify({ servers, config_path: CONFIG_PATH, help: "To add more servers, edit the configuration file at the path shown above.", version_differences: STRAPI_VERSION_DIFFERENCES, user_action_required: { message: "Please specify which server you want to work with by providing the server name in your next command.", example: "For example: 'I want to work with the server \"myserver\"' or 'Use server \"myserver\" for the next operations'", available_servers: servers.map(s => s.name), warning: "Only use servers that are listed in available_servers. Do not attempt to access servers that are not properly configured." }, security: { note: "For security reasons, only servers listed in the configuration file can be accessed.", requirement: "Each server must be properly configured with valid credentials before use." } }, null, 2), }, ], };