Skip to main content
Resources expose read-only data to MCP clients. Unlike tools (which perform actions), resources provide context:database schemas, config files, documentation, or any data the LLM needs to make better decisions.

Defining Resources

from concierge import Concierge

app = Concierge("my-server")

@app.resource("resource://app/settings")
def get_settings() -> str:
    """Current application settings."""
    return json.dumps({
        "max_cart_items": 50,
        "supported_currencies": ["USD", "EUR", "GBP"],
        "free_shipping_threshold": 100,
    })
The resource URI (resource://app/settings) is how clients reference this resource. For ChatGPT widget apps, use the ui:// scheme (e.g. ui://widget/my-widget).

Resource Templates

Use URI templates for dynamic resources:
@app.resource("resource://products/{product_id}")
def get_product_docs(product_id: str) -> str:
    """Product documentation and specifications."""
    # Replace with your own data source
    return f"# Product {product_id}\n\nA great product.\n\nPrice: $99"

When to Use Resources vs Tools

Use CaseResourceTool
Read-only dataYesNo
Database schemaYesNo
ConfigurationYesNo
Search/queryNoYes
Create/update/deleteNoYes
Side effectsNoYes
Resources are fetched once at the start of a conversation and cached. Use them for stable context that doesn’t change per-request.

Resources with Stages

Resources can be scoped to stages, just like tools. This means the LLM only sees resources relevant to the current workflow step.