ЁЯПл The SchoolтА║ЁЯФМ MCPтА║ЁЯФМ рдзрдбрд╛ 07 тАФ Client/host рдмрд╛рдВрдзрд╛: рд╕рддреНрддрд╛ рдЕрд╕рд▓реЗрд▓реА рдмрд╛рдЬреВ
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯФМ рдзрдбрд╛ 07 тАФ Client/host рдмрд╛рдВрдзрд╛: рд╕рддреНрддрд╛ рдЕрд╕рд▓реЗрд▓реА рдмрд╛рдЬреВ

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 8 рдкреИрдХреА рдзрдбрд╛ 07 ┬╖ рдорд╛рдЧреЗ: lesson-06-build-a-server ┬╖ рдкреБрдвреЗ: lesson-08-use-cases


ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ

рдзрдбреЗ 01тАУ06, рдЖрдгрд┐ client/mini_client.py рдЪреЗ рдорд╛рд░реНрдЧрджрд░реНрд╢рд┐рдд рд╡рд╛рдЪрди тАФ рдЦреЛрд▓реА, socket, рдЖрдгрд┐ (--drive mode рдордзреНрдпреЗ) рд╡рд┐рджреНрдпрд╛рд░реНрдерд┐рдиреА рдореНрд╣рдгреВрди рддреБрдореНрд╣реА.

ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ

Client рдмрд╛рдЬреВрдЪреА рддреАрди рдХрд╛рдореЗ рдЖрд╣реЗрдд, рдЖрдгрд┐ рдЖрдкрд▓рд╛ ~105 рдУрд│реАрдВрдЪрд╛ host рддрд┐рдиреНрд╣реА рдХрд░рддреЛ:

  1. рд╕реБрд░реВ рдХрд░рд╛ рдЖрдгрд┐ рдЬреЛрдбрд╛ ЁЯФМ тАФ subprocess.Popen([...python, server]): stdio transport рдореНрд╣рдгрдЬреЗ рдлрдХреНрдд "child рд╕реБрд░реВ рдХрд░рд╛, рддреНрдпрд╛рдЪреЗ stdin/stdout рдзрд░реВрди рдареЗрд╡рд╛" (L05, live). рдПрдХ MiniHost = рдПрдХ socket = рдПрдХ server (L02).
  2. Badge рдШрд╛рд▓рд╛ ЁЯкк тАФ send() JSON-RPC рдмрдирд╡рддреЛ: рд╡рд╛рдврдд рдЬрд╛рдгрд╛рд░рд╛ id рд▓рд╛рд╡рддреЛ, рдкреНрд░рддреНрдпреЗрдХ request рд▓рд╛ _meta badge (рдЖрд╡реГрддреНрддреА, clientInfo, clientCapabilities) рдЬреЛрдбрддреЛ, рдПрдХ рдУрд│ рд▓рд┐рд╣рд┐рддреЛ, рдПрдХ рдУрд│ рд╡рд╛рдЪрддреЛ, рдЙрддреНрддрд░рд╛рдЪреА id рдиреЗ рдЬреЛрдбрдгреА рдХрд░рддреЛ. рдордЧ main() L04 рдЪрд╛ рдиреЗрдордХрд╛ рдХреНрд░рдо рдкрд╛рд░ рдкрд╛рдбрддреЛ: server/discover (рдРрдЪреНрдЫрд┐рдХ) тЖТ tools/list тЖТ tools/call.
  3. Model рдЖрдгрд┐ рдЬрдЧ рдпрд╛рдВрдЪреНрдпрд╛рдордзреНрдпреЗ рдмрд╕рд╛ ЁЯзатЖТЁЯФМ тАФ scripted mode рдордзреНрдпреЗ, рддреАрди рддрдпрд╛рд░ calls "agent рдХрд╛рдп рдХрд░реЗрд▓" рдпрд╛рдЪрд╛ рдЕрднрд┐рдирдп рдХрд░рддрд╛рдд. --drive mode рдордзреНрдпреЗ, calls рддреБрдореНрд╣реА рдЯрд╛рдЗрдк рдХрд░рддрд╛ тАФ рдЖрдгрд┐ рдпрд╛ рдордЬреЗрдд рд▓рдкрд▓реЗрд▓рд╛ рдзрдбрд╛: model рдордЬрдХреБрд░рд╛рдд call рд╕реБрдЪрд╡рддреЛ; host рдордзреНрдпрд╕реНрдереА рдХрд░рддреЛ. рдЪрд╛рд▓рд╡рд╛рдпрдЪреЗ рдХреА рдирд╛рд╣реА рддреЗ host рдирд┐рд╡рдбрддреЛ тАФ рдЖрдгрд┐ server рдЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ рдкреНрд░рд╢реНрдирд╛рдВрдирд╛ рдЙрддреНрддрд░ рджреЗрдгрд╛рд░реА рдмрд╛рдЬреВрд╣реА рддреАрдЪ (input_required рдЪрд┐рдиреНрд╣рд╛рдВрдХрд┐рдд results, server рдиреЗ рд╕реБрд░реВ рдХреЗрд▓реЗрд▓реНрдпрд╛ sampling/elicitation requests рдЪреА рдЖрд╡реГрддреНрддреА 2026-07-28 рдордзреАрд▓ рдЬрд╛рдЧрд╛ рдШреЗрдгрд╛рд░реЗ). рдореНрд╣рдгрдЬреЗ permission prompts, allow-lists, write-gates (L05 рдзреЛрд░рдг 3!) рдЖрдгрд┐ logs host рдордзреНрдпреЗрдЪ рдЕрд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗрдд. рд╕рддреНрддрд╛ hosts рдХрдбреЗ рдЕрд╕рддреЗ; рддреЗ рд░рдЪрдиреЗрдиреБрд╕рд╛рд░рдЪ рдЖрд╣реЗ.

