Building Composable AI: A Developer's Guide to the Model Context Protocol (MCP)
If you've ever built an application that integrates with AI, you've likely run into the integration problem. Connecting your app to a language model is one thing, but how do you give that model access to your app's data, tools, and functions in a way that is secure, scalable, and not a tangled mess of custom APIs?
Today, most AI applications are black boxes with a few specific integrations. The Model Context Protocol (MCP) offers a different vision: an open standard for creating a rich ecosystem of interoperable AI components.
This guide will introduce you to the core concepts of MCP, with a deep dive into one of its most powerful features: Elicitation.
The Big Picture: What is MCP?
Imagine a universal adapter for AI. That's MCP.
It’s a standard communication protocol that allows an AI application (the "Host") to interact with various external data sources and functions (the "Servers"). This means your application can seamlessly integrate with tools that access local files, query a database, or call a web API, all using the same standard.
The core components are:
- Host/Client: The main application the user interacts with (e.g., an AI-powered desktop app). It hosts the AI and manages connections to servers.
- Server: A specialized service that provides context or tools. It could be a local process, a sandboxed container, or a remote service.
All communication happens via a defined set of messages, typically using JSON-RPC.
Part 1: The Core Interaction Primitives
MCP is built around a few fundamental request types. Understanding them is key to seeing how the whole system works together.
1. tool.call: How a Server Says "I Can Do This"
This is the primary way for an AI or user to trigger an action. The Host sends a tool.call request to a Server, asking it to execute a specific function.
Use Case: An AI agent needs to know the current weather. Action: It sends a
tool.callto a "Weather Server" with the tool nameget_weatherand arguments like{ "location": "New York" }. Result: The Server runs its function and returns the weather data.
2. notify: How a Server Says "Here's an Update"
This is a one-way, "fire-and-forget" message. It's used for sending information that doesn't require a direct response, like status updates.
Use Case: A long-running file analysis tool is 50% complete. Action: The Server sends a
notifymessage with the progress. Result: The Host application can display a progress bar to the user.
3. elicit: How a Server Says "I Need Your Help"
This is where things get really interactive. Elicitation is used when a Server is in the middle of a task and realizes it's missing information from the user to proceed. Instead of failing, it can pause and formally ask the Host to get that information.
Part 2: A Deep Dive into Elicitation
Elicitation is the standardized process for a Server to request structured input from a user via the Host application's UI. It turns a one-way command into a two-way conversation.
The Elicitation Dance: A Step-by-Step Flow
- Server Needs Input: A Server is executing a
publish_blog_posttool but is missing the "Post Title". - Server Sends Request: The Server sends an
elicitation/createrequest to the Host. This request contains a message for the user and a schema defining the exact data it needs. - Host Renders UI: The Host application receives this request, reads the schema, and dynamically generates a user interface, like a pop-up form.
- User Provides Input: The user sees the form, types in the blog post title, and clicks "Submit".
- Host Returns Response: The Host packages the user's input into a response message and sends it back to the Server.
- Server Continues Workflow: The Server receives the data it needed and can now complete the
publish_blog_posttool call.
The requestedSchema: A Simple, Powerful Contract
This is the heart of elicitation. A Server can't just send any random request. To guarantee that any Host application can handle it, the schema must follow a strict, simple contract.
- Format: It uses a restricted subset of JSON Schema.
- Why? This restriction is a feature, not a bug. It ensures that any Host can reliably render a UI for the request without having to parse a deeply complex or arbitrarily structured schema.
- The Rules:
- The schema MUST be a flat object. No nested objects or arrays.
- Properties MUST be one of the following primitive types:
string(for text input)number/integerboolean(for a checkbox/toggle)enum(for a dropdown list of choices)
Example Elicitation Request:
A "Git Server" needs a structured commit message. It would send this request to the Host:
{
"jsonrpc": "2.0",
"id": "request-123",
"method": "elicitation/create",
"params": {
"message": "Please provide the details for your commit.",
"requestedSchema": {
"type": "object",
"properties": {
"summary": {
"type": "string",
"title": "Commit Summary",
"description": "A short, one-line summary of the changes."
},
"type": {
"type": "string",
"title": "Commit Type",
"enum": ["feat", "fix", "docs", "chore"],
"enumNames": ["Feature", "Bugfix", "Documentation", "Chore"]
}
},
"required": ["summary", "type"]
}
}
}
The Response: Capturing User Intent
The response from the Host is just as structured. It tells the Server how the user responded, which is crucial for deciding what to do next.
accept: The user filled out the form and submitted it. The response contains the data.{ "jsonrpc": "2.0", "id": "request-123", "result": { "action": "accept", "content": { "summary": "Implement the elicitation feature", "type": "feat" } } }decline: The user explicitly rejected the request (e.g., clicked "Cancel").{ "jsonrpc": "2.0", "id": "request-123", "result": { "action": "decline" } }cancel: The user dismissed the UI without making a choice (e.g., pressedEsc).{ "jsonrpc": "2.0", "id": "request-123", "result": { "action": "cancel" } }
Tying It All Together
Elicitation doesn't exist in a vacuum. It works alongside MCP's other features to create a complete ecosystem. A Server can offer:
- Resources: Files and data that an AI can use for context.
- Tools: Actions the AI can take, which might use elicitation to get arguments.
- Prompts: Reusable templates that a user can trigger.
By standardizing these interactions, MCP allows developers to build powerful, reusable, and secure AI components that can plug into any compatible application. It’s a move away from monolithic AI systems and toward a more open, composable future.
Comments
Post a Comment