Skip to main content
Glama
InstaWP

WordPress MCP Server

by InstaWP

WordPress MCP 서버

이것은 WordPress용 Model Context Protocol(MCP) 서버로, Claude for Desktop과 같은 MCP 호환 클라이언트를 통해 자연어로 WordPress 사이트와 상호작용할 수 있게 해줍니다. 이 서버는 다양한 WordPress 데이터와 기능을 MCP 도구로 노출합니다.

사용 방법

Claude Desktop

  1. Claude Desktop을 다운로드하여 설치합니다.

  2. Claude Desktop 설정을 열고 "Developer" 탭으로 이동합니다.

  3. claude_desktop_config.json.example 파일의 내용을 복사합니다.

  4. "Edit Config"를 클릭하여 claude_desktop_config.json 파일을 엽니다.

  5. 예제 파일의 내용을 구성 파일에 복사하여 붙여넣습니다. WordPress 사이트의 실제 값으로 자리 표시자 값을 반드시 교체하세요. 애플리케이션 키를 생성하려면 이 가이드를 따르세요 - Application Passwords.

  6. 구성을 저장합니다.

  7. Claude Desktop을 다시 시작합니다.

Related MCP server: WordPress MCP Server

기능

이 서버는 핵심 WordPress 데이터와 상호작용하는 도구를 제공하며 다중 사이트 관리를 지원합니다 - 단일 MCP 서버 인스턴스에서 여러 WordPress 사이트를 관리할 수 있습니다.

다중 사이트 관리 (3개 도구)

단일 MCP 서버에서 여러 WordPress 사이트를 관리합니다:

  • list_sites: 구성된 모든 WordPress 사이트 나열

  • get_site: 특정 사이트 구성에 대한 세부 정보 가져오기

  • test_site: 특정 WordPress 사이트에 대한 연결 테스트

모든 콘텐츠 및 분류 도구는 특정 사이트를 대상으로 하는 선택적 site_id 매개변수를 지원합니다.

통합 콘텐츠 관리 (9개 도구)

단일 지능형 도구 세트로 모든 콘텐츠 유형(게시물, 페이지, 사용자 정의 콘텐츠 유형)을 처리합니다:

  • list_content: 필터링 및 페이지네이션으로 모든 콘텐츠 유형 나열

  • get_content: ID와 유형으로 특정 콘텐츠 가져오기

  • create_content: 모든 유형의 새 콘텐츠 생성

  • update_content: 모든 유형의 기존 콘텐츠 업데이트(대상 부분 편집 포함)

  • delete_content: 모든 유형의 콘텐츠 삭제

  • discover_content_types: 사이트에서 사용 가능한 모든 콘텐츠 유형 찾기

  • find_content_by_url: 모든 WordPress URL에서 콘텐츠를 찾고 선택적으로 업데이트할 수 있는 스마트 URL 해석기(대상 부분 편집 포함)

  • get_content_by_slug: 모든 콘텐츠 유형에서 슬러그로 검색

  • get_content_summary: 감사 및 조회 워크플로를 위한 최소 요약(id, title, slug, status, excerpt, taxonomies, 단어 수, Yoast SEO 필드) 반환. id 또는 url로 조회.

통합 분류 관리 (8개 도구)

단일 도구 세트로 모든 분류(카테고리, 태그, 사용자 정의 분류)를 처리합니다:

  • discover_taxonomies: 사이트에서 사용 가능한 모든 분류 찾기

  • list_terms: 모든 분류에서 용어 나열

  • get_term: ID로 특정 용어 가져오기

  • create_term: 모든 분류에서 새 용어 생성

  • update_term: 기존 용어 업데이트

  • delete_term: 모든 분류에서 용어 삭제

  • assign_terms_to_content: 모든 콘텐츠 유형에 용어 할당

  • get_content_terms: 모든 콘텐츠의 모든 용어 가져오기

