After reading the Python server tutorial, it looks like there is some tool calling going on, in the old terminology. That makes more sense. But none of the examples seem to indicate what the protocol is, whether it's a RAG sort of thing, do I need to prompt, etc.
It would be nice to provide a bit more concrete info about capabilities and what the purposes is before getting into call diagrams. What do the arrows represent? That's more important to know than the order that a host talks to a server talks to a remote resource.
I think this is something that I really want and want to build a server for, but it's unclear to me how much more time I will have to invest before getting the basic information about it!
The gist of it is: you have an llm application such as Claude desktop. You want to have it interact (read or write) with some system you have. MCP solves this.
For example you can give the application the database schema as a “resource”, effectively saying; here is a bunch of text, do whatever you want with it during my chat with the llm. Or you can give the application a tool such as query my database. Now the model itself can decide when it wants to query (usually because you said: hey tell me what’s in the accounts table or something similar).
It’s “bring the things you care about” to any llm application with an mcp client
It's not introducing new capabilities, just solving the NxM problem, hopefully leading to more tools being written.
(At least that's how I understand this. Am I far off?)
On tools specifically, we went back and forth about whether the other primitives of MCP ultimately just reduce to tool use, but ultimately concluded that separate concepts of "prompts" and "resources" are extremely useful to express different _intentions_ for server functionality. They all have a part to play!
It would probably be helpful for many of your readers if you had a focused document that addressed specifically that motivating question, together with illustrated examples. What does MCP provide, and what does it intend to solve, that a tool calling interface or RPC protocol can't?
The N×M problem may simply be moved rather than solved:
- Instead of N×M direct integrations
- We now have N MCP client implementations
- M MCP server implementations
This feels similar to SOAP but might be more of a lower level protocol similar to HTTP itself. Hard to tell with the implementation examples being pretty subjective programs in python. - A host never talks to a server directly, only via a Client (which is presumably a human). The host has or is the LLM (app).
- A server only supplies context data (readonly), in the form of tool call, direct resource URL, or pre populated prompt. It can call back to a client directly, for example to request something from the hosts LLM.
- A client sits in the middle, representing the human in the loop. It manages the requests bidirectionally
It seems mostly modeled around the security boundaries, rather than just AI capabilities domains. The client is always in the loop, the host and server do not directly communicate.https://github.com/modelcontextprotocol/servers/blob/main/sr...
How can an add on that works with arbitrary "servers" tell the difference between these two tools? Without being able to tell the difference you can't really build a generic way to ask for confirmation in the application that is using the server...
{
name: "create_directory",
description:
"Create a new directory or ensure a directory exists. Can create multiple " +
"nested directories in one operation. If the directory already exists, " +
"this operation will succeed silently. Perfect for setting up directory " +
"structures for projects or ensuring required paths exist. Only works within allowed directories.",
inputSchema: zodToJsonSchema(CreateDirectoryArgsSchema) as ToolInput,
},
{
name: "list_directory",
description:
"Get a detailed listing of all files and directories in a specified path. " +
"Results clearly distinguish between files and directories with [FILE] and [DIR] " +
"prefixes. This tool is essential for understanding directory structure and " +
"finding specific files within a directory. Only works within allowed directories.",
inputSchema: zodToJsonSchema(ListDirectoryArgsSchema) as ToolInput,
},import anthropic
client = anthropic.Anthropic()
response = client.messages.create( model="claude-3-5-sonnet-20241022", max_tokens=1024, [mcp_server]=... ## etc.? ... )
(forgive me if you know this and are asking a different question, but:)
I don't know how familiar you are with LLMs, but "context" used in that context generally has the pretty clear meaning of "the blob of text you give in between (the text of) the system prompt and (the text of) the user prompt"[1], which acts as context for the user's request (hence the name). Very often this is the conversation history in chatbot-style LLMs, but it can include stuff like the content of text files you're working with, or search/function results.
[1] If you want to be pedantic, technically each instance of "text" should say "tokens" there, and the maximum "context" length includes the length of both prompts.
1. The sampling documentation is confusing. "Sampling" means something very specific in statistics, and I'm struggling to see any connection between the term's typical usage and the usage here. Perhaps "prompt delegation" would be a more obvious term to use.
Another thing that's confusing about the sampling concept is that it's initiated by a server instead of a client, a reversal of how client/server interactions normally work. Without concrete examples, it's not obvious why or how a server might trigger such an exchange.
2. Some information on how resources are used would be helpful. How do resources get pulled into the context for queries? How are clients supposed to determine which resources are relevant? If the intention is that clients are to use resource descriptions to determine which to integrate into prompts, then that purpose should be more explicit.
Perhaps a bigger problem is that I don't see how clients are to take a resource's content into account when analyzing its relevance. Is this framework intentionally moving away from the practice of comparing content and query embeddings? Or is this expected to be done by indices maintained on the client?
One bit of constructive feedback: the TypeScript API isn't using the TypeScript type system to its fullest. For example, for tool providers, you could infer the type of a tool request handler's params from the json schema of the corresponding tool's input schema.
I guess that would be assuming that the model is doing constrained sampling correctly, such that it would never generate JSON that does not match the schema, which you might not want to bake into the reference server impl. It'd mean changes to the API too, since you'd need to connect the tool declaration and the request handler for that tool in order to connect their types.
Could I convince you to submit a PR? We'd love to include community contributions!
In case of Claude Desktop App, I assume the decision which MCP-server's tool to use based on the end-user's query is done by Claude LLM using something like ReAct loop. Are the prompts and LLM-generated tokens involved inside "Protocol Handshake"-phase available for review?
(Closest I can find is zed/cody but those aren't really general purpose)
From what I’ve seen, OpenAI attempted to solve the problem by partnering with an existing company that API-fys everything. This feels looks a more viable approach, if compared to effectively starting from scratch.
this is really cool stuff. I just started to write a server and I have a few questions. Not sure if HN is the right place, so where would you suggest to ask them?
Anyway, if there is no place yet, my questions are:
- In the example https://modelcontextprotocol.io/docs/first-server/python , what is the difference between read_resources and call_tool. In both cases the call the fetch_weather function. Would be nice to have that explained better. I implemented in my own server only the call_tool function and Claude seems to be able to call it.
- Where is inputSchema of Tool specified in the docs? It would be nice if inputSchema would be explained a bit better. For instance how can I make a list of strings field that has a default value.
- How can i view the output of logger? It would be nice to see somewhere an example on how to check the logs. I log some stuff with logger.info and logger.error but I have no clue where I can actually look at it. My work around now is to log to a local file and tail if..
General feedback
- PLEASE add either automatic reload of server (hard) or a reload button in the app (probably easier). Its really disrupting to the flow when you have ot restart the app on any change.
- Claude Haiku never calls the tools. It just tells me it can't do it. Sonnet can do it but is really slow.
- The docs are really really version 0.1 obviously :-) Please put some focus on it...
Overall, awesome work!
Thanks
In addition, I recommend looking at the specification documentation at https://spec.modelcontextprotocol.io. This should give you a good overview of how to implement a client. If you are looking to see an implemented open source client, Zed implements an MCP client: https://github.com/zed-industries/zed/tree/main/crates/conte...
If you have specific questions, please feel free to start a discussion on the respective https://github.com/modelcontextprotocol discussion, and we are happy to help you with integrating MCP.
Internally we have seen people experiment with a wide variety of different integrations from reading data files to managing their Github repositories through Claude using MCP. Alex's post https://x.com/alexalbert__/status/1861079762506252723 has some good examples. Alternatively please take a look at https://github.com/modelcontextprotocol/servers for a set of servers we found useful.
https://github.com/anaisbetts/mcp-youtube
Claude doesn't support YouTube summaries. I thought that was annoying! So I added it myself, instead of having to hope Anthropic would do it
Is there a recommended resource for building MCP client? From what I've seen it just mentions Claude desktop & co are clients. SDK readme seems to cover it a bit but some examples could be great.
The best starting point are the respective client parts in the SDK: https://github.com/modelcontextprotocol/typescript-sdk/tree/... and https://github.com/modelcontextprotocol/python-sdk/tree/main..., as well as the official specification documentation at https://spec.modelcontextprotocol.io.
If you run into issues, feel free to open a discussion in the respective SDK repository and we are happy to help.
(I've been fairly successful in taking the spec documentation in markdown, an SDK and giving both to Claude and asking questions, but of course that requires a Claude account, which I don't want to assume)
I'm looking at integrating MCP with desktop app. The spec (https://spec.modelcontextprotocol.io/specification/basic/tra...) mentions "Clients SHOULD support stdio whenever possible.". The server examples seem to be mostly stdio as well. In the context of a sandboxed desktop app, it's often not practical to launch a server as subprocess because:
- sandbox restrictions of executing binaries
- needing to bundle binary leads to a larger installation size
Would it be reasonable to relax this restriction and provide both SSE/stdio for the default server examples?
I can totally see your concern about sandboxed app, particularly for flatpack or similar distribution methods. I see you already opened a discussion https://github.com/modelcontextprotocol/specification/discus..., so let's follow up there. I really appreciate the input.
(and then having a smol node/bun/go/whatever app that can sit in front of any server that handles stdio - or a listening socket for a server that can handle multiple clients - and translates the protocol over to SSE or websockets or [pick thing you want here] lets you support all such servers with a single binary to install)
Not that there aren't advantages to having such things baked into the server proper, but making 'writing a new connector that works at all' as simple as possible while still having access to multiple approaches to talk to it seems like something worthy of consideration.
[possibly I should've put this into the discussion, but I have to head out in a minute or two; anybody who's reading this and engaging over there should feel free to copy+paste anything I've said they think is relevant]
Is it versioned? ie. does this release constitute an immutable protocol for the time being?
Thanks for your hard work! "LSP for LLMs" is a fucking awesome idea
It's not exactly immutable, but any backwards incompatible changes would require a version bump.
We don't have a roadmap in one particular place, but we'll be populating GitHub Issues, etc. with all the stuff we want to get to! We want to develop this in the open, with the community.
And the GitHub repo: https://github.com/modelcontextprotocol
Second, a question. Computer Use and JSON mode are great for creating a quasi-API for legacy software which offers no integration possibilities. Can MCP better help with legacy software interactions, and if so, in what ways?
The benefit would be that to the application connecting to your MCP server, it just looks like any other integration, and you can encapsulate a lot of the complexity of Computer Use under the hood.
If you explore this, we'd love to see what you come up with!
I'm looking at a PostgreSQL integration here: https://github.com/modelcontextprotocol/servers/tree/main/sr...
I have a case in mind where I would like to connect to multiple databases. Does the integration endpoint specification in claude_desktop_config.json allow us to pass some description so as to differentiate different databases? How?
For instance, when there is something wrong for MCP host, it query all data from database and transfer it to host, all data will be leaked.
It's hard to totally prevent this kind of problem when interacting with local data, But, Is there some actions to prevent this kind of situations for MCP?
MCP: I've gotten 2,415 times smarter since then.