Skip to main content
Glama
Dineshv0311

Dev.to Blog Publisher MCP Server

by Dineshv0311
README.md
# Dev.to Blog Publisher MCP Server

A custom [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that lets Claude publish markdown blog posts directly to [Dev.to](https://dev.to) — no copy-pasting into the Dev.to editor required.

Built with [FastMCP](https://github.com/jlowin/fastmcp) and the [Dev.to API](https://developers.forem.com/api).

## Overview

This server exposes a single MCP tool, `publish_blog_to_devto`, which any MCP-compatible client (like Claude Desktop) can call to create an article on your Dev.to account. Pair it with the official [filesystem MCP server](https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem) and you can ask Claude to:

> "Read `blog.txt` from my drafts folder, refine the content, and publish it to Dev.to as a draft with relevant tags."

Claude reads the file, cleans up the writing, and calls this server to publish it — all in one conversation, no manual formatting.

## Features

- Publish articles as **drafts** or **live**
- Set title, tags, series, canonical URL, and cover image
- Uses your personal Dev.to API key — the key never leaves your machine except to call Dev.to's own API

## Requirements

- Python 3.10+
- [`uv`](https://docs.astral.sh/uv/) for package management
- A [Dev.to API key](https://dev.to/settings/extensions) (Settings → Extensions → DEV Community API Keys)
- [Claude Desktop](https://claude.ai/download) or another MCP-compatible client

## Setup

### 1. Clone and install dependencies

```bash
git clone https://github.com/Dineshv0311/devto-mcp-server.git
cd devto-mcp-server
uv sync
```

### 2. Configure your API key

Copy the template and fill in your key:

```bash
cp .env.template .env
```

Then edit `.env`:

```
DEVTO_API_KEY=your_devto_api_key_here
```

> ⚠️ `.env` is listed in `.gitignore` — never commit your real API key.

### 3. Test the server standalone (recommended)

Before wiring it into Claude Desktop, verify the server works using the MCP Inspector:

```bash
uv run mcp dev dev-server.py
```

This opens a local web UI where you can call `publish_blog_to_devto` directly and inspect the raw request/response — useful for catching issues before debugging through a chat interface.

### 4. Connect it to Claude Desktop

Open your Claude Desktop config file:

- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`

Add this server **inside** the top-level `mcpServers` key:

```json
{
  "mcpServers": {
    "devto": {
      "command": "C:\\path\\to\\uv.exe",
      "args": ["--directory", "C:\\path\\to\\devto-mcp-server", "run", "dev-server.py"]
    }
  }
}
```

> 💡 On Windows, use the full path to `uv.exe` (find it with `where.exe uv`) — Claude Desktop doesn't always inherit your shell's PATH.

Fully quit and reopen Claude Desktop (check it's not lingering in the system tray) and confirm the server shows as **running** under Settings → Developer → Local MCP servers.

## Usage

Once connected, talk to Claude normally:

> "I have a file `blog.txt` in my drafts folder — refine its content and publish it to Dev.to as a draft with tags: mcp, ai, python."

### Tool: `publish_blog_to_devto`

| Parameter        | Required | Description                                            |
|-------------------|:--------:|----------------------------------------------------------|
| `title`           | ✅        | Article title                                             |
| `body_markdown`   | ✅        | Full article content in markdown                          |
| `tags`            | ❌        | List of tags (e.g. `["mcp", "ai", "python"]`)              |
| `published`       | ❌        | `true` for live, `false` for draft (default: `false`)      |
| `series`          | ❌        | Name of the series this article belongs to                 |
| `canonical_url`   | ❌        | Canonical URL if cross-posted                               |
| `cover_image`     | ❌        | URL of a cover image                                        |

Tip: publish with `published: false` first to review the draft on Dev.to before making it live.

## Project Structure

```
devto-mcp-server/
├── dev-server.py         # MCP server + publish_blog_to_devto tool
├── devto-test.py         # Standalone test script for the Dev.to API call
├── example-config.json   # Example Claude Desktop config snippet
├── .env.template         # Template for required environment variables
├── pyproject.toml        # Project dependencies (managed by uv)
└── README.md
```

## Troubleshooting

**`ModuleNotFoundError: No module named 'mcp.server.fastmcp'`**
There's an unrelated package squatting the `mcp` name on PyPI. Pin the real SDK explicitly:
```bash
uv remove mcp
uv add "mcp[cli]>=1.2.0,<2.0.0"
```

**Server doesn't show up in Claude Desktop**
Double-check `devto` is nested *inside* `mcpServers` in the config, not a sibling key. Fully restart Claude Desktop.

**`uv` not found after installing**
Close and reopen your terminal so it picks up the updated PATH.

**Dev.to API returns 422 Unprocessable Entity**
Usually means a duplicate title/slug already exists on your account. Try a slightly different title.

## License

MIT — see [LICENSE](./LICENSE)

TDQS

A4/5.0

Scored across 1 tool

Disambiguation5/5

Only one tool exists, so there is no possibility of confusing it with others. The tool's purpose is clear from its name and description.

Naming Consistency5/5

The single tool uses a clear verb_noun pattern (publish_blog_to_devto), consistent with common MCP naming conventions, though there is no other tool to compare.

Tool Count3/5

Having exactly one tool for a blogging platform is very thin; a typical integration would need at least listing, updating, and deleting articles. This falls on the borderline of being too few.

Completeness2/5

The server only supports publishing posts; there are no operations for reading, updating, deleting, or listing existing articles. This is a significant gap that would prevent an agent from managing a blog lifecycle.

Maintenance

ActivitySlowing
ResponsivenessNo issues