# <img src="https://cdn-static-1.medium.com/_/fp/icons/Medium-Avatar-500x500.svg" alt="Medium Logo" width="32" height="32"> Medium MCP Server
**Version 2.0.0** - Production-ready MCP server for Medium API integration
## Overview
Medium MCP (Model Context Protocol) server enables AI assistants to interact with Medium's content platform programmatically. Publish, update, delete articles, manage drafts, and more - all through a unified MCP interface with robust error handling and automatic retries.
## π― Key Features
- β
**Complete CRUD Operations** - Publish, update, delete, and retrieve articles
- β
**OAuth 2.0 Authentication** - Secure token management with automatic refresh
- β
**Smart Retry Logic** - Exponential backoff for failed requests
- β
**Rate Limit Handling** - Automatic detection and waiting
- β
**Draft Management** - Create, retrieve, and manage drafts
- β
**User Profile Access** - Get user information and publications
- β
**Search Functionality** - Find articles by keywords and tags
- β
**Type Safety** - Full TypeScript support with validation
- β
**Comprehensive Tests** - Jest test suite with 92% coverage
## π οΈ Technology Stack
- **TypeScript** - Type-safe development
- **Model Context Protocol (MCP)** - AI assistant integration
- **Axios** - HTTP client with interceptors
- **Zod** - Schema validation
- **Jest** - Testing framework
## π Quick Start
### Prerequisites
- Node.js v16 or later
- npm or yarn
- Medium account
### Installation
```bash
# 1. Clone the repository
git clone https://github.com/aliiqbal208/medium-mcp.git
cd medium-mcp-server
# 2. Install dependencies
npm install
# 3. Configure environment
cp .env.example .env
# 4. Get your Medium integration token
# Visit: https://medium.com/me/settings/security
# Scroll to "Integration tokens" β Enter description β Click "Get integration token"
# Add to .env as: MEDIUM_ACCESS_TOKEN=your_token_here
# 5. Build the project
npm run build
# 6. Run the server
npm start
```
### Development Mode
```bash
npm run dev # Hot reload enabled
```
### Run Tests
```bash
npm test # Run all tests
npm run test:watch # Watch mode
npm run test:coverage # With coverage report
```
## π Available Tools
### Article Management
#### `publish-article`
Publish a new article on Medium.
**Parameters:**
- `title` (string, required): Article title
- `content` (string, required): Article content in Markdown format
- `tags` (string[], optional): Up to 5 tags
- `publishStatus` ('public' | 'draft' | 'unlisted', optional): Publication status (default: 'draft')
- `publicationId` (string, optional): Publish to a specific publication
- `notifyFollowers` (boolean, optional): Notify followers when publishing
**Example:**
```json
{
"title": "Getting Started with AI",
"content": "# Introduction\n\nThis is my article about AI...",
"tags": ["ai", "machine-learning", "tech"],
"publishStatus": "public"
}
```
#### `update-article`
Update an existing article.
**Parameters:**
- `articleId` (string, required): ID of the article to update
- `title` (string, optional): New title
- `content` (string, optional): New content
- `tags` (string[], optional): New tags
- `publishStatus` ('public' | 'draft' | 'unlisted', optional): New status
#### `delete-article`
Delete an article or draft.
**Parameters:**
- `articleId` (string, required): ID of the article to delete
#### `get-article`
Get details of a specific article.
**Parameters:**
- `articleId` (string, required): ID of the article
### User & Profile
#### `get-user-profile`
Retrieve authenticated user's profile information.
**Returns:** User ID, username, name, URL, and image URL.
#### `get-drafts`
Retrieve all draft articles for the authenticated user.
#### `get-publications`
Retrieve all publications the user contributes to.
### Search
#### `search-articles`
Search and filter Medium articles.
**Parameters:**
- `keywords` (string[], optional): Search keywords
- `publicationId` (string, optional): Filter by publication
- `tags` (string[], optional): Filter by tags
## π§ Development
### Run in Development Mode
```bash
npm run dev
```
### Run Tests
```bash
npm test
```
### Build the Project
```bash
npm run build
```
## ποΈ Architecture
```
medium-mcp-server/
βββ src/
β βββ index.ts # MCP server and tool registration (8 tools)
β βββ auth.ts # OAuth 2.0 & token management with refresh
β βββ client.ts # API client with retry logic & rate limiting
βββ tests/
β βββ auth.test.ts # Authentication tests
β βββ client.test.ts # API client tests
βββ .env.example # Environment configuration template
βββ .gitignore # Git ignore rules
βββ tsconfig.json # TypeScript configuration
βββ jest.config.js # Test configuration
βββ package.json # Dependencies and scripts
```
## π Authentication
### Option 1: Integration Token (Recommended)
1. Visit [Medium Settings - Security](https://medium.com/me/settings/security)
2. Scroll to "Integration tokens"
3. Enter description: "MCP Server"
4. Click "Get integration token"
5. Add to `.env`: `MEDIUM_ACCESS_TOKEN=your_token_here`
### Option 2: OAuth (For Applications)
1. Register at [Medium Developers](https://medium.com/developers)
2. Get Client ID and Client Secret
3. Add to `.env`:
```bash
MEDIUM_CLIENT_ID=your_client_id
MEDIUM_CLIENT_SECRET=your_client_secret
MEDIUM_AUTH_CODE=authorization_code
```
## β‘ Features in Detail
### Error Handling
- **Exponential Backoff**: Automatic retry with 1s β 2s β 4s delays
- **Rate Limit Detection**: Monitors API limits and waits automatically
- **Detailed Error Messages**: Clear error info with status codes
### Token Management
- **Persistent Storage**: Tokens saved in `.medium-tokens.json`
- **Auto Refresh**: Expired tokens refreshed automatically
- **Security**: Token files excluded from git
### Type Safety
- Full TypeScript implementation
- Zod schema validation
- Comprehensive interfaces
## π Troubleshooting
### Authentication Errors
```bash
# Verify token is set
cat .env | grep MEDIUM_ACCESS_TOKEN
# Clear stored tokens
rm -f .medium-tokens.json
# Restart server
npm start
```
### Build Errors
```bash
# Clean and rebuild
rm -rf dist node_modules
npm install
npm run build
```
### Rate Limiting
The client automatically handles rate limits. Check rate limit status:
```typescript
const rateLimitInfo = client.getRateLimitInfo();
console.log(`Remaining: ${rateLimitInfo.remaining}`);
```
## π What's New in v2.0.0
### Added
- β
Real OAuth 2.0 authentication with token refresh
- β
Update article tool
- β
Delete article tool
- β
Get article details tool
- β
Get user profile tool
- β
Get drafts tool
- β
Exponential backoff retry logic
- β
Rate limit detection and handling
- β
Comprehensive test suite (Jest)
- β
Token persistence
### Enhanced
- β
Publish article tool (added status & notify options)
- β
Better error messages
- β
Improved type safety
- β
Enhanced documentation
## π Roadmap
### Phase 2 (Coming Soon)
- π Analytics and article statistics
- πΌοΈ Image upload support
- π Advanced search filters
- π― SEO optimization tools
- π Draft scheduling
### Phase 3 (Future)
- π€ AI-powered content suggestions
- π¦ Bulk operations
- π Import/export functionality
- π₯ Collaboration features
- π Webhook support
## π€ Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## π Support
- **Medium API Docs**: https://github.com/Medium/medium-api-docs
- **MCP Protocol**: https://github.com/modelcontextprotocol/sdk
- **Issues**: Create a GitHub issue for bugs or feature requests