WordPress MCP Server
README.md
# WordPress MCP Server
WordPress REST API를 MCP(Model Context Protocol)로 래핑한 Node.js 서버.
AI 에이전트에서 WordPress 게시글을 조회, 생성, 수정, 삭제할 수 있다.
## 프로젝트 구조
```
├── src/
│ ├── config.ts # 환경 변수 로드 및 설정 타입 정의
│ ├── logger.ts # stderr 기반 로거 (STDIO 모드 안전)
│ ├── wordpress-client.ts # WordPress REST API 클라이언트
│ ├── server.ts # MCP 서버 생성 + Tool 등록 (공통 로직)
│ ├── stdio.ts # STDIO 전송 방식 진입점
│ └── sse.ts # Streamable HTTP + 레거시 SSE 전송 방식 진입점
├── dist/ # TypeScript 빌드 출력
├── .env.example # 환경 변수 예시
├── package.json
└── tsconfig.json
```
## 아키텍처
```
┌─────────────┐ ┌──────────────────────────┐
│ stdio.ts │ │ sse.ts │
│ (StdioTx) │ │ (Express) │
│ │ │ ┌─────────────────────┐ │
│ │ │ │ Streamable HTTP │ │
│ │ │ │ POST|GET|DELETE /mcp │ │
│ │ │ ├─────────────────────┤ │
│ │ │ │ Legacy SSE │ │
│ │ │ │ GET /sse │ │
│ │ │ │ POST /messages │ │
│ │ │ └─────────────────────┘ │
└──────┬──────┘ └────────────┬─────────────┘
│ │
└───────────┬─────────────┘
│
┌───────▼───────┐
│ server.ts │
│ (McpServer + │
│ Tool 정의) │
└───────┬───────┘
│
┌─────────▼─────────┐
│ wordpress-client │
│ (REST API 호출) │
└─────────┬─────────┘
│
┌───────▼───────┐
│ WordPress │
│ /wp-json/v2 │
└───────────────┘
```
`server.ts`의 `createServer()`가 공통 로직 레이어이며, STDIO와 SSE 양쪽에서 동일하게 사용된다.
## 사전 요구사항
- Node.js 18+
- WordPress 사이트 (REST API 활성화 상태)
- WordPress Application Password 또는 Bearer Token
### WordPress Application Password 발급
1. WordPress 관리자 > 사용자 > 프로필
2. "애플리케이션 비밀번호" 섹션에서 이름을 입력하고 생성
3. 표시되는 비밀번호를 복사 (공백 포함 그대로 사용)
## 설치
```bash
npm install
npm run build
```
## 환경 변수 설정
```bash
cp .env.example .env
```
`.env` 파일을 편집한다:
```env
# WordPress 사이트 URL (trailing slash 없이)
WORDPRESS_BASE_URL=https://your-wordpress-site.com
# 인증 방식 1: Application Password (권장)
WORDPRESS_USERNAME=admin
WORDPRESS_APP_PASSWORD=xxxx xxxx xxxx xxxx xxxx xxxx
# 인증 방식 2: Bearer Token (Application Password 대신 사용)
# WORDPRESS_TOKEN=your-bearer-token
# SSE 서버 포트 (기본값: 3000)
SSE_PORT=3000
# 자체 서명 인증서 허용 (로컬 HTTPS 개발 환경에서 사용)
# WORDPRESS_TLS_REJECT_UNAUTHORIZED=false
```
| 변수 | 필수 | 설명 |
|------|------|------|
| `WORDPRESS_BASE_URL` | O | WordPress 사이트 URL |
| `WORDPRESS_USERNAME` | △ | Application Password 사용 시 |
| `WORDPRESS_APP_PASSWORD` | △ | Application Password 사용 시 |
| `WORDPRESS_TOKEN` | △ | Bearer Token 사용 시 |
| `SSE_PORT` | X | SSE 서버 포트 (기본값: 3000) |
| `WORDPRESS_TLS_REJECT_UNAUTHORIZED` | X | `false` 설정 시 자체 서명 인증서 허용 |
`WORDPRESS_TOKEN`이 설정되면 Bearer 인증을 사용하고, 없으면 `WORDPRESS_USERNAME` + `WORDPRESS_APP_PASSWORD`로 Basic 인증을 사용한다.
## 실행
### STDIO 모드
로컬 MCP 클라이언트(Claude Desktop, Claude Code 등)에서 사용하는 방식.
```bash
# 빌드 후 실행
npm run start:stdio
# 개발 모드 (tsx 직접 실행)
npm run dev:stdio
```
### SSE(HTTP) 모드
원격 MCP 클라이언트에서 HTTP로 접속하는 방식. **Streamable HTTP**(최신)와 **레거시 SSE**(구버전 클라이언트 호환) 두 가지 프로토콜을 동시에 지원한다.
```bash
# 빌드 후 실행
npm run start:sse
# 개발 모드
npm run dev:sse
```
서버 시작 후 사용 가능한 엔드포인트:
**Streamable HTTP (최신 프로토콜)**
| 메서드 | 경로 | 설명 |
|--------|------|------|
| `POST` | `/mcp` | JSON-RPC 요청 처리 (초기화 + 도구 호출) |
| `GET` | `/mcp` | SSE 스트림 (서버→클라이언트 알림) |
| `DELETE` | `/mcp` | 세션 종료 |
**Legacy SSE (구버전 클라이언트 호환)**
| 메서드 | 경로 | 설명 |
|--------|------|------|
| `GET` | `/sse` | SSE 스트림 연결 (세션 생성) |
| `POST` | `/messages?sessionId=...` | JSON-RPC 메시지 전송 |
**공통**
| 메서드 | 경로 | 설명 |
|--------|------|------|
| `GET` | `/health` | 서버 상태 확인 |
## 클라이언트 설정
### Claude Desktop
`claude_desktop_config.json`:
```json
{
"mcpServers": {
"wordpress": {
"command": "node",
"args": ["/절대경로/wordpress-mcp-server/dist/stdio.js"],
"env": {
"WORDPRESS_BASE_URL": "https://your-site.com",
"WORDPRESS_USERNAME": "admin",
"WORDPRESS_APP_PASSWORD": "xxxx xxxx xxxx xxxx xxxx xxxx"
}
}
}
}
```
### Claude Code
```bash
claude mcp add wordpress -- node /절대경로/wordpress-mcp-server/dist/stdio.js
```
또는 `.mcp.json`:
```json
{
"mcpServers": {
"wordpress": {
"command": "node",
"args": ["/절대경로/wordpress-mcp-server/dist/stdio.js"],
"env": {
"WORDPRESS_BASE_URL": "https://your-site.com",
"WORDPRESS_USERNAME": "admin",
"WORDPRESS_APP_PASSWORD": "xxxx xxxx xxxx xxxx xxxx xxxx",
"WORDPRESS_TLS_REJECT_UNAUTHORIZED": "false"
}
}
}
}
```
### SSE 모드 클라이언트 연결
SSE 서버를 실행한 후, MCP 클라이언트에서 접속:
```
# Streamable HTTP 지원 클라이언트 (최신)
http://localhost:3000/mcp
# Legacy SSE 지원 클라이언트 (구버전)
http://localhost:3000/sse
```
## MCP Tools
### listPosts
게시글 목록을 조회한다. 페이지네이션, 검색, 상태 필터를 지원한다.
| 파라미터 | 타입 | 필수 | 설명 |
|----------|------|------|------|
| `page` | number | X | 페이지 번호 (기본값: 1) |
| `per_page` | number | X | 페이지당 게시글 수 (기본값: 10, 최대: 100) |
| `search` | string | X | 검색어 |
| `status` | enum | X | `publish`, `draft`, `pending`, `private`, `trash` |
| `orderby` | enum | X | `date`, `id`, `title`, `slug`, `modified` |
| `order` | enum | X | `asc`, `desc` |
### getPost
게시글 하나를 ID로 조회한다.
| 파라미터 | 타입 | 필수 | 설명 |
|----------|------|------|------|
| `id` | number | O | 게시글 ID |
### createPost
새 게시글을 생성한다.
| 파라미터 | 타입 | 필수 | 설명 |
|----------|------|------|------|
| `title` | string | O | 게시글 제목 |
| `content` | string | O | 게시글 내용 (HTML 가능) |
| `status` | enum | X | `publish`, `draft`, `pending`, `private` (기본값: `draft`) |
| `excerpt` | string | X | 게시글 요약 |
| `categories` | number[] | X | 카테고리 ID 배열 |
| `tags` | number[] | X | 태그 ID 배열 |
### updatePost
기존 게시글을 수정한다. 전달된 필드만 변경된다.
| 파라미터 | 타입 | 필수 | 설명 |
|----------|------|------|------|
| `id` | number | O | 수정할 게시글 ID |
| `title` | string | X | 변경할 제목 |
| `content` | string | X | 변경할 내용 (HTML 가능) |
| `status` | enum | X | `publish`, `draft`, `pending`, `private` |
| `excerpt` | string | X | 변경할 요약 |
| `categories` | number[] | X | 변경할 카테고리 ID 배열 |
| `tags` | number[] | X | 변경할 태그 ID 배열 |
### deletePost
게시글을 삭제한다.
| 파라미터 | 타입 | 필수 | 설명 |
|----------|------|------|------|
| `id` | number | O | 삭제할 게시글 ID |
| `force` | boolean | X | `true`이면 영구 삭제, `false`이면 휴지통 이동 (기본값: `false`) |
## 기술 스택
| 항목 | 사용 기술 |
|------|-----------|
| 런타임 | Node.js 18+ |
| 언어 | TypeScript (ESM) |
| MCP SDK | `@modelcontextprotocol/sdk` ^1.26.0 |
| HTTP 클라이언트 | Node.js 내장 `fetch` |
| 스키마 검증 | `zod` |
| SSE 서버 | Express + `StreamableHTTPServerTransport` + `SSEServerTransport` |
| WordPress API | `/wp-json/wp/v2` (REST API v2) |
## 주요 설계 결정
- **공통 로직 분리**: `server.ts`의 `createServer(config)` 함수가 McpServer 인스턴스와 모든 Tool을 생성한다. STDIO와 SSE 진입점은 전송 방식만 다르다.
- **stderr 로깅**: STDIO 모드에서 stdout은 JSON-RPC 프로토콜 메시지 전용이므로, 모든 로그는 `console.error`(stderr)로 출력한다.
- **듀얼 전송 프로토콜**: SSE 서버가 Streamable HTTP(`/mcp`)와 레거시 SSE(`/sse` + `/messages`)를 동시에 제공한다. 최신 클라이언트와 구버전 클라이언트 모두 호환된다.
- **세션 관리**: 두 전송 방식 모두 클라이언트별 독립 세션을 생성한다. Streamable HTTP는 `mcp-session-id` 헤더, 레거시 SSE는 `sessionId` 쿼리 파라미터로 세션을 식별한다.
- **오류 처리**: WordPress API 오류 응답(4xx, 5xx)을 파싱하여 MCP `isError: true` 결과로 반환한다. 에이전트가 오류 내용을 이해하고 대응할 수 있다.
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues