Careeroza
Hosts, Clients and Servers
The Three Roles
| Role | What it is | Example |
|---|---|---|
| Host | the AI application the user works in | Claude Desktop, Claude Code, an IDE, your FastAPI chatbot |
| Client | a connection inside the host, one per server | created by the host when it starts a server |
| Server | a program that exposes tools, resources and prompts | GitHub MCP server, your ShopEase orders server |
Transports
- stdio: the host starts the server as a child process and talks over stdin/stdout. Used for local servers.
- Streamable HTTP: the server runs as a web service; clients send HTTP requests (with optional streaming). Used for remote and shared servers, usually with OAuth.
Messages are JSON-RPC 2.0: each request has jsonrpc, id, method and params; the reply has the same id and a result or error.
Example
Example
A tiny in-process imitation of the MCP message flow: initialize, tools/list and tools/call. Real servers use the mcp SDK; this shows the shape of the messages.
import json
TOOLS = [{"name": "get_order_status",
"description": "Get the status of a ShopEase order",
"inputSchema": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]}}]
ORDERS = {"SE1042": "delivered"}
def server(request):
method, params = request["method"], request.get("params", {})
if method == "initialize":
result = {"protocolVersion": "2025-06-18", "serverInfo": {"name": "shopease", "version": "1.0"},
"capabilities": {"tools": {}}}
elif method == "tools/list":
result = {"tools": TOOLS}
elif method == "tools/call":
status = ORDERS.get(params["arguments"]["order_id"], "not found")
result = {"content": [{"type": "text", "text": status}], "isError": False}
else:
return {"jsonrpc": "2.0", "id": request["id"], "error": {"code": -32601, "message": "Method not found"}}
return {"jsonrpc": "2.0", "id": request["id"], "result": result}
calls = [("initialize", {}), ("tools/list", {}),
("tools/call", {"name": "get_order_status", "arguments": {"order_id": "SE1042"}}),
("orders/delete", {})]
for i, (method, params) in enumerate(calls, start=1):
req = {"jsonrpc": "2.0", "id": i, "method": method, "params": params}
resp = server(req)
print("->", json.dumps(req)[:90])
print("<-", json.dumps(resp)[:90])Output
-> {"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {}}
<- {"jsonrpc": "2.0", "id": 1, "result": {"protocolVersion": "2025-06-18", "serverInfo": {"na
-> {"jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {}}
<- {"jsonrpc": "2.0", "id": 2, "result": {"tools": [{"name": "get_order_status", "description
-> {"jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": {"name": "get_order_status",
<- {"jsonrpc": "2.0", "id": 3, "result": {"content": [{"type": "text", "text": "delivered"}],
-> {"jsonrpc": "2.0", "id": 4, "method": "orders/delete", "params": {}}
<- {"jsonrpc": "2.0", "id": 4, "error": {"code": -32601, "message": "Method not found"}}