Retrieves and searches blog articles from the Alayman blog on Medium, providing access to 285+ articles with metadata including author, publication time, read time, and engagement metrics. Supports pagination and filtering by topic, title, or content across various software engineering subjects.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Alayman Article Retrievalfind recent articles about React and TypeScript"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Alayman MCP Server - Article Retrieval and Search
A Model Context Protocol (MCP) server that provides tools and prompts to retrieve and search blog articles from the Alayman blog (A Layman on Medium) by Jen-Hsuan Hsieh (Sean).
Overview
This MCP server provides tools and prompts to interact with Alayman blog articles, allowing you to:
Fetch paginated article lists (currently 285+ articles available)
Search and filter articles by topic, title, or content
Generate contextual prompts for article discovery
Access article metadata including author, publication time, read time, and engagement metrics
Features
Article Retrieval Tool: Fetches paginated articles with customizable limit and offset
Article List Prompt: Generates intelligent prompts for article discovery with optional filters
Structured Output: Returns validated data using Pydantic models
Pagination Support: Efficient handling of large article collections
Async HTTP: Uses httpx for efficient async API calls
Error Handling: Comprehensive exception handling for network and HTTP errors
SSE Transport: Server-Sent Events support for HTTP-based MCP connections
Dual Transport: Supports both stdio (for Claude Desktop/Code) and SSE (for HTTP clients)
Topics Covered in the Blog
The Alayman blog covers a wide range of software engineering topics, including:
Frontend Development: React, Angular, Next.js, Vue.js, TypeScript, JavaScript
Backend Development: Django, Node.js, NestJS, Python, GraphQL, RESTful APIs
Data Visualization: D3.js, Cytoscape.js, Highcharts, ECharts
Cloud & DevOps: AWS, Docker, Kubernetes, CI/CD, GitLab, GitHub Actions
Architecture & Patterns: Micro Frontends, Design Patterns, System Design
Testing: Unit Testing, Integration Testing, Karma, Jasmine
AI & Tools: Claude CLI, GitHub Copilot, RAG, LangChain.js
Web Performance: SEO, Optimization, Caching, SSR/SSG
Career & Soft Skills: Team Management, Digital Nomad Life, Conference Insights
Requirements
Python 3.11 or higher
uv (package manager)
Installation
Clone this repository
Install dependencies:
uv syncCreate a
.envfile in the project root with the required configuration:
# Required: API endpoint URL
ALAYMAN_API_URL=your_api_url_here
# Optional: Port for SSE server (default: 8000)
# PORT=8000Usage
Running the Server
The server supports two transport modes: stdio and SSE (Server-Sent Events).
SSE Transport (Default)
Start the MCP server with SSE transport over HTTP:
uv run server.pyBy default, the server will start on http://127.0.0.1:8000 with the SSE endpoint available at:
SSE endpoint:
http://127.0.0.1:8000/sseMessages endpoint:
http://127.0.0.1:8000/messages
You can specify a custom port using the PORT environment variable:
PORT=3000 uv run server.pyStdio Transport
For stdio transport (used by Claude Desktop and some MCP clients), the server will automatically use stdio when invoked by those clients through their configuration files.
Testing with MCP Inspector
The MCP Inspector is a web-based tool for testing MCP servers.
Testing with SSE Transport
To test the SSE server with MCP Inspector:
Start the server in SSE mode:
uv run server.pyIn a separate terminal, start the MCP Inspector and connect to the SSE endpoint:
npx @modelcontextprotocol/inspector http://127.0.0.1:8000/sseThe inspector will connect to your running SSE server and allow you to test tools and prompts interactively.
Testing with Stdio Transport
For stdio transport testing:
npx @modelcontextprotocol/inspector uv run server.pyThis will start the inspector and connect it to your server automatically using stdio.
Integration with Claude Desktop
To use this server with Claude Desktop, add it to your Claude Desktop configuration:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%/Claude/claude_desktop_config.json
{
"mcpServers": {
"shellserver": {
"command": "uv",
"args": ["run", "/absolute/path/to/server.py"],
"cwd": "/absolute/path/to/shellserver"
}
}
}Restart Claude Desktop after updating the configuration.
Integration with Claude Code
Claude Code supports both stdio and SSE transport for MCP servers. Choose the method that best fits your needs.
Option 1: SSE Transport (Recommended for Remote/Network Access)
First, start the MCP server with SSE transport:
uv run server.pyThen add the SSE server to Claude Code using the claude mcp add command:
claude mcp add --scope user --transport sse alayman http://127.0.0.1:8000/sseThis will add the SSE server with the name "alayman" to your user-level MCP configuration.
Alternatively, you can manually add it to your Claude Code MCP configuration:
macOS/Linux:
~/.claude/mcp.jsonWindows:
%USERPROFILE%\.claude\mcp.json
{
"mcpServers": {
"alayman": {
"url": "http://127.0.0.1:8000/sse"
}
}
}For remote SSE servers:
{
"mcpServers": {
"alayman": {
"url": "https://your-server.com/mcp/alayman/sse"
}
}
}Option 2: Stdio Transport (Default)
Add the server to Claude Code using the claude mcp add command. From the project directory, run:
claude mcp add --scope user alayman uv run $(pwd)/server.pyThis will add the server with the name "alayman" to your user-level MCP configuration, making it available across all your Claude Code sessions.
Alternatively, you can manually add it to your Claude Code MCP configuration:
{
"mcpServers": {
"alayman": {
"command": "uv",
"args": ["run", "/absolute/path/to/server.py"],
"cwd": "/absolute/path/to/alayman-mcp"
}
}
}Reloading Configuration
After updating the configuration, restart Claude Code or reload the MCP servers for the changes to take effect.
Integration with Docker and Claude Code
Build the Docker image
docker build -t alayman .Option 1: Docker with SSE Transport
Run the Docker container with SSE transport:
docker run -d -p 8000:8000 \
-e ALAYMAN_API_URL=your_api_url \
--name alayman-mcp \
alaymanThen add the SSE endpoint to Claude Code:
claude mcp add --scope user --transport sse alayman http://127.0.0.1:8000/sseOr manually configure:
{
"mcpServers": {
"alayman": {
"url": "http://127.0.0.1:8000/sse"
}
}
}Option 2: Docker with Stdio Transport
Add the Docker container as the MCP server with stdio:
claude mcp add-json --scope user alayman '{"type":"stdio","command":"docker","args":["run","-i","--rm","--init","-e","DOCKER_CONTAINER=true","alayman"]}'Or manually configure:
{
"mcpServers": {
"alayman": {
"command": "docker",
"args": ["run", "-i", "--rm", "--init", "-e", "DOCKER_CONTAINER=true", "alayman"]
}
}
}Using SSE Transport with MCP Clients
When running the server with SSE transport, you can connect to it from any MCP client that supports SSE/HTTP connections.
Connection Details
Base URL:
http://127.0.0.1:8000SSE Endpoint:
http://127.0.0.1:8000/sseMessages Endpoint:
http://127.0.0.1:8000/messagesTransport Type:
sse
Example: Connecting with MCP Client SDK
If you're building a custom MCP client using the MCP SDK, you can connect to the SSE server like this:
Python:
from mcp.client import Client
from mcp.client.sse import sse_client
async with sse_client("http://127.0.0.1:8000/sse") as (read, write):
async with Client(read, write) as client:
# Use the client to call tools
result = await client.call_tool("get_articles", {"limit": 10})
print(result)TypeScript/JavaScript:
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
const transport = new SSEClientTransport(
new URL("http://127.0.0.1:8000/sse")
);
const client = new Client({
name: "example-client",
version: "1.0.0",
}, {
capabilities: {}
});
await client.connect(transport);
// Call tools
const result = await client.callTool({
name: "get_articles",
arguments: { limit: 10 }
});Benefits of SSE Transport
HTTP-based: Works through standard HTTP infrastructure
Firewall-friendly: Easier to deploy in corporate environments
Debugging: Can use standard HTTP tools (curl, Postman, etc.)
Scalability: Can be load-balanced and proxied
No stdio: Doesn't require process spawning
Deploying SSE Server
For production deployments, you can run the SSE server as a service:
Using systemd (Linux):
[Unit]
Description=Alayman MCP Server
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/path/to/alayman-mcp
Environment="ALAYMAN_API_URL=your_api_url"
Environment="PORT=8000"
ExecStart=/usr/local/bin/uv run server.py
Restart=always
[Install]
WantedBy=multi-user.targetUsing Docker for SSE:
# Run with SSE transport exposed on port 8000
docker run -d \
-p 8000:8000 \
-e ALAYMAN_API_URL=your_api_url \
-e PORT=8000 \
--name alayman-mcp \
alaymanBehind a reverse proxy (nginx):
location /mcp/alayman/ {
proxy_pass http://127.0.0.1:8000/;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_buffering off;
proxy_cache off;
}Quick Start Examples
Once integrated with Claude Desktop or Claude Code, you can use the server in various ways:
Direct tool usage:
Show me the first 10 articles from the Alayman blog
Get articles 20-30 from the blog
Retrieve 5 articles starting from position 10Using the prompt command (Claude Code):
/alayman:list_articles 10 "the title contains 'React'"
/alayman:list_articles 5 "articles about Django"
/alayman:list_articles 15 "published in the last year"Natural language queries:
Find all articles about Angular
Show me articles related to AWS
List articles about data visualization with D3.jsAvailable Tools and Prompts
Tool: get_articles
Retrieves a paginated list of blog articles from the API.
Parameters:
limit(int, optional): Number of articles to return (default: 20, min: 1, max: 100)offset(int, optional): Number of articles to skip (default: 0, min: 0)
Returns: An ArticlesResponse object containing:
articles(list[Article]): List of article objectstotal(int): Total number of articles availableoffset(int): Current offset valuelimit(int): Current limit valuehas_more(bool): Whether more articles are available
Article Object Fields:
id(int): Unique article identifiertitle(str): Article titlesubtitle(str): Article subtitleimage(str): URL to article imageurl(str): URL to article pageauthor(str): Article author nametime(str): Publication timestamp (ISO 8601)readtime(str): Estimated reading timecategory(int): Article category IDdescription(str): Article descriptionshareCount(int): Number of sharescheckCount(int): Number of views/checks
Example usage in Claude:
Can you retrieve the first 10 articles?
Can you get articles 20-40?
Fetch the latest 5 articles from the blog.Prompt: list_articles
Generates an intelligent prompt to list and filter Alayman's articles. This prompt will instruct the LLM to use the get_articles tool and apply specific filters.
Parameters:
number(int, optional): Number of articles to list (default: 10)condition(str, optional): Condition or filter criteria for articles (default: "")
Example usage in Claude Code:
/alayman:list_articles 5 "the title contains 'React'"
/alayman:list_articles 10 "published in 2024"
/alayman:list_articles 15 "related to Python"When you run this prompt, it generates instructions for Claude to fetch articles and apply your specified conditions when presenting the results.
Project Structure
alayman-mcp/
├── server.py # Main MCP server implementation
├── pyproject.toml # Project dependencies and metadata
├── uv.lock # Dependency lock file
├── README.md # This file
├── CLAUDE.md # Claude Code project instructions
├── reference.md # Additional reference documentation
├── Dockerfile # Docker container configuration
├── .dockerignore # Docker build exclusions
├── .env.example # Example environment variables
├── .env # Environment variables (not in git)
├── .python-version # Python version specification (3.11)
├── .gitignore # Git exclusions
├── .venv/ # Virtual environment (created by uv)
└── rules/ # Development rules and guidelines
└── python.md # Python coding standardsDependencies
mcp[cli]>=1.22.0- Model Context Protocol SDK with CLI supporthttpx>=0.28.0- Modern async HTTP clientpython-dotenv- Environment variable management from .env files
Development
Architecture
The server uses the FastMCP framework from the MCP Python SDK, which provides:
Simple decorator-based tool and prompt registration
Automatic JSON schema generation from type hints
Built-in validation using Pydantic models
Support for async operations
Code Structure
Pydantic Models:
Article: Defines the article schema for type-safe data validationArticlesResponse: Defines the paginated response structure
Tool Function: The
get_articles()async function fetches and validates article data with pagination supportPrompt Function: The
list_articles()function generates contextual prompts for article discoveryServer Instance: FastMCP server configured with stdio transport
Error Handling
The server includes comprehensive error handling for:
HTTP errors (4xx, 5xx responses)
Network connectivity issues
JSON parsing errors
Data validation failures
All errors are caught and returned as descriptive exception messages.
License
This project is provided as-is for educational and development purposes.