Skip to main content
Glama
README.md
# <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

Maintenance

ActivityInactive
ResponsivenessUnresponsive