Every MCP client — Claude Desktop, Cursor, Windsurf, Cline — has slightly different auth expectations. The three-week glue job nobody talks about.
You write an MCP server that lets Claude query your Notion. It works on localhost. Then a colleague wants to use it from their machine. Then you realize you have to build OAuth. Then you realize you have to build it once per MCP client.
There are, at the time of writing, at least six MCP clients in active use: Claude Desktop, Cursor, Windsurf, Cline, Continue, and Zed. Each one has slightly different assumptions about how tokens arrive, when they refresh, and what happens when they don't. These differences aren't documented as differences — every client thinks its behavior is the obvious one. So you find out at 3am when a user reports that Cursor works but Windsurf doesn't.
Here's a partial list of things different MCP clients do differently, that a naive server author will not anticipate:
Every one of these is a nightmare on its own. Together they are why so many MCP servers say "works in Claude only."
Cognoverge sits in front of every server as an OAuth proxy. When Claude connects, we speak Claude's dialect. When Cursor connects, we speak Cursor's. We normalize everything to a single canonical token that the underlying server never sees.
This is unglamorous work — half of it is reading closed-source client behavior with a proxy and comparing hashes. But once the conformance matrix is built, the developer writing the server never touches it. They install the SDK and call getUser(). That's it. It works in every client.
OAuth conformance is the moat, and nobody wants to build it. That is why we're building it. If MCP settles into a single canonical client dialect, this moat evaporates. Until then, it deepens weekly as new clients ship.
Everything in this post runs in the platform we built. Free forever tier. Deploy in 30 seconds.