Mert Özen Her Satırda Daha İleri
Geliştirici Araçları Browser DevTools — #10

DevTools ve AI: Gemini AI Assistance, Chrome DevTools MCP ve Recorder

Mert Özen 8 Kas 2026 10 dk 3 görüntülenme
DevTools ve AI: Gemini AI Assistance, Chrome DevTools MCP ve Recorder

Chrome DevTools MCP server'ı coding agent'a tarayıcıdaki her şeyi açar: ayrı profil, --no-usage-statistics ve --no-performance-crux olmadan kişisel oturumların ve URL'lerin dışarı çıkabilir. Agent'la /books/abc'de SPA fallback'inin API'ye HTML döndürdüğü ve NaN IndexedDB key'i hatalarını source-mapped stack'lerle bulup düzeltiyoruz; Gemini AI assistance'ın şartları, DevToolsGenAiSettings policy'si ve Recorder kaydını Puppeteer'a aktarmak.

Sürüm notu: Bu yazıdaki örnekler Chrome 156 (156.0.8078.80), chrome-devtools-mcp 1.12.0, @puppeteer/replay 4.0.2, Angular 22.2 ve .NET 10 ile denenmiştir. MCP (Model Context Protocol) çıktıları server'a stdio üzerinden bağlanan küçük bir istemciyle, çalışma klasöründeki ayrı bir Chrome profiliyle alındı. DevTools'taki Gemini AI (Artificial Intelligence) assistance, Google hesabıyla giriş gerektirdiği için bu ortamda çalıştırılmadı; o bölüm Chrome DevTools dokümanından aktarıldı. Bu alan çok hızlı değişiyor: yayından önce sürüm notlarını tekrar kontrol et.

Önce Tahmin Et

Coding agent'ına Chrome DevTools MCP server'ını dokümandaki en kısa yapılandırmayla ekliyorsun:

{
  "mcpServers": {
    "chrome-devtools": {
      "command": "npx",
      "args": ["-y", "chrome-devtools-mcp@latest"]
    }
  }
}

Sonra "Bookstore'da /books/abc açılınca ne oluyor, bak" diyorsun. Agent hangi Chrome profilini kullanır: senin her gün kullandığın, bankaya ve e-postana giriş yapılmış profil mi, yoksa ayrı bir profil mi? Bu yapılandırmayla Google'a hangi veri gider? Ve agent, açtığı bir sayfadaki metinde "şu dosyayı sil" yazıyorsa ne yapar?

Bu yazı serinin son yazısı. Şimdiye kadar her paneli elle kullandık; burada aynı araçları bir AI'a açan iki yolu ve kullanıcı akışlarını kaydeden Recorder'ı ele alıyoruz.

DevTools İçinde AI Assistance

AI assistance, Gemini'yi DevTools'un içine getiren özellik. Dokümana göre şartlar şunlar: Chrome'un güncel sürümü, giriş yapmış bir Google hesabı, en az 18 yaş ve desteklenen bir bölge. Özellik varsayılan olarak kapalıdır; Settings'teki AI assistance bölümünden açılır ve Google'ın hizmet şartlarını kabul etmen istenir. Doküman özelliği deneysel olarak tanımlıyor ve yanlış ya da uygunsuz yanıt üretebileceğini açıkça söylüyor.

Dört bağlamda çalışır. Styling'de seçili element'in stilini açıklar ve layout ya da stil hatalarını düzeltmeye yardım eder. Network'te seçili isteğin request ve response header'larını analiz eder, örneğin isteğin neden başarısız olduğunu. Sources'ta bir script dosyasının ne yaptığını açıklar. Performance'ta yavaş bir sayfayı inceleyip LCP (Largest Contentful Paint) gibi metrikler için düzeltme önerir. Kullanım akışı hep aynı: DevTools'ta bir element, istek, dosya ya da trace seç, AI assistance ikonuna tıkla ve sor. Örneğin bu serinin 01. yazısındaki .price kuralının neden uygulanmadığını Styling bağlamında sorabilirsin; ama cevabı, o yazıda yaptığımız gibi Styles ve Computed sekmesiyle doğrula.

