usefulparadigm.

기술 노트튜토리얼

워드프레스 MCP Adapter와 커스텀 서버 만들기

이번 달 워드프레스(WordPress)의 MCP Adapter가 WordPress.org 플러그인 디렉터리에 공식 플러그인으로 올라왔습니다. 워드프레스 사이트를 MCP(Model Context Protocol) 서버로 만들어 주는 플러그인이죠. MCP는 Claude 같은 AI 앱이 외부 도구와 데이터에 연결하는 표준 방식입니다.

그런데 그 소식을 보고 처음 든 생각은 이거였습니다.

워드프레스에는 REST API도 있고, MCP 서버 플러그인도 이미 있는데, 굳이?

이 글에서는 이 질문에 먼저 답해 보고, MCP Adapter를 직접 써 봅니다. 기본 서버로 둘러본 뒤, 필요한 기능만 골라 노출하는 커스텀 서버를 만들어 Claude Code에 연결하는 데까지 다룹니다. 테스트는 이 블로그가 돌아가는 유스풀패러다임 사이트에서 직접 했습니다.

REST API가 있는데 왜?

MCP Adapter를 이해하려면 먼저 Abilities API를 알아야 합니다. 워드프레스 6.9에서 코어에 들어온 기능 레지스트리인데요. 여기서 어빌리티(ability)는 이름이 붙은 기능 하나를 말합니다. “최근 글 목록 가져오기” 같은 함수에 설명, 입출력 스키마, 권한 검사를 붙여 등록해 둔 덩어리죠.

MCP Adapter는 이 레지스트리의 어빌리티를 MCP로 번역해 AI에게 보여 주는 역할만 합니다. 스스로는 아무 기능도 갖고 있지 않아서, 쓸 만한 어빌리티가 없으면 어댑터를 붙여도 AI가 할 수 있는 일은 없습니다.

그럼 REST API와는 뭐가 다를까요? 일전에 커스텀 GPT를 워드프레스 REST API와 연동해 본 적이 있는데요.

그때도 AI가 글을 읽고 쓰는 데는 문제가 없었습니다. 기술적으로 보면 REST로는 안 되고 MCP Adapter로만 되는 일은 거의 없습니다. MCP Adapter의 HTTP 연결도 결국 REST 경로 위에서 돌아가니까요. 차이는 누구를 위해, 어떤 단위로 기능을 내놓느냐에 있습니다.

항목REST APIAbilities + MCP Adapter
주 사용자문서를 읽고 코드를 짜는 개발자실행 중에 스스로 판단하는 AI 에이전트
단위리소스(데이터)와 CRUD의도가 담긴 기능 하나
설명 정보경로와 인자 형식자연어 설명, 입출력 스키마, 읽기 전용·파괴적 작업 표시
공개 범위등록된 경로는 기본적으로 열림공개 표시한 것만 노출
AI 연결AI마다 연동 코드 작성MCP 클라이언트면 바로 연결
쓰이는 곳HTTPPHP, REST, JS, WP-CLI, MCP, AI Client

비유하자면 REST API는 개발자용 재료 창고, 어빌리티는 AI용 메뉴판, MCP는 표준 주문 방식인 셈이죠. 물론 어빌리티가 REST API를 대체하지는 않습니다. 앱이나 헤드리스 사이트, 외부 서비스 연동은 여전히 REST API의 몫입니다.

이미 MCP 서버도 있었는데 왜?

사실 워드프레스에는 공식 MCP 서버가 이미 있었습니다. Automattic이 만든 wordpress-mcp 플러그인인데요. 글, 페이지, 미디어, 사용자, WooCommerce까지 wp_posts_search, wp_add_post 같은 도구가 미리 들어 있었고, 관리 화면에서 만들기·수정·삭제 기능을 따로 켜고 끌 수도 있었습니다. (Themeisle의 Easy MCP AI처럼 도구를 내장한 서드파티 플러그인도 있구요)

이런 플러그인들은 대개 REST API를 MCP 도구로 감싸는 방식입니다. 사용하기엔 편하지만, 플러그인마다 자기 MCP 서버를 따로 띄우고 인증과 노출 범위도 제각각 관리하게 됩니다. 다른 플러그인이 도구를 보태려면 특정 MCP 플러그인의 훅에 맞춰야 하고, 그렇게 만든 기능은 MCP 밖에서는 다시 쓸 수 없죠.

