How MCP Works
This page walks through the MCP lifecycle from connection initialization to tool execution.
Lifecycle: Initialize and Negotiate
MCP connections are stateful and begin with an initialization handshake where client and server negotiate protocol version and capabilities.
Typical sequence:
- Client -> Server:
initialize(declares protocol version + client capabilities) - Server -> Client:
initializeresponse (declares server capabilities) - Client -> Server:
notifications/initialized(signals it's ready)
// 1. Client sends initialize
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {
"name": "mentium",
"version": "1.0.0"
}
}
}
// 2. Server responds with capabilities
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {}
},
"serverInfo": {
"name": "my-freight-server",
"version": "0.1.0"
}
}
}
// 3. Client sends initialized notification
{
"jsonrpc": "2.0",
"method": "notifications/initialized"
}Discovery: List Tools and Resources
After initialization, the client discovers what the server offers using list methods:
tools/list-- list available toolsresources/list-- list available resources
The server returns metadata including a JSON Schema for each tool's inputs. The host (Mentium) uses this to register the tools so AI Agents can call them.
// Request
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}
// Response
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"tools": [
{
"name": "quote_get_status",
"description": "Fetch current quote status and last activity",
"inputSchema": {
"type": "object",
"properties": {
"quoteId": { "type": "string" }
},
"required": ["quoteId"]
}
}
]
}
}Tool Execution: The Host Routes Tool Calls
When the model decides it needs an action, the host:
- Creates a
tools/callrequest - Sends it to the right MCP server
- Receives the tool result
- Feeds the result back into the model's context so it can continue
// Request: call a tool
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "quote_get_status",
"arguments": {
"quoteId": "Q-104883"
}
}
}
// Response: tool result
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "{\"quoteId\":\"Q-104883\",\"status\":\"SENT\",\"opened\":true,\"customerReplied\":false}"
}
]
}
}Resources: Context Without Actions
Resources are "look but don't touch" context. Your agent might read:
- Last 10 emails with a customer
- The original quote request payload
- Current rate table snapshot
Use resources when you want to avoid side effects and keep behavior predictable.
Transports: Local (stdio) vs Remote (Streamable HTTP)
MCP defines two standard transport mechanisms:
stdio (Local)
Local subprocess communication via stdin/stdout. Messages are newline-delimited JSON-RPC. stdout must contain only valid MCP messages.
Best for: local development, desktop apps, CLI tools.
Streamable HTTP (Remote)
Remote server accessed via an HTTP endpoint:
- POST to send messages (JSON-RPC requests)
- GET (optional) to open an SSE stream for server-to-client messages
WARNING
Streamable HTTP includes explicit security guidance: validate Origin headers, prefer binding to localhost for local servers, and require authentication on all connections.
| Transport | Use Case | Security |
|---|---|---|
| stdio | Local tools, development | Env vars for credentials |
| Streamable HTTP | Remote servers, production | TLS + API key / OAuth |
TIP
When connecting external MCP servers to Mentium, Streamable HTTP is the transport used. Your server needs to be accessible over HTTPS and accept an API key for authentication.