Model Context Protocol
Standardize AI agent tool integrations and resource access using Anthropic open-standard Model Context Protocol.
TL;DR
- Use
MCPto plug tools and data into any compatible app. - Start local servers over
stdio, the simplest transport. - Expose
tools, resources, and reusable prompt templates from one server.
MCP Server Architecture
Server InitializationCreate an MCP server instance with identity metadata.
import {
McpServer,
} from '@modelcontextprotocol/sdk/server/mcp.js';
import {
StdioServerTransport,
} from '@modelcontextprotocol/sdk/server/stdio.js';
const server = new McpServer({
name: 'inventory-server',
version: '1.0.0',
});Register Executable ToolExpose typed tool endpoint with Zod schema validation.
import { z } from 'zod';
server.tool(
'get_stock',
{ sku: z.string() },
async ({ sku }) => ({
content: [{ type: 'text', text: `SKU: ${sku}` }],
})
);Stdio Transport ConnectConnect server to standard input and output streams.
const transport = new StdioServerTransport();
await server.connect(transport);Resources And Prompts
Expose Static ResourceProvide read-only contextual document identified by URI.
server.resource(
'schema',
'schema://database/main',
async uri => ({
contents: [{
uri: uri.href,
text: 'CREATE TABLE users (id INT, email TEXT);',
}],
})
);Reusable Prompt TemplateExpose standardized prompt workflows to MCP clients.
server.prompt(
'review_code',
{ code: z.string() },
({ code }) => ({
messages: [{
role: 'user',
content: { type: 'text', text: `Code: ${code}` },
}],
})
);Dynamic URI TemplateRoute parameterized resource URIs dynamically.
import {
ResourceTemplate,
} from '@modelcontextprotocol/sdk/server/mcp.js';
const tmpl = new ResourceTemplate(
'users://{id}/profile',
{ list: undefined }
);
server.resource(
'user-profile',
tmpl,
async (u, { id }) => ({
contents: [{ uri: u.href, text: `User ${id}` }],
})
);MCP Client Consumption
Client Connection SetupEstablish client link to local MCP server process.
import {
Client,
} from '@modelcontextprotocol/sdk/client/index.js';
import {
StdioClientTransport,
} from '@modelcontextprotocol/sdk/client/stdio.js';
const transport = new StdioClientTransport({
command: 'node',
args: ['./dist/server.js'],
});
const client = new Client(
{ name: 'agent-client', version: '1.0' }
);
await client.connect(transport);List Available ToolsQuery server for active tools and their JSON schemas.
const { tools } = await client.listTools();
console.log(`Discovered ${tools.length} MCP tools`);Invoke Remote ToolDispatch tool execution call and receive content payload.
const result = await client.callTool({
name: 'get_stock',
arguments: { sku: 'WIDGET-01' },
});
console.log(result.content[0].text);Production MCP Hygiene
Stderr Logging RuleRedirect application logs to stderr to avoid stream corruption.
console.error('[MCP DEBUG] Processing tool execution');
// NEVER use console.log in Stdio mode
// It corrupts JSON-RPC stdout communicationTransport Error RecoveryHandle server process disconnection and automatic restart.
transport.onclose = () => {
logger.warn('MCP closed. Reconnecting...');
reconnectClient();
};Security SandboxingValidate client path requests against restricted directory.
function safePath(userPath: string, rootDir: string) {
const resolved = path.resolve(rootDir, userPath);
if (!resolved.startsWith(rootDir)) {
throw new Error('Access denied');
}
return resolved;
}Tips
- Use the official
@modelcontextprotocol/sdkto build type-safe MCP servers with automatic JSON-RPC protocol compliance. - Run local MCP servers over
StdioServerTransportso they talk through standard input and output with no open network port.
Warnings
- Validate every tool input with
zodbefore acting, because MCP clients can send parameters that trigger unauthorized local actions. - Do not call
console.login stdio mode, because stray text on standard output corrupts the JSON-RPC stream. Useconsole.error.
In Practice
Creates an MCP server, registers a typed weather tool with Zod, and binds standard I/O streams.
- Import McpServer and StdioServerTransport from SDK.
- Instantiate server with metadata name and version.
- Register typed tool with input schema and execution logic.
- Connect Stdio transport to begin serving JSON-RPC requests.
import {
McpServer,
} from '@modelcontextprotocol/sdk/server/mcp.js';
import {
StdioServerTransport,
} from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
const s = new McpServer({
name: 'srv', version: '1.0'
});
s.tool('temp', { city: z.string() },
async ({ city }) => ({
content: [{ type: 'text', text: `${city}: 21C` }],
})
);
const t = new StdioServerTransport();
await s.connect(t);FAQ
MCP is an open standard created by Anthropic that standardizes how applications provide context, tools, and data resources to large language models. It replaces custom one-off API integrations with a universal client-server architecture. Running models locally? See MCP With Local Models in the Ollama category.
Tools represent executable actions with side-effects that take arguments and return data. Resources represent read-only context data (like files or database schemas) identified by unique URIs that models can read.
MCP supports Stdio (standard input/output streams for local CLI and desktop tools) and SSE (Server-Sent Events over HTTP for networked and remote servers).