전문 도구

  • 미디어:

    • list_media: 모든 미디어 항목 나열(페이지네이션 및 검색 지원).

    • get_media: ID로 특정 미디어 항목 검색.

    • create_media: URL 또는 로컬 파일 경로에서 새 미디어 항목 생성.

    • update_media: 기존 미디어 항목 업데이트.

    • delete_media: 미디어 항목 삭제.

    • edit_media: 이전 버전과의 호환성을 위해 유지되는 update_media의 레거시 별칭.

  • 사용자:

    • list_users: 필터링, 정렬 및 페이지네이션 옵션으로 모든 사용자 나열.

    • get_user: ID로 특정 사용자 검색.

    • create_user: 새 사용자 생성.

    • update_user: 기존 사용자 업데이트.

    • delete_user: 사용자 삭제.

  • 댓글:

    • list_comments: 필터링, 정렬 및 페이지네이션 옵션으로 모든 댓글 나열.

    • get_comment: ID로 특정 댓글 검색.

    • create_comment: 새 댓글 생성.

    • update_comment: 기존 댓글 업데이트.

    • delete_comment: 댓글 삭제.

  • 플러그인:

    • list_plugins: 사이트에 설치된 모든 플러그인 나열.

    • get_plugin: 특정 플러그인에 대한 세부 정보 검색.

    • activate_plugin: 플러그인 활성화.

    • deactivate_plugin: 플러그인 비활성화.

    • create_plugin: 새 플러그인 생성.

  • 플러그인 저장소:

  • search_plugins: WordPress.org 저장소에서 플러그인 검색.

  • get_plugin_info: 저장소에서 플러그인에 대한 자세한 정보 가져오기.

  • 데이터베이스 쿼리:

  • execute_sql_query: WordPress 데이터베이스에 대해 읽기 전용 SQL 쿼리 실행(사용자 정의 엔드포인트 설정 필요).

주요 장점

미디어 업로드 워크플로

MCP 서버가 실행 중인 동일한 머신에서 로컬 스크린샷 업로드:

{
  "file_path": "./screenshots/homepage.png",
  "title": "Homepage Screenshot",
  "alt_text": "Homepage screenshot showing the hero section"
}

원격 URL에서 미디어 업로드:

{
  "source_url": "https://example.com/assets/hero-image.png",
  "title": "Hero Image",
  "caption": "Imported from the design system"
}

반환된 미디어 ID를 새 콘텐츠의 추천 미디어로 사용:

{
  "content_type": "post",
  "title": "Release Notes",
  "content": "<p>Launch summary...</p>",
  "featured_media": 123
}

스마트 URL 해석

find_content_by_url 도구는 다음을 수행할 수 있습니다:

  • 모든 WordPress URL을 가져와 해당 콘텐츠를 자동으로 찾기

  • URL 패턴에서 콘텐츠 유형 감지(예: /documentation/ → documentation 사용자 정의 콘텐츠 유형)

  • 단일 작업으로 콘텐츠를 선택적으로 업데이트

  • 게시물, 페이지 및 모든 사용자 정의 콘텐츠 유형에서 작동

감사 및 조회 요약

get_content_summary 도구는 단일 콘텐츠의 최소 고정 형태 표현을 반환합니다. 렌더링된 Recipe Maker 카드 HTML 때문에 레시피 게시물에서 50KB를 초과할 수 있는 전체 WP REST 응답이 과한 감사 및 조회 워크플로를 위해 설계되었습니다.

ID로 조회(선택적 content_type 포함, 기본값은 post):

{
  "id": 4274,
  "content_type": "post"
}

URL로 조회(콘텐츠 유형은 URL에서 감지됨):

{
  "url": "https://example.com/blog/easy-smoked-asparagus/"
}

idurl은 상호 배타적입니다 - 정확히 하나만 제공하세요.

응답 형태는 고정되어 있습니다:

{
  "id": 4274,
  "title": "Easy Smoked Asparagus & Hot Honey",
  "slug": "easy-smoked-asparagus",
  "status": "publish",
  "link": "https://example.com/blog/easy-smoked-asparagus/",
  "excerpt": "Smoky asparagus with hot honey.",
  "date_modified": "2026-04-30T10:14:00",
  "categories": [12, 7],
  "tags": [33],
  "featured_media": 9012,
  "word_count": 875,
  "yoast_focus_keyword": "smoked asparagus",
  "yoast_meta_title": "Easy Smoked Asparagus | Example",
  "yoast_meta_description": "Smoky charred asparagus finished with chili-lime hot honey."
}

