You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As the FastMCP package continues to evolve and add features inspired by FastAPI, the sort of "best practice" on how to do something MCP-related becomes increasingly obscure.
As an example, suppose I have some complex object I can't / don't want to serialize---I just want to expose a few simple (and stateful) methods as tools:
When you register this bound method, the system sees a callable that only expects the appropriate parameters, not self
Great, so the instance can be arbitrarily complex w/o polluting the Context with its internal details. But ofc, I have to couple the addition of tools to the object itself.
Option (2): Use dependency injection
Using the new Depends() feature, maybe a better way to go is to just inject the object itself:
This avoids explicitly coupling the object instance with the tool and avoid the schema generation like before. The only downside I see if you have to handle how to default-construct the object or otherwise pass arguments at the call-site somehow
Option (3): Use transforms
Yet another option to expose a complex object could be via the fairly complicated transforms api:
I really don't see the benefit of doing this unless one was already planning on setting up a large pipeline of composable transformations, or for some reason one didn't have access to the original tool signature(s).
~~Option (4) Use Context objects~~~
Despite the name Context, according to the docs each MCP operation (e.g. tool call, resource read) receives an independent context object. So, Context options are apparently not the way to encourage the LLM(s) to chain tool calls.
Basically I'm at a loss what the 'recommended' way to handle this is
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
As the
FastMCPpackage continues to evolve and add features inspired by FastAPI, the sort of "best practice" on how to do something MCP-related becomes increasingly obscure.As an example, suppose I have some complex object I can't / don't want to serialize---I just want to expose a few simple (and stateful) methods as tools:
How in the world am I supposed to expose
stateful_operation,add_messages,finish_up, etc. as MCP tools?Option (1): Use instance methods
According to the docs:
Great, so the instance can be arbitrarily complex w/o polluting the
Contextwith its internal details. But ofc, I have to couple the addition of tools to the object itself.Option (2): Use dependency injection
Using the new
Depends()feature, maybe a better way to go is to just inject the object itself:This avoids explicitly coupling the object instance with the tool and avoid the schema generation like before. The only downside I see if you have to handle how to default-construct the object or otherwise pass arguments at the call-site somehow
Option (3): Use transforms
Yet another option to expose a complex object could be via the fairly complicated transforms api:
I really don't see the benefit of doing this unless one was already planning on setting up a large pipeline of composable transformations, or for some reason one didn't have access to the original tool signature(s).
~~Option (4) Use
Contextobjects~~~Despite the name
Context, according to the docs each MCP operation (e.g. tool call, resource read) receives an independent context object. So,Contextoptions are apparently not the way to encourage the LLM(s) to chain tool calls.Basically I'm at a loss what the 'recommended' way to handle this is
Beta Was this translation helpful? Give feedback.
All reactions