# io.github.PaulRichez/devkit-for-strapi-mcp (npm · devkit-for-strapi-mcp)

Accurate Strapi project facts (UIDs, schemas, references) for AI agents — no more guessed UIDs.

- Trust score: 64/100 (medium)
- Change this week: −5
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-04

## Components

- npm · `devkit-for-strapi-mcp`: 64/100 (this document), [markdown](https://verifymcp.io/servers/paulrichez-devkit-for-strapi-mcp/devkit-for-strapi-mcp.md), [page](https://verifymcp.io/servers/paulrichez-devkit-for-strapi-mcp/devkit-for-strapi-mcp)

## Channel facts

- Registry: `npm`
- Package: `devkit-for-strapi-mcp`
- Version: `0.1.3`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-04.

- **Supply Chain Security**: 100/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - No install/post-install scripts declared.
  - No production dependencies, so there is no dependency health to assess.
- **Provenance & Transparency**: 6/100
  - Repository check failed: no source repository is declared.
  - Provenance check failed: no build-provenance attestation is published.
  - License check failed: the license (MIT AND LicenseRef-PolyForm-Shield-1.0.0) isn't a recognized OSI-approved license.
  - Actively maintained (last published 16 days ago).
  - Security-disclosure policy not yet verified: we couldn't inspect the source repository.
- **Schema Quality & AI Usability**: 69/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 4357 tokens (~145/item across 30 items; 30 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 97/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 90% of tool parameters carry a description.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add paulrichez-devkit-for-strapi-mcp -- npx -y devkit-for-strapi-mcp
```

### Codex

```bash
codex mcp add paulrichez-devkit-for-strapi-mcp -- npx -y devkit-for-strapi-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "paulrichez-devkit-for-strapi-mcp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "devkit-for-strapi-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add paulrichez-devkit-for-strapi-mcp --command npx --arg -y --arg devkit-for-strapi-mcp
```

### Hermes

```yaml
mcp_servers:
  paulrichez-devkit-for-strapi-mcp:
    command: "npx"
    args: ["-y", "devkit-for-strapi-mcp"]
```

### Other

```json
{
  "mcpServers": {
    "paulrichez-devkit-for-strapi-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "devkit-for-strapi-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-04 (score 64, +1)

No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-08-02 (score 63, +18)

- [security improvement] Malware scan: unverified → pass
- [functional improvement] Stability: unverified → 0.20

### 2026-07-31 (score 45, −24)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-27 (score 69, +32)

- [functional improvement] Tool coverage: unverified → 100
- [functional] First check of Schema quality: fail
- [functional] First check of Tool coverage: 90
- [functional] First check of Schema quality: excellent
- [functional] First check of Schema quality: fail

### 2026-07-26 (score 37)

First indexed and scored.

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

## MCP tools (30)

### `list_projects` (~35 tokens)

List Strapi projects

List the Strapi projects discovered in the workspace (name, root, version, counts). Call this first in a multi-project workspace.

### `add_project` (~114 tokens)

Register a Strapi project by path

Locate and index a Strapi project on demand from an ABSOLUTE path — either the project root, or any file/folder inside it (the server walks up to the project root; a folder is also scanned downward for monorepos). Use this when a tool returns `noProject`. Idempotent. Returns the projects now known (use a name/root with `from`/`project`).

Input parameters:

- `path` (string, required): Absolute path to the Strapi project root, or to any file/folder inside it.

### `refresh` (~119 tokens)

Re-index projects from disk (pick up external changes)

Re-scan every discovered Strapi project from disk and rebuild the index. The server does not watch the filesystem: files created, edited, or deleted OUTSIDE this MCP session (a manual edit, another tool, git checkout/pull, a branch switch) are invisible to every other tool until this runs — call it before find_references/list_broken_refs/list_unused/coverage whenever files may have changed outside apply_edits/apply_rename, or those tools reason over a stale snapshot and can wrongly report 0 references. Cheap to call defensively.

### `list_content_types` (~99 tokens)

List content-types

List the real content-type UIDs (e.g. api::article.article) of a Strapi project. Use these exact UIDs — do not invent them.

Input parameters:

- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.

### `list_components` (~85 tokens)

List components

List the real component UIDs (e.g. shared.seo) of a Strapi project.

Input parameters:

- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.

### `list_artifacts` (~100 tokens)

List services/controllers/policies/middlewares

List the real refs of a project's services, controllers, policies and middlewares (optionally one kind). Use the exact refs returned.

Input parameters:

- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `kind` (string)
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.

### `get_schema` (~131 tokens)

Get a content-type / component schema

Return the real attributes (fields, relations, components) of a content-type or component UID. Use this instead of guessing field names. Pass `uids` to fetch several at once.

Input parameters:

- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.
- `uid` (string): A content-type or component UID.
- `uids` (array): Several UIDs to fetch in one call.

### `resolve` (~100 tokens)

Resolve a reference to its file(s)

Resolve a Strapi reference (UID / service / controller / policy / middleware / route handler) to its defining file(s), tagged by kind.

Input parameters:

- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.
- `ref` (string, required)

### `validate_reference` (~115 tokens)

Validate a Strapi reference

Check whether a Strapi reference is real in the project. Returns valid | unknown (+ didYouMean) | external (a plugin not in the workspace — cannot be verified). Call this before writing a magic string.

Input parameters:

- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.
- `ref` (string, required)

### `find_references` (~215 tokens)

Find references to a Strapi entity

List every call-site that references a UID / service / controller / handler (or `ref#method`) across the project. Returns the total first, then a page of references. Compact by default (`path:line:col [via]  snippet`, 1-based) — pass `compact: false` for full objects. Pass `refs` to query several at once.

Input parameters:

- `compact` (boolean): Compact one-line-per-hit output (default true). false → full objects.
- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `limit` (integer): Max references returned per ref (default 50).
- `offset` (integer): Skip this many references (pagination).
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.
- `ref` (string)
- `refs` (array): Several refs to query in one call (batch).

### `list_routes` (~116 tokens)

List HTTP routes

List a project's HTTP route table (method, path, handler, policies, middlewares) — explicit routes plus the auto-CRUD routes synthesized from createCoreRouter. Statically parsed (no Strapi boot); framework/plugin-injected routes are not included.

Input parameters:

- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.

### `list_unused` (~180 tokens)

Find unused Strapi entities/methods

List definitions with 0 Strapi references — service/controller methods never called via strapi.service()/route handlers, plus unused content-types, components, services, policies and middlewares. Static: counts Strapi refs only, so a method called **directly in TS** still appears — verify before deleting. Use `file` for one file (else the whole app), `kinds` to narrow.

Input parameters:

- `file` (string): Restrict to one file; omit for the whole app.
- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `kinds` (array): Restrict to certain kinds (default: all).
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.

### `coverage` (~63 tokens)

List indexed call forms

List the Strapi call forms the engine indexes (with a `via` tag + example) and the notable ones it does NOT index yet (`indexed: false`). Use this to know whether find_references/list_unused can be trusted for a given pattern, instead of assuming completeness.

### `list_broken_refs` (~118 tokens)

Find references that point at nothing

List magic strings that resolve to no real entity — the inverse of list_unused, and the safety net after a move/rename (target: 0). Skips unverifiable external-plugin refs. Use after apply_edits to confirm nothing was left dangling.

Input parameters:

- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.

### `find_relation_usages` (~168 tokens)

Find relation-field usages

Find where a content-type's relation fields are used by name in queries (populate/filters). Pass `field` for one relation, omit it for all. Indispensable before retargeting or removing a relation. Only real relation fields are matched (top-level populate/filters; nested populate trees not yet — see coverage).

Input parameters:

- `field` (string): A relation field name; omit for all relations.
- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.
- `uid` (string, required): A content-type UID, e.g. api::article.article

### `list_refs` (~137 tokens)

List refs by glob

List entity refs matching a glob — e.g. `plugin::billing.*` for a plugin's whole surface, `api::*` for all APIs, `*` for everything. Only `*` is special. Each result carries the kinds it resolves to.

Input parameters:

- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `pattern` (string, required): Glob, e.g. plugin::billing.* or api::*
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.

### `dependencies` (~128 tokens)

What a ref uses (outgoing edges)

List the refs that `ref` depends on — relations in its schema, services/controllers it calls, etc. Pass `transitive: true` to follow the chain. Half of the cut-analysis for modularization.

Input parameters:

- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.
- `ref` (string, required)
- `transitive` (boolean): Follow dependencies recursively (default false).

### `dependents` (~137 tokens)

What uses a ref (incoming edges)

List the refs that depend on `ref` — what would break if it moved or changed. Pass `transitive: true` to follow the chain. The other half of cut-analysis: which edges become cross-namespace if you extract a set.

Input parameters:

- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.
- `ref` (string, required)
- `transitive` (boolean): Follow dependents recursively (default false).

### `plan_rename_method` (~186 tokens)

Plan a service/controller method rename (dry-run)

Compute the exact edits to rename a service/controller METHOD — its declaration, every `strapi.service(...).method()` call-site, and (for controllers) the action segment of route handlers. Dry-run: returns a plan (text edits + `planId`), writes nothing. Review, then apply with `apply_edits` (pass the `planId`).

Input parameters:

- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `method` (string, required): The current method name, e.g. notify
- `newName` (string, required)
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.
- `ref` (string, required): The owning service/controller ref, e.g. api::page.notifier

### `plan_rename_entity` (~171 tokens)

Plan an entity rename (dry-run)

Compute the exact edits to rename a content-type / service / controller / policy / middleware / component: every magic-string call-site and route handler, plus the file/folder renames. Dry-run: returns a plan (edits + `planId`), writes nothing. Review, then apply with `apply_edits` (pass the `planId`).

Input parameters:

- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `newName` (string, required)
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.
- `ref` (string, required): The entity UID/ref, e.g. api::product.product or shared.seo

### `plan_move` (~231 tokens)

Plan moving an artifact or content-type to another namespace (dry-run)

Compute the edits to move to another namespace (e.g. plugin::dst): a service/controller/policy/middleware, OR a content-type (its whole resource — content-type + service + controller + routes move together, relation `target`s repointed). Rewrites every call-site (full-UID forms, `strapi.plugin(...)` chains, route handlers) and relocates the files. Dry-run: returns a plan (+ `planId`, + `warnings`, incl. plugin content-type registration to verify), writes nothing. Apply with `apply_edits`. Refused all-or-nothing if unsafe.

Input parameters:

- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.
- `ref` (string, required): An artifact ref (plugin::src.helper) or a content-type UID (api::x.x)
- `toNamespace` (string, required): Destination namespace: plugin::dst or api::foo

### `plan_move_entities` (~171 tokens)

Plan moving a set of artifacts/content-types to one namespace (dry-run)

Like plan_move but for several refs at once (artifacts and/or content-types), to the same destination — one coherent plan so the cluster's internal refs stay consistent in a single pass. Dry-run (+ `planId`, + `warnings`); apply with `apply_edits`. Refused all-or-nothing on any unsafe spec.

Input parameters:

- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.
- `refs` (array, required): The artifact/content-type refs to move together.
- `toNamespace` (string, required): Destination namespace for all of them: plugin::dst or api::foo

### `create_plugin` (~159 tokens)

Scaffold a new local plugin (dry-run)

Plan the files for a new local Strapi plugin (`src/plugins/<name>/package.json` + `strapi-server.js`, and `config/plugins` if missing). Dry-run (+ `planId`, + `warnings` to verify the server entry for your Strapi version); apply with `apply_edits`. Use extract_to_plugin to scaffold AND move artifacts in one plan.

Input parameters:

- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `name` (string, required): Plugin name, kebab-case, e.g. billing.
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.

### `extract_to_plugin` (~166 tokens)

Extract artifacts into a new plugin (dry-run)

Scaffold a new local plugin AND move a set of services/controllers/policies/middlewares into it, in ONE plan: plugin files created, every call-site rewritten, files relocated. Dry-run (+ `planId`, + `warnings`); apply with `apply_edits`. Refused all-or-nothing if scaffold or move is unsafe. The one-pass extraction primitive.

Input parameters:

- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `name` (string, required): New plugin name, kebab-case.
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.
- `refs` (array, required): Artifact refs to extract together.

### `plan_change_relation` (~201 tokens)

Plan retargeting a relation field (dry-run)

Change the `target` of a content-type's relation field to another content-type, editing schema.json precisely. Dry-run: returns a plan (+ `planId`), writes nothing; apply with `apply_edits`. Refused if the field isn't a relation or the new target is unknown (external plugin → warning); a bidirectional relation warns about its now-orphaned inverse field.

Input parameters:

- `field` (string, required): The relation attribute name, e.g. author
- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `newTarget` (string, required): The new target content-type UID, e.g. api::user.user
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.
- `uid` (string, required): The content-type UID, e.g. api::article.article

### `change_relation` (~207 tokens)

[deprecated → plan_change_relation]

Deprecated alias of plan_change_relation. Change the `target` of a content-type's relation field to another content-type, editing schema.json precisely. Dry-run: returns a plan (+ `planId`), writes nothing; apply with `apply_edits`. Refused if the field isn't a relation or the new target is unknown (external plugin → warning); a bidirectional relation warns about its now-orphaned inverse field.

Input parameters:

- `field` (string, required): The relation attribute name, e.g. author
- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `newTarget` (string, required): The new target content-type UID, e.g. api::user.user
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.
- `uid` (string, required): The content-type UID, e.g. api::article.article

### `plan_rename_attribute` (~198 tokens)

Plan a content-type attribute rename — schema + relation query-keys only (dry-run)

Rename an attribute in schema.json, plus (for a RELATION) its populate/filters usages by name via the relation-field index. ⚠️ Does NOT rewrite object/data-access usages (`entity.field`, `data: { field }`, destructuring, populated results) — those are untyped property access we cannot rewrite without guessing; the result always warns to review them by hand. NOT a complete field rename. Dry-run (+ `planId`); apply with `apply_edits`.

Input parameters:

- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `newName` (string, required): New attribute name.
- `oldName` (string, required): Current attribute name.
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.
- `uid` (string, required): The content-type UID.

### `rename_attribute` (~204 tokens)

[deprecated → plan_rename_attribute]

Deprecated alias of plan_rename_attribute. Rename an attribute in schema.json, plus (for a RELATION) its populate/filters usages by name via the relation-field index. ⚠️ Does NOT rewrite object/data-access usages (`entity.field`, `data: { field }`, destructuring, populated results) — those are untyped property access we cannot rewrite without guessing; the result always warns to review them by hand. NOT a complete field rename. Dry-run (+ `planId`); apply with `apply_edits`.

Input parameters:

- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `newName` (string, required): New attribute name.
- `oldName` (string, required): Current attribute name.
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.
- `uid` (string, required): The content-type UID.

### `apply_edits` (~135 tokens)

Apply a reviewed plan to disk (contractual)

Apply a plan returned by plan_rename_* (and future move/extract plans). Pass `planId` to apply exactly the reviewed plan, or `plan` (a full plan object) to apply one you hold. The plan is verified against disk first — if any touched file changed since it was computed, nothing is written (the changed paths are returned). ⚠️ Modifies files on disk.

Input parameters:

- `plan` (object): A full, well-formed plan object (planId + fingerprints), if not using planId.
- `planId` (string): The planId from a plan_* result (preferred).

### `apply_rename` (~168 tokens)

Rename a Strapi entity or method (writes files)

Convenience: plan + apply a rename in one call. An entity (omit `method`) or a service/controller method (pass `method`). Rewrites every call-site + route handler and renames the files/folders. ⚠️ Modifies files on disk. Prefer plan_rename_* then apply_edits when you want to review first.

Input parameters:

- `from` (string): A path inside the target project (e.g. the file you are editing). Disambiguates a multi-project workspace.
- `method` (string): Pass to rename a method; omit to rename the entity.
- `newName` (string, required)
- `project` (string): A project name (its folder) or root path. Use when you have no file path in hand.
- `ref` (string, required)

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/paulrichez-devkit-for-strapi-mcp/devkit-for-strapi-mcp#diagnostics

## Score history

- 2026-08-04: 64
- 2026-08-03: 63
- 2026-08-02: 63
- 2026-08-01: 45
- 2026-07-31: 45
- 2026-07-30: 69
- 2026-07-29: 69
- 2026-07-28: 69
- 2026-07-27: 69
- 2026-07-26: 37

## Links

- npm package: https://www.npmjs.com/package/devkit-for-strapi-mcp
- Socket report: https://socket.dev/npm/package/devkit-for-strapi-mcp
- Website: https://devkit-for-strapi.paulrichez.fr/mcp/
- Changelog RSS feed: https://verifymcp.io/servers/paulrichez-devkit-for-strapi-mcp/devkit-for-strapi-mcp/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/paulrichez-devkit-for-strapi-mcp/devkit-for-strapi-mcp/changelog.json
- HTML version of this page: https://verifymcp.io/servers/paulrichez-devkit-for-strapi-mcp/devkit-for-strapi-mcp
