A year ago we built a custom Sentry integration for Claude Code. We wrote a wrapper around Sentry's REST API, exposed it as a set of tools Claude could invoke, and shipped it. It worked well. We used it for 8 months.
Then we rewrote the whole thing as an MCP server. This post is why. If you're evaluating custom integrations vs MCP for your own tooling, the tradeoff analysis here may save you time.
MCP (Model Context Protocol) is Anthropic's open protocol for exposing external tools and data to AI assistants. Instead of every AI tool building its own custom integrations, MCP lets any AI assistant talk to any MCP server. It's open source, actively developed, and has a growing ecosystem.
The custom integration (year one)
Our v1 setup: a set of custom slash commands like /sentry-issue, /sentry-search, /sentry-events. Each command wrapped a specific Sentry API call — fetch an issue by ID, search by query, get recent events for a project.
The commands worked. Claude could pull Sentry data when investigating incidents. Nothing wrong with it functionally. But over 8 months, the maintenance cost crept up:
- Sentry's API evolved. New endpoints for tags, breadcrumbs, session replay. Every new feature we wanted meant writing another wrapper command.
- Auth handling was ad-hoc. Each command had its own auth code. Token refresh, error handling, retries — duplicated across commands with slight variations.
- Error messages were inconsistent. Some commands returned pretty errors; some returned raw Sentry JSON. Depended on when each command was written.
- Documentation drift. The docs said one thing; the code did another. Nobody had time to sync them.
- No one else benefited. Every other team that wanted Claude Code + Sentry was writing their own custom integration, going through the same pain.
Every team that wanted Sentry in Claude Code was writing the same integration from scratch. That was the smell.
What MCP changed
The MCP-based integration is different in kind, not degree. Instead of individual slash commands wrapping API calls, there's one Sentry MCP server that exposes many tools (fetch_issue, search_issues, list_events, etc.). Claude discovers what's available at session start and can call any of them naturally.
The concrete wins:
- One integration, many tools. Adding a new capability (e.g., session replay support) means adding a tool to the MCP server. All Claude sessions get it automatically on the next restart.
- Auth handled centrally. The MCP server handles OAuth, token refresh, error handling once. Individual tools don't deal with it.
- Structured error responses. MCP has a defined error format. Consistent across all tools. Claude handles errors uniformly.
- Discovery is automatic. Claude sees available tools on session start. New tools appear without me telling anyone.
- Shared with the community. Sentry maintains the official Sentry MCP server. We just install it. When they add features, we benefit. When we find bugs, we file issues. Standard OSS dynamic.
The migration
The rewrite took about 2 weeks of one engineer's time. Most of that was validation — running old and new side-by-side on real incidents to confirm the MCP version returned equivalent results, checking that Claude used the new tools as effectively as the old commands.
The actual "swap the integration" step was maybe two hours: add the Sentry MCP server to .claude/settings.json, remove the old slash commands, update our incident-investigator subagent to reference the MCP tools instead of the custom ones.
{
"mcp": {
"sentry": {
"type": "http",
"url": "https://mcp.sentry.dev/mcp",
"auth": { "type": "oauth" }
}
}
}That's the entire integration. The MCP server exposes ~15 tools; Claude can use any of them. No command files, no auth code, no error handling code in our repo.
What we lost
Being honest — some things got worse:
- Less customization. Our custom commands had opinions (format the output this way, sort by X, filter Y). The MCP tools are more generic. We can wrap them in a custom command if we want the opinions back, but that's extra work.
- Debugging is harder. When our custom command failed, we could add a print statement. When the MCP server fails, we need to look at MCP server logs or file an issue with the maintainer.
- Latency is slightly higher. The MCP server is a separate process, one more network hop. In practice, adds ~50-200ms per tool call. Not noticeable in most cases but real.
- Dependency on external service. If the Sentry MCP server has bugs or breaks, we're waiting for a fix rather than fixing it ourselves.
For the "less customization" issue, we still write custom slash commands when we need opinionated output. Those commands call the MCP tools underneath. Best of both: shared infrastructure via MCP, team-specific opinions via commands. Not either/or.
The decision framework
When to pick MCP over custom integration:
- An official MCP server exists for the service you're integrating. If Sentry/Datadog/GitHub/Linear maintains an official server, install it. Reinventing it is wasted work.
- You want the integration to keep pace with the underlying service. MCP servers get updated by service maintainers. Custom integrations get updated by you.
- Other teams use the same service. You benefit from shared bug reports, features, docs. Ecosystem effects compound.
- The service has a well-defined API. MCP works well for services with stable REST/GraphQL APIs. Less well for services requiring extensive custom logic or complex auth flows.
When to stick with custom:
- No official MCP server exists and building one is more work than you want. Custom commands are lower effort for a one-off integration.
- Your integration is very team-specific. Wrapping your internal service that only your company uses. No shared value from making it an MCP server.
- You need extensive customization. If most of the value is in your custom logic (not the underlying service), custom commands stay simpler.
- Latency is critical. The extra hop adds tens to hundreds of milliseconds. For hot-path use, custom might be worth it.
Six months in
August 2026 update: we've been on the MCP-based Sentry integration for six months. Retrospective:
- Would we go back? No.
- Has the MCP integration kept up with our needs? Yes, mostly. Sentry added session replay support in May; the MCP server had it available a few weeks later. That would have been weeks of our engineering time in the custom-integration world.
- Have we hit MCP bugs? Two. Both filed as issues, one fixed within a week, one still open (workaround exists).
- Have we needed the custom slash-command layer on top? Yes — three of them, for team-specific incident triage patterns. That's the "MCP for infrastructure, commands for opinions" pattern in action.
- Would we recommend this to other teams? Yes, with the caveat that MCP is still a young ecosystem. Some services have great official MCP servers; some don't have any. Check availability before committing.
MCP for infrastructure, custom commands for opinions. Both, not either.
Applying this to your team
The general principle: use MCP for shared infrastructure, custom for team-specific opinions. This applies beyond Sentry — same logic for Datadog vs custom Datadog wrappers, GitHub MCP vs custom GitHub commands, etc.
The catalog of official MCP servers is at /mcp. We maintain integrations docs for the 12 most-used ones. If the service you use is on that list, install the MCP server first, then write custom commands on top only for the parts where you need team-specific opinions.
The 8 months we spent on the custom Sentry integration wasn't wasted — we learned what we needed from an integration, which helped us know what to look for in the MCP version. But if we'd had the MCP server available from day one, we'd have saved most of that effort. That's the pattern to watch for on your side: don't reinvent what already exists as an MCP server.
Get cctk running in one command
85 slash commands, 12 subagents, 12 MCP integrations, 12 hooks. All the patterns from this post are shipped in cctk.