Model Context Protocol (MCP) is a standard for how an AI model or agent discovers what a server can do — and how to call it — at the moment it needs to, instead of that knowledge being hard-coded into the agent ahead of time.
The problem before MCP
Before a standard existed, "giving an LLM a tool" meant writing a custom integration: a function definition matching the exact shape one specific API expected, wired into one specific agent framework. Every new tool was bespoke glue code. Every agent framework had its own convention for describing what a function did and how to call it. None of it was portable — a tool built for one agent couldn't be dropped into another without rewriting the integration layer.
MCP standardizes the interface between "thing that has capabilities" (an MCP server) and "thing that wants to use them" (an MCP client, usually embedded in an agent or IDE). A client that speaks MCP can connect to any compliant server and immediately know what it offers — no custom glue code per integration.
The core exchange
An MCP session, boiled down:
client -> server: initialize (protocol version, capabilities)
server -> client: capabilities, server info
client -> server: tools/list
server -> client: [ { name, description, inputSchema }, ... ]
client -> server: tools/call { name, arguments }
server -> client: { content: [...] } (or isError: true)Everything the client needs to use a tool correctly — its name, what it does in plain language, and a JSON Schema for its arguments — comes back from tools/list. The client never needs prior knowledge of that specific server.
Transports: stdio vs. Streamable HTTP
MCP defines more than one way to carry that exchange:
- stdio — the server runs as a local subprocess; the client writes JSON-RPC to its stdin and reads responses from stdout. Common for local dev tools and desktop agent apps.
- Streamable HTTP — the server is a normal web endpoint. A client POSTs a JSON-RPC request and gets a JSON-RPC response; a server that needs to push multiple messages can upgrade to a streamed response, but a stateless, read-only server (like a search tool) can just answer once per request with no persistent connection at all.
Agent Bazaar's MCP server uses Streamable HTTP in fully stateless mode — no session handshake, because none of its tools (search, get_resource, get_pricing, etc.) need to remember anything between calls:
curl -X POST https://bazaar.saylorinnovations.com/mcp \
-H "content-type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Tools, resources, and prompts
MCP defines three primitives a server can expose, though most servers (including this one) mainly use the first:
| Primitive | Purpose |
|---|---|
| Tools | Callable functions with side effects or computation — search_resources, get_resource. |
| Resources | Addressable, readable content a client can fetch, more like a file than a function call. |
| Prompts | Reusable prompt templates a server suggests to the client, parameterized by arguments. |
Building a minimal MCP server
The actual protocol surface is small enough to hand-roll without an SDK, which is exactly what Agent Bazaar's implementation does — it's a single JSON-RPC dispatcher over the same functions the REST /discovery API already calls:
async function handleRpc(request) {
const { id, method, params } = request;
if (method === 'initialize') {
return { jsonrpc: '2.0', id, result: {
protocolVersion: params.protocolVersion,
capabilities: { tools: {} },
serverInfo: { name: 'my-server', version: '1.0.0' },
}};
}
if (method === 'tools/list') {
return { jsonrpc: '2.0', id, result: { tools: TOOLS } };
}
if (method === 'tools/call') {
const result = await runTool(params.name, params.arguments);
return { jsonrpc: '2.0', id, result };
}
return { jsonrpc: '2.0', id, error: { code: -32601, message: 'method not found' } };
}That's the whole shape. The work is in TOOLS (accurate names, descriptions and JSON Schemas — this is what the client actually reasons over) and runTool (your real logic).
Where MCP fits next to x402 and A2A
MCP answers "what can this server do and how do I call it." It doesn't say anything about payment (that's x402) or about one agent describing itself to another agent as a whole entity rather than a tool server (that's A2A). See MCP vs REST vs x402 for the full comparison.