cd /news/developer-tools/i-built-an-mcp-server-that-lets-clau… · home topics developer-tools article
[ARTICLE · art-35434] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=↑ positive

I built an MCP server that lets Claude manage my GitHub profile and DEV.to articles — here's how

A developer built an MCP server in under 100 lines of Python that connects Claude to GitHub and DEV.to APIs, enabling natural language commands to manage repositories and articles. The server exposes seven tools for fetching profile stats, listing repos, and creating or updating DEV.to articles.

read3 min views1 publishedJun 21, 2026

I wanted Claude to know about my developer presence — my repos, my articles, my stats — without me having to paste links every time. So I built a small MCP server that connects both GitHub and DEV.to directly to Claude.

Now I can just say: "What's my most starred repo?" or "Draft a DEV.to article about my latest project" — and Claude actually does it.

Here's how I built it in under 100 lines of Python.

Model Context Protocol is an open standard that lets you connect external tools and APIs to Claude (and other LLMs). You define tools with a decorator, run a server, and Claude can call those tools during a conversation.

I'm a contributor to the MCP Python SDK, so naturally I wanted to build something real with it.

The server exposes 7 tools across two APIs:

GitHub:

get_github_profile

— followers, repos, biolist_repos

— sort by stars/forks/updatedget_repo_stats

— stars, forks, issues for any repoDEV.to:

list_articles

— all your articles with reaction/view countscreate_article

— draft or publish a new articleupdate_article

— edit title, body, or publish stateget_article_stats

— reactions, comments, page viewsInstall the only dependency:

pip install mcp[cli]

Create a .env

file:

GITHUB_TOKEN=your_github_token
GITHUB_USERNAME=your_github_username
DEV_TO_API=your_devto_api_key
DEV_USERNAME=your_devto_username

Here's the full server (server.py

):

import os, json, urllib.request
from mcp.server.fastmcp import FastMCP

GITHUB_USERNAME = os.environ.get("GITHUB_USERNAME", "")
DEV_USERNAME = os.environ.get("DEV_USERNAME", "")

mcp = FastMCP("developer-presence")

def _gh(path, method="GET", data=None):
    req = urllib.request.Request(f"https://api.github.com{path}", method=method)
    req.add_header("Authorization", f"token {os.environ['GITHUB_TOKEN']}")
    req.add_header("Accept", "application/vnd.github.v3+json")
    if data:
        req.add_header("Content-Type", "application/json")
        req.data = json.dumps(data).encode()
    with urllib.request.urlopen(req) as r:
        return json.loads(r.read())

def _dev(path, method="GET", data=None):
    req = urllib.request.Request(f"https://dev.to/api{path}", method=method)
    req.add_header("api-key", os.environ["DEV_TO_API"])
    req.add_header("Content-Type", "application/json")
    if data:
        req.data = json.dumps(data).encode()
    with urllib.request.urlopen(req) as r:
        return json.loads(r.read())

@mcp.tool()
def get_github_profile() -> dict:
    """Fetch public GitHub profile stats."""
    u = _gh(f"/users/{GITHUB_USERNAME}")
    return {"login": u["login"], "name": u.get("name"), "bio": u.get("bio"),
            "public_repos": u["public_repos"], "followers": u["followers"]}

@mcp.tool()
def list_repos(sort: str = "updated", limit: int = 10) -> list:
    """List public repos sorted by updated/stars/forks."""
    repos = _gh(f"/users/{GITHUB_USERNAME}/repos?sort={sort}&per_page={min(limit,100)}")
    return [{"name": r["name"], "stars": r["stargazers_count"],
             "language": r.get("language"), "url": r["html_url"]} for r in repos]

@mcp.tool()
def list_articles(per_page: int = 10) -> list:
    """List your DEV.to articles with stats."""
    articles = _dev(f"/articles/me?per_page={min(per_page,30)}")
    return [{"id": a["id"], "title": a["title"],
             "reactions": a.get("positive_reactions_count", 0),
             "page_views": a.get("page_views_count", 0)} for a in articles]

@mcp.tool()
def create_article(title: str, body_markdown: str,
                   tags: list[str] = None, published: bool = False) -> dict:
    """Create a new DEV.to article."""
    payload = {"article": {"title": title, "body_markdown": body_markdown, "published": published}}
    if tags:
        payload["article"]["tags"] = tags
    result = _dev("/articles", method="POST", data=payload)
    return {"id": result["id"], "url": result.get("url")}

if __name__ == "__main__":
    mcp.run()

(Full version with all 7 tools on GitHub)

mcp dev server.py

For Claude Desktop, add this to claude_desktop_config.json

:

{
  "mcpServers": {
    "developer-presence": {
      "command": "python",
      "args": ["/path/to/server.py"],
      "env": {
        "GITHUB_TOKEN": "...",
        "GITHUB_USERNAME": "...",
        "DEV_TO_API": "...",
        "DEV_USERNAME": "..."
      }
    }
  }
}

Once connected, I can ask Claude things like:

It sounds simple, but having your developer presence queryable from a conversation is surprisingly useful — especially when you're writing content and want to reference your own work.

Everything is on GitHub: enjoykumawat/developer-presence-mcp

If you want to adapt it for your own username, just update the .env

file — no other changes needed.

I'm a contributor to the MCP Python SDK. If you're interested in building MCP servers, feel free to reach out or check out the official SDK — it's a great place to start.

Follow me here on DEV.to @enjoy_kumawat for more AI tooling content.

── more in #developer-tools 4 stories · sorted by recency
── more on @claude 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/i-built-an-mcp-serve…] indexed:0 read:3min 2026-06-21 ·