Chrome 146, web sitelerinin yapay zekâ ajanlarına yapılandırılmış araçlar sunmasını sağlayan tarayıcı tabanlı bir API olan WebMCP'yi (Web Model Context Protocol) tanıtıyor. Ekran kazıma veya kırılgan seçicilere güvenmek yerine, ajanlar artık formları keşfedebilir, amaçlarını anlayabilir, onları akıllıca doldurabilir ve hatta doğrudan imperatif JavaScript fonksiyonlarını çağırabilir. Bu adım adım rehber, gerçek bir Next.js projesinde WebMCP'nin üç katmanının tamamını kod örnekleri ve üretim ortamından en iyi uygulamalarla anlatıyor.
Canlı Deneyin
WebMCP Nedir ve Neden Önemlidir?
WebMCP, yapay zekâ ajanları için robots.txt'nin arama motoru tarayıcıları için olduğu şeydir: web sitelerinin otomatik sistemlerle iletişim kurması için standartlaştırılmış bir yöntem. Ancak tarayıcılara neyi indekslememeleri gerektiğini söylemek yerine, WebMCP yapay zekâ ajanlarına bir sayfada neler yapabileceklerini söyler.
Bunu yapay zekâ için yapılandırılmış bir menü olarak düşünün. Bir ajan WebMCP destekli bir sayfayı ziyaret ettiğinde hemen şunu bilir: "Bu sayfada ad, e-posta ve mesaj kabul eden bir iletişim formu var. Formu görsel olarak doldurabilirim ya da verileri programatik olarak göndermek için bir JavaScript API'si çağırabilirim."
Bunu mümkün kılmak için üç katman birlikte çalışır:
| Katman | Nasıl Çalışır | Yapay Zekâ Ne Zaman Kullanır |
|---|---|---|
| Deklaratif HTML | Form ve giriş alanlarındaki öznitelikler araç amacını tanımlar | Ajan formu görsel olarak doldurup gönder butonuna tıklar |
| İmperatif JavaScript | navigator.modelContext.registerTool() bir API sunar | Ajan araç fonksiyonunu doğrudan kod ile çağırır |
| Manifest Keşfi | .well-known/webmcp uç noktası ve sayfa düzeyinde JSON | Ajan sayfaya gitmeden önce mevcut araçları keşfeder |
WebMCP için TypeScript Bildirimleri Nasıl Ayarlanır
Herhangi bir WebMCP özniteliği eklemeden önce TypeScript bildirimlerini ayarlayın. Bunlar olmadan JSX, toolname ve tooldescription gibi özel öznitelikleri derleme hatalarıyla reddedecektir.
Chrome 146'nın sağladığı global arayüzleri bildiren bir types/webmcp.d.ts dosyası oluşturun:
export {};
declare global {
interface WebMCPSubmitEvent extends Event {
agentInvoked?: boolean;
respondWith?: (response: string) => void;
}
interface WebMCPTool {
name: string;
description: string;
execute: (params: Record<string, unknown>) => unknown | Promise<unknown>;
inputSchema: {
type: string;
properties?: Record<string, {
type: string;
description?: string;
enum?: string[];
}>;
required?: string[];
};
}
interface ModelContext {
registerTool: (tool: WebMCPTool) => void;
unregisterTool: (name: string) => void;
}
interface Navigator {
modelContext?: ModelContext;
}
}
declare module "react" {
interface HTMLAttributes<T> {
toolname?: string;
tooldescription?: string;
toolparamdescription?: string;
}
}En İyi Uygulama: Neden Global Bildirimler?
Formlara Deklaratif HTML Öznitelikleri Nasıl Eklenir
Deklaratif katman uygulanması en basit olandır. Mevcut formlarınıza üç öznitelik ekleyin:
- 1Form elemanında toolname: ajanın bu araca başvurmak için kullandığı benzersiz bir tanımlayıcı
- 2Form elemanında tooldescription: ajana bu formu ne zaman ve neden kullanacağını söyleyen doğal dilde bir açıklama
- 3Her input, select ve textarea'da toolparamdescription: her alan için bağlam, ajana hangi değeri sağlayacağı konusunda rehberlik eder
<form
id="contactForm"
toolname="contact_form"
tooldescription="Submit a contact request with name, email, reason, and message."
noValidate
onSubmit={handleSubmit}
>
<input
type="text"
name="name"
required
toolparamdescription="Full name of the person submitting the request"
/>
<input
type="email"
name="email"
required
toolparamdescription="Email address for follow-up communication"
/>
<select
name="reason"
toolparamdescription="Reason for contact: 'support', 'sales', 'partnership', or 'other'"
>
<option value="support">Support</option>
<option value="sales">Sales</option>
</select>
<textarea
name="message"
required
toolparamdescription="Detailed message describing the request"
/>
<button type="submit">Send</button>
</form>En İyi Uygulama: Farklı Araç İsimleri Kullanın
Özel UI Bileşenleri Nasıl Ele Alınır
Formunuz yerel select elemanları yerine buton grupları veya radyo kartları gibi özel UI bileşenleri kullanıyorsa, gizli bir <select> elemanı ekleyin. Yapay zekâ ajanları seçenekleri yalnızca standart HTML form elemanları aracılığıyla keşfedebilir.
React'te Ajan Form Gönderimleri Nasıl İşlenir
Bir yapay zekâ ajanı deklaratif bir formu doldurup gönderdiğinde, Chrome yerel olayda iki ek özellikle normal bir submit olayı tetikler:
- agentInvoked: boolean — yapay zekâ ajanı gönderimi tetiklediğinde doğrudur
- respondWith(response: string) — ajana bir metin yanıtı gönderir
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const nativeEvent = e.nativeEvent as WebMCPSubmitEvent;
if (nativeEvent.agentInvoked) {
const fd = new FormData(e.currentTarget);
const data = {
name: fd.get("name") as string,
email: fd.get("email") as string,
reason: fd.get("reason") as string,
message: fd.get("message") as string,
};
const ref = "REF-" + Math.random().toString(36).substring(2, 8).toUpperCase();
// MUST be called synchronously, before any await!
nativeEvent.respondWith?.(
`Contact submitted successfully. Reference: ${ref}`
);
await submitToBackend(data);
setSubmitted(true);
return;
}
// Human path (unchanged)
setIsSubmitting(true);
};Kritik: respondWith() Senkron Olmalıdır
En İyi Uygulamalarla İmperatif Araç Kaydı Nasıl Yapılır
İmperatif katman, yapay zekâ ajanlarına ikinci bir yol sunar: formları görsel olarak doldurmak yerine, ajan doğrudan bir JavaScript fonksiyonunu çağırır. Bu daha hızlı, daha güvenilir ve form UI'ı karmaşık veya dinamik olsa bile çalışır.
En İyi Uygulama: Ref Guard Kayıt Kalıbı
const toolRegisteredRef = useRef(false);
useEffect(() => {
const mc = navigator.modelContext;
if (!mc || toolRegisteredRef.current) return;
toolRegisteredRef.current = true;
mc.registerTool({
name: "submit_contact_request",
description: "Submit a contact request programmatically.",
inputSchema: {
type: "object",
properties: {
name: { type: "string", description: "Full name" },
email: { type: "string", description: "Email address" },
reason: { type: "string", description: "Contact reason" },
message: { type: "string", description: "Message body" },
},
required: ["name", "email", "reason", "message"],
},
execute: async (params: Record<string, unknown>) => {
return dispatchAndWait("webmcp:submitContact", params);
},
});
}, []);Kayıt için React Hook Kullanmayın
İmperatif Araçları React State ile Köprüleme
İmperatif aracın execute fonksiyonu React'in bileşen ağacının dışında çalışır. React state'ini güncellemek için dispatchAndWait kalıbını kullanın:
export function dispatchAndWait(
eventName: string,
detail: Record<string, unknown>,
timeoutMs = 30000
): Promise<string> {
return new Promise((resolve, reject) => {
const requestId = Math.random().toString(36).substring(2, 15);
const completionEvent = `tool-completion-${requestId}`;
let timer: ReturnType<typeof setTimeout>;
const handleCompletion = (e: Event) => {
clearTimeout(timer);
window.removeEventListener(completionEvent, handleCompletion);
const customEvent = e as CustomEvent<{ result: string }>;
resolve(customEvent.detail?.result ?? "Action completed");
};
window.addEventListener(completionEvent, handleCompletion);
timer = setTimeout(() => {
window.removeEventListener(completionEvent, handleCompletion);
reject(new Error(`WebMCP tool timeout: ${eventName}`));
}, timeoutMs);
window.dispatchEvent(
new CustomEvent(eventName, { detail: { ...detail, requestId } })
);
});
}Manifest Tabanlı Keşif Nasıl Uygulanır
Manifest katmanı navigasyon öncesi keşfi sağlar. Bir ajan bir sayfayı açmadan önce bile, hangi araçların mevcut olduğunu öğrenmek için site manifestini çekebilir.
Next.js'te Site Düzeyi Manifest Nasıl Oluşturulur
import { NextResponse } from "next/server";
export const runtime = "edge";
export async function GET() {
const manifest = {
spec: "webmcp/0.1",
site: {
name: "My Website",
version: "2026.02",
description: "Website description for AI agents.",
pages: [
{
url: "/contact",
intents: ["contact_form", "submit_contact_request"],
},
],
flows: [
{
id: "contact_inquiry",
description: "Submit a contact request.",
steps: [{ intent: "contact_form", page: "/contact" }],
},
],
},
};
return NextResponse.json(manifest, {
headers: {
"Cache-Control": "public, max-age=86400, s-maxage=86400",
"Access-Control-Allow-Origin": "*",
},
});
}En İyi Uygulama: Middleware'den Hariç Tutun
Sayfa Düzeyi Manifest Nasıl Eklenir
{
"spec": "webmcp/0.1",
"page": { "url": "/contact", "title": "Contact Us" },
"context": {
"purpose": "Contact form for inquiries and support requests",
"entities": ["contact_request"],
"auth": { "required": false }
},
"intents": [
{
"id": "contact_form",
"description": "Submit a contact request",
"inputs": [
{ "name": "name", "type": "string", "required": true },
{ "name": "email", "type": "email", "required": true },
{ "name": "message", "type": "string", "required": true }
],
"policy": { "rateLimit": "5/min" }
}
]
}WebMCP CSS Sözde Sınıfları ile Görsel Geri Bildirim
Chrome 146, bir yapay zekâ ajanı bir formla etkileşime girdiğinde iki yeni CSS sözde sınıfı ekler:
- :tool-form-active — ajan etkileşim halindeyken form elemanına uygulanır
- :tool-submit-active — ajan gönderirken gönder butonuna uygulanır
"use client";
import { useEffect } from "react";
export default function WebMCPStyles() {
useEffect(() => {
const style = document.createElement("style");
style.setAttribute("data-webmcp", "true");
style.textContent = [
"*:tool-form-active {",
" outline: 2px solid rgba(147, 51, 234, 0.5);",
" outline-offset: 2px;",
"}",
"*:tool-submit-active {",
" background: linear-gradient(110deg, #7c3aed 30%, #a78bfa 50%, #7c3aed 70%);",
" background-size: 200% 100%;",
" animation: webmcp-shimmer 2s infinite linear;",
"}",
"@keyframes webmcp-shimmer {",
" to { background-position: 200% center; }",
"}",
].join("\n");
document.head.appendChild(style);
return () => { style.remove(); };
}, []);
return null;
}Yaygın WebMCP Uygulama Hataları ve Nasıl Kaçınılır
En İyi Uygulamalar: Hatalardan Kaçının
- 1Deklaratif ve imperatif araçlar için aynı isim. Chrome "Duplicate tool name" DOMException fırlatır. Her zaman farklı isimler kullanın.
- 2await'ten sonra respondWith() çağırmak. Yanıt kanalı asenkron işlem tamamlanmadan kapanır.
- 3registerTool için React hook kullanmak. Strict mod çift mount yapar ve registerTool'u iki kez çağırır.
- 4Eksik TypeScript bildirimleri. .d.ts dosyası olmadan öznitelikler TSX derleme hatalarına neden olur.
- 5Manifest rotalarını i18n middleware'den hariç tutmamak. Middleware /.well-known/webmcp'yi yönlendirir ve keşfi bozar.
- 6Hassas formlara WebMCP eklemek. Şifre veya kredi kartı işleyen formlara asla toolname eklemeyin.
En İyi Uygulamalar ve Temel Çıkarımlar
- WebMCP, yapay zekâ-web sitesi etkileşimi için standartlaştırılmış bir protokol sağlar ve kırılgan ekran kazımayı yapılandırılmış araç keşfi ile değiştirir.
- Üç katmanlı mimari (deklaratif, imperatif, manifest) ajanlara sitenizle etkileşim için birden fazla yol sunar.
- TypeScript bildirimleri vazgeçilmezdir ve herhangi bir öznitelik veya API çalışmasından önce ilk adım olmalıdır.
- Ref guard kalıbı, React'te imperatif araçları kaydetmenin doğru yoludur.
- respondWith() senkron olmalıdır. Bu, deklaratif katmandaki en kritik kuraldır.
- WebMCP manifestleri, yapay zekâ ajanları için robots.txt görevi görür.
Yapay zekâ ajanları tarayıcı iş akışlarında giderek yaygınlaştıkça, WebMCP web sitenizi ajantik web'de birinci sınıf bir katılımcı olarak konumlandırır. Uygulama çabası mütevazıdır, ancak getirisi önemlidir: formlarınız herhangi bir Chrome 146+ yapay zekâ ajanı tarafından özel entegrasyon çalışması olmadan keşfedilebilir ve kullanılabilir hale gelir.
Kaynakça
- 1
- 2
- 3Chrome 146 Sürüm Notları(Google Chrome Developers)