Jeremiah Lowin commited on
Commit
3d3691f
·
1 Parent(s): 80e30cd

Fix handling tools without descriptions

Browse files
src/fastmcp/resources/template.py CHANGED
@@ -148,7 +148,7 @@ class ResourceTemplate(BaseModel):
148
  f"URI parameters {uri_params} must be a subset of the function arguments: {func_params}"
149
  )
150
 
151
- description = description or fn.__doc__ or ""
152
 
153
  if not inspect.isroutine(fn):
154
  fn = fn.__call__
 
148
  f"URI parameters {uri_params} must be a subset of the function arguments: {func_params}"
149
  )
150
 
151
+ description = description or fn.__doc__
152
 
153
  if not inspect.isroutine(fn):
154
  fn = fn.__call__
src/fastmcp/tools/tool.py CHANGED
@@ -36,7 +36,7 @@ class Tool(BaseModel):
36
 
37
  fn: Callable[..., Any]
38
  name: str = Field(description="Name of the tool")
39
- description: str = Field(description="Description of what the tool does")
40
  parameters: dict[str, Any] = Field(description="JSON schema for tool parameters")
41
  tags: Annotated[set[str], BeforeValidator(_convert_set_defaults)] = Field(
42
  default_factory=set, description="Tags for the tool"
@@ -74,7 +74,7 @@ class Tool(BaseModel):
74
  if func_name == "<lambda>":
75
  raise ValueError("You must provide a name for lambda functions")
76
 
77
- func_doc = description or fn.__doc__ or ""
78
 
79
  # if the fn is a callable class, we need to get the __call__ method from here out
80
  if not inspect.isroutine(fn):
 
36
 
37
  fn: Callable[..., Any]
38
  name: str = Field(description="Name of the tool")
39
+ description: str | None = Field(description="Description of what the tool does")
40
  parameters: dict[str, Any] = Field(description="JSON schema for tool parameters")
41
  tags: Annotated[set[str], BeforeValidator(_convert_set_defaults)] = Field(
42
  default_factory=set, description="Tags for the tool"
 
74
  if func_name == "<lambda>":
75
  raise ValueError("You must provide a name for lambda functions")
76
 
77
+ func_doc = description or fn.__doc__
78
 
79
  # if the fn is a callable class, we need to get the __call__ method from here out
80
  if not inspect.isroutine(fn):
tests/server/test_proxy.py CHANGED
@@ -30,6 +30,10 @@ def fastmcp_server():
30
  """Greet someone by name."""
31
  return f"Hello, {name}!"
32
 
 
 
 
 
33
  @server.tool()
34
  def add(a: int, b: int) -> int:
35
  """Add two numbers together."""
@@ -110,6 +114,11 @@ class TestTools:
110
  assert "greet" in tools
111
  assert "add" in tools
112
  assert "error_tool" in tools
 
 
 
 
 
113
 
114
  async def test_list_tools_same_as_original(self, fastmcp_server, proxy_server):
115
  assert (
 
30
  """Greet someone by name."""
31
  return f"Hello, {name}!"
32
 
33
+ @server.tool()
34
+ def tool_without_description() -> str:
35
+ return "Hello?"
36
+
37
  @server.tool()
38
  def add(a: int, b: int) -> int:
39
  """Add two numbers together."""
 
114
  assert "greet" in tools
115
  assert "add" in tools
116
  assert "error_tool" in tools
117
+ assert "tool_without_description" in tools
118
+
119
+ async def test_tool_without_description(self, proxy_server):
120
+ tools = await proxy_server.get_tools()
121
+ assert tools["tool_without_description"].description is None
122
 
123
  async def test_list_tools_same_as_original(self, fastmcp_server, proxy_server):
124
  assert (