Goose is unable to handle enum literals
Describe the bug
It appears that Goose expects json schema definitions to not have inline enums and fails when it sees this (this is what the Literal usage causes)
To Reproduce Steps to reproduce the behavior:
uvx [email protected]- After enabling the extension, ask "Can you list the last alert in Panther"
Expected behavior Goose is able to use tools with enum literals
Please provide following information:
- OS & Arch: macOS
- Interface: UI & CLI
- Version: v1.0.27
- Extensions enabled: Developer, Memory, Panther
- Provider & Model: Anthropic, claude-4-sonnet
Additional context
- Using
uvx [email protected]works as expected, due to:
Taking a look at this issue via https://github.com/block/goose/pull/3047 👀
👋 Hey @glenn-sq , thank you for reporting this issue. I was unable to reproduce the issue you described above ("Steps to reproduce the behavior") because the mcp-pather list_alerts tool requires a PANTHER_INSTANCE_URL env var, which I do not have because I do not have a pather account.
Instead, I created a very simple mcp server on my local machine with one tool:
from enum import Enum
from fastmcp import FastMCP
class Color(Enum):
RED = "red" # Gryffindor
GREEN = "green" # Slytherin
YELLOW = "yellow" # Hufflepuff
BLUE = "blue" # Ravenclaw
mcp = FastMCP(name="EnumServer")
@mcp.tool()
def sort_student_into_house(student_name: str, color: Color) -> str:
"""Sorts a student into a Hogwarts house based on color and returns a funny description."""
...
This tool requires both a string and enum argument. Goose v1.0.27 and v.1.0.29 are both able to successfully invoke the tool:
https://github.com/user-attachments/assets/cae869e3-fc6b-4680-ae29-456836442310
@glenn-sq Could you either provide steps to reproduce that do not require a pather account? Or could you confirm this issue is resolved on your end and can be closed?
https://github.com/block/goose/pull/3047 adds integration test coverage for tool use with enum argument. The "Test Plan" section of the PR description demos tool usages with enum arguments for various LLM providers.
tagging in @darwayne from Panther who initially identified the issue
hey @danielzayas here's a sample server that reproduces the problem:
# server.py
from typing import Annotated, Literal
from pydantic import Field
from fastmcp import FastMCP
mcp = FastMCP("Demo 🚀")
@mcp.tool()
def hello(interval_in_minutes: Annotated[
Literal[15, 30, 60, 180, 360, 720, 1440], # <-- using a literal like so is what causes problems for goose
Field(
description="How data points are aggregated over time, with smaller intervals providing more granular detail of when events occurred, while larger intervals show broader trends but obscure the precise timing of incidents."
),
] = 1440) -> str:
return f"Hello, {interval_in_minutes}!"
def main():
mcp.run() # Default: uses STDIO transport
if __name__ == "__main__":
main()
Here's step by step instructions .. I would recommend using uv
uv init my-fastmcp-project --python 3.12cd my-fastmcp-projectuv add fastmcp==2.3.4- add server.py as shown above
- Make sure pyproject.yml looks something like the following
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "my-fastmcp-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.8"
dependencies = [
"fastmcp==2.3.4",
]
[project.scripts]
fastmcp-demo = "server:main"
[tool.hatch.build.targets.wheel]
packages = ["."]
- do
uv pip install -e .oruv tool install . - Update goose to use
fastmcp-demoas an extension and name it demo - Make a prompt: "what tools are available in demo?"
- You'll see this output
Ran into this error: Request failed: Request failed with status: 400 Bad Request. Message: Invalid value at 'tools.function_declarations[5].parameters.properties[0].value.enum[0]' (TYPE_STRING), 15 Invalid value at 'tools.function_declarations[5].parameters.properties[0].value.enum[1]' (TYPE_STRING), 30 Invalid value at 'tools.function_declarations[5].parameters.properties[0].value.enum[2]' (TYPE_STRING), 60 Invalid value at 'tools.function_declarations[5].parameters.properties[0].value.enum[3]' (TYPE_STRING), 180 Invalid value at 'tools.function_declarations[5].parameters.properties[0].value.enum[4]' (TYPE_STRING), 360 Invalid value at 'tools.function_declarations[5].parameters.properties[0].value.enum[5]' (TYPE_STRING), 720 Invalid value at 'tools.function_declarations[5].parameters.properties[0].value.enum[6]' (TYPE_STRING), 1440.
Please retry if you think this is a transient or recoverable error.
Whereas in Claude I would see a response like so:
Looking at the available tools, I can see there's one demo tool available:
**demo:hello** - This appears to be a demonstration tool that takes an `interval_in_minutes` parameter (defaulting to 1440 minutes/24 hours). The parameter description suggests it's related to data aggregation over time intervals, with options for 15, 30, 60, 180, 360, 720, or 1440 minute intervals. Smaller intervals provide more granular detail of when events occurred, while larger intervals show broader trends.
Thank you @darwayne !!
- I was able to successfully reproduce the tool invocation error on goose v1.0.27 (3625f2a1af9189af338d12c94291eaf556e6a81e), which is the light mode goose macOS app in the demo.
- Using goose v1.0.29 (d8b6e6011b0e8272268fc3b0c71ec808a616780b) I was able to successfully call the same tool from the above mcp server without the error, which is the dark mode goose macOS app in the demo.
@darwayne or @glenn-sq , could either of you try with goose v1.0.29 and see if that tool invocation succeeds? I've attached a demo 🙏
https://github.com/user-attachments/assets/a056d61e-4179-49a8-9398-d22dbf9582d6
Hey @danielzayas I just tried against Goose version 1.1.0-alpha.3 (latest on the website as of this writing) .. and problem still seems to be there for the demo script I showed you:
When I try against mcp-panther 1.1.0 .. it looks to work fine now with compatibility mode on and off .. which is nice.
However if I try to use mcp-panther version 1.0.0 .. I'm still seeing similar behavior as we were seeing before:
Still in progress?
Yes. I believe this still repros. I have been burning down other bugs but will close this one out by EOW I imagine.
Looking at this now
Posting debugging breadcrumbs.
I took the server setup @darwayne recommended and am using it for testing.
I've verified it is not an issue with the https://github.com/modelcontextprotocol/rust-sdk as a simple client implemented in a standalone rust file that: connects to the server, lists tools, calls the hello tool with rmcp's client works fine.
So the issue must be in goose
Ok good news @glenn-sq @danielzayas @darwayne
This is fixed in goose. We merged a number of things to how we handle json schemas in the rust sdk and I suspect something there handled this issue. I was experiencing another bug where there was no tool description and that tripped goose up, but after correcting it in a simple way in the server.py source code, I now get this result for a tool which has an enum in the input schema with goose:
Source code of the MCP server for testing is:
from typing import Annotated, Literal
from pydantic import Field
from fastmcp import FastMCP
mcp = FastMCP("Demo 🚀")
@mcp.tool()
def hello(interval_in_minutes: Annotated[
Literal[15, 30, 60, 180, 360, 720, 1440], # <-- using a literal like so is what causes problems for goose
Field(
description="How data points are aggregated over time, with smaller intervals providing more granular detail of when events occurred, while larger intervals show broader trends but obscure the precise timing of incidents."
),
] = 1440) -> str:
"""Says hello"""
return f"Hello, {interval_in_minutes}!"
def main():
mcp.run() # Default: uses STDIO transport
if __name__ == "__main__":
main()
Feel free to reopen if still an issue in panther, but I think this is resolved. Let me know if you can confirm @darwayne