그래서 워드프레스는 방향을 바꿨습니다. 2025년 7월 발표한 AI 빌딩 블록(AI Building Blocks) 계획에서, 기능은 Abilities API에 한 번만 등록하고 MCP는 그 위의 어댑터로 떼어 내기로 한 거죠.

워드프레스 AI 빌딩 블록 구조

가운데의 Abilities API에 코어와 플러그인, 사이트 코드가 어빌리티를 등록합니다. 외부 AI는 MCP Adapter를 거쳐 이 어빌리티를 쓰고, 반대로 워드프레스는 7.0에서 코어에 들어온 WP AI Client를 거쳐 외부 AI 모델을 부릅니다. 한 번 등록한 어빌리티는 PHP, 자바스크립트, WP-CLI, MCP에서 같은 권한 검사로 함께 쓰이고, 나중에 다른 프로토콜이 나와도 어댑터만 하나 더 만들면 됩니다. wordpress-mcp가 보관(archived) 처리되고 MCP Adapter로 안내하는 것도 이 때문입니다.

플랫폼 입장에서는 맞는 설계입니다. 다만 사이트를 운영하는 입장에서 보면, 도구가 다 갖춰진 완제품을 내주고 빈 틀을 받은 셈이기도 하죠.

기본 서버로 써 보기

그럼 직접 한번 써 볼까요? 저는 이 블로그, 유스풀패러다임 사이트에서 바로 해 봤습니다. 운영 사이트이긴 하지만 뒤에서 보듯 읽기와 초안 작성만 열고, 삭제는 “내가 만든 초안”으로 제한해서 부담이 크지 않았습니다. (스테이징 사이트가 있다면 물론 거기서 먼저 해 보는 게 좋구요)

MCP Adapter는 WordPress.org 플러그인 디렉터리에 있으니, 관리자 화면의 플러그인 → 새 플러그인 추가에서 “MCP Adapter”를 검색해 설치하고 활성화하면 됩니다.

플러그인 추가 화면에서 MCP Adapter 검색
플러그인 → 새 플러그인 추가에서 “MCP Adapter”를 검색한 화면

※ WP-CLI를 쓴다면 wp plugin install mcp-adapter --activate 한 줄로도 됩니다. 이 글을 쓰는 2026년 10월 현재 최신 버전은 0.7.1이며, 워드프레스 6.9 이상, PHP 7.4 이상이 필요합니다.

활성화해도 관리자 메뉴나 설정 화면은 생기지 않습니다. 대신 기본 서버(mcp-adapter-default-server)가 바로 열리는데, 이 서버가 AI에게 주는 도구는 딱 세 개입니다:

  • mcp-adapter-discover-abilities: 공개된 어빌리티 목록 보기
  • mcp-adapter-get-ability-info: 어빌리티 하나의 설명과 스키마 보기
  • mcp-adapter-execute-ability: 어빌리티 실행

AI는 이 세 도구로 발견 → 조회 → 실행 순서를 밟습니다. 목록에는 meta.mcp.public(또는 meta.public)이 true인 어빌리티만 나옵니다(나중에 자세히 설명). 공개는 옵트인이라는 거죠.

연결하기 전에 우선 AI가 쓸 사용자를 하나 만듭니다. 관리자 계정을 그대로 쓰면 AI도 관리자 권한으로 움직이니까요. 사용자 → 새로 추가에서 mcp-agent라는 사용자를 글쓴이 역할로 만들고, 그 사용자의 편집 화면 아래쪽에서 애플리케이션 비밀번호를 발급합니다. 비밀번호는 발급할 때 한 번만 보여 주니 바로 복사해 둡니다. (애플리케이션 비밀번호는 HTTPS 사이트에서만 쓸 수 있습니다)

mcp-agent 사용자의 애플리케이션 비밀번호 발급
mcp-agent 사용자의 애플리케이션 비밀번호 발급 (비밀번호는 가림)