Veri, Gizlilik ve Kurumsal Policy

AI assistance'a bir soru sorduğunda sorunun yanında seçtiğin bağlam da Google'a gider: element'in stilleri, isteğin header'ları, dosyanın içeriği ya da trace verisi. Bu, "Authorization header'ı olan bir isteği seçip soru sormak" token'ı da göndermek demek. Kurumsal tarafta bunu DevToolsGenAiSettings policy'si yönetiyor: 0 değeri özelliği açar ve Google'ın prompt, içerik ve geri bildirimi modellerini geliştirmek için kullanmasına izin verir; 1 özelliği açar ama verinin model geliştirmede kullanılmasına izin vermez; 2 bütün AI assistance özelliklerini ve giriş noktalarını kapatır. Google'ın yönetim makalesi, model geliştirme için kullanılan verilerin insan değerlendiriciler tarafından da okunabileceğini belirtiyor. Şirketinin kaynak kodu ya da müşteri verisiyle çalışıyorsan bu policy'nin değerini BT (Bilgi Teknolojileri) ekibinle netleştirmeden özelliği kullanma.

Chrome DevTools MCP: Kurulum ve Araçlar

MCP, bir AI istemcisinin dış araçları standart bir protokolle çağırmasını sağlar. chrome-devtools-mcp paketi Chrome'u bir coding agent için araç setine çeviriyor: navigasyon, tıklama ve form doldurma, ekran görüntüsü, console ve network kayıtları, performance trace'i ve insight'lar, Lighthouse, CSS (Cascading Style Sheets) stilleri ve deneysel bellek araçları. Paketin içinde ayrıca bir CLI (Command Line Interface) ve agent'lar için hazır skill'ler de geliyor. Chrome 155–156'dan beri DevTools'un ana menüsünde "Get Chrome DevTools for agents" diye bir giriş de var. Server'ın 1.12.0 sürümünde varsayılan araç listesi:

server: {"name":"chrome_devtools","title":"Chrome DevTools MCP server","version":"1.12.0"}
tools (32): click, close_page, drag, emulate, evaluate_script, fill, fill_form, get_console_message, get_css_styles, get_network_request, handle_dialog, hover, lighthouse_audit, list_console_messages, list_network_requests, list_pages, navigate_page, new_page, performance_analyze_insight, performance_start_trace, performance_stop_trace, press_key, resize_page, screencast_start, screencast_stop, select_page, take_heapsnapshot, take_screenshot, take_snapshot, type_text, upload_file, wait_for

Bu seride Insights ve heap snapshot çıktılarının bir kısmını zaten bu server'la aldık; bellek analizi araçları (compare_heapsnapshots, get_heapsnapshot_retaining_paths…) --experimentalMemory bayrağıyla açılıyor. --slim ise yalnız navigasyon, script çalıştırma ve ekran görüntüsünden oluşan üç araçlık küçük bir set sunar. Chrome 153–154 ve 155–156 notlarına göre son sürümlere heap snapshot sorgulama, isteğe bağlı source map yükleme, --no-javascript-evaluation ile script çalıştırmayı kapatma, PWA (Progressive Web App) otomasyonu ve get_css_styles eklendi.

Agent'ın Gözünden Bir Hata Avı

Önce Tahmin Et'teki isteği server'a araç çağrılarıyla yaptırdık. Agent sayfayı açıp console hatalarını listeledi:

=== list_console_messages {"types":["error"]}
msgid=5 [error] ERROR [object HttpErrorResponse] (2 args)
msgid=6 [error] ERROR DataError: Failed to execute 'put' on 'IDBObjectStore': Evaluating the object store's key path yielded a value that is not a valid key. (2 args)