рдЦрд░рд╛ host рдиреЗрдордХреЗ рддреЗрдЪ рдЬреЛрдбрддреЛ рдЬреЗ рддреБрдореНрд╣реА рдЕрдВрджрд╛рдЬ рдХрд░рд╛рд▓: calls рд╕реБрдЪрд╡рдгрд╛рд░рд╛ рдЦрд░рд╛ model (AI рдХреЛрд░реНрд╕ L11 рдЪрд╛ loop), model рдЪреНрдпрд╛ context рд▓рд╛ рдЬреЛрдбрд▓реЗрд▓реЗ tool results (рдмрд╛рдХ, AI рдХреЛрд░реНрд╕ L08), рдПрдХрд╛рдЪ рд╡реЗрд│реА рдЕрдиреЗрдХ sockets, рдЖрдгрд┐ рд╕рдВрдорддреАрдЪрд╛ UI. Plumbing рдЪреНрдпрд╛ рджреГрд╖реНрдЯреАрдиреЗ? рддреБрдореНрд╣реА рдЖрддрд╛ рддреЗ рд╕рдЧрд│реЗ рд╡рд╛рдЪрд▓реЗ рдЖрд╣реЗ.

ЁЯЧ║я╕П рдЖрдХреГрддреА

sequenceDiagram
    participant U as ЁЯзС you (--drive: the model)
    participant H as ЁЯПл MiniHost (room + socket)
    participant S as ЁЯФм school_server (child process)
    U->>H: 1 "call lookup_grade {student: katrina}"
    Note over H: 2 the POWER moment: host decides<br/>(real hosts: permission check here ЁЯЪз)
    H->>S: 3 tools/call {name, arguments, id: 4}
    S-->>H: 4 {id: 4, content: [{text: "Katrina (3A) has grade A+."}]}
    H-->>U: 5 "ЁЯУД lands on the desk: тАж"
    Note over U,S: the model proposes ┬╖ the host mediates ┬╖ the server provides

ЁЯУЦ рдпрд╛ рдУрд│реА рд╡рд╛рдЪрд╛ (рдореНрд╣рдгрдЬреЗ рддреБрдореНрд╣реА рд╣рд░рд╡рдгрд╛рд░ рдирд╛рд╣реА)

client/mini_client.py:

