Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions directory/crawlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1675,7 +1675,9 @@ def _mcp_parse_response(r):


# Per-server caps so a padded multi-tool server can't bloat our row/index.
_MAX_TOOLS = 60
# One hundred still bounds each row while avoiding silent capability loss for
# legitimate MCP servers whose tool inventories have grown beyond sixty.
_MAX_TOOLS = 100
_MAX_TOOL_DESC = 160


Expand All @@ -1687,7 +1689,9 @@ def _summarize_tools(tools: list) -> list:
that exposes 24 tools is 24 discoverable capabilities, not one.
"""
out = []
for t in tools[:_MAX_TOOLS]:
for t in tools:
if len(out) >= _MAX_TOOLS:
break
if not isinstance(t, dict):
continue
name = str(t.get("name") or "").strip()
Expand Down
30 changes: 30 additions & 0 deletions tests/test_mcp_tool_summarization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import unittest

from directory import crawlers


class McpToolSummarizationTests(unittest.TestCase):
def test_keeps_one_hundred_valid_capabilities_within_the_cap(self):
tools = [None, {"description": "missing a name"}]
tools.extend(
{
"name": f"tool-{index}",
"description": "x" * (crawlers._MAX_TOOL_DESC + 20),
}
for index in range(105)
)

summarized = crawlers._summarize_tools(tools)

self.assertEqual(crawlers._MAX_TOOLS, 100)
self.assertEqual(len(summarized), 100)
self.assertEqual(summarized[0]["name"], "tool-0")
self.assertEqual(summarized[-1]["name"], "tool-99")
self.assertEqual(
summarized[0]["description"],
"x" * crawlers._MAX_TOOL_DESC + "…",
)


if __name__ == "__main__":
unittest.main()