이제 설치가 제대로 됐는지 확인해 보겠습니다. MCP Inspector를 쓰면 MCP 서버에 붙어서 도구 목록을 보고 직접 실행까지 해 볼 수 있습니다. 내 컴퓨터의 터미널에서 실행합니다.

npx @modelcontextprotocol/inspector

브라우저에 Inspector가 열리면 Add Servers로 서버를 추가합니다. 사이트에 바로 붙는 대신, Automattic이 만든 @automattic/mcp-wordpress-remote 프록시를 실행하게 해서 연결합니다:

  • Server ID: 알아보기 쉬운 이름 (예: usefulparadigm)
  • Transport: stdio
  • Command: npx
  • Arguments: -y, @automattic/mcp-wordpress-remote@latest (한 줄에 하나씩)
  • Environment: 아래 세 줄
WP_API_URL=https://www.usefulparadigm.com/wp-json/mcp/mcp-adapter-default-server
WP_API_USERNAME=mcp-agent
WP_API_PASSWORD=발급받은 애플리케이션 비밀번호

※ Inspector는 Node 22.19 이상이 필요합니다.

MCP Inspector 서버 추가 설정
MCP Inspector에서 프록시로 기본 서버를 추가하는 설정

연결하면 Tools 탭에 도구 세 개가 보입니다. 여기까지 보이면 설치는 정상입니다. 도구마다 표시도 붙어 있는데, discover에는 읽기 전용(READ-ONLY) 표시가, execute에는 경고 아이콘이 붙어 있네요.

기본 서버의 메타 도구 세 개
기본 서버의 도구는 discover, get-info, execute 세 개뿐

이 상태에서 mcp-adapter-discover-abilities를 실행해 봤습니다. 아직 아무것도 공개하지 않았으니 비어 있을 줄 알았는데, 어빌리티가 11개나 나오더군요. 워드프레스 코어의 사이트·사용자·환경 정보 조회 3개, 그리고 Jetpack Forms의 8개였습니다. Jetpack Forms 쪽에는 양식 삭제, 양식 응답(방문자가 남긴 문의 내용) 조회와 수정까지 들어 있었구요. 제가 공개한 게 아니라 플러그인이 mcp.public을 켠 채로 배포한 겁니다.

어빌리티 등록 전 discover 결과
아무것도 공개하지 않았는데 discover에 나온 코어와 Jetpack Forms 어빌리티

물론 목록에 보인다고 다 실행되는 건 아닙니다. 실행 직전에 현재 사용자 기준으로 어빌리티의 권한 콜백이 다시 돌거든요. mcp-adapter-execute-ability로 jetpack-forms/get-responses를 실행해 보니, 글쓴이인 mcp-agent 계정으로는 권한 오류(Permission denied)가 났습니다.

양식 응답 조회가 권한 오류로 거부된 결과
글쓴이 계정으로 양식 응답 조회를 실행하면 권한 오류

현재 사이트의 캐시 플러그인과 Akismet도 어빌리티를 등록해 두었지만 MCP에는 공개하지 않았습니다. 공개 여부의 기본값이 플러그인마다 다르다는 거죠.

그럼 이제 공개할 어빌리티를 하나 만들어 봅니다. 코드를 붙일 곳은 Code Snippets 플러그인이 가장 간단합니다. 스니펫 → 새로 추가에서 아래 코드를 붙여 넣고, 실행 범위를 “Run everywhere”로 저장한 뒤 활성화합니다.

// Code Snippets: "MCP 테스트 1 - 최근 글 목록"
// 실행 범위: Run everywhere
// 기본 서버(discover)에 공개되는 읽기 전용 어빌리티 하나

add_action( 'wp_abilities_api_categories_init', function () {
	wp_register_ability_category( 'usefulparadigm', array(
		'label'       => 'Usefulparadigm',
		'description' => '유스풀패러다임 테스트용 어빌리티',
	) );
} );

