Lab 7 · MCP-style tool protocol
Tool discovery via a manifest
The Agent Lab already has tool implementations, Zod arg schemas, and a permission policy in three separate modules. Model Context Protocol takes those and renders them as one machine-readable manifest so any compatible client can discover what is available, what it requires, and what it costs in approval.
Why this lab matters: Tools need descriptions, schemas, and permission metadata to be discoverable. MCP is about tool interoperability, not magic intelligence — the same five tools below could be served from any MCP-compatible host and consumed by any MCP-compatible client.
getCustomer
Resolve a customer name or id into the canonical customer record.
Permission
Read-only data lookup. Safe to call without approval.
Input schema
{
"type": "object",
"properties": {
"customerNameOrId": {
"type": "string",
"minLength": 1
}
},
"required": [
"customerNameOrId"
],
"additionalProperties": false
}Simulated MCP handshake
What an agent would send and receive on first contact: initialize → tools/list → tools/call. No real socket; the lab generates the envelopes from the same manifest the runner already uses.
- 1. initializeclient→server
{ "protocolVersion": "2024-11-05", "clientInfo": { "name": "agent-lab-runner", "version": "0.1.0" }, "capabilities": {} } - 2. initialize/resultserver→client
{ "protocolVersion": "2024-11-05", "serverInfo": { "name": "agent-lab-mock-erp", "version": "0.1.0" }, "capabilities": { "tools": { "listChanged": false } } } - 3. tools/listclient→server
{} - 4. tools/list/resultserver→client
{ "tools": [ { "name": "getCustomer", "description": "Resolve a customer name or id into the canonical customer record.", "inputSchema": { "type": "object", "properties": { "customerNameOrId": { "type": "string", "minLength": 1 } }, "required": [ "customerNameOrId" ], "additionalProperties": false } }, { "name": "getCreditStatus", "description": "Return the current credit limit, exposure, available credit, status, and risk level.", "inputSchema": { "type": "object", "properties": { "customerId": { "type": "string", "minLength": 1, "maxLength": 64 } }, "required": [ "customerId" ], "additionalProperties": false } }, { "name": "getOpenInvoices", "description": "List all open and overdue invoices for a customer.", "inputSchema": { "type": "object", "properties": { "customerId": { "type": "string", "minLength": 1, "maxLength": 64 } }, "required": [ "customerId" ], "additionalProperties": false } }, { "name": "checkOrderEligibility", "description": "Compute whether a proposed order can be released given current credit and aging.", "inputSchema": { "type": "object", "properties": { "customerId": { "type": "string", "minLength": 1, "maxLength": 64 }, "orderAmount": { "type": "integer", "maximum": 10000000, "exclusiveMinimum": 0 } }, "required": [ "customerId", "orderAmount" ], "additionalProperties": false } }, { "name": "createCreditReviewTicket", "description": "Create a persistent credit-review ticket. Write action; always requires approval.", "inputSchema": { "type": "object", "properties": { "customerId": { "type": "string", "minLength": 1, "maxLength": 64 }, "reason": { "type": "string", "minLength": 8 } }, "required": [ "customerId", "reason" ], "additionalProperties": false } } ] } - 5. tools/callclient→server
{ "name": "getCustomer", "arguments": { "customerNameOrId": "ACME" } }