MCP clients
You know what an MCP server is and why it exists. Now the question is how your application actually talks to one — and the answer is the MCP client, the piece of code that handles all the protocol details so your application logic does not have to.
The MCP client is the communication bridge between your server and the MCP servers you connect to. It is your single access point for discovering and invoking whatever tools an MCP server offers, and it abstracts away the transport and message formatting.
Transport agnostic communication
The client and server communicate over whatever transport makes sense for the deployment. The most common setup runs both on the same machine and talks over stdin/stdout — fast, local, zero network. But MCP is transport agnostic: the same protocol works over HTTP, WebSockets, and other network transports when you need to cross process or machine boundaries.
For this course, stdin/stdout is what you will use. Everything else is a deployment detail.
The two message types that matter
Once a client and server are connected, they exchange structured messages defined in the MCP spec. For tools, there are two request/result pairs you will see constantly:
- ListToolsRequest / ListToolsResult — the client asks the server "what tools do you provide?" and gets back the list of available tools with their schemas.
- CallToolRequest / CallToolResult — the client asks the server to run a specific tool with a given set of arguments, and gets back the tool's result.
That is the whole tool-side vocabulary. Discovery, then invocation.
The full request flow
Here is what actually happens when a user asks your chatbot "What repositories do I have?" End to end, user back to user:
- User query. The user submits the question to your server.
- Tool discovery needed. Your server needs the list of available tools to pass to Claude.
- Server asks the client. Your server calls into the MCP client for the current tool list.
- ListTools exchange. The MCP client sends a
ListToolsRequestto the MCP server and receives aListToolsResult. - Claude request. Your server sends the user's query plus the tool list to Claude.
- Tool use decision. Claude decides it needs to call a tool to answer the question.
- Execution request. Your server asks the MCP client to run the tool Claude specified.
- CallTool exchange. The MCP client sends a
CallToolRequestto the MCP server, which performs the actual GitHub API call. - Results flow back. GitHub responds, the MCP server wraps the result as a
CallToolResult, and it returns to your server. - Results to Claude. Your server sends the tool results back to Claude.
- Final response. Claude uses the repository data to formulate an answer.
- User gets the answer. Your server delivers Claude's response to the user.
Twelve steps sounds like a lot, but each component has a single, clear responsibility. The MCP client's job is to abstract steps 4 and 8 — the actual protocol exchange — so your application code only has to ask for a tool list or request a tool call. Everything else is either your server's orchestration or Claude's reasoning.
Internalise this flow now. You will see every one of these steps in the next module when you run the CLI chatbot and build out both sides of this conversation yourself.
Key Takeaways
- 1The MCP client is the communication bridge between your server and MCP servers, handling protocol details so your application logic stays clean.
- 2MCP is transport agnostic — stdin/stdout is the common local setup, but HTTP and WebSockets work equally well.
- 3Tools rely on two request/result pairs: ListTools for discovery and CallTool for invocation.
- 4Every user query flows through a well-defined chain: your server, the MCP client, the MCP server, the external API, Claude, and back — each component with a single responsibility.