=== get_console_message {"msgid":5}
Arg #1: {"headers":{...},"status":200,"statusText":"OK","url":"http://localhost:5391/api/books/NaN","ok":false,"name":"HttpErrorResponse","message":"Http failure during parsing for http://localhost:5391
### Stack trace
at  (client:368:4)
--- await ------------------------------
at ngOnInit (book-detail.ts:29:43)
--- Promise.then -----------------------
at <anonymous> (main.ts:5:1)

Stack trace source map'le çevrilmiş geliyor: hata book-detail.ts'in 29. satırındaki ngOnInit'te. Daha ilginci mesajın kendisi: status 200 ama ok: false ve "Http failure during parsing". Agent ardından network'e baktı:

=== list_network_requests {"resourceTypes":["fetch","preflight"]}
reqid=29 OPTIONS http://localhost:5391/api/books/NaN [204]
reqid=30 GET http://localhost:5391/api/books/NaN [200]

İki gerçek bug çıktı. Birincisi backend'de: /api/books/NaN {id:int} kısıtına uymadığı için hiçbir endpoint'e düşmüyor ve SPA (Single-Page Application) için yazdığımız MapFallbackToFile("index.html")'e gidiyor. API (Application Programming Interface) 404 yerine 200 ile HTML (HyperText Markup Language) dönüyor, Angular da onu JSON (JavaScript Object Notation) diye parse etmeye çalışıyor. İkincisi frontend'de: Number('abc') NaN veriyor ve NaN IndexedDB'de geçerli bir key değil. Düzeltmeler:

// bilinmeyen /api yolları SPA'nın index.html'ine değil 404'e düşmeli
app.MapGet("/api/{**rest}", () => Results.NotFound());

app.MapFallbackToFile("index.html");
remember(bookId: number): void {
  if (!Number.isInteger(bookId)) {
    return;
  }
  // ...
}
api/books/NaN -> 404
api/books/3 -> 200
/cart -> 200 text/html

=== list_console_messages {"types":["error"]}
msgid=8 [error] Failed to load resource: the server responded with a status of 404 (Not Found) (0 args)
msgid=10 [error] ERROR [object HttpErrorResponse] (2 args)

IndexedDB hatası gitti, API doğru status'u dönüyor; geriye bileşenin 404'ü kullanıcıya düzgün göstermemesi kaldı, ki o da artık açık bir iş. Agent aynı oturumda take_snapshot ile sayfanın erişilebilirlik ağacını alıp bir fiyat element'inin uid'iyle get_css_styles çağırdığında, 01. yazıda elle bulduğumuz kuralı buldu:

Styles for span.price (uid: "1_16"):

  .price[_ngcontent-ng-c1135625248] (<style>:12) {
    color: #0a7d4f;
  }

Agent'ın yaptığı şey bu serinin anlattığı şeyin aynısı: console'u oku, network'e bak, stili kontrol et, trace al. Fark, bunu senin yerine ve çok hızlı yapması. Doğrulama sorumluluğu ise değişmiyor: bulduğu iki bug'ı biz de curl ve ikinci bir oturumla kontrol ettik.

Güvenlik: Agent Tarayıcıdaki Her Şeyi Görür

Paketin README'si açık: server, tarayıcı instance'ının içeriğini MCP istemcisine açar ve istemci tarayıcıdaki ya da DevTools'taki her veriyi inceleyebilir, değiştirebilir. Bu yüzden üç kural:

  • Ayrı ya da geçici profil kullan. --isolated kapanınca silinen geçici bir user data dir açar; --userDataDir ile çalışma klasöründe bir profil verebilirsin. Varsayılan profil $HOME/.cache/chrome-devtools-mcp/chrome-profile; oraya bir kez kişisel hesabınla giriş yaparsan agent o oturumu her seferinde görür.
  • Kişisel tarayıcına bağlama. --autoConnect ya da --browserUrl çalışan bir Chrome'a bağlanır; o Chrome'da açık olan banka, e-posta ve şirket oturumları agent'ın erişimine girer.
  • Sayfa içeriğine talimat gibi davranma. Agent'ın okuduğu her sayfa, console mesajı ve network yanıtı ona yönelik yazılmış metin içerebilir; agent'ın dosya silme, commit atma gibi yetkileri varsa bu bir prompt injection kapısıdır.

