A Model Context Protocol (MCP) server for interacting with the dev.to public API. Includes both read-only tools for browsing and authenticated write tools for creating, updating, and deleting articles.
This MCP server provides access to the following dev.to API endpoints:
- get_challenges - List active and recent DEV.to challenges (fetches from @devteam + #devchallenge tag)
- get_challenge_detail - Get the full article content of a challenge: description, prizes, judging criteria, key dates
- plan_challenge_submissions - Generate a 3–4 article submission plan with draft templates, ready to pass to
batch_create_articles
- get_articles - Get articles from dev.to with optional filters (username, tag, state, pagination)
- get_article - Get a specific article by ID or path
- get_user - Get user information by ID or username
- get_tags - Get popular tags from dev.to
- get_comments - Get comments for a specific article
- search_articles - Search articles using query parameters
- create_article - Create a new draft or published article
- update_article - Update an existing article (title, body, tags, series, etc.)
- delete_article - Unpublish an article
- publish_article - Publish a draft article by ID
- batch_create_articles - Create up to 20 articles in one call; returns per-item success/error
- batch_update_articles - Update up to 20 articles in one call; returns per-item success/error
- get_my_articles - List your own articles filtered by state:
all,published, orunpublished - get_draft_articles - List all your unpublished (draft) articles
- search_articles - Full-text search using the DEV.to search API
- advanced_search_articles - Filter articles by tag, username, state, reading time range, and published date
- validate_api_key - Check if your API key is valid and return your account profile
If you want to install and build from source using npm:
npm install
npm run buildThe server runs as a remote HTTP server on port 3000 (or the PORT environment variable) and can be used with any MCP-compatible client.
npm startThe server will be available at http://localhost:3000 for MCP connections.
# Build the project
npm run build
# Watch mode for development
npm run dev
# Linting
npm run lint
npm run lint:fix
# Formatting
npm run format
npm run format:checkPull and run the pre-built Docker image:
# Pull the image
docker pull docker.io/nickytonline/dev-to-mcp:latest
# Run it
docker run -d \
--name dev-to-mcp \
-e NODE_ENV=production \
-e PORT=3000 \
-p 3000:3000 \
--restart unless-stopped \
docker.io/nickytonline/dev-to-mcp:latestOnce it's up, check health status via:
curl -fsS http://127.0.0.1:3000/mcpThe server will be available at http://localhost:3000/mcp for MCP connections.
Build and run the MCP server using Docker:
# Build the Docker image
docker build -t dev-to-mcp .
# Run the container
docker run -p 3000:3000 dev-to-mcpUsing the pre-built image with Docker Compose:
services:
dev-to-mcp:
image: docker.io/nickytonline/dev-to-mcp:latest
container_name: dev-to-mcp
restart: unless-stopped
environment:
NODE_ENV: production
PORT: 3000
networks:
- main
healthcheck:
# Uses $PORT at runtime; defaults to 3000 if not set
test:
[
"CMD-SHELL",
"curl -fsS http://127.0.0.1:${PORT:-3000}/mcp >/dev/null || exit 1",
]
interval: 15s
timeout: 5s
retries: 5
start_period: 30s
networks:
main: {}For development with a local build, you can also use Docker Compose:
# docker-compose.yml
version: "3.8"
services:
dev-to-mcp:
build: .
ports:
- "3000:3000"
environment:
- PORT=3000docker-compose up --buildAll endpoints use the public dev.to API (https://dev.to/api) and do not require authentication.
Get articles with optional filtering:
username- Filter by author usernametag- Filter by tagtop- Top articles (1, 7, 30, or infinity days)page- Pagination page (default: 1)per_page- Articles per page (default: 30, max: 1000)state- Filter by state (fresh, rising, all)
Get a specific article:
id- Article IDpath- Article path (e.g., "username/article-slug")
Get user information:
id- User IDusername- Username
Get popular tags:
page- Pagination page (default: 1)per_page- Tags per page (default: 10, max: 1000)
Get comments for an article:
article_id- Article ID (required)
Search articles:
q- Search query (required)page- Pagination page (default: 1)per_page- Articles per page (default: 30, max: 1000)search_fields- Fields to search (title, body_text, tag_list)
The recommended flow for participating in a DEV.to challenge:
1. get_challenges → find an open challenge
2. get_challenge_detail → read requirements, judging criteria, prizes
3. plan_challenge_submissions → generate a 3-4 article plan with full draft templates
4. batch_create_articles → create all drafts in one call (published: false)
5. update_article → edit each draft as you build
6. publish_article → publish each article when ready
List recent DEV.to challenges:
per_page- Number of results (default: 10)page- Page number (default: 1)
Challenges are articles posted by the official
@devteamaccount tagged#devchallenge. DEV.to has no dedicated/api/challengesendpoint.
Fetch the full content of a challenge article:
path- Article path fromget_challenges, e.g.devteam/join-the-june-solstice-game-jam-1000-in-prizes-3jla
Generate a ready-to-use multi-article submission plan:
challenge_title- Name of the challenge (required)challenge_description- Short description of requirements (required)theme- The challenge theme, e.g."light and darkness, passage of time"(required)your_angle- What you plan to build, e.g."a puzzle game where daylight is your resource"(required)tags- Extra tags for every article (max 2;devchallengeis auto-added)count- Number of articles to plan:3or4(default: 3)
Returns a series_name, a submissions array with full body_markdown templates, and a note reminding you to pass it to batch_create_articles.
All write operations require the DEVTO_API_KEY environment variable to be set with a valid dev.to API key.
Create a new article:
title- Article title (required)body_markdown- Article body in Markdown (required)published- Whether to publish immediately (default: false = draft)tags- Array of tag slugs, up to 4 (e.g.,["javascript", "webdev"])series- Series name to add the article tocanonical_url- Canonical URL if published elsewheredescription- Short description/subtitle for listings
Update an existing article:
id- Article ID (required)title- New titlebody_markdown- New body in Markdownpublished- Set to true to publish, false to unpublishtags- Replacement tag listseries- Series namecanonical_url- Canonical URLdescription- Short description
Only provide the fields you want to change.
Unpublish an article (the dev.to public API does not support hard-delete):
id- Article ID (required)
This sets published: false on the article.
Publish a draft article immediately:
id- Article ID (required)
List your own articles:
state-published,unpublished, orall(default:all)page- Page number (default: 1)per_page- Articles per page (default: 30)
List your unpublished drafts (shorthand for get_my_articles with state: unpublished):
page- Page numberper_page- Drafts per page
Search with rich filtering — all parameters are optional:
tag- Filter by tag slugusername- Filter by author usernamestate-fresh,rising, oralltop- Trending window in days (1, 7, 30)page/per_page- Paginationmin_reading_time- Minimum reading time in minutes (client-side)max_reading_time- Maximum reading time in minutes (client-side)since- Only articles published on or after this date (ISO 8601, e.g.2024-01-01)
Validate the configured API key and return the authenticated user's profile. No parameters required — reads from the DEVTO_API_KEY environment variable.
Create multiple articles in one call:
articles- Array of article objects (max 20), each with the same fields ascreate_article
Returns a summary (succeeded, failed, total) and a per-item result array — a single failure does not abort the rest.
Update multiple articles in one call:
articles- Array of update objects (max 20), each with anidplus any fields fromupdate_article
Returns a summary and per-item results — failures are isolated per article.
All API requests include automatic retry logic:
- Rate limiting (429) — respects the
Retry-Afterheader - Server errors (5xx) — exponential backoff: 500ms → 1s → 2s
- Network errors — retries up to 3 times with backoff
- Structured errors — every error includes the HTTP status code and the raw DEV.to error body for easier debugging
DEVTO_API_KEY- Your dev.to API key (required for write operations)PORT- HTTP server port (default: 3000)NODE_ENV- Environment (default: development)LOG_LEVEL- Log level: error, warn, info, debug (default: info)
MIT