fastmcp icon indicating copy to clipboard operation
fastmcp copied to clipboard

`@mcp.resource` with dynamic parameters example don't work

Open CNSeniorious000 opened this issue 11 months ago โ€ข 8 comments

In the README, there is an example:

@mcp.resource("users://{user_id}/profile")
def get_user_profile(user_id: str) -> str:
    """Dynamic user data"""
    return f"Profile data for user {user_id}"

This don't work

I can't see any resources in the mcp inspector

CNSeniorious000 avatar Dec 09 '24 16:12 CNSeniorious000

Same for me, I copied the example server from README.md

from fastmcp import FastMCP

# Create an MCP server
mcp = FastMCP("Demo")


# Add an addition tool
@mcp.tool()
def add(a: int, b: int) -> int:
    """Add two numbers"""
    return a + b


# Add a dynamic greeting resource
@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:
    """Get a personalized greeting"""
    return f"Hello, {name}!"


if __name__ == "__main__":
    mcp.run()

Then started the inspector with:

uv run fastmcp dev fastmcp.py

I can see the add tool but I get errors for the resource in Error output from MCP server

[12/10/24 17:30:03] INFO Processing request of type __init__.py:431 ListResourcesRequest 

(btw it's a bit weird that the log is labelled as INFO in the error output, not sure if this is a bug or a feature :) )

In history I have:

resources/listโ–ผ
Request:

{
  "method": "resources/list",
  "params": {}
}

Response:

{
  "resources": []
}

@jlowin

vemonet avatar Dec 10 '24 16:12 vemonet

Anyone got a solution to this problem? Thanks.

mcp2everything avatar Jan 03 '25 07:01 mcp2everything

It appears to be an issue when there is a parameter for a resource. Resources without parameters appear to work fine.

gmr avatar Jan 03 '25 21:01 gmr

This is related to #10, the current version of fastmcp simply doesn't support resource templates listing

micpst avatar Jan 10 '25 22:01 micpst

hi all @micpst @gmr @mcp2everything @vemonet @CNSeniorious000 - ICYMI

https://github.com/jlowin/fastmcp?tab=readme-ov-file#-fastmcp-has-been-added-to-the-official-mcp-sdk-

zzstoatzz avatar Jan 10 '25 22:01 zzstoatzz

@zzstoatzz thanks my bad, seems to be fixed but not released yet

micpst avatar Jan 10 '25 23:01 micpst

I'm having a similar issue on the official python-sdk. I can't get any resource params to show up in my MCP Inspector, might have to switch to native.

This works fine.

@mcp.resource("config://app")
def get_config() -> str:
    """Static configuration data"""
    return "App configuration here"

Once I add an input param it does not show up as a listed resource

@mcp.resource("users://{hello}/message")
def get_config(hello: str) -> str:
    """dynamic user message"""
    return "Message here {hello}"

ICeZer0 avatar Feb 15 '25 15:02 ICeZer0

I have the same issue. Anthropic suggests that for dynamic resources should be registered with a template however FastMCP says that dynamic resources are automatically handled as templates. FastMCP has list_templates function implemented too. Not sure what is happening.

KeerthiNingegowda avatar Mar 28 '25 22:03 KeerthiNingegowda

On top of the problem, the mcp.resource doesn't work in case when function has a ctx parameter:

mcp = FastMCP("Resonanz")


@mcp.resource("system://status")
async def get_system_status(ctx: Context) -> dict:
    """Checks system status and logs information."""
    ctx.log(ctx.request_context)
    return {
        "status": "ok",
        "message": "System is running",
        "request_context": ctx.request_context,
    }

raises:

    94 โ”‚   โ”‚   # Validate that URI params match function params                                 โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ locals โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ                             โ”‚
โ”‚    95 โ”‚   โ”‚   uri_params = set(re.findall(r"{(\w+)}", uri_template))                           โ”‚  description = None                โ”‚                             โ”‚
โ”‚    96 โ”‚   โ”‚   if not uri_params:                                                               โ”‚    func_name = 'get_system_status' โ”‚                             โ”‚
โ”‚ โฑ  97 โ”‚   โ”‚   โ”‚   raise ValueError("URI template must contain at least one parameter")         โ”‚    mime_type = None                โ”‚                             โ”‚
โ”‚    98 โ”‚   โ”‚                                                                                    โ”‚         name = None                โ”‚                             โ”‚
โ”‚    99 โ”‚   โ”‚   func_params = set(inspect.signature(fn).parameters.keys())                       โ”‚         tags = None                โ”‚                             โ”‚
โ”‚   100                                                                                          โ”‚   uri_params = set()               โ”‚                             โ”‚
โ”‚                                                                                                โ”‚ uri_template = 'system://status'   โ”‚                             โ”‚
โ”‚                                                                                                โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ 

renardeinside avatar Apr 16 '25 21:04 renardeinside

Only tools support context injection (see documentation https://gofastmcp.com/servers/context). There is an open issue for supplying context to resources and prompts (#134) if you'd like to support it.

jlowin avatar Apr 16 '25 22:04 jlowin