тЭУ рдХрд╛рдп (рдЪреЛрд░рдгреНрдпрд╛рд╕рд╛рд░рдЦреЗ рддрдкрд╢реАрд▓)

ЁЯдФ рдХрд╛

"model рдлрдХреНрддтАж рдХрд░реВ рд╢рдХрдд рдирд╛рд╣реА рдХрд╛?" рдЕрд╢рд╛ рд╕реНрд╡рд░реВрдкрд╛рдЪреНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ MCP рдкреНрд░рд╢реНрдирд╛рдЪреЗ рдЙрддреНрддрд░ рд╣реА file рджреЗрддреЗ: рдирд╛рд╣реА тАФ рддреЛ рдлрдХреНрдд рд╕реБрдЪрд╡реВ рд╢рдХрддреЛ; host рдордзреНрдпрд╕реНрдереА рдХрд░рддреЛ. Host рдЪрд╛ рд╣рд╛ рдЕрд░реБрдВрдж рдорд╛рд░реНрдЧ рд╕рдордЬрд▓рд╛ рдХреА safety рдХреБрдареЗ рд░рд╛рд╣рддреЗ, server рдЪреНрдпрд╛ рд╕рдВрдЦреНрдпреЗрдкреЗрдХреНрд╖рд╛ host рдЪреА рдЧреБрдгрд╡рддреНрддрд╛ рдХрд╛ рдЬрд╛рд╕реНрдд рдорд╣рддреНрддреНрд╡рд╛рдЪреА, рдЖрдгрд┐ рдПрдЦрд╛рджреНрдпрд╛ app рдЪреНрдпрд╛ MCP settings рдордзреНрдпреЗ "always allow" toggle рдХрд░рддрд╛рдирд╛ рддреБрдореНрд╣реА рдирдХреНрдХреА рдХрд╢рд╛рд╡рд░ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдареЗрд╡рддрд╛ рддреЗ рдХрд│рддреЗ (рддреБрдореНрд╣реА рд╡рд░рдЪреНрдпрд╛ sequence рдЖрдХреГрддреАрдЪреА рдУрд│ 2 рд╣рдЯрд╡рдд рдЕрд╕рддрд╛ ЁЯШД).

ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛

python3 client/mini_client.py --drive
# model calls> get_student_count {"class_name":"3B"}
# model calls> add_homework {"title":"build my own host"}

рдордЧ L05 рдордзреАрд▓ рдПрдХрд╛ рдУрд│реАрдЪреА рддрд╛рдХрджрд╡рд╛рдв: --drive mode рдордзреНрдпреЗ tools/call рдЪреНрдпрд╛ рдЖрдзреА write-gate рдЬреЛрдбрд╛ (if name.startswith("add"): input("allow? ")). рдкреБрдиреНрд╣рд╛ рдЪрд╛рд▓рд╡рд╛, рдлрд░рдХ рдЕрдиреБрднрд╡рд╛. --drive prompt рдЪрд╛рд░ рдХреНрд░рдо рд╕реБрдЪрд╡рддреЛ (aтАУd): (a) рджреЛрди reads, (b) model рдкреНрд░рддрд┐рд╕рд╛рдж рджреЗрдК рд╢рдХреЗрд▓ рдЕрд╢реА tool error, (c) рдЧрд╣рд╛рд│ рдлрд╛рдЯрдХ, (d) host рдЯрд┐рдХреВрди рд░рд╛рд╣рддреЛ рдЕрд╢реА protocol error тАФ рд╕рдЧрд│реЗ рдЪрд╛рд▓рд╡рд╛. рдЖрддрд╛ рддреБрдореНрд╣реА MCP рдЪреНрдпрд╛ рджреЛрдиреНрд╣реА рдмрд╛рдЬреВ рдЖрдгрд┐ рддреНрдпрд╛рдЪреЗ рд╕рд░реНрд╡рд╛рдд рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ safety feature рдмрд╛рдВрдзрд▓реЗ рдЖрд╣реЗ. ЁЯФМ

тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ

