cra
mr

A Bigger Toolbox for MCP

A Bigger Toolbox for MCP

If you don’t know about it already, Sentry has an MCP server that has quite a large adoption spectrum. It started as a focused way to get error context into your coding agent, and has only grown since then. Unfortunately there was a serious problem with Sentry’s MCP server - and most other MCP servers - in that it has or needs too many tools. We explicitly minimized this problem by constraining the number of tools we expose to agents, as by having too many you worsen the behavior of agents due to context noise (and thus, degrade overall quality). In practice that meant rejecting many user requests to add additional behavior.

To work around that we tried a few things that worked with mixed results. Agent Mode was our first pass, which bundled up all the tools within an agent, exposing that as a single use_sentry tool. That worsened the user experience. Steering got worse (organic inputs didn’t always pick up the tools), and response times were ~doubled.

Our next attempt was to overload the tools we did have. We took things like get_issue_details and buried it inside of a get_sentry_resource tool. That meant a single tool to get a large variety of objects/URLs. It worked somewhat ok, but only solved a fraction of our problems. This gets more complicated when you consider how fetching objects often needs relations, or even worse when you’re trying to resolve concerns like listing/searching those objects.

#Enter Code Mode

In parallel you keep hearing about Code Mode and how it’s so fucking great (author has no opinion) and helps solve this problem. What they don’t tell you is how Code Mode requires you to control the agent, because under the hood all it’s doing is progressive tool loading via search and execute tools. To do that it has to have an agent determine which tools it needs, write the code to execute against those tools, then execute said code. Suffice to say it’s complex.

What if you could accomplish the same thing - to a degree - without Code Mode? That is, what if we could bundle up a bunch of tools behind search? That would let us offload the responsibility of agent optimization to the agent authors, and work around the negatives of exposing a large quantity of tools to the agent.

#Exit Code Mode

So we did just that. We shipped search_tools and execute_tool inside of the Sentry MCP server.

With the default permissions, this now reduces Sentry’s tool surface area even further while drastically increasing the capabilities we provide. We went from exposing 14 native tools by default, to now 8 native tools with another 19 catalog tools (and counting!) exposed behind search and execute. This allows agents to make fewer errors at the cost of another round-trip or two. It can choose to use get_sentry_resource or directly call execute_tool to hit the underlying get_issue_details tool.

Implementing this was about as simple as you can imagine, but there’s a bit of complexity depending on what you’re trying to do.

execute_tool is the easiest component. It just requires you to accept the toolName and the arguments that get passed into it. We have some wrappers around this so under the hood it’s the same tool signatures for everything, but if you throw an agent on this it will do a good job.

{
  "name": "execute_tool",
  "arguments": {
    "toolName": "get_issue_details",
    "arguments": {
      "organizationSlug": "acme",
      "issueId": "123456"
    }
  }
}

search_tools is where things get a bit more complicated, and might vary based on your situation. For instance, with Code Mode (used behind the scenes at Sentry) we have found that you may need a search index to reliably identify the right tools (often using semantic search). In the MCP server all we’ve done is a simple string comparison on terms in the search query, but you can imagine how you might approach it.

For example, to do semantic search, we’d generate embedding vectors and write them into the source code whenever we changed the tool name, description or input parameters. We’d then run a single embedding pass with every search_tools call (which, yes, has a small cost).

A simpler, but more expensive, alternative approach would be to run a cheap model which has access to all the same information as part of its system prompt, and run that to determine the best tools. It will have a ~similar outcome to embeddings, is more flexible, but the cost could vary widely.

#In Practice

We often dogfood heavily these behaviors to come back with an intuition on what is good and bad, and angle in that direction. In addition to that though we use Sentry’s tracing product as a poor man’s (rich man’s? unclear) analytics provider. As soon as we implemented this there were obvious gaps that we had to address to understand customer behavior better.

The first was tool call attribution. Our native MCP integration automatically annotates every tool call, but in this case we care less about execute_tool and more about the underlying child call. This is important as it gives us an idea of what’s being used, roughly who’s using it, and helps us understand more broadly what’s going on. To address this we expanded traces so both execute_tool and the underlying tool get the same semantics applied (e.g. gen_ai.tool.name, parent -> child), but additional concerns arise here that are more subjective.

Tracing MCP tool calls

“How well is it working?”, or “what tools are people after” are almost more important, and interestingly easy to answer now with this. Our search_tools contains the query param (which we capture), and we also tag a gen_ai.tool.call.result.count value. This lets us easily find no-result queries, and more so we can run an agent across a sampling of these spans to analyze what is and isn’t working well. We actually couldn’t have known about this before, as we don’t have visibility into the actual prompts that trigger our tool calls, so knowing what folks are after would require the customers directly telling us.

We’re still early here - we shipped this to GA in early June - but so far things appear to be working quite well in our own experience. The agents are naturally making the right tool calls, similar to how they were when many of these tools were exposed natively. Importantly this is going to allow us to fill in a LOT of gaps in our tool suite, making the MCP even more powerful, and bringing its scope up to par with Sentry’s CLI.

More Reading

2026

Context Management and MCP

MCP, Skills, and Agents

2025

Rethinking Tools in MCP