Skip to content

[BUG]: Tag filter returns 500 Exception for list tools api #2329

@childrenofaqsa

Description

@childrenofaqsa

🐞 Bug Summary

The tags query parameter in the /tools endpoint does not work after the schema change from List[str] to List[Dict[str, str]]. The tag filtering logic compares plain strings against dictionary objects, which always fails. Attempting to filter tools by tag either returns a 500 Internal Server Error (database path) or returns 0 results (in-memory path), even when matching tools exist.


🧩 Affected Component

Select the area of the project impacted:

  • mcpgateway - API
  • mcpgateway - UI (admin panel)
  • mcpgateway.wrapper - stdio wrapper
  • Federation or Transports
  • CLI, Makefiles, or shell scripts
  • Container setup (Docker/Podman/Compose)
  • Other (explain below)

🔁 Steps to Reproduce

  1. Create a tool with tags in the new dict format:

    [{"id": "automation", "label": "automation"}, {"id": "data-analysis", "label": "data-analysis"}]
  2. Attempt to filter tools using the tags query parameter:

    GET /tools?tags=automation
    

    Result: 500 Internal Server Error

  3. Attempt to filter using visibility parameter (triggers in-memory filter path):

    GET /tools?visibility=public&tags=automation
    

    Result: Returns 0 tools, even though tools with automation tag exist

  4. Verify tools exist without the tag filter:

    GET /tools?include_inactive=true
    

    Result: Returns all tools including those with automation tag


🤔 Expected Behavior

The API should return all tools that have a tag with id or label matching the provided filter value. For example, GET /tools?tags=automation should return all tools where any tag dict has "id": "automation" or "label": "automation".


📓 Logs / Error Output

Path 1 - Database filter (500 error):
When calling GET /tools?tags=automation, the json_contains_expr function in sqlalchemy_modifier.py fails because it's designed for plain string arrays (["automation"]) but the tags column now contains dict arrays ([{"id": "automation", "label": "automation"}]).

Path 2 (0 results):
When calling GET /tools?visibility=public&tags=automation, the filtering logic at main.py:2587 performs:

any(tag in tool.tags for tag in tags_list)

This checks if string "automation" is in the list [{"id": "automation", ...}], which evaluates to False because string equality against dict objects never matches.


🧠 Environment Info

Key Value
Version or commit Post-migration 9e028ecf59c4 (tag dict format)
Runtime Python 3.13
Platform / OS Windows 10
Container N/A

🧩 Additional Context (optional)

Affected files:

  • mcpgateway/main.py

Schema change reference:

  • Migration: 9e028ecf59c4_tag_records_changes_list_str_to_list_.py
  • Tags changed from List[str] to List[Dict[str, str]] with format {"id": "<tag>", "label": "<tag>"}

Related: The same issue likely affects tag filtering in other entity list endpoints (resources, prompts, servers, gateways, a2a_agents) that use the same tag filtering pattern.

Metadata

Metadata

Assignees

Labels

SHOULDP2: Important but not vital; high-value items that are not crucial for the immediate releasebugSomething isn't workingpythonPython / backend development (FastAPI)

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions