cd /news/developer-tools/i-built-a-custom-mcp-server-that-pub… Β· home β€Ί topics β€Ί developer-tools β€Ί article
[ARTICLE Β· art-82786] src=dev.to β†— pub= topic=developer-tools verified=true sentiment=Β· neutral

I Built a Custom MCP Server That Publishes My Blogs for Me: A Debugging Log

A developer built a custom Model Context Protocol (MCP) server that enables Claude to read draft blog posts and publish them directly to Dev.to, bypassing the UI. The project involved creating two MCP servers and overcoming several debugging challenges, including a dependency name collision on PyPI and configuration pitfalls in Claude Desktop. The developer shared lessons on verifying package versions and correctly structuring MCP server configuration.

read4 min views11 publishedAug 1, 2026

I've been deep in AI engineering prep lately β€” deployed a couple of full-stack AI projects, fine-tuned an open-weight LLM, and been grinding DSA for placements. Somewhere in the middle of all that, I got curious about MCP (Model Context Protocol) and decided to actually build something with it instead of just reading about it.

The idea was simple: what if Claude could read a rough draft blog post sitting on my machine, clean it up, and publish it straight to Dev.to β€” without me touching the Dev.to UI at all?

Turns out, that's exactly what MCP is for.

MCP is a protocol that lets an AI model like Claude call tools you define β€” read files, hit APIs, run scripts β€” instead of just generating text. You write a small server exposing "tools" (plain Python functions with docstrings), plug it into Claude Desktop's config, and suddenly Claude can act, not just talk.

I set up two servers for this:

publish_blog_to_devto

tool, wrapping the Dev.to APII started with uv

for Python package management β€” much faster than plain pip/venv.

First hiccup: PowerShell couldn't find uv

right after installing it, because my terminal session was already open before the installer updated PATH. Closing and reopening the terminal fixed that instantly. A small thing, but easy to panic over if you don't know why it's happening.

Second hiccup was more interesting. I created a fresh venv and tried uv add "mcp[cli]"

, but it kept failing dependency resolution β€” because my pyproject.toml

had requires-python = ">=3.9"

left over from when the project was first scaffolded against system Python 3.9, but the actual MCP SDK needs 3.10+. I fixed it by pinning explicitly:

uv python pin 3.12
uv venv --python 3.12

Then I edited requires-python

to >=3.10

in pyproject.toml

, and the install went through clean.

Here's the one that actually got me for a while. After a supposedly successful install, importing fastmcp

kept throwing ModuleNotFoundError: No module named 'mcp.server.fastmcp'

β€” even though import mcp

worked fine and the folder clearly had a server

directory in it.

It turned out uv pip show mcp

revealed the installed package was version 2.0.0

, with dependencies like httpx2

, mcp-types

, pyjwt

, and pywin32

β€” none of which belong to the real MCP SDK. There's an unrelated package squatting the name mcp

on PyPI, and it got pulled in instead of the real modelcontextprotocol

SDK.

The fix was to pin the version range explicitly:

uv remove mcp
uv add "mcp[cli]>=1.2.0,<2.0.0"

That pulled in the legit SDK (1.29.0 at the time), and from mcp.server.fastmcp import FastMCP

finally worked.

Lesson: if uv add somepackage

"succeeds" but nothing makes sense afterward, check uv pip show

β€” don't assume the name on PyPI is the project you think it is.

Claude Desktop reads its MCP server list from claude_desktop_config.json

, under a top-level mcpServers

key. This file has other unrelated app preferences in it now, so it's easy to accidentally add your server as a sibling of mcpServers

instead of nested inside it β€” which silently does nothing. I learned that one the hard way, staring at Settings β†’ Developer β†’ Local MCP servers wondering why only filesystem

showed up.

Correct shape:

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "C:\\Technical\\mcp-code"]
    },
    "devto": {
      "command": "C:\\Users\\vdine\\.local\\bin\\uv.exe",
      "args": ["--directory", "C:\\Technical\\custom-mcp\\devto-mcp-server", "run", "dev-server.py"]
    }
  }
}

One more Windows-specific gotcha: Claude Desktop doesn't always inherit your shell's PATH, so "command": "uv"

alone sometimes fails to launch. Using the full path from where.exe uv

fixed it for good.

After a full quit-and-reopen of Claude Desktop (not just closing the window β€” it lingers in the tray), both servers showed up as running.

Before wiring anything into Claude Desktop, I tested the server standalone using:

uv run mcp dev src/mcp_server_demo/__init__.py

This spins up the MCP Inspector β€” a local web UI where you can call your tools directly and see raw request/response payloads, without needing Claude in the loop at all. Genuinely useful for catching bugs early instead of debugging through a chat interface.

With both servers connected, the actual publishing step is almost anticlimactic β€” I just talk to Claude normally:

"I have a file blog.txt in [folder], refine its content, then publish it to Dev.to as a draft with relevant tags."

Claude chains the tools itself:

read_text_file

(filesystem server) to pull the raw draftpublish_blog_to_devto

(my custom server) with the title, markdown body, and tagsNo copy-pasting into Dev.to's editor, no manual formatting. I set published: false

first to review as a draft before making it live β€” cheap insurance against publishing something half-baked.

Most of the real learning here wasn't about MCP the protocol β€” it was standard environment debugging: PATH issues, Python version pinning, a squatted package name, and a JSON nesting mistake. MCP itself, once the environment was sane, was maybe 20 lines of Python with a docstring.

That's probably the underrated lesson: agent tooling is only as reliable as the boring plumbing underneath it. Get the venv, the package versions, and the config shape right, and the "AI does the interesting part" takes care of itself.

Next up, I'm planning to add a couple more tools to the same server β€” maybe one that pulls my GitHub commit history to help draft "what I built this week" posts automatically.

── 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-a-custom-mcp…] indexed:0 read:4min 2026-08-01 Β· β€”