Docs › Slima MCP › Structured-file protections: how to read a refusal

Structured-file protections: how to read a refusal

Last updated September 9, 2026 · 6 min read

In one line: how to read an MCP refusal — which ones mean "use a different tool", which mean "this needs a plan", and which mean "never".

What this solves

Refusals all look like walls, and they are not. Slima's MCP errors carry deliberately different codes because the right next step is completely different: sometimes it is another tool, sometimes it is asking the author to do it in the app, sometimes it is a subscription. An AI that cannot tell them apart does the worst available thing — retries the identical call.

Why structured files are guarded at all

When the in-app AI Coach aims a whole-file write at a .beats file, the front end blocks it, and the cost is one wasted call.

Over MCP the same write would succeed. A .beats file holds acts, beats and the chapter cards the author dragged onto it; the AI saw part of that and sent back the whole document. The file still opens, a piece of the author's work is gone, and nothing errored.

So the gate lives on the server, not only in a tool description. A description is advice to a model; the server's refusal is the guarantee.

Four refusals you will meet

Code Status What it means What to do next
AI_READONLY_FILE_TYPE 403 This type is not one an AI may write whole For the five structured types, the message names the update_* tool to use instead. For .character / .location / .json / .yaml there is no alternative route: read it, then describe the change you recommend
SUBSCRIPTION_REQUIRED 403 This capability belongs to the subscription plans Reading is not restricted. Read the file, say clearly what you would change, and the author can make the change or subscribe and let the AI make it
INVALID_PATH 400 An older Script Studio book, written outside the planning tree Write under .script_studio/planning/ instead, or hand it to the author
FOLDER_NOT_EMPTY 422 The folder you asked to delete still has things in it If you really mean the whole subtree, send it again with recursive: true. Not a permission problem — a "what you asked for is bigger than what you said" problem

The two 403s use different codes on purpose, because one is "an upgrade unlocks this" and the other is "nothing unlocks this". Under a single code an AI cannot tell whether to mention subscribing or to stop asking and switch to describing the change in words.

The refusal is the answer

Slima's MCP errors are written so that an AI can fix the problem from the message alone rather than guessing:

  • An id that does not exist → the message lists the real ids
  • A place tier that does not exist → the message lists the real tiers
  • A field from operation B sent to operation A → the message says which operation owns it
  • A wrong guide slug → the reply carries the full list of guides
  • An over-long intent → the message explains that it becomes the commit's name, so it has to be one line

Which makes the rule simple: read the error and do what it says. One failure costs a round trip. A second guess can cost the author's data.

What this gate does not do

  • It does not make the file read-only. The author edits it freely in the app. This only stops whole-file writes from outside.
  • It does not restrict reading. All five structured types are readable, on any account.
  • It does not block creation. create_file works on those extensions; the content is ignored and the server writes an empty skeleton.
  • It is not a review step. Changes arriving through MCP skip the dashed-card review, but they are commits — fully visible in version history and fully revertible.

Deleting follows the same rule as writing

Deleting a .map and editing a .map are gated identically: both belong to the subscription plans. One rule is easier to remember, and it rules out a genuine absurdity — a free account's agent deleting a file it could neither create nor change.

Older Script Studio books

If you still have one, it follows a separate rule set based on paths: the only writable area is the .script_studio/planning/ tree, while series.json, *.character, *.scene, *.storyline, *.note and *.location are all read-only over MCP, as is the .script_studio/planning/.initialized marker.

That planning tree is where an AI's drafts belong: outlines, research notes, proposals. To change a scene itself, write the proposal there and let the author apply it in the app. For one book's exact rules, read the slima://books/{book_token}/schema resource — see Query book schema with the resource.

Related

Try it in Slima

Open the app and do this with your own book. Free to start, no credit card.

Open Slima
Was this helpful?