TL;DR Each MCP tool puts a contract in the model鈥檚 context. I keep related typed filters together and let the agent shape authorised results in code. Server-side scoping stays where access requires it. Progressive discovery stops a large catalog from using too much context. The tempting way to build a data MCP server is one
query_data(dataset, filters) tool. Every new slice adds another branch to its filter grammar. The agent clients I use give the model a code execution environment, so I first ask whether the server needs to shape the result. If the caller may see the full dataset, the tool can return the rows and let the agent work with them in Python or DuckDB. A small
skill can explain the dataset鈥檚 conventions.