This tutorial walks you through setting up a basic MCP (Model Context Protocol) server to expose read-only resources to Large Language Models (LLMs) like Claude. You’ll learn what MCP is, why resources are useful, and how to initialize a Node.js/TypeScript project with the @modelcontextprotocol/sdk
.
- What is Model Context Protocol?
- What are MCP Resources?
- Why Use Resources?
- Example Servers
- Getting Started
- Next Steps
- MCP Tools (Dynamic Actions)
- Tools vs Prompts
- Complete Our Greeting Server
- Sources & Additional Reading
- License
The Model Context Protocol (MCP) is a standardized interface that allows LLMs to safely interact with external data and services. With MCP, you can expose files, databases, APIs, and more to your AI models in a controlled manner.
Resources are read-only endpoints that expose content (text or binary) via a unique URI. Examples include:
file:///path/to/file.txt
database://users/123
api://weather/latest
Each resource has metadata like a display name and MIME type.
Resources enable LLMs to:
- Read files and databases
- Execute commands
- Access APIs
- Interact with local tools
All interactions require explicit user permission, ensuring security and auditability.
Expose your documentation:
docs://api/reference → API documentation
docs://guides/getting-started → User guides
Serve system logs:
logs://system/today → Today's logs
logs://errors/recent → Recent error messages
Provide customer insights:
customers://profiles/summary → Customer overview
customers://feedback/recent → Latest feedback
- Node.js (>= 16)
- npm (>= 8)
- TypeScript
mkdir hello-mcp
cd hello-mcp
npm init -y
npm install @modelcontextprotocol/sdk
npm install -D typescript @types/node
-
Update
package.json
:{ "name": "hello-mcp", "version": "1.0.0", "type": "module", "scripts": { "build": "tsc", "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { "@modelcontextprotocol/sdk": "^1.1.0" }, "devDependencies": { "typescript": "^5.7.2", "@types/node": "^22.10.5" } }
-
Create
tsconfig.json
:{ "compilerOptions": { "target": "ES2022", "module": "Node16", "moduleResolution": "Node16", "outDir": "./build", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "include": ["src/**/*"] }
-
Create a
src/
directory and start coding your MCP server.
Check out Part 2 for configuring transports and advanced features.
MCP Tools (also called dynamic actions) let you define custom functions that the LLM can call during a session, extending MCP’s capabilities beyond static resources.
Aspect | MCP Tools | Prompts |
---|---|---|
Capability | Executes code & actions | Static natural language |
Security | Controlled & auditable | No external effects |
Flexibility | High (custom logic) | Limited to inference |
Below is a simple example of a greeting server exposing a greeting resource:
import { ResourceServer } from "@modelcontextprotocol/sdk";
const server = new ResourceServer({ port: 3000 });
server.addResource({
uri: "greeting://hello",
displayName: "Greeting Resource",
fn: async (req) => {
const name = req.query.name || "World";
return `Hello, ${name}!`;
},
});
server.listen(() => console.log("Greeting server running on port 3000"));
- MCP Prompts
- unichat-mcp-server
- Claude Prompt Engineering
- 10 Prompt Engineering Best Practices
- Prompting Guide
MIT