본문으로 건너뛰기
L13.2

Tool and Resource Protocols

Goal

Distinguish callable tools from retrievable resources and apply different validation, permission, freshness, and caching rules to each boundary.

Separate actions from information​

A remote integration may expose things you can do and things you can read. Treating those as the same kind of object makes policy harder to reason about. A tool represents a callable capability. A resource represents data that can be identified and read. Both are remote inputs, but their risks and lifecycle are different.

Suppose a server exposes a tool called create_ticket and a resource containing the current incident handbook. Calling create_ticket can change external state, so the harness needs argument validation, authorization, possible approval, idempotency, and effect tracing. Reading the handbook is not the same side effect, but it still needs access checks, provenance, freshness, and content handling.

A simplified local teaching record might look like this; these are not MCP wire objects:

{"tool":"create_ticket","side_effect":true}
{"resource":"incident_handbook","side_effect":false,"uri":"kb://incident/current"}

The MCP 2026-07-28 release includes list and read behavior with explicit cache hints for list results and resource reads. That does not mean every result should be cached forever. A client should interpret cache information together with user scope, sensitivity, and application policy.

Treat discovery as untrusted input​

Discovery creates another trust boundary. A server may describe tools or resources the client has never seen before. The local application should not convert every discovered capability directly into executable authority. It can filter names, validate schemas, map capabilities to local policy, and expose only an allowed subset to the model or controller.

Tool arguments need structural validation before execution. If a tool expects an order ID and amount, the client should reject missing or wrongly typed fields before reaching the side effect. A protocol schema helps communicate shape, but business constraints such as maximum refund amount remain local policy.

Preserve resource identity and typed errors​

Resources need identity and provenance. If two resources share similar text but come from different scopes, the client should preserve which URI or identifier produced each one. The same memory lesson from Level 12 applies: a convenient summary should not erase the source needed to make a later trust decision.

Errors should also remain typed. 'Unknown tool' is different from 'tool denied by local policy' and different again from 'remote server unavailable.' If the harness merges all three into a generic failure, retry and user messaging become unreliable.

Normalize without erasing differences​

A useful integration layer can therefore normalize remote protocol objects into local controller concepts without pretending they are identical. For example, a discovered tool can become a candidate action that must pass policy. A resource read can become an observation carrying source and freshness metadata.

Keeping these categories separate improves future changes. If a later protocol revision changes list caching, that should not silently alter side-effect approval. If a resource becomes stale, that should not change whether a tool name is syntactically valid.

Predict

A server advertises a new side-effecting tool during discovery. What is the safest local treatment?

Run the local Lab​

Run:

python3 labs/notebooks/level-13/l13-02-tools-resources.py

The Lab classifies tools and resources with different controls.

  1. Run it unchanged. Compare get_ticket, create_ticket, and incident_handbook. The read-only tool does not need approval/idempotency, while the side-effecting tool does.
  2. Find {"kind": "tool", "name": "get_ticket", "side_effect": False}. Before editing, predict which two tool-control fields should change if this one tool becomes side-effecting, and which resource fields should stay fixed.
  3. Change only "side_effect": False to "side_effect": True for get_ticket, then rerun.
  4. Confirm that needs_approval and needs_idempotency_key become True for that tool while the resource freshness/provenance rules are unchanged.

Loading lab…

Quick Check

1. Why distinguish tools from resources?
2. What should happen to a newly discovered remote tool?
3. Which concern is especially important for a resource read?

0 of 3 questions answered.

Explain it back​

Compare a create-ticket tool with an incident-handbook resource. List the controller checks that differ and the checks they still share.

Key Takeaways

  • Tools represent callable capabilities; resources represent retrievable data.
  • Discovery is not authorization.
  • Tool calls need argument and effect controls.
  • Resource reads need provenance, scope, freshness, and cache controls.
  • Typed failures make retry and diagnosis safer.

Next Lesson

Next, L13.3 — MCP Concepts: Servers, Clients, and Capabilities examines the version-pinned MCP boundary.

References

Lesson actions

Completion is stored locally on this device.

View progress