add_action( 'wp_abilities_api_init', function () {
	wp_register_ability( 'usefulparadigm/list-recent-posts', array(
		'label'        => '최근 글 목록',
		'description'  => '최근 발행된 글의 제목, URL, 날짜를 반환합니다.',
		'category'     => 'usefulparadigm',
		'input_schema' => array(
			'type'       => 'object',
			'properties' => array(
				'count' => array( 'type' => 'integer', 'default' => 5, 'minimum' => 1, 'maximum' => 20 ),
			),
		),
		'output_schema'       => array( 'type' => 'array' ),
		'execute_callback'    => function ( $input ) {
			$posts = get_posts( array( 'numberposts' => $input['count'] ?? 5 ) );
			return array_map( fn( $p ) => array(
				'title' => get_the_title( $p ),
				'url'   => get_permalink( $p ),
				'date'  => get_the_date( 'c', $p ),
			), $posts );
		},
		'permission_callback' => fn() => current_user_can( 'edit_posts' ),
		'meta'                => array(
			'annotations' => array( 'readonly' => true ),
			'mcp'         => array( 'public' => true ),
		),
	) );
} );

코드는 간단합니다. wp_abilities_api_categories_init 훅에서 카테고리를, wp_abilities_api_init 훅에서 어빌리티를 등록합니다. 가져올 글 수(1 ~ 20)를 받는 입력 스키마, 글 편집 권한을 확인하는 권한 콜백, 읽기 전용 표시를 붙였고, mcp.public을 true로 줘서 기본 서버에 공개했습니다.

Code Snippets에 등록한 스니펫 1
Code Snippets에 등록한 스니펫 1 (실행 범위: 전역에서 실행)

※ 운영 사이트에서 오래 쓸 코드라면 맨 위에 <?php를 붙여 wp-content/mu-plugins/ 폴더에 파일로 올리는 방법(mu-plugin)을 권합니다. Git으로 버전 관리를 할 수 있고, 관리자 화면에서 실수로 끄거나 고칠 일이 없거든요.

Inspector로 돌아가 discover를 다시 실행하면, 이번에는 방금 만든 usefulparadigm/list-recent-posts가 목록에 추가됩니다.

어빌리티 등록 후 discover 결과
스니펫 1을 켠 뒤 discover에 추가된 usefulparadigm/list-recent-posts

※ 공개 여부와 상관없이 사이트에 등록된 어빌리티 전체는 Abilities API의 REST 경로로 볼 수 있습니다. 브라우저 주소창으로 열면 rest_forbidden 오류가 나니, 애플리케이션 비밀번호로 인증해서 요청합니다.

curl -u '사용자명:애플리케이션 비밀번호' https://www.usefulparadigm.com/wp-json/wp-abilities/v1/abilities

기본 서버의 한계와 커스텀 서버

써 보니 기본 서버에는 아쉬운 점이 두 가지 있습니다.

첫째, 한 가지 일에도 호출이 여러 번 필요합니다. “최근 글 3개 알려 줘”라는 요청에도 AI는 목록을 보고(discover), 필요하면 설명을 확인한 뒤(get-info), 실행(execute)하는 식으로 도구를 여러 번 부르게 됩니다. 대신 어빌리티가 수십 개여도 도구 목록이 늘지 않으니 AI의 컨텍스트는 아낄 수 있구요.

둘째, 승인 단위가 뭉개집니다. AI 클라이언트가 보기에 모든 실행은 mcp-adapter-execute-ability 도구 하나입니다. 저희 사이트의 기본 서버에서 도구 목록을 받아 보면, 이 도구에는 파괴적인 작업이라는 표시(destructiveHint: true)가 일괄로 붙어 있습니다. 사이트 정보를 읽는 것도, 양식을 삭제하는 것도 클라이언트에게는 똑같이 “파괴적일 수 있는 도구” 하나로 보이는 거죠. 어빌리티에 붙인 읽기 전용 표시가 승인 화면까지 전달되지 않습니다.

개인적으로는 이 부분이 조금 과한 추상화로 느껴집니다. MCP에는 이미 도구 목록을 알려 주는 기능(tools/list)이 있는데, 그 위에 발견·조회·실행을 다시 만든 셈이니까요. (사실 처음 보는 구조는 아닙니다. 예전 wordpress-mcp에도 list_api_functions, get_function_details, run_api_function이라는 같은 구조의 범용 도구가 있었죠. 거기서는 선택 기능이었던 게 여기서는 기본값이 됐을 뿐입니다)

