Click any question to reveal the answer. Questions are grouped by difficulty.
MCP is an open protocol that standardises how AI applications connect to external data sources and tools. It solves the M x N integration problem where each AI app would need custom integrations with each tool. With MCP, tools implement the protocol once and any MCP-compatible AI application can use them, similar to how USB standardised device connections.
Tool discovery is the process by which an MCP client learns what tools a server offers. The client calls the tools/list method, and the server responds with a list of available tools including their names, descriptions, and input schemas (JSON Schema). The host then presents these tools to the LLM so it can decide when and how to use them.
Official SDKs exist for TypeScript/JavaScript and Python, which are the most popular choices. Community SDKs are available for Kotlin, Go, Rust, C#, and other languages. The TypeScript SDK is the most mature with the best documentation. Choose based on your team's expertise and the ecosystem of the services you are integrating with.
MCP uses a client-server model where the AI application (host) contains an MCP client that connects to MCP servers. Each server exposes capabilities like tools, resources, and prompts. The host manages multiple client connections to different servers. Communication happens via JSON-RPC 2.0 over transports like stdio or SSE. The client initiates connections and the server responds to requests.
The three primitives are: Tools (model-controlled functions the LLM can invoke, like API calls or computations), Resources (application-controlled data the client can read, like files or database records), and Prompts (user-controlled templates for common interactions). Tools are called by the model, resources are read by the application, and prompts are selected by users.
Create an MCP server that exposes search and retrieval tools for the knowledge base. Implement tools like search_documents(query), get_document(id), and list_categories(). Use resources to expose document content. Add authentication via the transport layer. Handle pagination for large result sets. Include proper error handling and rate limiting. Test with multiple MCP clients.
Stdio transport communicates via standard input/output streams and is used for local server processes spawned by the client. SSE (Server-Sent Events) transport uses HTTP for remote servers, with SSE for server-to-client messages and HTTP POST for client-to-server messages. Stdio is simpler for local tools; SSE enables remote and shared server deployments.
MCP implements security through transport-level encryption (TLS for SSE), OAuth 2.0 for authentication with remote servers, and a human-in-the-loop approval model where the host application can require user confirmation before tool execution. Servers should validate inputs, implement rate limiting, and follow least-privilege principles. Sensitive operations should always require explicit user consent.
Write clear, specific descriptions that explain what the tool does, when to use it, and what inputs it expects. Include parameter descriptions with examples. Specify constraints and valid values. Add negative instructions (when NOT to use the tool). Use consistent naming conventions. Test with actual LLMs to verify they invoke tools correctly in various scenarios.
Resources are read-only data sources exposed by MCP servers, identified by URIs (like file:///path or db://table/id). Unlike tools which are model-controlled and perform actions, resources are application-controlled and provide data. The client application decides when to read resources, often to provide context. Resources support subscriptions for real-time updates.
Expose tools like query_database(sql) with read-only access, list_tables(), and describe_table(name). Use resources to expose schema information. Implement SQL injection prevention by parameterising queries. Add result size limits and timeout handling. Restrict to SELECT queries only for safety. Include proper error messages for invalid queries. Support connection pooling for performance.
JSON-RPC 2.0 is the messaging format used for all MCP communication. It provides a standardised structure for requests (method + params), responses (result or error), and notifications (one-way messages). It supports batch requests and has a simple error handling model. MCP uses it as the application-level protocol over different transport layers.
Return structured error responses with clear error codes and human-readable messages. Implement isRetryable flags for transient errors. The host application should implement exponential backoff for retryable errors. Design tools to be idempotent where possible. Log errors for debugging. The LLM should receive informative error messages to adjust its approach rather than raw stack traces.
MCP prompts are pre-defined interaction templates exposed by servers that users can select to initiate specific workflows. They can include dynamic arguments and generate structured messages with roles. Unlike system prompts which set global behaviour, MCP prompts are task-specific templates that combine instructions, context, and tool usage patterns for common operations.
During the initialise handshake, client and server exchange their supported capabilities. The client declares what features it supports (like sampling or roots), and the server declares its capabilities (tools, resources, prompts, logging). This negotiation ensures both sides understand what features are available and prevents errors from using unsupported features.
Write unit tests for individual tool handlers with mock inputs. Use the MCP Inspector tool for interactive testing. Test with actual MCP clients like Claude Desktop. Verify schema validation for all inputs. Test error handling with invalid parameters. Load test for performance under concurrent connections. Test transport layer reliability with connection drops and reconnects.
Implement per-client rate limiting using token buckets or sliding window counters. Return appropriate error codes (429) with retry-after headers. Track usage per authenticated user. Set tool-specific rate limits based on the cost of the underlying operation. Communicate limits through tool descriptions. Cache frequent requests. Consider implementing priority queues for different user tiers.
An MCP server is specifically designed for AI consumption with structured tool descriptions, input schemas, and standardised discovery. A REST API requires custom integration code, prompt engineering to teach the LLM the API format, and manual error mapping. MCP provides a universal protocol so any AI host can use any MCP server without custom integration code.
Use JSON Schema with clear type definitions and descriptions for every parameter. Mark required vs optional parameters. Include validation constraints (min/max, patterns, enums). Provide default values where sensible. Keep schemas simple; break complex operations into multiple simpler tools. Include examples in descriptions. Validate inputs server-side regardless of schema enforcement.
Use the protocol version field in the initialise handshake. Add new tools without removing old ones. Deprecate tools by updating their descriptions before removal. Make new parameters optional with defaults. Use semantic versioning for the server itself. Test new versions against existing clients. Document breaking changes clearly. Support multiple versions simultaneously during transitions.
MCP specifies that the host application should have the ability to require user approval before executing tool calls, especially for sensitive operations. This is crucial because LLMs may make incorrect tool calls or attempt unintended actions. The host acts as a gatekeeper, presenting tool calls to the user for confirmation, ensuring safety and maintaining user control.
Use MCP's built-in logging capability to send structured log messages to the client. Log all tool invocations with parameters, execution time, and outcomes. Implement correlation IDs to trace requests across the system. Export metrics (latency, error rate, usage) to monitoring systems. Set up alerts for unusual patterns. Store logs with appropriate retention for audit compliance.
Multiple servers follow the Unix philosophy of doing one thing well, enabling independent development, deployment, and scaling. A monolithic server is simpler to deploy but harder to maintain. Compose multiple servers when tools have different security requirements, update frequencies, or team ownership. Use a monolithic server for tightly coupled tools that share state.
MCP adds a layer of abstraction and latency that may be unnecessary for simple, single-tool integrations. It requires both client and server support. The ecosystem is still maturing with limited SDKs in some languages. For high-throughput, low-latency requirements, direct API integration may be more appropriate. If you only integrate with one or two tools, the protocol overhead may not be justified.
Define tools with clear names, descriptions, and parameter schemas. Present available tools to the LLM in the system prompt or through function calling APIs. Parse the LLM's tool selection and arguments. Execute the tool with validation and error handling. Feed the result back as an observation. Implement safeguards like confirmation prompts for destructive actions and rate limiting.
Expose tools for checking transaction status, viewing payment history, and generating payment links. Use resources for account balance and recent transactions. Implement strict authentication with OAuth 2.0 and require human approval for any payment-related actions. Handle UPI-specific formats (VPA validation, transaction IDs). Comply with RBI guidelines for data handling and ensure audit logging.
Sampling allows MCP servers to request LLM completions through the client, enabling agentic behaviours within tools. The server sends a sampling/createMessage request to the client, which routes it to the LLM. This enables sophisticated patterns like tool chains where one tool's execution requires LLM reasoning as an intermediate step, while keeping the human in the loop.
Create separate MCP servers for each domain: HR (employee data, leave management), Finance (invoicing, expense reports), CRM (customer data), and IT (ticket management). Implement a gateway server for authentication and routing. Use SSE transport for shared remote servers. Standardise tool naming and error handling across servers. Document tools for both LLMs and developers.
MCP supports resource subscriptions where clients can subscribe to specific resource URIs. When the underlying data changes, the server sends a notifications/resources/updated notification. The client can then re-read the resource to get the latest data. This enables live dashboards, real-time monitoring, and collaborative features where AI assistants track changing data.
Use progress notifications to report incremental status updates to the client. Implement timeouts with configurable limits. For very long operations, return a task ID and provide a separate status-checking tool. Support cancellation through the MCP cancellation mechanism. Avoid blocking the server's event loop. Consider breaking long operations into smaller, resumable steps.
Map existing function definitions to MCP tool schemas. Create an MCP server that wraps the existing tool implementations. Update the host application to use an MCP client instead of direct function calling. Migrate incrementally, running both systems in parallel. Test tool discovery and invocation thoroughly. Update error handling to use MCP's error format. The tool logic itself stays the same.