Eonevolve Learning
Unity and DevelopmentUnity and codeIntermediate~7 min

Design Narrow MCP Read and Write Tools

Snapshot

~85 sec

A useful MCP tool performs one named operation with typed inputs, a bounded target, and structured output. Keep reads separate from writes. Validate arguments before execution, cap result size, and make mutating tools expose the exact proposed change before approval.

You will learn

  • Turn a broad project tool into one read contract and one write contract.
  • Bound targets and results with typed fields, limits, and validation.
  • Place dry-run, approval, deterministic checks, and post-change evidence around mutation.

Target outcome

You can design a narrow MCP read or write tool whose responsibility, authority, and evidence are inspectable.

Visual walkthrough

Visual walkthrough

~7 min

  1. Five properties of a narrow tool

    • One operation

      The name states one action, such as read_console or rename_scene_object.

    • Typed input

      Fields declare valid values, required identifiers, and bounded limits.

    • Bounded target

      A stable scene path or object identifier replaces vague instructions like fix the project.

    • Structured output

      The result separates items, status, truncation, and evidence instead of returning an unshaped text dump.

    • Read/write boundary

      Inspection cannot mutate; mutation is separately named, reviewed, approved, and verified.

  2. One broad tool versus two inspectable contracts

    ApproachResponsibilityTarget and result boundsAuthorityEvidence
    do_project_taskOne tool can inspect, edit, save, and return an open-ended response.The caller cannot tell which operation will happen from the tool name.The target may expand from one invented object to unrelated scenes and assets.Read and write permissions collapse into one ambiguous approval.A prose success message may hide what changed or what was skipped.
    read_consoleRead only filtered error or warning entries with a limit and cursor.The operation reads console entries and cannot edit the project.Severity, text filter, limit, and pagination constrain the response.Read-only policy can allow this tool without granting a scene write.Stable entry IDs and truncation state show what the result covers.
    rename_scene_objectRename one invented object identified by an exact scene path.The operation changes one name and does not save unrelated assets.Scene, object ID, expected current name, and proposed name are required.Dry-run output is reviewed before a separate write approval.The result returns before and after names plus the exact changed object ID.
  3. Keep read, write, and proof on distinct layers

    The smallest useful surface starts with inspection. A proposed mutation crosses explicit validation and approval before it reaches the project, then returns post-change evidence.

    Read layer

    1. Inspect exact target

      Read the invented object ID, current name, and owning scene.

    2. Return dry-run

      Show the one intended rename and declare that no write has occurred.

    Write layer

    1. Validate inputs

      Reject a missing object, stale expected name, invalid new name, or target outside the allowed scene.

    2. Approve exact call

      Review tool name, target ID, before value, after value, and verification plan.

    3. Apply one mutation

      Rename only the approved object; do not save or edit unrelated content.

    Proof layer

    1. Return structured proof

      Read the object again and report changed ID, before, after, and check status.

    • Inspect exact targetReturn dry-rundescribes
    • Return dry-runValidate inputsif requested
    • Validate inputsApprove exact callthen review
    • Approve exact callApply one mutationpermits
    • Apply one mutationReturn structured proofmust prove
    The smallest useful surface starts with inspection. A proposed mutation crosses explicit validation and approval before it reaches the project, then returns post-change evidence.

    Reading order

    1. Inspect exact target

      Read the invented object ID, current name, and owning scene.

    2. Return dry-run

      Show the one intended rename and declare that no write has occurred.

    3. Validate inputs

      Reject a missing object, stale expected name, invalid new name, or target outside the allowed scene.

    4. Approve exact call

      Review tool name, target ID, before value, after value, and verification plan.

    5. Apply one mutation

      Rename only the approved object; do not save or edit unrelated content.

    6. Return structured proof

      Read the object again and report changed ID, before, after, and check status.

    Connection explanations

    1. Inspect exact target → Return dry-run (describes)

      A dry-run is credible only when it is based on the current exact target.

    2. Return dry-run → Validate inputs (if requested)

      The write path receives explicit values rather than reinterpreting the original intent.

    3. Validate inputs → Approve exact call (then review)

      Schema and target validation remove invalid calls before a person considers authority.

    4. Approve exact call → Apply one mutation (permits)

      Approval applies to the reviewed tool and arguments, not to every future write.

    5. Apply one mutation → Return structured proof (must prove)

      The tool must return evidence from the post-change project state, not only claim success.

  4. Make the read contract visible

    Conceptual MCP tool contract. The exact schema representation depends on the server implementation, but the responsibility and bounds should remain explicit.

    Languagejson
    {
      "name": "read_console",
      "description": "Read filtered console entries without changing the project.",
      "input": {
        "severity": "error | warning",
        "contains": "optional string",
        "limit": "integer, 1..50",
        "cursor": "optional opaque string"
      },
      "output": {
        "items": [{ "id": "string", "severity": "string", "message": "string" }],
        "nextCursor": "string | null",
        "truncated": "boolean"
      }
    }

    Code annotations

    1. Lines 2-3

      One honest operation

      The name and description say this is a console read and that it does not change the project.

      Effect: A client can distinguish it from every mutating capability before use.

    2. Lines 4-9

      Bound the query

      Enumerated severity, optional text filter, finite limit, and opaque cursor constrain input.

      Effect: The server can reject invalid requests before reading project state.

    3. Lines 10-14

      Report coverage

      Items, next cursor, and truncation state tell the caller what evidence was returned.

      Effect: The caller can request more detail deliberately rather than assume the first page was complete.

  5. Split a broad tool

    An invented manage_scene tool can list objects, rename any match, delete missing-reference objects, save the scene, and return a paragraph. What is the first redesign?

    Expected reasoning

    Split inspection from mutation. Start with bounded read tools, such as list_scene_objects(scene, parentId, limit, cursor) and inspect_object(id). Give each write one operation, such as rename_scene_object(id, expectedName, newName, dryRun). Keep deletion separate or unavailable until exact-target validation, dependency preview, explicit approval, deterministic checks, and recovery evidence exist. Return structured fields rather than a success paragraph.

Go deeper