다행히 기본값은 바꿀 수 있습니다. 커스텀 서버를 만들면 원하는 어빌리티만 골라 개별 MCP 도구로 바로 노출할 수 있습니다. 도구마다 이름과 스키마가 따로 보이니 클라이언트에서 도구별로 승인을 다르게 걸 수 있구요. 기본 서버와 커스텀 서버는 동시에 띄울 수도 있고, 기본 서버만 끌 수도 있습니다.

커스텀 서버 만들기

이번에는 콘텐츠 작업에 필요한 세 가지만 노출하는 서버를 만들어 보겠습니다:

  • usefulparadigm/list-recent-posts: 최근 글 목록 (읽기 전용)
  • usefulparadigm/create-draft: 초안 만들기 (항상 draft로 저장)
  • usefulparadigm/trash-own-draft: 내가 만든 초안만 휴지통으로 보내기 (파괴적 작업)

어빌리티 등록 방식은 앞과 같고, meta.annotations의 readonly, destructive 값만 다르게 붙였습니다. 이번에는 mcp.public을 주지 않았는데요. 커스텀 서버에 이름으로 직접 지정한 어빌리티는 공개 표시 없이도 노출되거든요. 거꾸로 말하면 기본 서버의 discover 목록에는 나오지 않습니다.

※ 지면 관계상 어빌리티 세 개와 서버 설정을 포함한 전체 코드는 GitHub 저장소에 올려 두었습니다. Code Snippets용과 mu-plugin용 두 가지 형태가 있습니다. 스니펫 2에도 list-recent-posts가 들어 있으니, 앞의 스니펫 1은 끄고 스니펫 2를 켜세요. 같은 이름을 두 곳에서 등록하면 나중 쪽이 실패합니다.

운영 사이트에서 AI에게 삭제를 맡기는 건 아무래도 부담스럽죠. 그래서 세 번째 어빌리티는 권한 콜백에서 범위를 좁혔습니다.

// 스니펫 2 중 usefulparadigm/trash-own-draft의 권한 콜백
'permission_callback' => function ( $input ) {
	$post = get_post( (int) ( $input['id'] ?? 0 ) );
	return $post
		&& 'draft' === $post->post_status
		&& (int) $post->post_author === get_current_user_id()
		&& current_user_can( 'delete_post', $post->ID );
},

글이 초안이고, 지금 사용자가 직접 만든 것이고, 워드프레스 권한으로도 삭제할 수 있을 때만 통과합니다. 발행된 글이나 다른 사람의 글을 지정하면 실행 전에 거부되구요. 어빌리티의 권한 콜백은 “누가”뿐 아니라 “무엇을”까지 따질 수 있으니, AI에게 열어 줄 범위를 이렇게 기능 단위로 좁힐 수 있습니다.

서버는 mcp_adapter_init 훅에서 만듭니다.

// 스니펫 2 중 서버 부분
add_action( 'mcp_adapter_init', function ( $adapter ) {
	$adapter->create_server(
		'usefulparadigm-content',                        // 서버 ID
		'usefulparadigm',                                // REST 네임스페이스
		'mcp',                                           // REST 경로
		'Usefulparadigm Content Server',                 // 서버 이름
		'글 목록 조회, 초안 작성, 내 초안 휴지통 이동만 노출', // 설명
		'v0.1.0',                                        // 버전
		array( \WP\MCP\Transport\HttpTransport::class ),
		\WP\MCP\Infrastructure\ErrorHandling\ErrorLogMcpErrorHandler::class,
		\WP\MCP\Infrastructure\Observability\NullMcpObservabilityHandler::class,
		array(                                           // 개별 도구로 노출할 어빌리티
			'usefulparadigm/list-recent-posts',
			'usefulparadigm/create-draft',
			'usefulparadigm/trash-own-draft',
		),
		array(),                                         // 리소스
		array()                                          // 프롬프트
	);
} );

