Skip to content

Commit addce22

Browse files
committed
work in progress attempting to implement RFC 356
1 parent ed25167 commit addce22

File tree

4 files changed

+18
-2
lines changed

4 files changed

+18
-2
lines changed

src/mcp/server/fastmcp/server.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ async def list_tools(self) -> list[MCPTool]:
251251
name=info.name,
252252
description=info.description,
253253
inputSchema=info.parameters,
254+
outputSchema=info.output,
254255
annotations=info.annotations,
255256
)
256257
for info in tools

src/mcp/server/fastmcp/tools/base.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class Tool(BaseModel):
2323
name: str = Field(description="Name of the tool")
2424
description: str = Field(description="Description of what the tool does")
2525
parameters: dict[str, Any] = Field(description="JSON schema for tool parameters")
26+
output: dict[str, Any] = Field(description="JSON schema for tool output")
2627
fn_metadata: FuncMetadata = Field(
2728
description="Metadata about the function including a pydantic model for tool"
2829
" arguments"
@@ -69,12 +70,14 @@ def from_function(
6970
skip_names=[context_kwarg] if context_kwarg is not None else [],
7071
)
7172
parameters = func_arg_metadata.arg_model.model_json_schema()
73+
output = func_arg_metadata.output_model.model_json_schema()
7274

7375
return cls(
7476
fn=fn,
7577
name=func_name,
7678
description=func_doc,
7779
parameters=parameters,
80+
output=output,
7881
fn_metadata=func_arg_metadata,
7982
is_async=is_async,
8083
context_kwarg=context_kwarg,

src/mcp/server/fastmcp/utilities/func_metadata.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ def model_dump_one_level(self) -> dict[str, Any]:
3838

3939
class FuncMetadata(BaseModel):
4040
arg_model: Annotated[type[ArgModelBase], WithJsonSchema(None)]
41+
output_model: Annotated[type[ArgModelBase], WithJsonSchema(None)]
4142
# We can add things in the future like
4243
# - Maybe some args are excluded from attempting to parse from JSON
4344
# - Maybe some args are special (like context) for dependency injection
@@ -128,6 +129,7 @@ def func_metadata(
128129
sig = _get_typed_signature(func)
129130
params = sig.parameters
130131
dynamic_pydantic_model_params: dict[str, Any] = {}
132+
dynamic_pydantic_model_output: dict[str, Any] = {}
131133
globalns = getattr(func, "__globals__", {})
132134
for param in params.values():
133135
if param.name.startswith("_"):
@@ -167,12 +169,20 @@ def func_metadata(
167169
dynamic_pydantic_model_params[param.name] = (field_info.annotation, field_info)
168170
continue
169171

172+
# dynamic_pydantic_model_output[]
173+
170174
arguments_model = create_model(
171175
f"{func.__name__}Arguments",
172176
**dynamic_pydantic_model_params,
173177
__base__=ArgModelBase,
174178
)
175-
resp = FuncMetadata(arg_model=arguments_model)
179+
180+
output_model = create_model(
181+
f"{func.__name__}Output",
182+
**dynamic_pydantic_model_output,
183+
__base__=ArgModelBase
184+
)
185+
resp = FuncMetadata(arg_model=arguments_model, output_model=output_model)
176186
return resp
177187

178188

@@ -210,5 +220,5 @@ def _get_typed_signature(call: Callable[..., Any]) -> inspect.Signature:
210220
)
211221
for param in signature.parameters.values()
212222
]
213-
typed_signature = inspect.Signature(typed_params)
223+
typed_signature = inspect.Signature(typed_params, return_annotation=signature.return_annotation)
214224
return typed_signature

src/mcp/types.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,8 @@ class Tool(BaseModel):
762762
"""A human-readable description of the tool."""
763763
inputSchema: dict[str, Any]
764764
"""A JSON Schema object defining the expected parameters for the tool."""
765+
outputSchema: dict[str, Any] | None = None
766+
"""A JSON Schema object defining the expected outputs for the tool."""
765767
annotations: ToolAnnotations | None = None
766768
"""Optional additional tool information."""
767769
model_config = ConfigDict(extra="allow")

0 commit comments

Comments
 (0)