--drive рдордзреНрдпреЗ tools/call рдЪреНрдпрд╛ рдЖрдзреА рд╕рд╣рд╛ рдУрд│реАрдВрдЪреЗ рдлрд╛рдЯрдХ рдЬреЛрдбрд▓реНрдпрд╛рд╡рд░ add_homework allow? рд╕рд╛рдареА рдерд╛рдВрдмрддреЛ рдЖрдгрд┐ n рджрд┐рд▓реНрдпрд╛рд╕ рдмрд╛рдХрд╛рд╡рд░ рдХрд╛рд╣реАрдЪ рдЫрд╛рдкрд▓реЗ рдЬрд╛рдд рдирд╛рд╣реА, рддрд░ lookup_grade рди рд╡рд┐рдЪрд╛рд░рддрд╛ рдЪрд╛рд▓рдд рд░рд╛рд╣рддреЛ. fly_to_moon {} тЭМ server error -32602 рдЫрд╛рдкрддреЛ рдЖрдгрд┐ loop рдЪрд╛рд▓реВ рд░рд╛рд╣рддреЛ тАФ host protocol error рдордзреВрди рдЯрд┐рдХрд▓рд╛.

ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ

Host рд╣реАрдЪ рд╕рддреНрддреЗрдЪреА рд╕реАрдорд╛ рдЖрд╣реЗ: model рдЪреА рд╕реВрдЪрдирд╛ рдЖрдгрд┐ wire рдпрд╛рдВрдЪреНрдпрд╛рдордзреНрдпреЗ рддреБрдореНрд╣реА рдорд╛рдгрд╕рд╛рдЪрд╛ рдирд┐рд░реНрдгрдп рдШрд╛рддрд▓рд╛, рджреЛрдиреНрд╣реА рдкрд╛рд╣реВ рд╢рдХрдгрд╛рд▒реНрдпрд╛ рдПрдХрдореЗрд╡ рдЬрд╛рдЧреА.

тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: hosts рдЕрдиреЗрдХ servers рдЪреНрдпрд╛ tool lists рдПрдХрд╛ рдХрдкреНрдкреНрдпрд╛рдд рдПрдХрддреНрд░ рдХрд░рддрд╛рдд, рдореЗрд▓реЗрд▓реЗ child processes рдкреБрдиреНрд╣рд╛ рдЬреЛрдбрддрд╛рдд, рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ call рднреЛрд╡рддреА рд╕рдВрдорддреАрдЪрд╛ UI, allow-lists рдЖрдгрд┐ audit logs рдареЗрд╡рддрд╛рдд. Server рдЪреНрдпрд╛ рд╕рдВрдЦреНрдпреЗрдкреЗрдХреНрд╖рд╛ host рдЪреА рдЧреБрдгрд╡рддреНрддрд╛ рдЬрд╛рд╕реНрдд рдорд╣рддреНрддреНрд╡рд╛рдЪреА.

тПня╕П рдкреБрдвреЗ

рд╢реЗрд╡рдЯрдЪрд╛ рдЯрдкреНрдкрд╛: рдкрд╛рдЪ рдЦрд▒реНрдпрд╛ рдЬрдЧрд╛рддреАрд▓ рд░рдЪрдирд╛ тАФ coding, support, data, рдмреИрдардХрд╛, automation тАФ рдкреНрд░рддреНрдпреЗрдХреА рдХреНрд░рдорд╛рдВрдХрд┐рдд flow рдЖрдгрд┐ sequence рдЖрдХреГрддреАрд╕рд╣.

git checkout lesson-08-use-cases

ЁЯФМ Lesson 07 тАФ Build a client/host: the side with the power

ЁЯУН You are here: Lesson 07 of 8 ┬╖ Previous: lesson-06-build-a-server ┬╖ Next: lesson-08-use-cases


ЁЯУж What's in this branch

Lessons 01тАУ06, plus the guided read of client/mini_client.py тАФ the room, the socket, and (in --drive mode) you as the student.

ЁЯзТ Explain like I'm 5