인자가 열두 개나 되지만 바꿀 곳은 몇 군데 안 됩니다. 앞의 세 개(서버 ID, 네임스페이스, 경로)가 주소를 정해서, 이 서버의 엔드포인트는 https://www.usefulparadigm.com/wp-json/usefulparadigm/mcp가 됩니다. 열 번째 배열이 노출할 어빌리티 목록이고, 나머지는 README 예제 그대로 두면 됩니다. 도구 이름은 /가 -로 바뀌어 usefulparadigm-list-recent-posts 같은 형태가 됩니다.

기본 서버를 아예 끄고 싶다면 필터 한 줄을 추가합니다.

add_filter( 'mcp_adapter_create_default_server', '__return_false' );
Code Snippets에 등록한 스니펫 2
Code Snippets에 등록한 스니펫 2 (스니펫 1은 끈 상태)

Inspector에서 WP_API_URL만 커스텀 서버 주소로 바꿔 다시 연결해 볼까요? 이번에는 메타 도구 대신 어빌리티 세 개가 각각 도구로 보입니다.

커스텀 서버의 개별 도구 세 개
커스텀 서버에서는 어빌리티 세 개가 각각 도구로 보인다
휴지통 도구의 상세 화면
휴지통 도구에 옮겨진 DESTRUCTIVE, IDEMPOTENT 표시

어빌리티에 붙인 표시도 그대로 옮겨집니다. 휴지통 도구에는 파괴적 작업(DESTRUCTIVE)과 멱등(IDEMPOTENT) 표시가, 목록 도구에는 읽기 전용 표시가 따로 붙어 있죠. 기본 서버에서는 execute 하나에 가려져 볼 수 없던 정보입니다.

usefulparadigm-list-recent-posts를 count: 3으로 실행하면 최근 글 세 개가 돌아옵니다.

최근 글 목록 도구 실행 결과
최근 글 목록 도구를 count: 3으로 실행한 결과

그럼 방금 목록에 나온 발행된 글의 ID를 휴지통 도구에 넣어 보면 어떨까요?

발행된 글을 휴지통으로 보내려다 거부된 결과
발행된 글을 휴지통으로 보내려 하면 권한 콜백에서 거부

권한 콜백에서 막혀 Permission denied가 납니다. 어빌리티를 개별 도구로 바로 노출해도 권한 콜백은 그대로 돈다는 거죠.

이제 Claude Code에 연결해 봅니다. Inspector와 같은 프록시를 쓰니 설정도 같습니다.

claude mcp add usefulparadigm \
  --env WP_API_URL=https://www.usefulparadigm.com/wp-json/usefulparadigm/mcp \
  --env WP_API_USERNAME=mcp-agent \
  --env WP_API_PASSWORD='발급받은 애플리케이션 비밀번호' \
  -- npx -y @automattic/mcp-wordpress-remote@latest

서버 이름(usefulparadigm)은 add 바로 뒤에 씁니다. --env 옵션들 뒤에 두면 이름까지 환경변수로 읽어서 “Invalid environment variable format” 오류가 나거든요. (기본으로는 지금 디렉터리에서만 쓰는 설정으로 저장되니, 어디서나 쓰려면 --scope user를 붙입니다)

Claude Code에서 /mcp를 입력하면 연결된 도구 세 개가 보입니다. 도구마다 read-only, destructive 표시도 따라오네요.

Claude Code의 /mcp 도구 목록
Claude Code의 /mcp 화면. 도구마다 read-only, destructive 표시가 보인다

이제 “유스풀패러다임 최근 글 목록 3개”, “제목이 ‘Claude Code 테스트’인 초안 하나 만들어 줘”, “방금 만든 초안을 휴지통으로 보내 줘”를 차례로 요청해 봤습니다.

Claude Code에서 글 목록 조회, 초안 작성, 휴지통 이동을 요청한 결과
Claude Code에서 글 목록 조회, 초안 만들기, 휴지통 이동을 차례로 요청한 결과

요청마다 도구를 한 번씩 불러서 끝났습니다. 초안(ID 8825)을 만들고, 그 초안을 휴지통으로 보내는 것까지 잘 되네요. 저는 자동 모드로 실행해서 승인 창 없이 진행됐지만, 도구마다 이름이 따로 있으니 Claude Code의 권한 설정에서도 목록 조회는 그냥 허용하고 휴지통 이동은 매번 확인하는 식으로 도구 단위로 나눠 걸 수 있습니다. 기본 서버였다면 mcp-adapter-execute-ability 하나에 허용 여부를 걸 수밖에 없었겠죠.

