MCP resources

Tools are for actions the LLM triggers. But what about background data the app needs proactively? That is what resources are for. Let's add some to our Wikipedia server.

When should you use a resource instead of a tool? Two scenarios: 1. The app needs background context before the LLM makes decisions, like showing cached topics in a sidebar. 2. The data is read-only and changes rarely, like a list of available categories. The app reads resources proactively. The LLM reads tools reactively.

servers/wikipedia-server-full-stdio.py
python
@mcp.resource("wiki://topics")
def get_available_topics() -> str:
    """List all cached Wikipedia topics."""
    topics = []
    if os.path.exists(WIKI_DIR):
        for item in os.listdir(WIKI_DIR):
            info_path = os.path.join(WIKI_DIR, item, "articles_info.json")
            if os.path.isfile(info_path):
                topics.append(item)
    if not topics:
        return "No topics cached yet. Use search_articles to add some."
    return "Cached topics:\n" + "\n".join(f"- {t}" for t in topics)

Static URI resource: wiki://topics always returns the same endpoint.

servers/wikipedia-server-full-stdio.py
python
@mcp.resource("wiki://{topic}")
def get_topic_articles(topic: str) -> str:
    """Get cached articles for a specific topic."""
    topic_dir = os.path.join(WIKI_DIR, topic)
    info_path = os.path.join(topic_dir, "articles_info.json")
    if not os.path.isfile(info_path):
        return f"No articles cached for '{topic}'."
    with open(info_path) as f:
        articles = json.load(f)
    result = f"Articles for '{topic}':\n\n"
    for article in articles:
        result += f"Title: {article['title']}\n"
        result += f"URL: {article['url']}\n"
        result += f"Summary: {article.get('summary', 'N/A')}\n\n"
    return result

Templated URI resource: wiki://{topic} accepts a variable in the URI.

Client reading resources
python
# Discover available resources
resources = await session.list_resources()

# Read a static resource
topics = await session.read_resource("wiki://topics")

# Read a templated resource
articles = await session.read_resource("wiki://python")

Clients discover and read resources through the same session.

Fill in the blanks: Complete the resource decorator

Loading practice…

Quiz: Quiz

Loading practice…