Model Context Protocol (MCP): What, Why and How?
No one knows the future of human-computer interfacing. Will apps remain on phones, or will they be AR apps or brain-computer interfaces? The future is exciting yet confusing.
And with the widespread adoption of LLM chatbots, it’s possible that future apps will be embedded in them, like Claude and ChatGPT.
In fact, great minds like Naval Ravikant believes AI will end the current form of UI.
Not long ago, Anthropic introduced MCPs (Model Context Protocol), making it easier for developers to extend popular LLM hosts with their own functionality or data sources. It’s like building extensions for famous LLM hosts like Claude.
This is great news. It lets us connect to data sources and build agents/tools for popular chat interfaces. It also standardizes them so they can be portable on any compliant host.
These are some of the MCP hosts that you can extend as of Mar 2025 (see full list here)
- Claude Desktop
- Cursor IDE
- Zed IDE
- Windsurf IDE
- and more
Concepts and Architecture
The official website for model context protocol explains the architecture in terms of:
- MCP Hosts: These are programs like Claude Desktop, IDEs, or AI tools that want to access data through MCP.
- MCP Clients: These are like messengers that set up direct connections with servers.
- MCP Servers: These are lightweight programs that you can build to offer specific tools/functions using the Model Context Protocol.
- Local Data Sources: These are files, documents, databases, etc that MCPs can consume.
- Remote Services: These are external systems you can access over the internet (like through APIs) that MCP servers can connect to.
Example
Let’s build an MCP server to extend Claude and make it shorten any given URL. I will be using the TypeScript SDK but please feel free to use the Python SDK if you want.
Project Setup
First we follow the official protocol website's guide on how to initialize a new MCP server
# Create a new directory for our project
mkdir url-shortener
cd url-shortener
# Initialize a new npm project
npm init -y
# Install dependencies
npm install @modelcontextprotocol/sdk zod
npm install -D @types/node typescript
# Create our files
mkdir src
touch src/index.ts
Then we update our package.json
to add the type as module
and add the build script
{
"name": "url-shortener",
"type": "module",
"version": "1.0.0",
"bin": {
"url-shortener": "./build/index.js"
},
"scripts": {
"build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\""
},
"files": [
"build"
],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.6.1",
"zod": "^3.24.2"
},
"devDependencies": {
"@types/node": "^22.13.5",
"typescript": "^5.7.3"
}
}
Last piece of the project setup is to create a tsconfig.json
file
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
Implementation
The first thing we need to do is to initialize the MCP server as follows
import { z } from 'zod'
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
const server = new McpServer({
name: 'url-shortener',
version: '1.0.0',
})
Then let's write a simple function that makes an https call to the URL Shortener API passing the long url and receiving the short one:
interface ShortenUrlResponse {
result_url: string
}
async function shortenUrl(longUrl: string): Promise<string> {
const response = await fetch('https://cleanuri.com/api/v1/shorten', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `url=${encodeURIComponent(longUrl)}`,
})
const data = (await response.json()) as ShortenUrlResponse
return data.result_url
}
With that in place we are ready to create our first server tool.
A server tool enables servers to expose executable functionality to clients. Through tools, LLMs can interact with external systems, perform computations, and take actions in the real world.
server.tool(
'shorten-url',
'Shorten a URL given a long URL',
{
longUrl: z.string().url().describe('The long URL to shorten'),
},
async ({ longUrl }) => {
const shortUrl = await shortenUrl(longUrl)
return {
content: [
{
type: 'text',
text: `Shortened URL: ${shortUrl}`,
},
],
}
},
)
In the above code, we describe what the tool is and what the tool does as well as what inputs it takes and define the tool implementation itself
Let's add a simple main function that runs the MCP server
async function main() {
const transport = new StdioServerTransport()
await server.connect(transport)
console.error('Weather MCP Server running on stdio')
}
main().catch((error) => {
console.error('Fatal error in main():', error)
process.exit(1)
})
And that's it! Now we can build the server using the build command
npm run build
then you open your Claude Desktop App and find "Developer" settings from which you can edit the MCP config. The config should be empty so let's add our new server to the config but make sure you modify the path to index.ts
to yours.
{
"mcpServers": {
"url-shortener": {
"command": "node",
"args": [
"/Users/amirhesham/Developer/weather/build/index.js"
]
}
}
}
We are done! Now restart Claude and it should be able to shorten any given url!
Now it's up to your imagination to decide what stuff you can build with it.
Happy hacking.