Lộ trình học›Claude API›Building with the Claude API Mở bản đồ

6.66 · Định nghĩa resources qua MCP

Bài viếtTrung cấp15 phút đọc

3 concepts MCP:

Sau bài này, bạn sẽ
  1. Hiểu MCP resources — read-only data exposed by server
  2. Static vs dynamic resources
  3. Use @mcp.resource decorator
  4. URI patterns cho resources

Mở đầu: Resources = data, not actions

  • Tools — actions (create, update, delete)
  • Prompts — instructions (templates)
  • Resources — data (read-only)

Resource = document, database record, API response. Client read, doesn't execute.

When resources vs tools?

ResourceTool
PurposeExpose dataPerform action
Side effectNone (read)May have
URIYes (unique identifier)No
Examplefile://report.pdf, db://users/123get_user(123), create_post()

Resource = GET. Tool = POST/PUT/DELETE (loose analogy).

Static resource

Fixed URI, content:

@mcp.resource("docs://report.pdf")
def get_report():
    return """This report describes Q3 performance..."""

Clients can read resource docs://report.pdf.

Dynamic resource (URI template)

URI with parameters:

@mcp.resource("docs://{doc_id}")
def get_doc(doc_id: str):
    if doc_id not in docs:
        raise ValueError(f"Doc {doc_id} not found")
    return docs[doc_id]

Client reads docs://report.pdf or docs://plan.md — same function.

Full example — documents

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("DocumentMCP")

docs = {
    "report.pdf": "Q4 report content...",
    "plan.md": "Project plan content...",
}


@mcp.resource("docs://all")
def list_all_docs() -> str:
    return "\n".join(docs.keys())


@mcp.resource("docs://{doc_id}")
def read_doc(doc_id: str) -> str:
    if doc_id not in docs:
        raise ValueError(f"Doc '{doc_id}' not found")
    return docs[doc_id]

Test via Inspector → Resources tab.

Client read resource

resources = await client.list_resources()

result = await client.read_resource("docs://report.pdf")
for content in result.contents:
    if content.type == "text":
        print(content.text)

Why resources matter

1. Auto-discovery

Client list all resources without prior knowledge. User browse data without remembering tool names.

2. Caching-friendly

Read-only + URI-identified → client can cache by URI.

3. Standard contract

Any client can read any resource từ any MCP server. Universal data access pattern.

4. Claude awareness

Claude thấy resources available, có thể reference: "Based on docs://report.pdf, the answer is..."

Resource types

Text

@mcp.resource("schema://users")
def get_schema() -> str:
    return """CREATE TABLE users (
        id INT PRIMARY KEY,
        name VARCHAR(100)
    )"""

JSON

import json

@mcp.resource("config://app")
def get_config() -> str:
    return json.dumps({"version": "1.0", "debug": False})

Binary (via URI)

@mcp.resource("image://logo")
def get_logo():
    with open("logo.png", "rb") as f:
        return f.read()  # binary content

MCP supports binary resources qua specific content type.

Resources + tools combo

Resources cho browsing, tools cho mutation:

@mcp.resource("docs://{doc_id}")
def get_doc(doc_id):
    return docs[doc_id]

@mcp.tool()
def edit_doc(doc_id: str, old: str, new: str):
    docs[doc_id] = docs[doc_id].replace(old, new)

Clean separation.

URI conventions

Good:

  • docs://report.pdf — clear scheme + identifier
  • users://alice — namespace
  • file:///home/jimmy/note.md — RFC 3986 format

Bad:

  • doc1 — no scheme
  • somedata — no structure

Use scheme that makes sense cho domain.

Anti-patterns

Resource with side effects

@mcp.resource("counter://next")
def counter():
    global count
    count += 1
    return str(count)  # MUTATING on read!

Resources MUST be read-only. Client caches, call multiple times → inconsistent.

Fix: Tool if action needed.

Expose entire database as resource

Too much data, tied to impl details.

Fix: Curated views. docs://all, docs://{id}, specific.

Mix text + binary without content type

Client parse fail.

Fix: Explicit MIME types.

Áp dụng ngay

Bài tập 1: Add resources (20 phút)

Add to server:

  • docs://list — list all doc IDs
  • docs://{id} — specific doc
  • docs://stats — count + total size

Test via Inspector.

Bài tập 2: Client list + read (15 phút)

Client enumerate resources, read one, print content.

Tóm tắt bài học

Những điều cốt lõi
  • Resources = read-only data với URI.
  • Static: fixed URI. Dynamic: URI template with params.
  • @mcp.resource("scheme://path") decorator.
  • Complement tools: resources for browse, tools for mutate.
  • Never mutate on resource read — contract.
Kiểm tra nhanh1 câu hỏi · chọn đáp án để xem giải thích
    Bạn đã hoàn thành bài này chưa?Tiến độ lưu trên trình duyệt của bạn.