The client side has three jobs, and our ~105-line host does all three:

  1. Launch & plug in ЁЯФМ тАФ subprocess.Popen([...python, server]): the stdio transport IS just "start the child, hold its stdin/ stdout" (L05, live). One MiniHost = one socket = one server (L02).
  2. Wear the badge ЁЯкк тАФ send() builds JSON-RPC: stamps an incrementing id, adds the _meta badge (revision, clientInfo, clientCapabilities) to every request, writes a line, reads a line, matches the answer by id. Then main() performs L04's exact sequence: server/discover (optional) тЖТ tools/list тЖТ tools/call.
  3. Sit between model and world ЁЯзатЖТЁЯФМ тАФ in scripted mode, three canned calls play "what an agent would do". In --drive mode, YOU type the calls тАФ and here's the lesson hiding in the fun: the model proposes a call, in text; the host mediates. The host chooses whether to execute тАФ and it is also the side that answers a server's own questions (results marked input_required, revision 2026-07-28's replacement for server-initiated sampling/elicitation requests). Which means the host is where permission prompts, allow-lists, write-gates (L05 policy 3!) and logs belong. Hosts hold the power; that's by design.

A real host adds exactly what you'd guess: a real model proposing the calls (AI course L11's loop), tool results appended to the model's context (the desk, AI course L08), multiple sockets at once, and the consent UI. Plumbing-wise? You've now read all of it.

ЁЯЧ║я╕П Diagram

sequenceDiagram
    participant U as ЁЯзС you (--drive: the model)
    participant H as ЁЯПл MiniHost (room + socket)
    participant S as ЁЯФм school_server (child process)
    U->>H: 1 "call lookup_grade {student: katrina}"
    Note over H: 2 the POWER moment: host decides<br/>(real hosts: permission check here ЁЯЪз)
    H->>S: 3 tools/call {name, arguments, id: 4}
    S-->>H: 4 {id: 4, content: [{text: "Katrina (3A) has grade A+."}]}
    H-->>U: 5 "ЁЯУД lands on the desk: тАж"
    Note over U,S: the model proposes ┬╖ the host mediates ┬╖ the server provides

ЁЯУЦ Read these lines (so you don't get lost)

client/mini_client.py:

тЭУ What (details worth stealing)

ЁЯдФ Why

Every MCP question of the form "can the model justтАж?" is answered by this file: no тАФ it can only propose; the host mediates. Understanding the host's chokepoint tells you where safety lives, why host quality matters more than server count, and exactly what you're trusting when you toggle "always allow" in some app's MCP settings (you're deleting line 2 of the sequence diagram above ЁЯШД).

ЁЯзк Try it

python3 client/mini_client.py --drive
# model calls> get_student_count {"class_name":"3B"}
# model calls> add_homework {"title":"build my own host"}

Then the one-line power-up from L05: add a write-gate before the tools/call in --drive mode (if name.startswith("add"): input("allow? ")). Run again, feel the difference. The --drive prompt suggests four sequences (aтАУd): (a) two reads, (b) a tool error the model can act on, (c) the missing gate, (d) a protocol error the host survives тАФ run them all. You've now built both sides of MCP and its most important safety feature. ЁЯФМ

тЬЕ Verify тАФ what you should see

With the six-line gate added before tools/call in --drive, add_homework waits for allow? and n prints nothing on the desk, while lookup_grade still runs without asking. fly_to_moon {} prints тЭМ server error -32602 and the loop continues тАФ the host survived a protocol error.

ЁЯПБ What you just proved

The host is the power boundary: you inserted a human decision between the model's proposal and the wire, in the only place that can see both.

тЪая╕П Common mistakes

ЁЯПн Why this matters in production: hosts merge tool lists from many servers into one shelf, reconnect dead child processes, and put consent UI, allow-lists and audit logs around every call. Host quality matters more than server count.

тПня╕П Next

The finale: five real-world setups тАФ coding, support, data, meetings, automation тАФ each with a numbered flow AND a sequence diagram.

git checkout lesson-08-use-cases
тЖР Previousbuild a serverNext тЖТuse cases

This page is the lesson's README from the lesson-07-build-a-client branch, shown here so the whole School stays on one site. Code files open on GitHub at the same branch.