
WebMCP 선언형 API로 시작하는 AI 에이전트 대응 웹 페이지 제작 방법
요약
WebMCP는 AI 에이전트가 웹 페이지를 정확하게 조작할 수 있도록 페이지 스스로 도구를 선언하는 새로운 웹 표준안입니다. 기존의 DOM 추측 방식에서 벗어나 선언형 API를 통해 구조화된 도구 목록을 제공함으로써 에이전트와의 상호작용 정확도를 높입니다.
핵심 포인트
- WebMCP는 MCP의 웹 브라우저 버전으로 페이지가 직접 도구를 공개함
- 선언형 API를 통해 HTML 속성 추가만으로 에이전트 대응 가능
- 추측 기반의 DOM 조작 방식보다 훨씬 견고하고 정확한 상호작용 실현
- Chrome 실험적 기능을 통해 구현 및 테스트 가능
AI 에이전트가 웹 페이지를 조작할 때, 기존에는 DOM을 "눈으로 보듯" 읽고 조작했습니다.
"아마 이것이 검색 폼일 것이다"라고 추측하기 때문에, 깨지기 쉽고 부정확했습니다.
WebMCP는 이 문제를 해결하기 위한 새로운 웹 표준안입니다.
페이지 측에서 에이전트에게 "이러한 도구(tool)가 있습니다"라고 구조화된 형태로 선언할 수 있습니다.
본 기사에서는 **선언형 API (Declarative API)**에 집중하여, 실제로 동작하는 데모를 만들면서 사용법을 해설합니다.
WebMCP는 MCP (Model Context Protocol)의 웹 브라우저 버전이라는 위치에 있습니다. 웹 페이지 자체가 MCP 서버가 되는 이미지로, 에이전트는 getTools()로 페이지의 도구 목록을 취득하고, executeTool()로 실행합니다.
"Puppeteer MCP"나 "DevTools MCP"와 같은 브라우저 조작 계열의 도구는, 외부에서 페이지를 강제로 조작합니다.
에이전트 → 외부 MCP 서버 → 브라우저를 원격 조작 → DOM을 추측하여 클릭·입력
페이지는 아무것도 모르는 상태에서, 에이전트가 "아마 이것이 검색 폼일 것이다"라고 추측하며 조작하기 때문에 깨지기 쉽습니다.
WebMCP는 발상이 반대로, 페이지 스스로가 도구를 선언하여 공개합니다.
에이전트 → 페이지에 "무엇을 할 수 있어?"라고 질문 → 페이지가 구조화된 형태로 도구를 반환
주도권이 에이전트(외부)에서 페이지(내부)로 옮겨짐으로써, 추측에 의존하지 않는 정확한 상호작용이 실현됩니다.
WebMCP에는 두 종류의 API가 있습니다.
**선언형 API (Declarative API)**는 기존의 HTML 폼에 속성을 추가하는 것만으로 도구를 공개할 수 있습니다.
JSON Schema는 브라우저가 자동으로 생성하므로, 추가적인 JavaScript는 거의 필요하지 않습니다.
기존 폼에 에이전트 대응 기능을 나중에 추가할 때 적합합니다.
**명령형 API (Imperative API)**는 JavaScript로 명시적으로 도구를 등록합니다.
폼을 가지지 않는 조작(토글, 애니메이션, API 호출 등)을 도구화하고 싶을 때나, 스키마를 세밀하게 제어하고 싶을 때 사용합니다.
본 기사에서는 선언형 API에 대해 해설합니다.
- Chrome에서
chrome://flags/#enable-webmcp-testing을 연다 - Enabled로 변경
- Chrome을 재시작
WebMCP는 개발 중인 API이기 때문에, Chrome 버전에 따라 프로퍼티의 위치가 다릅니다.
- Chrome 149:
navigator.modelContext에 구현 - Chrome 150 이후:
document.modelContext로 이동 (navigator.modelContext는 권장되지 않음)
두 버전 모두에 대응하려면 ?? 연산자로 폴백(fallback) 처리를 합니다.
// document.modelContext가 있으면 사용하고, 없으면 navigator.modelContext로 폴백
const modelContext = document.modelContext ?? navigator.modelContext;
HTML 폼에 toolname과 tooldescription을 추가하는 것만으로 도구를 사용할 수 있게 됩니다.
<form
toolname="searchBooks"
tooldescription="키워드로 책을 검색합니다. 장르로 필터링할 수도 있습니다."
...
단지 이것만으로도 에이전트는 searchBooks라는 도구를 인식할 수 있게 됩니다.
폼 요소에 toolparamdescription을 추가하면, 에이전트에 대한 설명을 더욱 상세하게 전달할 수 있습니다.
<select
name="genre"
toolparamdescription="필터링할 장르. 지정하지 않으면 all을 사용함."
...
브라우저는 폼 요소의 형식(type), name, toolparamdescription으로부터 JSON Schema를 자동 생성하며, getTools()로 확인하면 다음과 같습니다.
{
"name": "searchBooks",
"description": "키워드로 책을 검색합니다. 장르로 필터링할 수도 있습니다.",
...
toolautosubmit을
추가하면, 에이전트가 필드를 채운 후 자동으로 폼을 제출합니다.
<form
toolname="searchBooks"
tooldescription="키워드로 책을 검색합니다"
...
추가하지 않은 경우: 에이전트가 값을 입력하지만, 제출은 사용자가 수동으로 수행
추가한 경우: 에이전트가 값을 입력하고 자동 제출까지 수행
폼의 submit 이벤트에서 e.agentInvoked를 확인하면, 에이전트에 의한 호출인지 사용자 조작인지 판별할 수 있습니다.
에이전트에 의한 호출인 경우 e.respondWith()로 결과를 반환합니다.
form.addEventListener('submit', (e) => {
e.preventDefault();
const data = new FormData(e.target);
...
실제로 2개의 폼을 가진 데모를 만듭니다.
<!DOCTYPE html>
<html lang="ja">
<head>
...
페이지를 HTTP 서버로 연 상태에서 DevTools 콘솔을 사용합니다.
// 툴 목록을 가져옴
const tools = await navigator.modelContext.getTools();
console.log(tools);
...
// 툴을 실행
const tools = await navigator.modelContext.getTools();
const searchTool = tools.find(t => t.name === 'searchBooks');
...
executeTool()의 첫 번째 인자는 툴 이름 문자열이 아니라, getTools()가 반환한 RegisteredTool 객체입니다. 문자열을 전달하면 TypeError: The provided value is not of type 'RegisteredTool'이 발생합니다.
여기까지는 DevTools 콘솔에서 수동으로 실행하여 동작을 확인했지만,
실제로 AI 에이전트로부터 툴을 호출하는 방법은 크게 두 가지가 있습니다.
Google이 제공하는 공식 검증 툴입니다.
Gemini를 사용하여 페이지의 툴을 실제로 호출할 수 있습니다.
Chrome 웹 스토어에서 "Model Context Tool Inspector"를 검색하여 설치하고,
페이지를 연 상태에서 확장 기능을 실행하면,
등록된 툴 목록 확인, 수동 실행, Gemini를 통한 실행이 가능합니다.
Chrome에 내장된 Gemini가 페이지의 WebMCP 툴을 자동으로 인식하여 조작합니다.
현재는 한정 공개 중인 기능이며, 향후 더 널리 사용할 수 있게 될 예정입니다.
CSS 의사 클래스(Pseudo-class)를 사용하면, 에이전트가 툴을 조작 중임을 사용자에게 시각적으로 전달할 수 있습니다.
/* 에이전트가 폼을 조작 중 */
form:tool-form-active {
outline: 2px dashed blue;
...
WebMCP의 선언형 API는 HTML 속성을 몇 줄 추가하는 것만으로 기존 폼을 에이전트 대응형으로 만들 수 있습니다.
toolname / tooldescription으로 툴을 공개
toolparamdescription으로 JSON Schema를 보완
toolautosubmit으로 자동 제출을 허용
e.agentInvoked + respondWith()로 결과를 반환
아직 실험 단계의 API이지만, 웹 페이지와 에이전트의 관계를 근본적으로 바꿀 가능성을 느꼈습니다. 꼭 한번 시도해 보세요.
참고
끝까지 읽어주셔서 감사합니다!
평소에는 디자인과 프론트엔드를 중심으로 Qiita에 글을 게시하고 있으니, Qiita 팔로우와 X(Twitter) 팔로우를 부탁드립니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기