WebMCP 도구용 공개 레지스트리와 SDK를 구축했습니다. 왜 중요한지 알려드립니다.

발행: (2026년 6월 9일 AM 10:28 GMT+9)
8 분 소요
원문: Dev.to

출처: Dev.to

WebMCP 도구를 위한 공개 레지스트리와 SDK를 구축했습니다. 왜 중요한지 알려드립니다.

Jeffrey Nwankwo

아직 WebMCP를 접해보지 못했다면, 간단히 말하면 이렇습니다: W3C 제안서로, document.modelContext를 이용해 웹 페이지가 브라우저 안에서 직접 호출 가능한 동작을 등록할 수 있게 합니다. 브라우저 안에 있는 MCP 서버와 같은 개념이죠. AI 에이전트가 UI를 스크래핑하거나 별도의 백엔드와 통신하는 대신, 페이지가 수행할 수 있는 작업을 선언하고 에이전트가 사용자의 현재 세션과 상태를 그대로 활용해 직접 호출합니다. 기본 개념을 먼저 이해하고 싶다면 Sylwia Lasek이 작성한 첫 번째 소개 글을 여기에서 확인해 보세요.

우리가 발견한 문제는, 사양이 브라우저 내에서 도구가 어떻게 실행되는지는 다루지만 **발견(discovery)**에 대해서는 전혀 다루지 않는다는 점입니다. 에이전트가 페이지에 방문했을 때 document.modelContext.getTools()를 호출해 사용할 수 있는 도구를 조회할 수는 있지만, 페이지를 로드하기 전에는 해당 사이트가 어떤 도구를 제공하는지 알 방법이 없습니다. 이 공백은 미리 계획을 세워야 하거나, 시스템 프롬프트에 도구 스키마를 삽입하거나, 방문할 가치가 있는 사이트를 판단해야 하는 에이전트에게는 큰 문제입니다.

그래서 우리는 두 가지를 만들었습니다.

WebMCP 레지스트리는 개발자들이 자신의 도메인과 도구 계약을 등록할 수 있는 공개 디렉터리(webmcp-registry.dev)입니다. 키워드, 카테고리, 도메인별로 검색할 수 있고, DNS TXT 레코드를 이용한 검증 시스템을 갖추었으며, 에이전트가 사이트를 방문하기 전에 해당 사이트가 어떤 작업을 수행할 수 있는지 조회할 수 있는 공개 HTTP API를 제공합니다. 레지스트리 자체도 WebMCP를 사용해 자신의 도구를 등록했으며, 이는 자연스러운 선택이라고 생각했습니다.

@webmcp-registry/kit은 개발자 측면을 담당하는 npm 패키지입니다. Zod 스키마와 핸들러로 도구를 정의하는 defineTool, 컴포넌트에서 도구를 등록할 수 있는 React 훅, 그리고 도구 계약을 레지스트리에 자동으로 동기화해 주는 webmcp CLI를 제공합니다.

다음은 실제 도구 정의 예시입니다:

import { defineTool } from '@webmcp-registry/kit'
import { z } from 'zod'

export const addTodoTool = defineTool({
  name: 'add-todo',
  description: "사용자의 현재 todo 리스트에 새 항목을 추가합니다",
  kind: 'write',
  input: z.object({
    text: z.string().describe('todo 항목의 텍스트'),
  }),
  handler: ({ text }) => {
    const todo = addTodo(text)
    return { added: todo }
  },
})

defineTool은 Zod 입력으로부터 JSON Schema를 자동 생성하고, 검증 로직과 WebMCP 사양이 요구하는 { content: [...] } 응답 형식을 감싸며, 브라우저가 등록할 수 있는 순수 객체를 반환합니다. 스키마를 직접 작성할 필요가 없습니다.

도구를 등록하려면 제공된 훅을 사용해 컴포넌트에 삽입하면 됩니다:

import { useWebMCPTools } from '@webmcp-registry/kit/react'
import { todoTools } from './todo.tools'

function TodoApp() {
  useWebMCPTools(todoTools)
  // 나머지 컴포넌트 로직
}

이 훅은 컴포넌트가 마운트될 때 도구를 등록하고 언마운트될 때 정리합니다. document.modelContext가 아직 사용 불가능한 경우(현재 대부분의 브라우저는 Chrome에서 플래그 뒤에 숨겨져 있음)에는 프로덕션에서는 조용히 무시하고, 개발 환경에서는 어떤 부분이 플랫폼을 기다리고 있는지 알려주는 콘솔 경고를 출력합니다.

키트가 다루면서도 눈에 띄지 않는 부분이 하나 더 있습니다: 일부 도구 핸들러는 컴포넌트 상태에 접근해야 하기 때문에 모듈 스코프에 둘 수 없습니다. useState 세터나 useReducer 디스패치가 그 예입니다. 이런 경우에는 defineToolContract를 사용해 스키마와 핸들러를 분리합니다. 이렇게 하면 CLI가 정적으로 스키마를 발견할 수 있으면서도 핸들러는 실제로 필요한 위치에 남겨둘 수 있습니다:

// draft.tools.ts
export const setDraftContract = defineToolContract({
  name: 'set-draft-text',
  description: '새 todo 입력란의 텍스트를 제출 없이 설정합니다',
  kind: 'write',
  input: z.object({ text: z.string() }),
})

// App.tsx
useWebMCPTool(setDraftContract, ({ text }) => {
  setDraft(text)
  return { draft: text }
})

도구 정의가 끝났다면 레지스트리에 동기화하는 명령은 단 한 줄입니다:

npx webmcp sync --domain yoursite.com --api-key $WEBMCP_REGISTRY_KEY

CLI는 프로젝트 내 *.tools.ts 파일을 찾아 격리된 Node 컨텍스트에서 import한 뒤, 각 도구 계약을 해시하고 변경된 부분만 푸시합니다. 소스에서 사라진 도구는 완전히 삭제되지 않고 tombstone 처리되어 히스토리가 보존됩니다. 배포 시마다 실행하면 변경 사항이 없을 때는 아무 작업도 하지 않습니다.

패키지는 npm에 @webmcp-registry/kit으로, 레지스트리 소스는 github.com/WebMCP-Registry/kit에서 확인할 수 있습니다. WebMCP 자체는 아직 널리 사용 가능하지 않지만, 인프라를 미리 준비해 두면 실제 도입 시 개발자가 처음부터 시작할 필요가 없습니다.

웹 앱을 만들고 직접 체험해 보고 싶다면, 도구를 하나 정의하고 레지스트리에 푸시한 뒤, 에이전트 측에서 조회되는 모습을 확인해 보세요. 다양한 유형의 앱에 어떻게 적용되는지 이야기를 들려주시면 좋겠습니다.

0 조회
Back to Blog

관련 글

더 보기 »

Eidentic 소개

Today we're releasing Eidentic, an open-source TypeScript SDK for building AI agents with self-improving memory and the production fundamentals built in — not b...

Typescript의 타입

Introdução Tipos são uma forma de definir a “forma” ou o contrato dos dados que estamos usando no código. Pensando em Javascript puro, ele é dinâmico: você pode...