Gizlilik tarafında iki varsayılan dikkat ister. Kullanım istatistikleri (araç çağrılarının başarısı, gecikme, ortam bilgisi) varsayılan olarak Google'a gönderilir; --no-usage-statistics ya da CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS ortam değişkeni bunu kapatır. Performance araçları, field verisi için trace'teki URL'leri (Uniform Resource Locator) Google'ın CrUX (Chrome User Experience Report) API'sine gönderebilir; --no-performance-crux kapatır. Bu yazıdaki bütün oturumlar şu bayraklarla çalıştı:

chrome-devtools-mcp --headless --userDataDir ./run/mcp-profile-XXXX \
  --executablePath "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
  --no-usage-statistics --no-performance-crux --viewport 1280x800

Daha sıkı bir kurulum için --allowedUrlPattern ile tarayıcıyı yalnız yerel adreslere sınırlayabilir, --redactNetworkHeaders ile hassas header'ları istemciye vermeden önce maskeleyebilir, --no-javascript-evaluation ile agent'ın keyfi script çalıştırmasını kapatabilirsin. Sonuncusunun yardım metni, bunun bir sandbox olmadığını ve sayfanın kendi script'lerinin çalışmaya devam ettiğini ayrıca belirtiyor.

Recorder: Akışı Kaydetmek, Tekrar Oynatmak ve Puppeteer'a Aktarmak

