Skip to content

list_tables crashes MCP server for large schemas — needs pagination and metadata trimming #25

Open
@puneet-sutar

Description

@puneet-sutar

list_tables crashes MCP server for large schemas — needs pagination and metadata trimming

📝 Updated Issue Description:

When using list_tables on databases with a large number of tables (100+), the MCP server may crash or disconnect. This is likely due to the payload size exceeding internal limits, especially when passed to an LLM or when streaming via stdio.

This issue can manifest as BrokenResourceError, unhandled exceptions in TaskGroup, or server transport unexpectedly closing. We've seen this happen in ClickHouse Cloud setups where schemas are large and metadata (like comments) is verbose.

✅ Proposed Fix:

  • Add pagination to the list_tables tool (e.g., limit and offset params).
  • Avoid returning redundant metadata such as the comments array—most of this is already embedded in the create_table_query.
  • Update the tool description to make its limitations and expected usage clearer.
  • Optionally, cap the total number of tables fetched in a single call to a configurable value (e.g., 100–200).

Original Description

I am trying it with my clickhouse cloud instance and the project always crashes when list_tables is called on the databases with more then 100 tables.

Anything I can do the fix it?

Pasting some log lines if they help. Let me know if you need more info here.

 + Exception Group Traceback (most recent call last):
  |   File "/Users/puneetsutar/.cache/uv/archive-v0/UJ0ZpE2MZyeSn-kocDSZB/bin/mcp-clickhouse", line 12, in <module>
  |     sys.exit(main())
  |              ~~~~^^
  |   File "/Users/puneetsutar/.cache/uv/archive-v0/UJ0ZpE2MZyeSn-kocDSZB/lib/python3.13/site-packages/mcp_clickhouse/main.py", line 5, in main
  |     mcp.run()
  |     ~~~~~~~^^
  |   File "/Users/puneetsutar/.cache/uv/archive-v0/UJ0ZpE2MZyeSn-kocDSZB/lib/python3.13/site-packages/mcp/server/fastmcp/server.py", line 159, in run
  |     anyio.run(self.run_stdio_async)
  |     ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
  |   File "/Users/puneetsutar/.cache/uv/archive-v0/UJ0ZpE2MZyeSn-kocDSZB/lib/python3.13/site-packages/anyio/_core/_eventloop.py", line 74, in run
  |     return async_backend.run(func, args, {}, backend_options)
  |            ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File "/Users/puneetsutar/.cache/uv/archive-v0/UJ0ZpE2MZyeSn-kocDSZB/lib/python3.13/site-packages/anyio/_backends/_asyncio.py", line 2310, in run
  |     return runner.run(wrapper())
  |            ~~~~~~~~~~^^^^^^^^^^^
  |   File "/opt/homebrew/Cellar/[email protected]/3.13.2/Frameworks/Python.framework/Versions/3.13/lib/python3.13/asyncio/runners.py", line 118, in run
  |     return self._loop.run_until_complete(task)
  |            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  |   File "/opt/homebrew/Cellar/[email protected]/3.13.2/Frameworks/Python.framework/Versions/3.13/lib/python3.13/asyncio/base_events.py", line 725, in run_until_complete
  |     return future.result()
  |            ~~~~~~~~~~~~~^^
  |   File "/Users/puneetsutar/.cache/uv/archive-v0/UJ0ZpE2MZyeSn-kocDSZB/lib/python3.13/site-packages/anyio/_backends/_asyncio.py", line 2298, in wrapper
  |     return await func(*args)
  |            ^^^^^^^^^^^^^^^^^
  |   File "/Users/puneetsutar/.cache/uv/archive-v0/UJ0ZpE2MZyeSn-kocDSZB/lib/python3.13/site-packages/mcp/server/fastmcp/server.py", line 460, in run_stdio_async
  |     async with stdio_server() as (read_stream, write_stream):
  |                ~~~~~~~~~~~~^^
  |   File "/opt/homebrew/Cellar/[email protected]/3.13.2/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py", line 221, in __aexit__
  |     await anext(self.gen)
  |   File "/Users/puneetsutar/.cache/uv/archive-v0/UJ0ZpE2MZyeSn-kocDSZB/lib/python3.13/site-packages/mcp/server/stdio.py", line 83, in stdio_server
  |     async with anyio.create_task_group() as tg:
  |                ~~~~~~~~~~~~~~~~~~~~~~~^^
  |   File "/Users/puneetsutar/.cache/uv/archive-v0/UJ0ZpE2MZyeSn-kocDSZB/lib/python3.13/site-packages/anyio/_backends/_asyncio.py", line 772, in __aexit__
  |     raise BaseExceptionGroup(
  |         "unhandled errors in a TaskGroup", self._exceptions
  |     ) from None
  | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
  +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    |   File "/Users/puneetsutar/.cache/uv/archive-v0/UJ0ZpE2MZyeSn-kocDSZB/lib/python3.13/site-packages/mcp/server/stdio.py", line 69, in stdin_reader
    |     await read_stream_writer.send(message)
    |   File "/Users/puneetsutar/.cache/uv/archive-v0/UJ0ZpE2MZyeSn-kocDSZB/lib/python3.13/site-packages/anyio/streams/memory.py", line 255, in send
    |     raise BrokenResourceError from None
    | anyio.BrokenResourceError
    +------------------------------------
2025-03-30T21:23:43.811Z [mcp-clickhouse] [info] Server transport closed
2025-03-30T21:23:43.811Z [mcp-clickhouse] [info] Client transport closed
2025-03-30T21:23:43.811Z [mcp-clickhouse] [info] Server transport closed unexpectedly, this is likely due to the process exiting early. If you are developing this MCP server you can add output to stderr (i.e. `console.error('...')` in JavaScript, `print('...', file=sys.stderr)` in python) and it will appear in this log.
2025-03-30T21:23:43.811Z [mcp-clickhouse] [error] Server disconnected. For troubleshooting guidance, please visit our [debugging documentation](https://modelcontextprotocol.io/docs/tools/debugging) {"context":"connection"}
2025-03-30T21:23:43.812Z [mcp-clickhouse] [info] Client transport closed

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions