对《对MCP的批判性审视》的批判性审视
A Critical Look at "A Critical Look at MCP."

原始链接: https://docs.mcp.run/blog/2025/05/16/mcp-implenda-est/

这篇帖子为消息通信协议 (MCP) 辩护,反驳了对其提出的批评,特别是关于传输协议的批评。作者承认 MCP 的不足之处,但认为 MCP 的核心价值在于其能够通过标准化接口赋能大型语言模型 (LLM),使其能够使用工具并进行真实世界的交互。 作者强调,传输方法(STDIO、SSE、HTTP)是次要的,核心功能才是主要的,传输方法将根据实际需要不断发展。MCP 的一个重要优势是集成了 OAuth 2.0 进行身份验证,简化了对现有 API 的访问。 MCP 面临的真正挑战包括:混合匹配服务器带来的安全问题;令牌使用管理;以及确保安全上下文。远程服务器的多租户也带来了复杂性,例如一致的工具描述和潜在的恶意行为。此外,资源和服务器发送事件等某些功能缺乏广泛的客户端实现,可能面临被放弃的风险。重点应该放在引导协议向安全且易于访问的实现方向发展。

Hacker News 上的一个帖子讨论了对 MCP (mcp.run) 的批评。评论者“nip”称赞这篇批评指出了当前 MCP 规范的局限性,特别是关于远程服务器上的租户管理。他们认为最大的问题是缺乏工具调用上下文。理想情况下,此上下文将传递关于原始请求者的身份验证、授权和跟踪信息,从而实现“代表用户身份调用的工具”。这需要一个上游的身份验证和授权系统。“nip”声称在过去一年中一直在生产环境中设计了一个多租户工具调用实现,并邀请感兴趣的人通过他们的电子邮件(在其个人资料中列出)与他们联系。核心问题围绕着通过提供更好的工具调用上下文来增强远程服务器使用的安全性和问责制。
相关文章
  • 对MCP的批判性审视 2025-05-10
  • 2025-04-14
  • MCP 的一切问题 2025-04-14
  • (评论) 2025-03-26
  • MCP中的“S”代表安全。 2025-04-06

  • 原文

    or, a critical look at "A Critical Look at MCP."

    I came across this post shortly after finishing support for the HTTP Streaming transport on mcp.run. After a week or so of banging my head against the matrix of OAuth RFC support and client transport support, I should be in a sympathetic frame of mind to receive a critique of the protocol. And yet! Here I am, defending MCP. After all, the good that interfaces do oft lay interred with their blemishes.

    And MCP has blemishes.

    But I don't think we're in agreement about what they are, and where they pose actual danger to the value that MCP creates.

    level setting

    First, a bit about mcp.run, to level-set. (And, well, because it's business that sells goods and services -- and, not to put too fine a point on it, one which employs me.)

    mcp.run is a website that lets you build your own MCP server combined out of a number of other MCP servers. Those servers might be remote connections or they might be written in Wasm and run on your computer, or a combination of the two. Our goal is to make it easier for businesses to adopt MCP tools by handling the configuration and co-location of servers. We're sort of a "virtual" MCP server, in that sense.

    This is important for two reasons:

    One, MCP started out as a primarily "on-device" protocol, which meant that your MCP servers would run as a sub-process spawned by your client (Cursor, Windsurf, Claude Desktop, etc.) So delivering MCP servers in Wasm meant that these sub-processes couldn't take unexpected action. It also meant that we could safely host these servers ourselves in preparation for remote server transports to gain client adoption.

    Two, as we can host all of these servers for you, we can also hold onto any necessary configuration -- OAuth client data, tokens, configuration -- and ensure that it is only accessed on our servers using separately stored encryption keys. As adoption of MCP begins to tilt from "local servers" to "connecting to remote servers", this becomes more appealing: you can bring your configuration with you across multiple clients and ensure that only trusted tools can be run together. (This sidesteps one of the big security pain points of MCP, which is that MCP is only as secure as the least secure tool you've made available in your client.)

    And here's the important thing: MCP is an interface that's ratcheting up to meet the needs of its users. For a while, clients and servers were both local, then servers got more advanced via the SSE transport and tools like mcp-remote. Then clients caught up: see Claude's recent integration of OAuth and SSE transports. Now servers are on the move again: mcp-remote started to make the new HTTP transport available just this last week.

    transports are not the bottleneck

    Let me underline this: transports are the least important part of MCP. Whether communicating via STDIO, SSE+POST requests, WebSockets, carrier pigeons or HTTP streaming, it doesn't really matter, because they can change (and they have!) JSON-RPC over a bidirectional stream is an incidental choice. You can cobble a bidirectional stream together out of most household items in a pinch, depending on your tolerance for pain. JSONRPC is a useful framing but doesn't really affect the core information carried across that bidirectional wire once you've connected it.

    That said, the existing transports can be a pain. Keeping a stateful HTTP connection around (or mapping sessions to outgoing connections) isn't fun: it means having to keep some sticky information around about what server process is executing which client requests, and propagating that mapping down through layers of reverse proxies and CDNs. But even if MCP moved to WebSockets, that's still a long-lived, stateful connection -- and one of those parties between that client and your server is going to eventually close the connection. So the idea that you can map the statefulness of MCP to the statefulness of the transport is an illusory benefit. You must plan for disconnects and reconnects. And yeah, there's probably going to be a queue involved to shuttle messages from ingress MCP route A to egress MCP SSE connection B. But that's life! I fully expect the transports to change to address pain points in hosting MCP servers.

    oauth has been going great, really

    I turn now to something that MCP is doing really well: baking the concept of authentication into the protocol via OAuth 2.0 standards. This may come as a surprise, because OAuth can be Kind of A Lot -- but it makes a lot of sense if you look at why MCP is valuable in the first place. The promise of MCP -- of any of the tool calling standards -- is that tool-use promotes LLMs from "content printers" to agents that can affect the real world. And you really want a standard around tool use -- how to describe the tool to the LLM for use, how to format the arguments and what to expect from the output. The value there is so great that it really doesn't matter what else you get wrong so long as people -- client and server authors alike -- vote with their feet and implement your protocol.

    And that's happening! And at this stage of the protocol's evolution, these servers are starting to be predominately remote. And the easiest way for server authors to give an LLM something to affect the world is to give it access to existing, OAuth 2.0-authenticated APIs. Server authors working on large systems likely already have an OAuth 2.0 API. So they're not stuck reinventing the wheel to get clients authenticated to talk to their APIs.

    real problems

    So what are the problems with MCP as it stands?

    Well, I alluded to one before: the idea that a client will allow you to mix and match connections to various servers is a neat one, but ultimately it works against users. Tools in MCP work by contributing to the system prompt, which gives them privileged access to the LLM and the other tools they work with. So you have a dual problem of managing token usage and ensuring that tools are only used in secure contexts.

    (You can see where mcp.run slots into this system: consider paying us money to solve the problem for you!)

    Further, one of the issues with remote servers is tenancy -- whether servers are single or multi-tenant, and what that means for the tool descriptions they provide. As I mentioned before, MCP servers started out as predominantly local processes: mapping one server to one client via one connection. As remote transports mature, we're seeing that MCP servers may be multi-tenant -- one server to many client connections, dispatching MCP-level operations like tool listing and calling based on authentication information sent along with the request.

    There's an immediate problem: early MCP servers were written with single tenants in mind. It will require work to make them multi-tenant. But that's just typing work. And, I hear, we've got new-fangled tools to make the cost of typing work disappear to zero.

    The more subtle problem is that there's no longer a guarantee that an MCP server will advertise the same list of tools or resources to different users (or even the same user over time!) From a certain frame, this is a good thing: servers have control over tool lists, and control makes servers flexible. But consider that the descriptions from tool lists contribute to the system prompt in MCP-enabled sessions! This starts to become a problem: how do you surface that a server became malicious to end users?

    (Well, we're working on this solving this over at mcp.run -- and if you're interested, we sell goods and servic-cough. You've heard the spiel enough at this point.)

    Finally: the last issue is that there are features in MCP that are less widely implemented. In particular, I'm thinking of resources, prompting, and server sent events. These are features that represent more of a lift for LLM clients. That is to say: while Claude has support for resources, how do other LLMs fare with the concept? The idea of a resource is that you can create a chunk of data that doesn't have to appear in the context window, but the tradeoff is that the LLM has to know to faithfully convey the URI representing that resource to subsequent tool calls. This requires training, which is a far cry from the simple adapter one can write to translate from ChatGPT tool use calls to MCP tool calls.

    Similarly, server-sent events requires servers proactively keep a sideband connection to clients open in case they want to send a notification for tool list or resource changes. Many clients don't implement support for this, so it's kind of a dicey proposition for servers to support. Not supporting these notifications costs nothing, while supporting the feature is not guaranteed to pay off.

    There's a risk that features like these are annealed out as adoption of the protocol grows, and that's a shame because there are benefits to them.

    our job

    in which chris spins a sign pointing you to mcp.run for memorial day deals

    So if I were to leave you with something, it would be this: MCP's problems aren't caused by a lack of WebSockets. A lot of what you see about the protocol today is the result of rapid adoption, and the danger of rapid adoption is that useful features can be shaved off or implemented in insecure fashion. It's easy to look at STDIO servers and identify a thousand-and-one ways in which they're insecure, but that's not where the puck is heading. Our collective job, as the folks voting with our feet, is to try to shift the protocol's momentum with our implementations so that the when the protocol sets up, it's easy for everyone to use safely.

    联系我们 contact @ memedata.com