필드 참고 사항:

  • titleexcerpt는 일반 텍스트로 변환됩니다(HTML 태그 제거, 기본 엔티티 디코딩).

  • word_count는 Yoast SEO가 활성화된 경우 yoast_head_json.schema.@graph[].wordCount를 우선 사용하고, 그렇지 않으면 HTML이 제거된 렌더링된 게시물 콘텐츠에서 계산됩니다.

  • yoast_meta_titleyoast_meta_description은 게시물의 yoast_head_json에서 읽습니다. Yoast SEO가 활성화되지 않은 경우 null입니다.

  • yoast_focus_keywordmeta._yoast_wpseo_focuskw에서 읽습니다. WordPress 코어는 show_in_rest로 등록된 메타 키만 노출하며, Yoast SEO는 기본적으로 이 키를 등록하지 않습니다 — 따라서 이 필드는 일반적으로 null입니다(더 넓은 메타 키 REST 노출 문제에 대한 맥락은 PR #17 참조).

  • 이 도구는 yoast_head_json을 읽을 수 있도록 PR #16에서 추가된 응답 트리밍을 내부적으로 우회합니다. 트리밍은 다른 모든 도구에는 여전히 적용됩니다.

범용 콘텐츠 작업

모든 콘텐츠 작업은 단일 content_type 매개변수를 사용합니다:

{
  "content_type": "post", // for blog posts
  "content_type": "page", // for static pages
  "content_type": "product", // for WooCommerce products
  "content_type": "documentation" // for custom post types
}

대상 콘텐츠 편집

update_contentfind_content_by_url.update_fields는 전체 문서를 다시 보내지 않고 기존 원시 WordPress 콘텐츠를 패치할 수 있습니다.

정확한 일치를 쉽게 하기 위해 get_contentfind_content_by_url은 모두 include_raw_content: true를 허용합니다. 활성화하면 응답이 WordPress 편집 컨텍스트로 가져와지며 content_edit.target_text가 필요로 하는 것과 일치하는 최상위 content_raw 필드를 포함합니다.

{
  "content_type": "page",
  "id": 7,
  "include_raw_content": true
}

게시물 끝에 짧은 릴리스 노트 추가:

{
  "content_type": "post",
  "id": 42,
  "content_edit": {
    "operation": "append",
    "value": "\n<p>Update: Early access is now open.</p>",
    "content_format": "html"
  }
}

고유한 HTML 조각 또는 마커 주석을 제자리에서 교체:

{
  "content_type": "page",
  "id": 7,
  "content_edit": {
    "operation": "replace",
    "target_text": "<!-- pricing-card -->\n<p>Old price</p>\n<!-- /pricing-card -->",
    "value": "<!-- pricing-card -->\n<p>New price</p>\n<!-- /pricing-card -->",
    "content_format": "html"
  }
}

참고 사항:

  • 렌더링된 WordPress HTML은 엔티티가 이스케이프되고 마크업이 확장될 수 있으므로 content.raw와 다를 수 있습니다. 정확한 target_text가 필요한 경우 include_raw_content를 사용하세요.

  • target_text는 저장된 원시 WordPress 콘텐츠와 정확히 일치합니다.

  • 동일한 target_text가 여러 번 나타나는 경우 occurrence를 전달하여 1부터 시작하는 일치 항목을 선택하세요.

  • Gutenberg 블록으로 저장된 게시물의 경우 블록이 되어야 하는 Markdown 또는 HTML을 삽입할 때 content_edit.convert_to_blocks를 설정하세요.

범용 분류 작업

모든 분류 작업은 단일 taxonomy 매개변수를 사용합니다:

{
  "taxonomy": "category", // for categories
  "taxonomy": "post_tag", // for tags
  "taxonomy": "product_category", // for WooCommerce
  "taxonomy": "skill" // for custom taxonomies
}

taxonomy 매개변수는 분류 슬러그 또는 해당 rest_base를 허용합니다(사용자 정의 분류의 경우 다를 수 있음, 예: 슬러그 documentation_category와 rest_base documentation-categories). 도구는 /wp/v2/taxonomies를 통해 식별자를 해석하고 추측하는 대신 알 수 없는 분류에 대해 오류를 반환합니다. assign_terms_to_content는 WordPress 응답에 대해 쓰기를 검증하고 용어가 실제로 저장되지 않은 경우 오류를 보고합니다.

레시피 카드 (WP Recipe Maker)

WP Recipe Maker(WPRM)을 실행하는 사이트는 주변 블로그 게시물의 단축 코드로 참조되는 별도의 wprm_recipe 사용자 정의 콘텐츠 유형에 레시피 카드를 저장합니다. 통합 콘텐츠 도구는 이러한 레시피를 직접 처리합니다 — 레시피 전용 도구 모음이 필요하지 않습니다.

레시피 읽기get_content, list_content, find_content_by_url, get_content_by_slug는 모두 content_type: "wprm_recipe"와 함께 작동합니다. WPRM은 재료, 조리법, 시간, 장비, 영양 정보, 메모 및 평점을 포함한 전체 구조화된 레시피 페이로드를 REST 응답의 recipe 필드로 노출합니다.

레시피 쓰기create_content 또는 update_contentcustom_fields.recipe를 통해 레시피 페이로드를 전달합니다. WPRM은 WordPress REST 삽입 작업(rest_insert_wprm_recipe)에 연결되어 요청 본문 루트에서 recipe를 읽으므로 WPRM의 데이터 모델에 문서화된 모든 필드가 허용됩니다.

recipe 페이로드는 custom_fields를 통해 전달되어야 합니다(요청 본문 루트에 펼쳐집니다). meta 매개변수는 값을 meta 키 아래에 중첩하므로 WPRM의 REST 훅에 도달하지 않습니다.

업데이트 예시:

{
  "content_type": "wprm_recipe",
  "id": 4274,
  "custom_fields": {
    "recipe": {
      "name": "Easy Smoked Asparagus",
      "summary": "Smoky asparagus with hot honey.",
      "servings": "4",
      "servings_unit": "people",
      "prep_time": "5",
      "cook_time": "60",
      "total_time": "65",
      "ingredients": [
        {
          "name": "",
          "ingredients": [
            { "uid": 0, "amount": "1", "unit": "Bunch", "name": "Asparagus Spears", "notes": "" },
            { "uid": 1, "amount": "1", "unit": "tbsp", "name": "Olive Oil", "notes": "" }
          ]
        }
      ],
      "instructions": [
        {
          "name": "",
          "instructions": [
            { "uid": 0, "name": "", "text": "Preheat smoker to 225°F.", "ingredients": [] },
            { "uid": 1, "name": "", "text": "Drizzle with oil, season, smoke 1 hour.", "ingredients": [] }
          ]
        }
      ],
      "notes": "Thicker spears need more time."
    }
  }
}

그룹화된 재료 및 조리법 — 레시피는 항목을 "소스용" / "치킨용"과 같은 명명된 그룹으로 분할할 수 있습니다. 외부 ingredients(또는 instructions) 배열의 각 항목은 자체 name과 내부 배열을 가진 하나의 그룹입니다:

{
  "ingredients": [
    { "name": "For the sauce",   "ingredients": [ /* items */ ] },
    { "name": "For the chicken", "ingredients": [ /* items */ ] }
  ]
}

일반적으로 사용되는 레시피 필드:

필드

유형

참고 사항

name

string

레시피 카드 제목

summary

string

짧은 설명(HTML 허용)

servings

string

예: "4"

servings_unit

string

예: "people", "servings"

prep_time

string

분, 예: "15"

cook_time

string

total_time

string

ingredients

array of groups

위에 표시된 중첩 구조

instructions

array of groups

위에 표시된 중첩 구조

notes

string

HTML 허용

equipment

array

{ id, name, notes, amount, uid } 형태의 항목

image_url

string

image_id가 제공되지 않을 때 URL로 업로드

코스, 요리, 키워드는 WPRM 분류(wprm_course, wprm_cuisine, wprm_keyword)로 저장됩니다. 통합 분류 도구(list_terms, create_term, ...)로 관리하고 assign_terms_to_content로 레시피에 연결하세요.

WPRM은 저장 시 recipe.summary를 WordPress post_content 필드에 자동으로 다시 동기화합니다. 게시물 본문과 레시피 요약을 다르게 하려면 custom_fields.recipe와 함께 content를 명시적으로 전달하세요.

구성

단일 사이트 구성

단일 WordPress 사이트를 관리하려면 다음 환경 변수를 사용하세요:

WORDPRESS_API_URL=https://your-wordpress-site.com
WORDPRESS_USERNAME=wp_username
WORDPRESS_PASSWORD=wp_app_password

다중 사이트 구성

단일 MCP 서버에서 여러 WordPress 사이트를 관리하려면 번호가 매겨진 환경 변수를 사용하세요:

# Site 1 (Production)
WORDPRESS_1_URL=https://production-site.com
WORDPRESS_1_USERNAME=admin
WORDPRESS_1_PASSWORD=app_password_1
WORDPRESS_1_ID=production
WORDPRESS_1_DEFAULT=true
WORDPRESS_1_ALIASES=prod,main

# Site 2 (Staging)
WORDPRESS_2_URL=https://staging-site.com
WORDPRESS_2_USERNAME=admin
WORDPRESS_2_PASSWORD=app_password_2
WORDPRESS_2_ID=staging
WORDPRESS_2_ALIASES=stage,dev

# Site 3 (Development)
WORDPRESS_3_URL=https://dev-site.com
WORDPRESS_3_USERNAME=admin
WORDPRESS_3_PASSWORD=app_password_3
WORDPRESS_3_ID=development

다중 사이트 구성 옵션:

  • WORDPRESS_N_URL: WordPress 사이트 URL (필수)

  • WORDPRESS_N_USERNAME: WordPress 사용자 이름 (필수)

  • WORDPRESS_N_PASSWORD: WordPress 애플리케이션 비밀번호 (필수)

  • WORDPRESS_N_ID: 사이트 식별자 (선택, 기본값은 siteN)

  • WORDPRESS_N_DEFAULT: true로 설정하면 이 사이트가 기본 사이트가 됩니다 (선택, 첫 번째 사이트가 기본값)

  • WORDPRESS_N_ALIASES: 사이트 감지를 위한 쉼표로 구분된 별칭 (선택)

이 서버는 최대 10개 사이트를 지원합니다. 다중 사이트 구성을 사용할 때 모든 도구는 선택적 site_id 매개변수를 받아 특정 사이트를 대상으로 지정할 수 있습니다.

npx 및 .env 파일과 함께 사용하기

이 MCP 서버를 전역으로 설치하지 않고 npx를 사용하여 직접 실행할 수 있습니다:

npx -y @instawp/mcp-wp

현재 디렉터리에 다음 변수가 포함된 .env 파일이 있는지 확인하세요:

WORDPRESS_API_URL=https://your-wordpress-site.com
WORDPRESS_USERNAME=wp_username
WORDPRESS_PASSWORD=wp_app_password

# Optional: Custom SQL query endpoint (default: /mcp/v1/query)
WORDPRESS_SQL_ENDPOINT=/mcp/v1/query

# Optional: Comma-separated list of top-level fields to strip from
# WordPress REST API responses before they are returned to the MCP
# client. Defaults to "yoast_head,yoast_head_json" — read-only schema
# markup that adds ~10KB to every response but is rarely useful to the
# LLM. Set to an empty string to disable trimming.
MCP_WP_STRIP_FIELDS=yoast_head,yoast_head_json

사용자 에이전트

이 서버가 만드는 모든 아웃바운드 요청(모든 도구가 사용하는 WordPress REST 클라이언트, SQL 엔드포인트, 두 개의 api.wordpress.org 조회, 원격 미디어 다운로드)은 axios의 기본 axios/<version> 사용자 에이전트를 보냅니다.

WORDPRESS_USER_AGENT를 설정하면 모든 곳에서 이를 재정의합니다:

WORDPRESS_USER_AGENT=MyAgency-MCP/1.0 (+https://example.com)

사이트 앞단의 CDN이나 WAF가 기본값을 거부하지 않는 한 설정하지 않은 채로 두세요. 빈 값이나 공백만 있는 값은 설정되지 않은 것으로 처리됩니다. 단순한 Mozilla/5.0은 피하세요 — 잘 알려진 봇 시그니처이며 여러 엣지가 정확히 차단하는 대상입니다(#28 참조). 그래서 여기서는 아무것도 이를 보내지 않습니다.

응답 트리밍

기본적으로 서버는 MCP 클라이언트에 반환하기 전에 모든 WordPress REST API 응답에서 최상위 yoast_headyoast_head_json 필드를 제거합니다. 이 필드에는 Yoast SEO의 사전 렌더링된 스키마 마크업이 포함되어 있으며, LLM이 거의 필요로 하지 않지만 모든 요청에서 토큰을 지불하게 됩니다.

  • 트리밍은 단일 객체 응답과 객체 배열 모두에 적용됩니다.

  • 최상위 필드만 제거됩니다. 중첩된 객체는 그대로 둡니다.

  • MCP_WP_STRIP_FIELDS 환경 변수(쉼표로 구분)로 목록을 재정의할 수 있습니다. 빈 문자열로 설정하면 트리밍이 완전히 비활성화됩니다.

메타 필드 제한 사항

create_content, update_content, find_content_by_url(의 update_fields.meta)의 meta 매개변수는 WordPress /wp/v2/{type}/{id} 엔드포인트로 직접 전달됩니다. WordPress 코어는 register_post_meta(..., ['show_in_rest' => true])를 통해 등록되지 않은 메타 키를 조용히 버립니다. MCP 서버에는 자체 허용 목록이 없습니다 — 어떤 키가 유지되는지 강제하는 것은 WordPress에 의존합니다.

즉, SEO 플러그인 키는 기본적으로 이 MCP 서버를 통해 쓸 수 없습니다. 여기에는 다음이 포함됩니다:

  • Yoast SEO: _yoast_wpseo_* (focuskw, metadesc, title, opengraph-, twitter-, canonical, meta-robots-*, primary_category, …)

  • Rank Math: rank_math_* (title, description, focus_keyword, robots, facebook_, twitter_, primary_category, …)

  • All in One SEO (v4+): SEO 데이터를 wp_postmeta가 아닌 사용자 정의 테이블(wp_aioseo_posts)에 저장 — 어떤 방법으로도 meta 필드를 통해 접근할 수 없습니다.

서버는 WordPress가 보낸 키 중 일부를 버렸는지 감지하고 도구 결과 앞에 이를 나열하는 Warning: 블록을 추가합니다. 이렇게 하면 조용한 삭제가 LLM 호출자에게 보이지만, WordPress가 키를 받아들이게 할 수는 없습니다.

SEO 메타 쓰기를 활성화하려면 각 원하는 키에 대해 show_in_rest => true와 적절한 auth_callback으로 register_post_meta를 호출하는 작은 WordPress 동반 플러그인을 설치하세요. 별도의 mcp-wp-seo-bridge 플러그인이 정확히 이 작업을 수행하도록 범위가 정해져 있습니다.

현재 작동하는 키

플러그인 작성자가 이미 REST용으로 등록한 플러그인 키 — 예: Genesis 레이아웃 메타(_genesis_layout), WP Recipe Maker 필드(wprm-*), ConvertKit의 _wp_convertkit_post_meta. 사이트에서 어떤 키가 왕복하는지 확인하려면 update_content를 통해 테스트 값을 쓰고 응답의 meta 블록을 검사하세요 — 키가 나타나면 유지된 것입니다.

동일한 제한이 unified-taxonomies 도구(create_term, update_term)의 용어 메타에도 적용됩니다.

SQL 쿼리 도구 활성화 (선택)

execute_sql_query 도구를 사용하면 WordPress 데이터베이스에 대해 읽기 전용 SQL 쿼리를 실행할 수 있습니다. 이는 WordPress 사이트에 사용자 정의 REST API 엔드포인트를 추가해야 하는 선택적 기능입니다.

보안 참고 사항:

  • 이 도구는 안전을 위해 읽기 전용 쿼리(SELECT, WITH...SELECT, EXPLAIN)만 허용합니다

  • INSERT, UPDATE, DELETE, DROP 또는 기타 수정 문이 포함된 쿼리는 거부됩니다

  • SQL 주입을 방지하기 위해 다중 문 쿼리는 차단됩니다

  • 쿼리와 결과는 logs/wordpress-api.log에 기록됩니다 — 쿼리에 민감한 데이터를 포함하지 마세요

  • 이 도구는 관리자 수준 권한(manage_options 기능)이 필요합니다

구성: 기본적으로 도구는 /mcp/v1/query 엔드포인트를 기대합니다. WORDPRESS_SQL_ENDPOINT 환경 변수(예: WORDPRESS_SQL_ENDPOINT=/custom/v1/query)를 설정하여 사용자 정의할 수 있습니다.

이 기능을 활성화하려면 WordPress 사이트(사용자 정의 플러그인 또는 테마의 functions.php를 통해)에 다음 코드를 추가하세요:

add_action('rest_api_init', function() {
    register_rest_route('mcp/v1', '/query', array(
        'methods' => 'POST',
        'callback' => function($request) {
            global $wpdb;

            $query = $request->get_param('query');

            // Additional security check
            if (!current_user_can('manage_options')) {
                return new WP_Error('unauthorized', 'Unauthorized', array('status' => 401));
            }

            // Only allow SELECT queries
            if (stripos(trim($query), 'SELECT') !== 0) {
                return new WP_Error('invalid_query', 'Only SELECT queries allowed', array('status' => 400));
            }

            $results = $wpdb->get_results($query, ARRAY_A);

            if ($wpdb->last_error) {
                return new WP_Error('query_error', $wpdb->last_error, array('status' => 400));
            }

            return array(
                'results' => $results,
                'num_rows' => count($results)
            );
        },
        'permission_callback' => function() {
            return current_user_can('manage_options');
        }
    ));
});

이 코드를 추가한 후 execute_sql_query 도구를 사용하여 다음과 같은 쿼리를 실행할 수 있습니다:

SELECT * FROM wp_posts WHERE post_type = 'post' AND post_status = 'publish' LIMIT 10

개발

사전 요구 사항

  • Node.js 및 npm: Node.js(버전 18 이상)와 npm이 설치되어 있는지 확인하세요. Node 18이면 서버를 실행하기에 충분합니다. 기여에는 Node 20 이상이 필요합니다. 테스트 도구(Vitest 4)가 이를 요구하기 때문입니다 — CI는 20.x 및 22.x를 실행합니다.

  • WordPress 사이트: REST API가 활성화된 활성 WordPress 사이트가 필요합니다.

  • WordPress API 인증: WordPress REST API에 대한 인증을 설정하세요. 일반적으로 인증 플러그인 또는 방법(예: 애플리케이션 비밀번호)이 필요합니다.

  • MCP 클라이언트: MCP 서버와 통신할 수 있는 애플리케이션이 필요합니다. 현재 Claude Desktop이 권장됩니다.

설치 및 설정

  1. 저장소 복제:

    git clone <repository_url>
    cd wordpress-mcp-server
  2. 의존성 설치:

    npm install
  3. .env 파일 생성:

    프로젝트 디렉터리 루트에 .env 파일을 만들고 WordPress API 자격 증명을 추가하세요.

    단일 사이트의 경우:

    WORDPRESS_API_URL=https://your-wordpress-site.com
    WORDPRESS_USERNAME=wp_username
    WORDPRESS_PASSWORD=wp_app_password

    다중 사이트의 경우:

    WORDPRESS_1_URL=https://site1.com
    WORDPRESS_1_USERNAME=admin
    WORDPRESS_1_PASSWORD=app_password_1
    WORDPRESS_1_ID=site1
    WORDPRESS_1_DEFAULT=true
    
    WORDPRESS_2_URL=https://site2.com
    WORDPRESS_2_USERNAME=admin
    WORDPRESS_2_PASSWORD=app_password_2
    WORDPRESS_2_ID=site2

    자리 표시자를 실제 값으로 바꾸세요.

  4. 서버 빌드:

    npm run build
  5. Claude Desktop 구성:

    • Claude Desktop 설정을 열고 "Developer" 탭으로 이동합니다.

    • "Edit Config"를 클릭하여 claude_desktop_config.json 파일을 엽니다.

    • mcpServers 섹션 아래에 새 서버 구성을 추가합니다. build/server.js 파일의 절대 경로와 WordPress 환경 변수를 제공해야 합니다.

    • 구성을 저장합니다.

서버 실행

Claude Desktop을 구성하면 Claude Desktop이 시작될 때마다 서버가 자동으로 시작됩니다.

테스트를 위해 명령줄에서 직접 서버를 실행할 수도 있습니다:

npm start

또는 개발 모드에서:

npm run dev

테스트 실행

이 저장소는 단위 테스트에 Vitest를 사용합니다. 테스트는 tests/ 아래에 있으며 다중 사이트 SiteManager와 MCP 도구 레지스트리 연결을 다룹니다.

npm test          # one-shot run
npm run test:watch  # watch mode

테스트는 .github/workflows/test.yml을 통해 pull_requestmain에 대한 푸시에서 실행됩니다.

릴리스

수정 사항을 병합해도 아무에게도 도달하지 않습니다 — 릴리스가 실행될 때까지 npm은 마지막으로 게시된 버전을 계속 제공합니다. 게시는 버전 태그에 의해 트리거되는 .github/workflows/release.yml에 의해 자동화됩니다:

# on main, with the fix already merged:
# 1. move the CHANGELOG's [Unreleased] block under a `[x.y.z] - <date>` heading and commit it
# 2. bump and tag — `npm version` writes package.json, commits, and creates the vx.y.z tag
npm version patch          # or minor / major
# 3. push the commit and the tag; the tag is what triggers the publish
git push origin main --follow-tags

npm version 전에 CHANGELOG 편집을 하세요. 이후에 커밋을 수정하면 태그가 수정 전 커밋을 가리키게 되고 워크플로우가 해당 커밋에서 게시하게 됩니다.

워크플로우는 태그와 package.json이 일치하지 않거나 해당 버전이 이미 npm에 있는 경우 게시를 거부합니다. 그런 다음 빌드하고, 테스트를 실행하고, provenance로 게시하고, 레지스트리가 실제로 새 버전을 제공하는지 확인한 후 성공을 보고합니다.

태그가 존재하지만 게시가 실패한 경우(또는 이 워크플로우 이전인 경우), Actions → Release → Run workflow에서 다시 실행하고 브랜치 선택기를 main(워크플로우 파일을 읽는 위치)에 두고 입력에 태그 이름을 전달하세요. 두 가지 주의 사항: 태그의 트리에는 아래 설명된 repository 필드가 이미 포함되어 있어야 하며, provenance 증명은 태그가 아닌 워크플로우가 디스패치된 ref를 기록합니다 — 따라서 실제 릴리스의 경우 버전을 다시 절단하고 태그 푸시 경로를 사용하는 것이 좋습니다.

게시는 성공했지만 검증 단계가 빨간색으로 표시되는 경우(레지스트리가 2분 이상 느리게 유지된 경우), 아무것도 하기 전에 npmjs.com을 확인하세요: 버전이 게시되었으며, 재실행하면 설계상 이미 npm에 있는 가드에서 실패할 것입니다. 그 경우 수정할 것은 없습니다.

설정(1회): 워크플로우는 @instawp 범위에 게시 권한이 있는 npm 자동화 토큰이 필요하며, 저장소 비밀 NPM_TOKEN(Settings → Secrets and variables → Actions)으로 저장됩니다. 특히 자동화 토큰이어야 합니다 — 클래식 게시 토큰은 2FA가 적용된 계정에서 CI에서 실패합니다.

npm의 trusted publishing은 저장된 토큰을 완전히 제거하지만, npm ≥ 11.5.1이 필요하고 setup-node가 현재 Node 22와 함께 npm 10.x를 제공하므로 작업 내에서 npm을 업그레이드하지 않는 한 여기서 사용할 수 없습니다.

provenance로 게시하려면 package.jsonrepository 필드가 이 저장소와 일치해야 합니다 — 그렇지 않으면 레지스트리가 게시를 거부합니다. 제거하지 마세요.

보안

  • API 키나 비밀을 버전 관리에 커밋하지 마세요.

  • 클라이언트와 서버 간 통신에는 HTTPS를 사용하세요.

  • 인젝션 공격을 방지하기 위해 클라이언트에서 받은 모든 입력을 검증하세요.

  • 적절한 오류 처리와 속도 제한을 구현하세요.

프로젝트 개요

아키텍처

서버는 복잡성을 줄이기 위해 통합 도구 아키텍처를 사용합니다:

src/
├── server.ts                    # MCP server entry point
├── wordpress.ts                 # WordPress REST API client
├── cli.ts                      # CLI interface
├── config/
│   └── site-manager.ts         # Multi-site management
├── types/
│   └── wordpress-types.ts      # TypeScript definitions
└── tools/
    ├── index.ts                # Tool aggregation
    ├── site-management.ts      # Site management (3 tools)
    ├── unified-content.ts      # Universal content management (8 tools)
    ├── unified-taxonomies.ts   # Universal taxonomy management (8 tools)
    ├── media.ts               # Media management (5 canonical tools + edit_media alias)
    ├── users.ts               # User management (~5 tools)
    ├── comments.ts            # Comment management (~5 tools)
    ├── plugins.ts             # Plugin management (~5 tools)
    ├── plugin-repository.ts   # WordPress.org plugin search (~2 tools)
    └── sql-query.ts           # Database queries (1 tool)

주요 기능

  • 다중 사이트 지원: 단일 MCP 서버 인스턴스에서 여러 WordPress 사이트 관리

  • 스마트 URL 해석: URL에서 콘텐츠 유형을 자동으로 감지하고 해당 콘텐츠 찾기

  • 범용 콘텐츠 관리: 단일 도구 세트로 게시물, 페이지 및 사용자 정의 게시 유형 처리

  • 범용 분류 관리: 단일 도구 세트로 카테고리, 태그 및 사용자 정의 분류 처리

  • 유형 안전성: Zod 스키마 검증을 통한 전체 TypeScript 지원

  • 포괄적 로깅: 디버깅을 위한 상세한 API 요청/응답 로깅

  • 오류 처리: 정보 제공 메시지가 포함된 우아한 오류 처리

시작하기

  1. 저장소를 복제하고 npm install로 의존성을 설치합니다

  2. WordPress 자격 증명으로 .env 파일을 만듭니다.

  3. npm run build로 프로젝트를 빌드합니다.

  4. 서버로 Claude Desktop을 구성합니다.

  5. 자연어를 사용하여 WordPress 사이트를 관리하세요!

기여

이 프로젝트를 개선하려면 이슈를 열거나 풀 리퀘스트를 자유롭게 만들어 주세요. 자세한 개발 지침은 CLAUDE.md를 확인하세요.

A
license - permissive license
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
3wRelease cycle
4Releases (12mo)
Commit activity
Issues opened vs closed

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    F
    maintenance
    Enables AI assistants to interact with WordPress sites through the WordPress REST API. Supports multiple WordPress sites with secure authentication, enabling content management, post operations, and site configuration through natural language.
    24
    116
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to interact with WordPress sites through the REST API. Supports multiple WordPress sites with secure authentication, enabling content management, post operations, and site configuration through natural language.
    24
    MIT
  • A
    license
    Not graded
    quality
    F
    maintenance
    Enables interaction with WordPress sites through the REST API, supporting content management for posts, pages, users, plugins, and custom post types with Application Password authentication.
    1,270
    2
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to manage WordPress sites through natural conversation, supporting post creation, content updates, site queries, and draft-to-publish workflows via the WordPress REST API.
    9
    MIT

View all related MCP servers

Related MCP Connectors

  • Sync Lightroom, Figma, Dropbox & Canva assets to WordPress and Shopify via natural language.

  • Sync Lightroom, Figma, Dropbox & Canva assets to WordPress and Shopify via natural language.

  • Publish to self-hosted WordPress from AI agents: markdown, images, SEO, and Notion sync.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/InstaWP/mcp-wp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server