언제 무엇을 쓸까

정리하면 이렇게 고르면 될 것 같습니다:

  • 사이트 하나에 에이전트 하나라면 REST API나 WP-CLI로도 충분합니다. Claude Code처럼 셸을 쓸 수 있는 에이전트라면 wp 명령을 직접 쓰는 편이 더 빠를 수도 있구요.
  • 우리 사이트에서 무엇이 노출되는지 둘러볼 때는 기본 서버와 Inspector를 씁니다.
  • 운영 사이트에 붙인다면 커스텀 서버로 필요한 어빌리티만 노출하고 기본 서버는 끕니다.
  • 도구가 갖춰진 완제품이 필요하다면 호스팅형인 WordPress.com MCP도 있습니다. (※ 2026년 10월 현재 Personal 이상 유료 플랜에 포함, 셀프 호스팅 사이트는 Jetpack AI나 Complete 플랜 필요)

운영 사이트라면 몇 가지를 더 챙겨야 합니다. 앞에서 본 것처럼 저희 사이트에서도 Jetpack Forms가 양식 응답 조회·수정과 양식 삭제를 공개 상태로 내놓고 있었죠. Themeisle의 테스트를 보면 Secure Custom Fields를 설치한 사이트에서 기본 서버에 어빌리티 51개가 노출됐고, 그중 5개가 영구 삭제 기능이었습니다. 어빌리티 하나의 정보 응답이 8만 5천 ~ 12만 2천 자에 이르기도 했구요. 플러그인을 설치하거나 업데이트할 때마다 공개 어빌리티가 조용히 늘 수 있다는 뜻입니다. 커스텀 서버는 노출 목록이 코드에 고정되니 이 걱정을 덜 수 있죠.

그 밖에 WebDevStudios가 정리한 운영 원칙 중 기억해 둘 만한 것들입니다:

  • 에이전트 전용 워드프레스 사용자를 만들고 역할은 최소로 줍니다.
  • 스테이징에서 먼저 운영해 봅니다.
  • 로그를 남기고, 플러그인을 추가할 때마다 노출 목록을 다시 검토합니다.
  • 댓글, 폼, 가져온 콘텐츠에 섞인 문장이 AI를 조종할 수 있다는 점(프롬프트 인젝션)도 염두에 둡니다.

그리고 MCP Adapter는 아직 1.0 이전이라 업데이트마다 호환되지 않는 변경이 나올 수 있습니다.


여기서는 MCP Adapter가 왜 나왔는지, 기본 서버와 커스텀 서버를 어떻게 쓰는지까지만 다뤘습니다. 리소스와 프롬프트 노출, 실행 중 사용자에게 되묻기(elicitation) 같은 기능은 GitHub 저장소의 문서를 참고하세요.

써 보니 MCP Adapter는 “AI를 붙이는 플러그인”이라기보다 “무엇을 열어 줄지 정하는 틀”에 가깝다는 인상을 받았습니다. 기본 서버는 둘러보기용으로 쓰고, 실제로 쓸 때는 커스텀 서버로 필요한 기능만 골라 내는 게 맞는 것 같습니다. 예전 완제품 MCP에 비하면 손이 더 가는 건 사실이지만, 어빌리티를 등록하는 플러그인이 늘어나면 이야기가 달라지지 않을까요?

물론 저는 아직 REST API를 직접 액세스하는 방식이 익숙합니다. AI 에이전트에서 사용하는 데도 큰 불편은 못 느끼구요. 하지만 앞으로 AI 에이전트를 통한 워드프레스 접속이 점점 늘어날 테고, 그때가 되면 지금의 이 MCP Adapter가 ‘투자’였다는 생각이 들지도 모르죠.

여러분 사이트에도 MCP Adapter가 깔려 있다면, Inspector로 붙어서 discover부터 한번 돌려 보세요. 생각보다 많은 게 열려 있을지도 모릅니다. 🙂

참고자료

댓글 남기기