DEV Community

Akın Coşkun
Akın Coşkun

Posted on

I Published My Own MCP Server on npm — Here's Why Every Developer Should

TL;DR
MCP (Model Context Protocol) is becoming the standard for connecting AI models to external data. I built a personal portfolio MCP server and published it on npm. Now anyone can add my server to Claude Desktop and ask AI about my projects, skills, and experience. Here's how I built it and why this matters for your career.

What is MCP?
If you've used Claude Desktop, Cursor, or Claude Code recently, you've probably seen MCP in action. MCP is an open protocol developed by Anthropic that lets AI models talk to external tools and data sources.
Think of it this way:

REST API: Human (browser) → your server → data → human reads it
MCP: AI model (Claude) → your server → data → AI uses it to answer questions

If you know how to build an Express API, you already know 90% of what you need to build an MCP server. The concepts are identical — you define endpoints (called "tools" in MCP), handle inputs, and return responses. The only difference is the protocol.

Why I Built a Portfolio MCP Server
The idea is simple: instead of copy-pasting my project details into every AI conversation, I built a server that AI can query directly.
When someone adds my MCP server to Claude Desktop and asks "What are Akın's projects?", Claude calls my server, gets the data, and presents it naturally.
This is powerful for three reasons:

Personal branding. Almost nobody has a personal MCP server. It immediately signals that you understand cutting-edge AI infrastructure.
Practical demonstration. Instead of saying "I know MCP" on your resume, you can say "Here's my MCP server — install it and try it."
It's the future. MCP is becoming the de facto standard. OpenAI is sunsetting their Assistants API in favor of MCP. Over 1,000 community-built MCP servers already exist. This ecosystem is only growing.

How I Built It
The Stack

TypeScript (strict mode)
@modelcontextprotocol/sdk (official MCP SDK)
Zod (input validation)
stdio transport (runs locally, no server needed)

Project Structure
akin-portfolio-mcp/
├── src/
│ ├── index.ts # MCP server entry point
│ ├── data/
│ │ ├── about.ts # Personal info
│ │ ├── skills.ts # Tech stack
│ │ └── projects.ts # All 8 projects
│ ├── tools/
│ │ ├── about.ts # get_about, get_contact tools
│ │ ├── skills.ts # get_skills tool
│ │ └── projects.ts # get_projects, search_projects tools
│ └── types/
│ └── index.ts # TypeScript interfaces
├── package.json
├── tsconfig.json
└── README.md
Defining a Tool
Here's the core pattern. If you've ever written an Express route handler, this will look familiar:
typescriptserver.tool(
"get_projects",
"Lists all of Akın's projects with descriptions and tech stacks",
async () => {
return {
content: [{
type: "text",
text: JSON.stringify(projects, null, 2)
}]
};
}
);
That's it. Define a name, a description (this is what the AI reads to decide when to call your tool), and a handler function.
For tools with parameters, you add a Zod schema:
typescriptserver.tool(
"search_projects",
"Search projects by technology or keyword",
{ keyword: z.string().describe("Technology or keyword to search for") },
async ({ keyword }) => {
const results = projects.filter(p =>
p.stack.some(s => s.toLowerCase().includes(keyword.toLowerCase())) ||
p.description.toLowerCase().includes(keyword.toLowerCase())
);
return {
content: [{
type: "text",
text: results.length > 0
? JSON.stringify(results, null, 2)
: No projects found matching "${keyword}"
}]
};
}
);
Publishing to npm
The key insight: MCP servers distributed via npm can be run with npx — no installation required. Users just add this to their Claude Desktop config:
json{
"mcpServers": {
"akin-portfolio": {
"command": "npx",
"args": ["-y", "akin-portfolio-mcp"]
}
}
}
To make this work, your package.json needs a bin field pointing to your compiled entry point, and you need .npmignore to exclude source files from the published package.

The 7 Tools My Server Provides

get_about — Personal information and bio
get_skills — Full tech stack by category
get_projects — All 8 projects with details
get_project_detail — Deep dive into a specific project
search_projects — Find projects by technology keyword
get_contact — Contact information
get_experience_summary — Career overview

What I Learned
MCP is easier than you think. If you can write a TypeScript function, you can build an MCP server. The SDK handles all the protocol complexity.
Descriptions matter more than code. The tool descriptions are what the AI reads to decide when to call your tools. Poor descriptions = AI never uses your tools. Good descriptions = seamless integration.
stdio is the simplest transport. No server deployment needed. The MCP server runs as a local process on the user's machine. npm distribution makes it effortless.
Error handling is critical. When a user asks about a project that doesn't exist, your server should return a helpful error, not crash. I use isError: true in responses so Claude can communicate failures gracefully.

Try It Yourself
Install my server:
bashnpx akin-portfolio-mcp
Or add it to Claude Desktop / Claude Code:
bashclaude mcp add akin-portfolio npx -y akin-portfolio-mcp
Then ask: "What are Akın's projects?" or "Does Akın know N8N?"
Source code: github.com/akincskn/akin-portfolio-mcp
npm: npmjs.com/package/akin-portfolio-mcp

You Should Build One Too
Seriously. Here's why:

It takes a weekend (mine took a day)
It demonstrates real MCP knowledge
It's a conversation starter in interviews and on LinkedIn
Almost nobody has one yet — you'll stand out

Start with your portfolio data. Add your projects, skills, and experience. Publish it on npm. Link it in your GitHub README. That's it — you now have an MCP server that AI assistants can use to learn about you.
The developers who understand MCP early will have a significant advantage as this ecosystem grows. Don't wait.

I'm Akın Coşkun, a full-stack developer building AI-powered tools and MCP servers. Find me on GitHub or try my MCP server: npx akin-portfolio-mcp

Top comments (0)