how to trigger a resources_changed or listChanged
Hi,
The protocol specifies that there's a notification sent to clients when the list of tools or resources changes on the server-side, but I'm not sure how to trigger this. Does it happen automatically when add_resource gets called, or do I need to trigger something manually?
thanks
so, (i) this capability is not mandatory - servers may or may not declare resources: {listChanged: true} when announcing their capabilities to the client in response to initialize, a la:
{
"capabilities": {
"experimental": {},
"prompts": {},
"resources": {
"listChanged": true
},
"tools": {}
},
"serverInfo": {
...
},
...
}
(ii) even if the server does announce this as a capability, it seems like it is a SHOULD (but not a MUST):
When the list of available resources changes, servers that declared the listChanged capability SHOULD send a notification:
source: https://modelcontextprotocol.io/specification/2025-03-26/server/resources#list-changed-notification
WRONG - I was able to wire up the notification, but I had to do it manually.
[
From my current experience in Inspector, it seems like you can get resource update notifications from the server for a subscribed resource (notifications/resources/updated), but i have not seen notifications/resources/list_changed notifications appear if i add a resource.
The resources/updated notifications started coming in without me adding any custom code, once I got the subscription working. So I would expect the updated notifications to come in without any custom code, as long as the server announces that it has the capability. But, from what I can tell, (i) it's not mandatory for the server to send these notifications even if they advertise the capability; (ii) it's totally optional what the client does (if anything) if these notifications are sent.
My guess is that if the server was actually sending the notification, it would show up in Inspector, since Inspector seems at least to be showing the server-notifications that it receives. Whether or not anything is supposed to happen after that, I can't say. But it would appear to me that the server is probably not sending the notification, which is a shame, but not strictly speaking a violation of the protocol, which suggests that sending the notifications is a SHOULD and not a MUST.
That being said, I would hope the official mcp python SDK server does what it "SHOULD" do even if it's not a MUST. ]
CORRECTION
My mistake, I was reading my code again, and I am actually sending the resource/updated manually when a subscribed resource is changed, via session.send_notification, so my reply above is not fully accurate.
Yeah so I just added some code to send the list_updated notification to all sessions when resource list changes, and it's coming through, but I had to do it manually, and I'm keeping track of all the session objects.
In relation to #741, I am manually keeping a list of all the sessions in my server code, so that's how i achieved this, see: "Implementing a custom session registry in user code, but this is error-prone and would be better handled by the framework."
Can anyone tell how to declare resources: {listChanged: true}while running mcp server. default i see something like this.
"capabilities": {
"experimental": {},
"prompts": {
"listChanged": false
},
"resources": {
"subscribe": false,
"listChanged": false
},
"tools": {
"listChanged": false
}
},
"serverInfo": {
"name": "mcp-search",
"version": "1.9.3"
}
}```
@salman-khandu i think you need to pass it in to InitializationOptions, see this snippet on python-sdk readme
async def run():
async with mcp.server.stdio.stdio_server() as (read_stream, write_stream):
await server.run(
read_stream,
write_stream,
InitializationOptions(
server_name="example",
server_version="0.1.0",
capabilities=server.get_capabilities(
notification_options=NotificationOptions(),
experimental_capabilities={},
),
),
)
I'm not at my computer so double-check, i think i had to use pydantic validate base model function or some such.
@hesreallyhim
@salman-khandu i think you need to pass it in to InitializationOptions, see this snippet on python-sdk readme
async def run(): async with mcp.server.stdio.stdio_server() as (read_stream, write_stream): await server.run( read_stream, write_stream, InitializationOptions( server_name="example", server_version="0.1.0", capabilities=server.get_capabilities( notification_options=NotificationOptions(), experimental_capabilities={}, ), ), )I'm not at my computer so double-check, i think i had to use pydantic validate base model function or some such.
I use
mcp = FastMCP(
"mcp-search",
description="MCP server for search",
host=os.getenv("HOST", "0.0.0.0"),
port=os.getenv("PORT", "8050"),
)
and then
async def main():
transport = os.getenv("TRANSPORT", "sse")
if transport == 'sse':
# Run the MCP server with sse transport
await mcp.run_sse_async()
else:
# Run the MCP server with stdio transport
await mcp.run_stdio_async()
So i don't see options
Thank you
you might have to create the server using a different method, in the end I had to use lowlevel server :(
@hesreallyhim if i send listChanged: true then client will automatically sync tool? like let say i have add new tool and restart server
@salman-khandu this would depend on the client, I don't think the spec says what the client is supposed to do if it gets a resource-update or a list-changed notification. E.g. here it discusses the requirements on the server for these notifications: https://modelcontextprotocol.io/specification/2025-03-26/server/tools#list-changed-notification
When the list of available tools changes, servers that declared the listChanged capability SHOULD send a notification:
but I don't know of anything saying that a client has to actually take some action in response to that notification.
If you restart the server then it'll know about the new tool because of "tools/list" but that's different than responding to a list-changed notification. You can search the spec if you want, but AFAIK the client is free to just ignore those notifications if it doesn't care.
EDIT: Sorry somehow got mixed up with tools and resources, but in either case, I don't think there are statements about what a client must or should do.
If you're asking about how to do this on FastMCP you currently need to do this manually by modifying lowlevel - see https://github.com/modelcontextprotocol/python-sdk/issues/1126
This may also be addressed by https://github.com/modelcontextprotocol/python-sdk/pull/1043