We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/andychoi/mcp-strapi'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
# MCP-Strapi
Full CRUD access to Strapi 5.x CMS for AI agents via the [Model Context Protocol](https://modelcontextprotocol.io/), plus secure document storage with ABAC-filtered semantic search and RAG.
## Plugins
| Plugin | Path | Purpose |
|--------|------|---------|
| **mcp-server** | `strapi-plugins/mcp-server/` | MCP protocol (Streamable HTTP). AI agent CRUD via Document Service. |
| **secure-documents** | `strapi-plugins/secure-documents/` | Private document upload, S3 storage, ABAC policy engine, RAG pipeline (extract/chunk/embed/store). |
| **secure-search** | `strapi-plugins/secure-search/` | Semantic vector search (pgvector), ABAC-filtered facets, RAG answer generation. |
| *(standalone)* | `strapi-mcp-server/` | Legacy external MCP server via REST API. For cases where Strapi can't be modified. |
## Quick Start (Docker)
```bash
git clone https://github.com/andychoi/mcp-strapi.git
cd mcp-strapi
# Create .env
cat > .env <<EOF
DATABASE_CLIENT=postgres
DATABASE_HOST=postgres-db
DATABASE_PORT=5432
DATABASE_NAME=strapi
DATABASE_USERNAME=strapi
DATABASE_PASSWORD=password
JWT_SECRET=your-jwt-secret-change-me
ADMIN_JWT_SECRET=your-admin-jwt-secret-change-me
APP_KEYS=key1,key2,key3,key4
API_TOKEN_SALT=your-api-token-salt
TRANSFER_TOKEN_SALT=your-transfer-token-salt
S3_BUCKET=secure-documents
S3_ENDPOINT=http://minio:9000
S3_FORCE_PATH_STYLE=true
S3_PUBLIC_ENDPOINT=http://localhost:9000
AWS_ACCESS_KEY_ID=minioadmin
AWS_SECRET_ACCESS_KEY=minioadmin
EOF
# Start Strapi + PostgreSQL/pgvector + MinIO
docker compose up -d
# Endpoints:
# MCP: http://localhost:1337/api/mcp-server/mcp
# Document API: http://localhost:1337/api/secure-documents/documents
# Search API: http://localhost:1337/api/secure-search/search
# Strapi admin: http://localhost:1337/admin
# MinIO console: http://localhost:9001
```
Demo users (seeded on first boot, password `Admin1234!`): `admin@example.com` (Super Admin), `editor@example.com` (Editor), `author@example.com` (Author).
## Quick Start (Standalone Server)
```bash
cd strapi-mcp-server
npm install
npm run build
# Configure
cat > .env <<EOF
STRAPI_URL=http://localhost:1337
STRAPI_ADMIN_EMAIL=admin@example.com
STRAPI_ADMIN_PASSWORD=your_password
EOF
# Run
node --env-file=.env build/index.js
```
Add to Claude Desktop (`~/Library/Application Support/Claude/claude_desktop_config.json`):
```json
{
"mcpServers": {
"mcp-strapi": {
"command": "npx",
"args": ["mcp-strapi"],
"env": {
"STRAPI_URL": "http://localhost:1337",
"STRAPI_ADMIN_EMAIL": "admin@example.com",
"STRAPI_ADMIN_PASSWORD": "your_password"
}
}
}
}
```
## Plugin Configuration
```typescript
// config/plugins.ts
export default ({ env }) => ({
'mcp-server': {
enabled: true,
config: {
auth: env('MCP_AUTH_MODE', false), // 'jwt' | 'admin' | false
},
},
'secure-documents': {
enabled: true,
config: {
auth: env('MCP_AUTH_MODE', false),
storage: {
bucket: env('S3_BUCKET', 'secure-documents'),
region: env('S3_REGION', 'us-east-1'),
endpoint: env('S3_ENDPOINT', ''),
forcePathStyle: env.bool('S3_FORCE_PATH_STYLE', false),
publicEndpoint: env('S3_PUBLIC_ENDPOINT', ''),
},
embedding: {
provider: env('EMBEDDING_PROVIDER', 'ollama'),
model: env('EMBEDDING_MODEL', 'nomic-embed-text'),
dimensions: env.int('EMBEDDING_DIMENSIONS', 768),
ollamaEndpoint: env('OLLAMA_ENDPOINT', 'http://host.docker.internal:11434'),
},
},
},
'secure-search': {
enabled: true,
config: {
auth: env('MCP_AUTH_MODE', false),
rag: {
enabled: env.bool('RAG_ENABLED', true),
provider: env('RAG_PROVIDER', 'ollama'),
model: env('RAG_MODEL', ''),
},
},
},
});
```
## MCP Tools
20 production tools (25 with dev mode). All tools work in both standalone and plugin modes.
### Content (Collection Types)
| Tool | Description |
|------|-------------|
| `list_content_types` | List all content types |
| `get_entries` | Get entries with filtering, pagination, sorting, population |
| `get_entry` | Get a specific entry by ID |
| `create_entry` | Create a new entry |
| `update_entry` | Update an existing entry |
| `delete_entry` | Delete an entry |
| `publish_entry` | Publish an entry |
| `unpublish_entry` | Unpublish an entry |
### Content (Single Types)
| Tool | Description |
|------|-------------|
| `get_single_type` | Get a single type entry |
| `update_single_type` | Update a single type |
| `delete_single_type` | Delete a single type |
| `publish_single_type` | Publish a single type |
| `unpublish_single_type` | Unpublish a single type |
### Media
| Tool | Description |
|------|-------------|
| `upload_media` | Upload via base64 (max ~750KB) |
| `upload_media_from_path` | Upload from file path (max 10MB) |
### Schema & Relations
| Tool | Description |
|------|-------------|
| `get_content_type_schema` | Get content type schema |
| `connect_relation` | Connect related entries |
| `disconnect_relation` | Disconnect related entries |
| `list_components` | List all components |
| `get_component_schema` | Get component schema |
### Dev Mode Only
| Tool | Description |
|------|-------------|
| `create_content_type` | Create a new content type |
| `update_content_type` | Update content type attributes |
| `delete_content_type` | Delete a content type |
| `create_component` | Create a new component |
| `update_component` | Update a component |
## Secure Document API
Private document upload with ABAC policy enforcement and RAG pipeline.
| Method | Path | Description |
|--------|------|-------------|
| POST | `/api/secure-documents/documents` | Upload document (multipart) |
| GET | `/api/secure-documents/documents` | List documents (ABAC-filtered) |
| GET | `/api/secure-documents/documents/:id` | Get document metadata |
| PUT | `/api/secure-documents/documents/:id` | Update metadata/policy |
| DELETE | `/api/secure-documents/documents/:id` | Delete document + S3 + vectors |
| GET | `/api/secure-documents/documents/:id/download` | Get presigned download URL |
| POST | `/api/secure-documents/documents/:id/reindex` | Trigger re-indexing |
| GET | `/api/secure-documents/documents/:id/status` | Get indexing status |
Upload flow: file → S3 storage → text extraction (PDF/DOCX/text) → sliding window chunking → embedding generation → pgvector storage with ABAC metadata per chunk.
## Secure Search API
Semantic vector search with ABAC filtering and optional RAG answer generation.
| Method | Path | Description |
|--------|------|-------------|
| POST | `/api/secure-search/search` | Semantic vector search |
| POST | `/api/secure-search/search/rag` | RAG answer generation |
| GET | `/api/secure-search/search/facets` | Faceted counts (ABAC-filtered) |
## ABAC Policy Model
Documents carry a JSON `policy` field controlling access:
```json
{
"allowed_departments": ["engineering", "security"],
"min_clearance": 2,
"classification": "confidential",
"excluded_employmentTypes": ["contractor"]
}
```
Classification hierarchy: public (0) → internal (1) → confidential (2) → restricted (3). Double enforcement: SQL pre-filter on pgvector + server-side re-check per document.
## Authentication & Ownership
All three plugins share the same auth patterns:
| Mode | Config | Use Case |
|------|--------|----------|
| External JWT | `auth: 'jwt'` | Production with IdP (JWKS verification) |
| Strapi admin | `auth: 'admin'` | Direct admin token access |
| No auth | `auth: false` | Development only |
The MCP plugin maps each client to a real Strapi admin user — `createdBy`/`updatedBy` tracks the actual user, enabling native "own entries" restriction.
See [docs/authentication-flow.md](docs/authentication-flow.md) for details.
## Architecture
See [docs/architecture.md](docs/architecture.md) for the full design and [docs/secure-plugins-plan.md](docs/secure-plugins-plan.md) for the secure plugins implementation plan.
Key decisions:
- **Streamable HTTP** transport (MCP spec 2025-03-26)
- **Server-per-session** (MCP SDK requires one transport per server)
- **MCP client = Strapi user** (no shared service account)
- **PostgreSQL + pgvector** for vector search (same DB as Strapi)
- **ABAC-first** authorization with double enforcement
- **Dual embedding providers**: Ollama (dev) / AWS Bedrock (prod)
- **S3/MinIO storage** with presigned download URLs
## Docker
```bash
# Dev: Strapi + PostgreSQL/pgvector + MinIO
docker compose up -d
# Strapi admin panel: http://localhost:1337/admin
# MCP endpoint: http://localhost:1337/api/mcp-server/mcp
# MinIO console: http://localhost:9001
# View logs
docker compose logs -f strapi
# Stop
docker compose down
```
### Dev Services (docker-compose.yml)
- **strapi** -- Strapi 5 + 3 plugins (port 1337)
- **postgres-db** -- PostgreSQL 16 with pgvector extension
- **minio** -- S3-compatible object storage (ports 9000/9001)
- **minio-init** -- Creates `secure-documents` bucket on startup
### Production (docker-compose.prod.yml overlay)
- **postgres-db** -- pgvector/pgvector:pg16
- **redis-cache** -- Redis 7 (session store for multi-instance MCP)
- AWS Bedrock for embeddings/RAG, real S3 for storage
## Environment Variables
### Strapi App
`DATABASE_CLIENT`, `APP_KEYS`, `ADMIN_JWT_SECRET`, `API_TOKEN_SALT`, `TRANSFER_TOKEN_SALT`, `JWT_SECRET`
### MCP Plugin
`MCP_AUTH_MODE`, `JWT_ISSUER`, `JWT_AUDIENCE`, `JWT_JWKS_URI`, `MCP_SECRET_KEY`
### Secure Documents
`S3_BUCKET`, `S3_REGION`, `S3_ENDPOINT`, `S3_FORCE_PATH_STYLE`, `S3_PUBLIC_ENDPOINT`, `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `EMBEDDING_PROVIDER`, `EMBEDDING_MODEL`, `EMBEDDING_DIMENSIONS`, `OLLAMA_ENDPOINT`
### Secure Search
`RAG_ENABLED`, `RAG_PROVIDER`, `RAG_MODEL`, `AWS_REGION`
### Standalone Server
`STRAPI_URL`, `STRAPI_ADMIN_EMAIL`, `STRAPI_ADMIN_PASSWORD`, `STRAPI_API_TOKEN`, `STRAPI_DEV_MODE`, `LOG_LEVEL`, `STRAPI_CACHE_TTL`
## Testing
```bash
# Run all 11 integration test suites
npm run test:integration
# Run specific suites
node tests/run-all.js 09 10 11 # Secure plugin tests only
# List available suites
npm run test:integration:list
```
| Suite | Description |
|-------|-------------|
| 01-08 | MCP plugin: CRUD, publish, search, auth, roles, media, JWT |
| 09 | Secure document CRUD (upload, list, get, update, delete, download) |
| 10 | ABAC enforcement across user profiles (classification, department, contractor exclusion) |
| 11 | Secure search & RAG (semantic search, facets, RAG answer generation) |
## Development
```bash
# Standalone server
cd strapi-mcp-server
npm install
npm run watch # Auto-rebuild on changes
npm run inspector # MCP Inspector for debugging
# Plugin
cd strapi-plugins
npm install
npm run watch # Auto-rebuild plugin
```
## License
MIT