directus-safe-mcp
Provides tools for managing Directus collections and items, including schema discovery (overview and detail), reading items, creating items (single and batch), updating items (with verification and dry-run), deleting items (with confirmation), and running dry-run mutation plans, all with schema validation and security policies.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@directus-safe-mcplist first 5 articles with title and author from articles collection"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
directus-safe-mcp
Schema-aware, dry-run/verify-guarded Directus MCP sidecar.
Directus REST API'yi güvenli, schema-first ve LLM dostu bir MCP (Model Context Protocol) ara katmanıyla saran bağımsız Node.js / TypeScript servisi. Directus resmi remote MCP'deki items tool'undaki stringified-JSON serialization bug sınıfını (#26891 / PR #27005) kendi içinde çözer; ek olarak dry-run, verify, after-read doğrulaması, collection allowlist, system collection guard ve batch limit politikaları uygular.
Bu MCP Directus'un yerine geçmez. Directus API'yi güvenli ve LLM dostu bir ara katmanla kullanır. RBAC bypass etmez — token'ın sahip olduğu izinler neyse MCP de onu kullanır.
Bu MCP iş kuralı bilmez. Koleksiyon anlamları (örneğin "şu koleksiyon satın alma kaynağıdır", "bu alan şu vendor'a bağlıdır") MCP'nin değil, bağlanan ajan prompt'larının / skill'lerin / ai_prompts kayıtlarının sorumluluğundadır. MCP sadece: schema oku, veri oku, güvenli yaz, validate et, dry-run yap, verify yap, after-read yap.
Özellikler
MCP TypeScript SDK üzerinde
streamable-http(varsayılan, production) +stdio(local debug) transport. Legacy HTTP+SSE transport desteklenmez; Streamable HTTP kendi içinde gerektiğindetext/event-streamresponse kullanabilir (bu, SDK'nın resmi Streamable HTTP davranışıdır).Stateless Streamable HTTP —
sessionIdGenerator: undefinedile gerçek stateless mod. Her HTTP request için tazeMcpServer+ tazeStreamableHTTPServerTransportoluşturulur;mcp-session-idheader üretilmez. Bu sayedeinitializesonrasıtools/listtek HTTP bağlantısında çalışır.Endpoint path guard — sadece
MCP_ENDPOINT_PATH(default/mcp) MCP endpoint.GET /healthzliveness probe, diğer path'ler 404.Bearer auth gate —
MCP_REQUIRE_AUTH=true(default) ise her HTTP requestAuthorization: Bearer <MCP_AUTH_TOKEN>taşır. Constant-time compare. Stdio exempt (local subprocess).Origin / Host guard —
MCP_ALLOWED_ORIGINSveMCP_ALLOWED_HOSTSile DNS rebinding + CSRF koruması.Verify enforcement —
MUTATION_REQUIRE_VERIFY=true(default) ikendirectus_update_itemvedirectus_batch_update_itemsverify olmadan çalışmaz;directus_update_items_same_datatamamen reddedilir (per-key verify desteklemez).All-or-nothing batch apply —
directus_batch_update_itemsvedirectus_create_itemsapply (dry_run=false) sırasında önce preflight çalıştırır. Herhangi bir item validation/verify/dedupe hatası verirse tüm batch abort edilir, sıfır yazma yapılır.allow_partial_apply=trueile eski partial-success davranışına geri dönülebilir.Single-mode read query —
directus_read_itemartıklimit/page/offsetparametrelerini reddeder (tek kayıt endpoint'inde anlamsız; LLM karışıklığını gösterir).fields/deep/versionhala destekleniyor.Recursive JSON normalisation —
data,query,filter,deep,keys,headers,verify,dedupe,items,operationsalanları JSON string olarak gelirse otomatik parse.Schema-first validation — her yazma işleminde field set şemadan doğrulanır; unknown ve readonly field'lar Directus'a gitmeden reddedilir.
Read-before, verify, diff, after-read doğrulama zinciri update'lerde.
Dry-run default —
MUTATION_DRY_RUN_DEFAULT=trueile yazma işlemleri varsayılan olarak simulate edilir.Collection allowlist +
directus_*blocklist.Delete default kapalı —
DIRECTUS_ALLOW_DELETE=true+confirm="DELETE <collection>:<keys>"gerekli.Batch size limiti —
MUTATION_MAX_BATCH_SIZE.Filter operator whitelist — sadece spec'te listelenen operatorlere izin verilir.
Safe default fields —
fieldsverilmezse PK + ilk 10 scalar field döner;*wildcard default olarak reddedilir.Partial success reporting — batch işlemler per-item sonuç döner.
Audit log — her mutation girişimi loglanır.
Related MCP server: Strapi MCP Suite
Hızlı Başlangıç
1. Environment
.env.example'ı kopyalayıp doldurun:
cp .env.example .env
# .env içine:
# DIRECTUS_URL=https://your-directus.example.com
# DIRECTUS_TOKEN=replace-with-directus-static-token
# MCP_AUTH_TOKEN=<random 32+ byte string>2. Production (Docker, Streamable HTTP)
docker compose up --buildContainer 3333 portunda Streamable HTTP MCP sunar. Bearer token ile auth zorunludur (MCP_REQUIRE_AUTH=true default).
3. Local debug (Node, stdio)
npm install
npm run build
MCP_TRANSPORT=stdio node dist/index.jsStdio modu local subprocess olduğu için MCP_REQUIRE_AUTH yok sayılır — auth parent process'in sorumluluğundadır.
4. Local HTTP debug
MCP_TRANSPORT=streamable-http \
MCP_HTTP_PORT=3333 \
MCP_REQUIRE_AUTH=true \
MCP_AUTH_TOKEN=dev-token \
node dist/index.jsConfiguration (env)
Variable | Default | Açıklama |
| (zorunlu) | Directus instance URL'i |
| (zorunlu) | Directus access token (RBAC'ye tabi) |
|
|
|
|
| Streamable HTTP port |
|
| Network interface ( |
|
| MCP HTTP endpoint path. |
|
| HTTP transport'ta Bearer auth zorunlu mu |
| (zorunlu HTTP auth için) | Bearer token; constant-time compare |
| (boş = tümü) | Virgülle ayrılmış Origin allowlist (DNS rebinding koruması) |
| (boş = tümü) | Virgülle ayrılmış Host allowlist. Port-tolerant: |
| (boş = hepsi) | Virgülle ayrılmış allowlist |
|
| Yasaklı prefix'ler |
|
| Delete tool'larını açar |
|
| (rezerve) |
|
| dry-run default |
|
| Update'lerde verify zorunlu; |
|
| Batch limit |
|
| Read default limit |
|
| Read maksimum limit (clamp) |
|
|
|
|
| Schema cache TTL |
|
| Verify string compare modu |
|
| pino log level |
MCP Tool Listesi
11 tool register edilir (hepsi directus_ prefix'i ile):
Tool | Açıklama |
| Koleksiyon listesi + PK + field count |
| Bir veya birden fazla koleksiyonun tam şema detayı |
| Liste okuma (validate edilmiş query ile) |
| Tek item okuma |
| Tek item create (dedupe + dry-run destekli) |
| Batch create (serial, per-item result) |
| Tek item update (read-before → verify → diff → write → after-read) |
| Bulk PATCH /items/{collection} (aynı data, multi key) |
| Per-item different data update (serial PATCH) |
| Delete (default kapalı, confirm gerekli) |
| Çoklu operasyon planı (dry-run only) |
Tool input kuralları
data,items,keys,query,filter,deep,verify,dedupe,operationshem native JSON hem de<field>_jsonstring formunda kabul edilir. Wrapper otomatik parse eder.Update işlemlerinde
verifyfield'ları mevcut kayıtla eşleşmezseVERIFY_FAILEDhatası döner; yazma yapılmaz.Unknown field →
UNKNOWN_FIELDhatası (sessizce drop edilmez).Readonly / system audit field'lar (
user_created,date_created,user_updated,date_updated) →READONLY_FIELDhatası.Primary key update →
PRIMARY_KEY_UPDATE_DENIED.directus_*koleksiyonlarında mutation →SYSTEM_COLLECTION_DENIED.Filter operator whitelist dışı →
INVALID_FILTER_OPERATOR.Wildcard field default olarak reddedilir (
ALLOW_WILDCARD_FIELDS=false).
Hata formatı
{
"ok": false,
"error": {
"code": "UNKNOWN_FIELD",
"message": "Field 'bogus' does not exist in 'articles'",
"details": { "collection": "articles", "field": "bogus" }
}
}Hata kodları: CONFIG_ERROR, DIRECTUS_API_ERROR, COLLECTION_NOT_ALLOWED, SYSTEM_COLLECTION_DENIED, SCHEMA_NOT_FOUND, PRIMARY_KEY_NOT_FOUND, UNKNOWN_FIELD, READONLY_FIELD, PRIMARY_KEY_UPDATE_DENIED, REQUIRED_FIELD_MISSING, INVALID_QUERY, INVALID_FILTER_OPERATOR, VERIFY_FAILED, VERIFY_REQUIRED, ABORTED_BY_PREFLIGHT, DUPLICATE_FOUND, BATCH_LIMIT_EXCEEDED, DELETE_DISABLED, CONFIRMATION_REQUIRED, INVALID_JSON, INVALID_DATA_TYPE, DRY_RUN_REQUIRED, NOT_FOUND.
Client Bağlantı Örnekleri
1. Streamable HTTP (production, Docker/LibreChat)
LibreChat veya başka bir MCP client url alanını destekliyorsa:
mcpServers:
directus-safe:
url: http://directus-safe-mcp:3333/mcp
headers:
Authorization: "Bearer ${MCP_AUTH_TOKEN}"
timeout: 90000Container'ı MCP_TRANSPORT=streamable-http + MCP_AUTH_TOKEN=<token> ile çalıştırın.
2. stdio (local debug, Claude Desktop / Cursor)
mcpServers:
directus-safe:
command: docker
args:
- exec
- -i
- directus-safe-mcp
- node
- dist/index.js
env:
DIRECTUS_URL: "${DIRECTUS_URL}"
DIRECTUS_TOKEN: "${DIRECTUS_TOKEN}"
MCP_TRANSPORT: "stdio"
timeout: 90000
initTimeout: 60000Stdio modunda MCP_REQUIRE_AUTH yok sayılır (auth parent process'in sorumluluğunda).
Örnek Kullanım
1. Schema keşfi
{ "tool": "directus_schema_overview", "input": { "include_system": false } }
{ "tool": "directus_schema_detail", "input": { "collections": ["articles"] } }2. Okuma
{
"tool": "directus_read_items",
"input": {
"collection": "articles",
"query": {
"fields": ["id", "title", "slug"],
"filter": { "title": { "_icontains": "MCP" } },
"limit": 10
}
}
}3. Dry-run update (önerilen akış)
{
"tool": "directus_batch_update_items",
"input": {
"collection": "articles",
"items": [
{ "key": 1, "verify": { "title": "Intro to MCP" }, "data": { "status": "published" } },
{ "key": 2, "verify": { "title": "Directus Deep Dive" }, "data": { "status": "published" } }
],
"dry_run": true
}
}LLM sonucu kullanıcıya sunar; kullanıcı onaylayınca dry_run: false ile gerçek yazma yapılır.
4. Stringified JSON regression test
Eğer client data'yı string olarak gönderirse (Directus issue #26891):
{
"tool": "directus_update_item",
"input": {
"collection": "articles",
"key": 1,
"data": "{\"status\":\"published\"}",
"dry_run": true
}
}Sidecar bunu otomatik parse eder ve validation'a sokar.
Ajan Kullanım Talimatı
Bağlanan ajana şunu verin:
Directus verisi için resmi Directus remote MCP items tool yerine directus-safe-mcp tool'larını kullan.
Her görevde sıra:
1. directus_schema_detail ile ilgili koleksiyonları incele.
2. directus_read_items veya directus_read_item ile mevcut kayıtları oku.
3. Yazma işleminden önce dry_run=true kullan.
4. Kullanıcı/ana ajan onayı olmadan dry_run=false yapma.
5. Update'lerde verify kullan.
6. Unknown/readonly field hatasında tahminle devam etme.
7. Tool schema hatası alırsan aynı payload'u tekrar etme; data_json veya query_json kullan.İş kuralları (koleksiyon anlamları, vendor mapping'leri, domain-specific davranışlar) MCP'de değil, ajan prompt'larında / skill'lerde / ai_prompts kayıtlarında tutulur.
Test
npm test # vitest run
npm run test:watch # vitest watch
npm run typecheck # tsc --noEmit (strict)Test kapsamı:
normalize.test.ts— recursive JSON normalisation (regression testleri dahil)diff-verify.test.ts— diff ve verify davranışıpermissions.test.ts— collection / batch guard'larvalidators.test.ts— query validation + field validationmutations.test.ts— DirectusRestClient + items operations + relation type inferencemcp-tools.test.ts— fetch-mock ile MCP tool entegrasyon testleri (dry-run, verify fail, unknown field, batch partial success, stringified JSON regression)transports.test.ts— Streamable HTTP auth gate + transport alias parsing
Mimari Notlar
Stateless Streamable HTTP
StreamableHTTPServerTransport'a sessionIdGenerator: undefined veriyoruz. Bu, SDK'ya "session üretme, her request self-contained" der. Bu olmadan SDK her initialize'da mcp-session-id header üretir; client sonraki request'te bu header'ı göndermek zorundadır; ama server tarafında session map tutmadığımız için ikinci request "Server not initialized" 400 hatası alır. undefined ile bu davranış tamamen kapanır.
Her HTTP request için taze McpServer + taze transport oluşturulur. Tool'lar zaten stateless — Directus REST çağrısı yapıyorlar, server içinde kullanıcı state'i tutmaya gerek yok.
Bearer auth
MCP_REQUIRE_AUTH=true (default) ise her HTTP request Authorization: Bearer <MCP_AUTH_TOKEN> taşır. Token karşılaştırması constant-time yapılır (timing side-channel önlemi). Stdio transport exempt — auth parent process'in sorumluluğunda.
Config yükleme sırasında: eğer streamable-http + MCP_REQUIRE_AUTH=true + MCP_AUTH_TOKEN boşsa server refuse-to-start eder. Yanlışlıkla unauthenticated HTTP açmamak için.
Transaction garantisi yok (V1)
directus_batch_update_items tek tek PATCH /items/{collection}/{id} çağrıları yapar. Bir kayıt başarısız olursa diğerleri devam eder (fail_fast=false default). Partial success summary alanında raporlanır. All-or-nothing transaction gerekiyorsa Directus API extension içinde ItemsService + database transaction kullanmak gerekir (V2 planı).
Different-data batch update
Resmi Directus Items API "Update Multiple Items" endpoint'i (PATCH /items/{collection}) sadece aynı data'yı birden fazla key'e uygular ({ keys, data } body). Per-key farklı data için sidecar serial PATCH /items/{collection}/{id} kullanır.
RBAC
Sidecar Directus RBAC'yi bypass etmez. Token'ın sahip olduğu permission'lar geçerlidir. 403/401 hataları DIRECTUS_API_ERROR olarak sarılır.
Schema cache
/collections, /fields/{collection}, /relations çağrıları TTL cache'lenir (default 5 dakika). Schema değişikliği olursa servisi restart edin veya cache'i temizleyin.
Dosya Yapısı
directus-safe-mcp/
Dockerfile
docker-compose.yml
.env.example
package.json
tsconfig.json
vitest.config.ts
README.md
scripts/
smoke-stdio.mjs # stdio transport smoke test (initialize + tools/list)
smoke-http.mjs # Streamable HTTP smoke test (healthz, 404, 401, initialize, tools/list)
src/
index.ts # entry: load config → server factory → connect transport
config.ts # env loader + pino logger + transport alias parsing
mcp/
server.ts # ToolContext + buildServer
transports.ts # stdio / stateless streamable-http + Bearer auth
tools.ts # registerAllTools wrapper (normalise + error mapping)
directus/
client.ts # low-level items operations
rest.ts # DirectusRestClient + DirectusApiError
schema.ts # internal schema model + relation inference
schemaService.ts # /collections + /fields + /relations cache
query.ts # read query validation + filter operator whitelist
validators.ts # field validation (unknown, readonly, pk, required)
mutations.ts # read/create/update/delete orchestration
errors.ts # McpUserError + ErrorCode union
safety/
normalize.ts # recursive JSON normaliser
permissions.ts # collection / batch / delete guards
diff.ts # MutationDiff + deepEqual
dryRun.ts # dry-run result shape
verify.ts # verify record vs expectations
audit.ts # in-memory audit log
tools/
schemaOverview.ts
schemaDetail.ts
readItems.ts
readItem.ts
createItem.ts
createItems.ts
updateItem.ts
updateItemsSameData.ts
batchUpdateItems.ts
deleteItems.ts
dryRunMutation.ts
test/
helpers.ts # expectErrorCode test helper
normalize.test.ts
diff-verify.test.ts
permissions.test.ts
validators.test.ts
mutations.test.ts
mcp-tools.test.ts
transports.test.tsKabul Kriterleri
Tüm kabul kriterleri (spec §25) karşılanır:
✅ Docker Compose ile ayağa kalkar.
✅
stdioMCP transport çalışır (+streamable-httpproduction default).✅ 11 tool register edilir (spec minimum 8).
✅
datastringified JSON olarak gelirse native objeye çevrilir.✅
querystringified JSON olarak gelirse native objeye çevrilir.✅ Update dry-run before/after diff döndürür.
✅ Update apply sonrası after-read doğrulama yapar.
✅ Unknown field update Directus'a gitmeden reddedilir.
✅ Readonly field update Directus'a gitmeden reddedilir.
✅
directus_*collection mutation reddedilir.✅ Delete default kapalıdır.
✅ Batch update partial success raporlar.
✅ Tests pass (
npm test).✅ README içinde hem Streamable HTTP hem stdio bağlantı örneği vardır.
✅ Kod TypeScript strict modda compile olur.
✅ Streamable HTTP varsayılan transport, Bearer auth gate zorunlu.
✅ Şirket/koleksiyon sabiti yok — generic Directus ürünü.
✅ Stateless Streamable HTTP:
sessionIdGenerator: undefinedileinitialize→tools/listtek HTTP bağlantısında çalışır.✅ Endpoint path guard: sadece
/mcpMCP endpoint,/healthzliveness probe, diğerleri 404.✅ Origin/Host guard (DNS rebinding + CSRF).
✅
MUTATION_REQUIRE_VERIFY=trueiken update'lerde verify zorunlu,update_items_same_datareddedilir.✅ Smoke testler proje içinde (
scripts/smoke-stdio.mjs,scripts/smoke-http.mjs) — HTTP smoke testtools/list'i de doğrular.✅ Host allowlist port-tolerant:
mcp.example.comallowlist'imcp.example.com:3333Host header'ını da kabul eder.✅
batch_update_itemsvecreate_itemsapply sırasında all-or-nothing preflight (allow_partial_applydefault false). Abort durumunda sıfır yazma yapılır.✅
read_itemsingle-mode:limit/page/offsetreddedilir, default limit enjekte edilmez.
Kaynaklar
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/asukakimya/directus-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server