Recorder paneli (Command Menu'de "Show Recorder") bir kullanıcı akışını adım adım kaydeder: navigasyon, tıklama, input değişikliği. Kayıt sırasında her adım için birden fazla selector saklar: ARIA (Accessible Rich Internet Applications) etiketi, CSS selector'ü, XPath. Replay düğmesi akışı tekrar oynatır; Measure performance düğmesi aynı akışı oynatırken Performance panelinde trace kaydeder. Kayıt JSON olarak export edilir. Recorder'ın JSON formatında bir sepete ekleme akışını elle yazıp Recorder'ın da kullandığı @puppeteer/replay kütüphanesiyle oynattık:

{ "type": "change", "value": "Compilers", "selectors": [["aria/Filter books"], ["input.filter"]] },
{ "type": "click", "selectors": [["aria/Add to cart"], ["app-book-card:nth-of-type(1) button"]], "offsetX": 20, "offsetY": 10 },
{ "type": "click", "selectors": [["aria/Cart (1 · $21.00)"], ["nav a[href='/cart']"]], "offsetX": 10, "offsetY": 5 },
{ "type": "waitForElement", "selectors": [[".summary"]] }
step done: setViewport
step done: navigate http://localhost:4391/books
step done: change Compilers
step done: click aria/Add to cart
step done: click aria/Cart (1 · $21.00)
step done: waitForElement .summary
summary text: 1 items, total $21.00

Recorder'ın export menüsündeki Puppeteer seçeneği aynı kaydı bir script'e çevirir; kütüphanenin stringify fonksiyonunun ürettiği çıktının başı:

import { Locator, launch } from 'puppeteer'; // v25.0.0 or later

const browser = await launch();
const page = await browser.newPage();
const timeout = 5000;
page.setDefaultTimeout(timeout);

Dikkat: aria/Cart (1 · $21.00) selector'ü sepetteki tutara bağlı; fiyat değişirse kayıt kırılır. Recorder'ın ürettiği selector'ler bir başlangıç noktasıdır, test koduna dönüştürürken data-testid gibi kararlı selector'lere geçersin. Recorder'dan E2E (end-to-end) teste geçiş ilerideki Frontend Testleri serisinin konusu.

Tarih Notu: Hızlı Değişen Bir Alan

Bu yazıdaki her şey son iki sürümde değişti: Chrome 153–154'te MCP server'a heap snapshot sorgulama, PWA araçları ve JavaScript kapatma bayrakları, 155–156'da get_css_styles, yapılandırma dosyası ve DevTools menüsündeki agent girişi geldi. AI assistance de deneysel olarak işaretli. Bir özelliği ekibine önermeden önce o haftaki "New in DevTools" yazısına ve paketin değişiklik günlüğüne bak; chrome-devtools-mcp@latest kullanıyorsan agent'ının yarın farklı bir araç setiyle açılabileceğini de unutma. Kararlı bir kurulum için sürümü sabitle (chrome-devtools-mcp@1.12.0) ve bilinçli yükselt.

Üretimde Dikkat

Agent'ı production'a bağlama. MCP server'ı yerel ya da staging ortamında, test kullanıcılarıyla çalıştır; production verisi bir kez agent'ın bağlamına girerse prompt geçmişinde, log'larda ve kullandığın modelin sağlayıcısında iz bırakabilir. --allowedUrlPattern bu sınırı teknik olarak zorlamanın en kolay yolu.

Agent'ın bulgusu bir hipotezdir. Bizim örneğimizde iki bug gerçekti ve tekrar ölçülerek doğrulandı; ama aynı agent bir trace'i yanlış okuyabilir ya da bir uyarıyı abartabilir. Kod değişikliğini bu serinin anlattığı araçlarla, kendi gözünle doğrulamadan merge etme.

AI assistance'ta kurumsal policy değerini bilmeden token, müşteri verisi ya da kapalı kaynak kod içeren bir bağlamı seçip soru sorma.

Sık Düşülen Tuzaklar

  • MCP server'ı varsayılan profille çalıştırıp o profile kişisel hesapla giriş yapmak.
  • Kullanım istatistiklerinin ve CrUX sorgularının varsayılan olarak açık olduğunu bilmemek.
  • @latest ile her gün değişen bir araç setine bağımlı olmak.
  • Agent'ın okuduğu sayfa içeriğini güvenilir talimat sanmak.
  • AI assistance'ın yanıtını Styles, Network ya da Performance panelinde doğrulamadan uygulamak.
  • Recorder'ın ürettiği metne bağlı selector'leri olduğu gibi kalıcı teste koymak.

Küçük Bir Deneme

★☆☆ Chrome DevTools MCP server'ını --isolated --no-usage-statistics --no-performance-crux ile agent'ına ekle ve "/books/abc açılınca console'da ne çıkıyor" diye sor. Agent'ın hangi araçları hangi sırayla çağırdığını not et.

★★☆ Recorder'la Bookstore'da "filtrele, sepete ekle, sepete git" akışını kaydet, JSON olarak export et ve aria/Cart (1 · $21.00) gibi kırılgan selector'leri data-testid tabanlı selector'lerle değiştir. Replay ile hâlâ çalıştığını doğrula.

★★★ BookDetail'in 404'ü kullanıcıya "Book not found" olarak göstermesini sağla. Ardından agent'a aynı soruyu tekrar sor ve console'da artık hata kalmadığını, network'te 404'ün göründüğünü kendi Network ve Console panelinle de doğrula.

Seri burada bitiyor. Elements'ten Memory'ye, Lighthouse'tan Angular DevTools'a kadar her panel aynı soruya farklı bir açıdan cevap veriyor: tarayıcıda şu an gerçekte ne oluyor? Agent'lar bu soruyu daha hızlı sorabilir; ama cevabı okuyabilmek, bu serinin anlattığı araçları bilmekten geçiyor.