Two Protocols, Three Translations: How a Host Bridges MCP and an LLM Provider API
DEV Community

Two Protocols, Three Translations: How a Host Bridges MCP and an LLM Provider API

Following one question through the MCP stack - from the user's prompt to the final answer

Modern AI applications increasingly sit between two different worlds: MCP (Model Context Protocol) and an LLM provider API. MCP provides a standardized way for an AI application to discover and invoke external tools. The LLM provider API provides the interface through which the application sends prompts, tool definitions, and tool results to the model. The important part is that these two systems do not necessarily speak the same format.

The Host sits between them. The Host discovers tools from an MCP Server, translates those tools into the format expected by the LLM provider, receives the LLM's tool decision, translates that decision back into an MCP request, executes the tool, and finally translates the result back into the provider's format so the LLM can produce a natural-language response.

This creates a useful mental model: Two protocols. Three translations. One complete tool-call lifecycle.

In this article, we will follow one simple question through the entire process: "What is 5 plus 7?"

Our MCP Server exposes one tool: add_numbers(a: number, b: number) -> number

We will follow the request through 20 steps, divided into four phases:

  1. Discovery - Steps 1-6
  2. Translation and LLM Decision - Steps 7-10
  3. Execution - Steps 11-16
  4. Result and Response - Steps 17-20

1. The Architecture

Before looking at the 20 steps, we need to understand the components involved. The architecture looks approximately like this:

┌──────────────────┐
│ USER │
│ "What is 5 + 7?" │
└────────┬─────────┘
         │
         โ–ผ
┌──────────────────┐
│ HOST │
││ │
│ Agent /│
│ Orchestrator │
└────────┬─────────┘
         │ MCP / JSON-RPC
         โ–ผ
┌──────────────────┐
│CLIENT│
└────────┬─────────┘
         │
         โ–ผ
┌──────────────────┐
│SERVER│
││ │
│ Tool Registry│
││ │
│ add_numbers│
└──────────────────┘
┌──────────────────┐
│ HOST │
└────────┬─────────┘
         │ Provider API
         โ–ผ
┌──────────────────┐
│ LLM│
││ │
│ Tool selection │
│ Argument creation│
└──────────────────┘

The most important thing to understand is that there are two protocol boundaries.

The first is the MCP side. The MCP Client and MCP Server communicate using MCP messages based on JSON-RPC. For example:

{ "method" : "tools/list" , "id" : 1 }

Or:

{ "method" : "tools/call" , "params" : { "name" : "add_numbers" , "arguments" : { "a" : 5 , "b" : 7 } }, "id" : 2 }

The second side is the LLM provider API. The Host does not simply send those MCP JSON-RPC messages directly to the LLM. Instead, the Host translates the MCP tool definition into the format expected by the provider. For example, conceptually:

{ "name" : "add_numbers" , "description" : "Adds two numbers" , "parameters" : { "type" : "object" , "properties" : { "a" : { "type" : "number" }, "b" : { "type" : "number" } }, "required" : [ "a" , "b" ] } }

The LLM can then respond with a provider-specific tool or function call such as:

{ "function_call" : { "name" : "add_numbers" , "arguments" : "{ \" a \" :5, \" b \" :7}" } }

The Host then translates this back into an MCP tools/call request. That is the bridge.

Phase 1 - Discovery Steps 1-6

The first phase answers one fundamental question: What tools are available? At this point, the LLM has not yet been asked to solve the user's question. The Host first needs to discover what tools are available from the MCP Server.

Step 1 - The User asks a question

The user enters: What is 5 plus 7?

The Host receives this prompt. At this moment, the Host knows what the user wants, but it may not yet know what tools are available on the connected MCP Server.

Step 2 - The Host starts discovery

The Host's orchestration layer starts the agent process. Conceptually, we could imagine something like:

await agent . run ( " What is 5 plus 7? " );

The Host now needs to discover the tools that are available. It asks the MCP Client to perform tool discovery.

Step 3 - The Client sends tools/list

The MCP Client sends an MCP request to the Server. Conceptually:

{ "method" : "tools/list" , "id" : 1 }

This is an MCP request using JSON-RPC. The important point is that this message is part of the MCP communication between the Client and Server. The LLM is not involved yet.

Step 4 - The Server reads its tool registry

The MCP Server receives the tools/list request. The server maintains a tool registry. Conceptually, the registry might contain:

{ name : " add_numbers " , description : " Adds two numbers " , inputSchema : { ... }, handler : ... }

The registry contains both the public definition of the tool and the executable handler. However, the Server does not send the implementation of the handler to the Client. Instead, it exposes the public contract: name, description, input schema.

For example:

{ "name" : "add_numbers" , "description" : "Adds two numbers" , "inputSchema" : { "type" : "object" , "properties" : { "a" : { "type" : "number" }, "b" : { "type" : "number" } }, "required" : [ "a" , "b" ] } }

The Server is effectively saying: "I have a tool called add_numbers. It accepts two numbers: a and b."

Step 5 - The Server returns the tool list

The Server responds to the Client. Conceptually:

{ "id" : 1 , "result" : { "tools" : [ { "name" : "add_numbers" , "description" : "Adds two numbers" , "inputSchema" : { "type" : "object" , "properties" : { "a" : { "type" : "number" }, "b" : { "type" : "number" } }, "required" : [ "a" , "b" ] } } ] } }

Notice what was returned. The Server returned:

  • name
  • description
  • schema

It did not return:

  • the implementation of the function

The handler remains on the Server.

Step 6 - The Client gives the tools to the Host

The MCP Client receives the response. It passes the discovered tools back to the Host. The Host now knows:

  • Tool: add_numbers
  • Arguments: a: number, b: number

The discovery phase is complete. The Host can now tell the LLM what tools are available.

Phase 2 - Translation and LLM Decision Steps 7-10

This is where one of the most important architectural concepts appears. The Host has an MCP tool definition. But the LLM provider does not necessarily understand MCP's tool representation. Therefore, the Host must perform a translation.

Step 7 - Translation #1

The Host converts the MCP tool schema into the tool/function schema expected by the LLM provider. Conceptually:

MCP Tool Schema
|
| Translation #1
v
LLM Provider Tool Schema

The MCP tool might look conceptually like:

{ "name" : "add_numbers" , "description" : "Adds two numbers" , "inputSchema" : { "type" : "object" , "properties" : { "a" : { "type" : "number" }, "b" : { "type" : "number" } }, "required" : [ "a" , "b" ] } }

The Host transforms it into something the provider understands:

{ "name" : "add_numbers" , "description" : "Adds two numbers"
Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.