Agent se direktno povezuje sa tvojim svakodnevnim Chrome pregledačem, nosi prijavljeno stanje.
Prošli period smo PaiCLI-u povezali Chrome DevTools MCP, Agent konačno može otvoriti pregledač. Može navigirati stranice, praviti snimke ekrana, uzimati DOM snapshot, čak i članke sa WeChat javnih naloga može čitati.
Ali postoji još jedan problem.

Svaki put Agent otvori "novi" Chrome, nema prijavljeno stanje, nema Cookie-e. Ako mu kažeš da vidi GitHub privatnog repozitorijuma README, nemoćan je, jer treba prijava.
I svaki put ponovo mora uneti korisničko ime i lozinku, to je vrlo neugodno.
U ovom periodu, rešićemo ovaj problem: neka Agent direktno povezuje tvoj svakodnevni Chrome, ponovo upotrebi tvoje postojeće prijavljeno stanje, kao ti sam biraš bilo koju stranicu koja zahteva prijavu.
01, Zašto treba ponovno upotrebiti prijavljeno stanje
Prvo da podsjetimo arhitekturu prošlog perioda.
chrome-devtools-mcp podrazumevano startuje sa --isolated=true, svaki put kreira privremeni user-data-dir, kad se pregledač zatvori ovaj privremeni direktorijum se briše.
Ovaj mehanizam izolacije jeste siguran, ali takođe znači da je Agent-ov pregledač i tvoj svakodnevni Chrome uopšte nisu ista stvar. Tvoje GitHub prijavljeno stanje, Feishu sesija, kompanijski intranet SSO token, nijedan ne može koristiti.
Stvarni razvoj će naići na mnogo scenara koji zahtevaju prijavljeno stanje: pregled koda GitHub privatnog repozitorijuma, čitanje kompanijskog internog Wiki-ja, čitanje opisa zahteva u Feishu cloud dokumentu, pregledanje monitoring panela Grafana itd.
Ovi scenariji imaju jednu zajedničku osobinu: pristup zahteva autentifikaciju.
Agent nema prijavljeno stanje, znači da je pola sposobnosti je zapečaćena.

chrome-devtools-mcp podržava jedan parametar --browser-url, može se povezati na već pokrenut Chrome instancu.
Ideja: ti pokreneš Chrome, uključiš debug port, kroz --browser-url povežeš, Agent može videti tvoje sve prijavljeno stanje.
02, Uključi Chrome remote debug
Da bi PaiCLI povezao tvoj Chrome, prvi korak je da Chrome otvori CDP debug port.

Ne treba zatvarati Chrome i ponovo pokretati iz komandne linije, direktno u tvoje trenutno korišćenom Chrome radi.
Otvori adresnu traku Chrome-a, unesi:
chrome://inspect/#remote-debuggingNa stranici ćeš videti prekidač: Allow remote debugging for this browser instance. Uključi ga.
Tako jednostavno, jednim korakom završi.

Nakon uključivanja, Chrome dozvoljava spoljni program da se poveže kroz CDP protokol.
Prošli period smo rekli, CDP način komunikacije je WebSocket, chrome-devtools-mcp će automatski otkriti i povezati se na ovu Chrome instancu.
Ovaj način najveća prednost: u tvoje trenutno Chrome-u već prijavljen GitHub, Feishu, kompanijski intranet, svi Cookie-i i sesije su tu, ne treba ponovo prijavljivati. PaiCLI se povezuje i može direktno koristiti tvoje postojeće prijavljeno stanje.
03, Agent automatski menja prijavljeno stanje
Nakon uključenja Chrome remote debug-a, vrati se u PaiCLI.
Ne treba ti ručno izvršavati komandu povezivanja. Agent sam procenjuje da li trenutna stranica treba prijavljeno stanje, kad treba automatski se prebacuje na shared režim, kad ne treba koristi isolated režim.
Direktno probaj.
Neka Agent pročita jednu stranicu koja ne treba prijavu:
Pomozi mi da vidim https://paicoding.com početnu stranicu
Agent će koristiti isolated režim da otvori privremeni pregledač, dobiti sadržaj stranice. Javne stranice ne trebaju prijavljeno stanje, isolated je dovoljan.
Zatim probaj jednu koja treba prijavu:
Pomozi mi da vidim ovaj dokument na Yuque-u https://www.yuque.com/itwanger/gykdzgPrvo će se pojaviti takav dijalog potvrde.

Nakon odobrenja koristiće tvoje prijavljeno stanje.

Obrati pažnju na gornji desni ugao, u dva režima prijavljeni korisnici su različiti, jedan je moj već prijavljen Chrome nalog, drugi je privremeni korisnik.
isolated režim automatski detektuje da li na lokalnoj mašini ima uključen remote debug Chrome, otkrije, prebači se na shared režim (--autoConnect) ponovo pristupa.

Ceo proces u Chrome-u možeš real-time videti da stranica skače.
Agent-ov proces razmišljanja će se ispisati: prvo pokuša isolated, otkrije da treba prijavu, automatski se prebaci na shared ponovni pokušaj.

Xiaohongshu, Yuque, Feishu cloud dokumenti, kompanijski intranet sistemi ove stranice koje trebaju prijavljeno stanje, Agent sve može automatski obraditi. Ti ne briguš o kojem režimu koristi, kad treba promeniti sam će se promeniti.
Koristi /browser status možeš bilo kad videti trenutno stanje režima:
/browser status
Ako tvoj Chrome nema uključen remote debug, nakon što --autoConnect povezivanje ne uspe Agent će nastaviti koristiti isolated režim i podsseteće te da možeš uključiti remote debug da dobiješ podršku prijavljenog stanja.
04, Dizajn automatskog prebacivanja
Ovaj dizajn automatskog prebacivanja prošao je kroz nekoliko iteracija, vredno razrade.
Prvi rešenje je bilo da korisnik ručno izvršava /browser connect i /browser disconnect prebacivanje. Ali stvarno korišćenje iskustvo je vrlo loše, korisnik svaki put mora razmišljati "da li ova stranica treba prijavljeno stanje", razmisli još mora ručno kucati naredbe, nakon korišćenja mora pamtiti da prekine. Ovo nije iskustvo koje Agent treba imati, Agent treba sam da reši ove stvari.
Drugi rešenje je registrovati dva MCP server-a: jedan chrome-devtools-isolated, jedan chrome-devtools-shared. Agent sam bira koji. Ali ovo rešenje je još ludije, 28 alata postaje 56, system prompt token-a se direktno udvostručuje. LLM vidi dva skupa gotovo identičnih alata.
Konačno rešenje: ime server-a se ne menja, Agent kad treba prijavljeno stanje automatski menja startne parametre, u memoriji promeni i restartuje server.
Jezgro implementacije u McpServerManager.restartWithArgs():
public synchronized String restartWithArgs(String name, List<String> newArgs) {
McpServer server = servers.get(name);
if (server == null) {
return "❌ MCP server nije pronađen: " + name;
}
server.config().setArgs(newArgs);
return restart(name); // Ide postojećim restart putem
}Toliko par linija.
Promeni args, restart, gotovo.
LLM vidi uvek ovih 28 alata mcp__chrome-devtools__*, prompt se ne menja, HITL logika se ne menja.
Agent-ov proces odluke je ovakav:
Prvi korak, Agent koristi isolated režim da otvori stranicu (podrazumevano ponašanje, sigurno).
Drugi korak, Agent nakon što dobije sadržaj stranice procenjuje da li je prijavna stranica. Ako je normalan sadržaj direktno koristi, proces se završava.
Treći korak, ako otkrije da je prijavna stranica ili nedovoljno dozvola, Agent poziva restartWithArgs da promeni startne parametre chrome-devtools-mcp sa --isolated=true na --autoConnect. --autoConnect je mehanizam automatskog otkrivanja chrome-devtools-mcp, automatski će naći lokalnu mašinu uključen remote debug Chrome instancu i povezati se, ne treba navoditi broj porta. Nakon uspešnog povezivanja ponovo pristupa istoj stranici, ako povezivanje ne uspe kaže korisniku da treba uključiti Chrome remote debug.

Kad se prebaci na shared režim, jedna stvar mora uraditi: očisti approvedAllByServer("chrome-devtools").
browserSession.switchToShared("autoConnect");
hitlHandler.clearApprovedAllForServer("chrome-devtools");Prebacivanje se vrši samo u memoriji, neće ići da menja tvoj ~/.paicli/mcp.json fajl.
Nakon PaiCLI restart-a se vraća u isolated režim, podrazumevano sigurno.
Takođe možeš koristiti /browser status bilo kad videti trenutni režim, /browser disconnect ručno se prebaci natrag u isolated. Ali normalno korišćenje uopšte ne moraš brinuti o ovim, Agent sam će rešiti.

05, autoConnect mehanizam otkrivanja
Ponovo sam spomenuo --autoConnect, kako Agent pronalazi tvoj lokalni Chrome?
Mnogih ljudi prva reakcija je skeniranje porta — prođe kroz uobičajene portove proba jedan po jedan, koji prođe taj se poveže. chrome-devtools-mcp nije to radio. Skeniranje porta je sporo, nepouzdano, lako pogrešno povezati na druge servise.
On koristi otkrivanje fajlova.
Chrome nakon uključenja remote debug-a, u svom korisničkom direktorijumu upisuje jedan fajl: DevToolsActivePort. Ovaj fajl ima samo dva reda:
52837
/devtools/browser/a1b2c3d4-e5f6-7890-abcd-ef1234567890Prvi red je Chrome dinamički dodeljen debug broj porta, drugi red je WebSocket putanja.
chrome-devtools-mcp dobija ova dva reda, slaže u ws://127.0.0.1:52837/devtools/browser/a1b2c3d4..., direktno uspostavlja WebSocket vezu.
Ceo proces otkrivanja je čitanje jednog fajla, nema mrežne detekcije, nema skeniranje porta.
// chrome-devtools-mcp logika povezivanja (prosto)
const portPath = path.join(userDataDir, 'DevToolsActivePort');
const fileContent = await fs.promises.readFile(portPath, 'utf8');
const [rawPort, rawPath] = fileContent
.split('\n')
.map(line => line.trim())
.filter(line => !!line);
const port = parseInt(rawPort, 10);
const browserWSEndpoint = `ws://127.0.0.1:${port}${rawPath}`;Zašto koristiti fajl umesto fiksni port?
Jer Chrome svaki put kad uključi remote debug, port je random dodeljen, nije fiksni 9222. Fiksni port lako konfliktaš — na tvojoj mašini pokreneš više Chrome instanci ili drugi alati zauzmu 9222, direktno ne možeš povezati. Random port + zapis fajla, Chrome sam piše, MCP sam čita, neće konfliktoovati.

Lokacija DevToolsActivePort fajla je povezana sa operativnim sistemom:
- macOS:
~/Library/Application Support/Google/Chrome/DevToolsActivePort - Linux:
~/.config/google-chrome/DevToolsActivePort - Windows:
%LOCALAPPDATA%\Google\Chrome\User Data\DevToolsActivePort
chrome-devtools-mcp interno kroz Puppeteer pozicionira Chrome korisnički direktorijum, ne treba ti ručno navoditi putanju.
--autoConnect plus --channel=stable (podrazumevana vrednost), Puppeteer zna gde tražiti.

Još govorimo o kontroli dozvola tokom povezivanja.
Ti u chrome://inspect/#remote-debugging uključi remote debug prekidač, Chrome ne prihvća sve veze bezuslovno.
Kad chrome-devtools-mcp prvi put pokuša povezati, Chrome će iskociti nativni dijalog potvrde, pita te da li dozvoljavaš ovom spoljnom programu da se poveže.
Ti klikneš "Dozvoli", veza može uspostaviti. Ovo je Chrome sopstveni bezbedonosni mehanizam, nije PaiCLI dodat.

Celi proces spoji ovako:
- Ti u
chrome://inspect/#remote-debugginguključi remote debug - Chrome dinamički dodeljuje port, upisuje broj porta i WebSocket putanju u
DevToolsActivePortfajl - Kad Agent treba prijavljeno stanje, PaiCLI koristi
--autoConnectrestartuje chrome-devtools-mcp - chrome-devtools-mcp čita
DevToolsActivePortfajl, dobija port i putanju - Kroz WebSocket povezuje Chrome, Chrome iskačuje dijalog potvrde
- Korisnik klikne "Dozvoli", veza uspostavljena, Agent ima tvoje prijavljeno stanje
Jedan hard uslov: Chrome verzija mora biti 144 ili više. chrome://inspect/#remote-debugging ova stranica i odgovarajući remote debug dozvola UI je Chrome 144 uveo. Ispod ove verzije Chrome-a otvaranje ove adrese će vidjeti samo praznu stranicu.
Vidi tvoju Chrome verziju: u adresnoj traci unesi chrome://version, prvi red je broj verzije.

06, Mehanizam zaštite osetljivih stranica
U shared režimu Agent ima tvoje prave naloge dozvole, ovo je dvostrivi mač.
Kažeš mu da pročita kod GitHub repozitorijuma, nema problema. Ali ako ode na GitHub Settings i nasumce klikće, ili na Alipay stranici izvršava neki JavaScript skript, to je katastrofa.
PaiCLI rešenje je BrowserGuard + SensitivePagePolicy, skup politike sloja bezbednosnog mehanizma.
SensitivePagePolicy ugrađuje 14 podrazumevanih pravila osetljivog URL-a, koristi glob način poklapanja:
private static final List<String> DEFAULT_PATTERNS = List.of(
"*://*.bank.*/*",
"*://*.alipay.com/*",
"*://*.paypal.com/*",
"*://*.stripe.com/*",
"*://github.com/settings/*",
"*://*.feishu.cn/admin/*",
"*://*.larksuite.com/admin/*",
"*://*.console.cloud.google.com/*",
"*://*.console.aws.amazon.com/*",
"*://*.portal.azure.com/*"
// ... još nekoliko
);Banka, Alipay, PayPal, GitHub Settings, Feishu admin pozadina, cloud servis konzola, ova mesta jednom se pogrešno operiše, posledice mogu biti vrlo ozbiljne.
Logika poklapanja je pretvaranje glob u regex, neosetljivo na velika i mala slova:
private static String globToRegex(String glob) {
StringBuilder regex = new StringBuilder("^");
for (int i = 0; i < glob.length(); i++) {
char c = glob.charAt(i);
switch (c) {
case '*' -> regex.append(".*");
case '?' -> regex.append('.');
default -> regex.append(Pattern.quote(String.valueOf(c)));
}
}
regex.append('$');
return regex.toString();
}Ako podrazumevana pravila nisu dovoljna, još uvek možeš u ~/.paicli/sensitive_patterns.txt dodati prilagođena pravila, jedan red jedan glob, # početak je komentar. Na primer kompanijski intranet admin pozadina:
# Kompanijski interni sistemi
*://admin.mycompany.com/*
*://erp.mycompany.com/*PaiCLI start-up-a čita ovaj fajl, sa podrazumevanim pravilima spaja. Ako fajl ne postoji, nema problema, neće prijaviti grešku.

Nakon što pogodi osetljivu stranicu, BrowserGuard radi graničnu obradu.
Alati za čitanje (take_snapshot, take_screenshot, list_pages itd.) nisu pogođeni, i dalje prolaze kroz server puno propuštanja. Jer operacije čitanja ne menjaju stanje stranice, rizik je kontrolabilan.
Alati za izmenu će se nadograditi na obavezno korak-po-korak odobrenje. Ova lista je definisana u BrowserGuard.WRITE_TOOLS:
private static final Set<String> WRITE_TOOLS = Set.of(
"click", "drag", "fill", "fill_form",
"handle_dialog", "hover", "press_key",
"resize_page", "upload_file", "evaluate_script"
);click, fill, evaluate_script ove operacije koje mogu promeniti stanje stranice, jednom se izvrše na osetljivoj stranici, svaki put će iskočiti HITL odobrenje prozor, i ne prikazuje "odobri sve" opciju:
⚠️ Detektovana osetljiva stranica, ova operacija treba zasebnu potvrdu (ne prihvća "odobri sve")
Trenutni URL: https://github.com/settings/profile
Poklapanje pravila: *://github.com/settings/*
Izaberite operaciju: [y/Enter] Odobri [n] Odbij [s] Preskoči [m] Izmeni parametreNakon napuštanja osetljive stranice (Agent skače na ne-oesetljiv URL), server puno propuštanje automatski se obnavlja, ne treba korisniku ponovo birati.
Verifikacija zaštite osetljivih stranica:
Osiguraj da si već izvršio /browser connect, zatim:
Otvori https://github.com/settings/profile da vidim moje lične informacijeAgent poziva navigate_page da skače na Settings stranicu, videćeš HITL odobrenje prozor, podsseteće "detektovana osetljiva stranica". Nakon odobrenja, Agent će koristiti take_snapshot da pročita sadržaj stranice (operacije čitanja ne iskačuju prozor). Ako Agent hoće da izvrši click ili fill da izmeni informacije, opet će iskočiti prozor.
07, Sprečavanje nehotičnog zatvaranja kartica
U shared režimu postoji još jedan rizik: Agent može zatvoriti tvoju karticu koju koristiš.
Ti imaš otvorenih 7 kartica na radu, GitHub PR je treći, Feishu dokument je peti. Nakon što Agent završi zadatak hoće "počistiti", pozvao close_page i zatvorio tvoj GitHub.
Ovakve stvari apsolutno ne mogu da se dese.
PaiCLI rešenje je u BrowserSession održavati agentOpenedTabs skup, beleži kartice ID koje je Agent sam otvorio kroz new_page:
private final Set<String> agentOpenedTabs = new LinkedHashSet<>();
public synchronized void recordOpenedTab(String pageId) {
if (pageId != null && !pageId.isBlank()) {
agentOpenedTabs.add(pageId);
}
}
public synchronized boolean isAgentOpenedTab(String pageId) {
return pageId != null && agentOpenedTabs.contains(pageId);
}Nakon što Agent pozove new_page da otvori novu karticu, BrowserGuard.applyAfterExecution() će iz povratnog rezultata parsirati pageId i zabeležiti. Zatim kad Agent pozove close_page, BrowserGuard.check() će proveriti da li je ciljni pageId u agentOpenedTabs:
if ("close_page".equals(localTool)
&& session.mode() == BrowserMode.SHARED
&& !session.isAgentOpenedTab(pageId(args))) {
return BrowserCheckResult.block(
"shared pregledač režim odbija zatvaranje ne-PaiCLI kreiranih kartica, molim ručno zatvori ovu Chrome karticu",
metadata);
}Verifikacija zaštite kartica:
Prvo u Chrome-u ručno otvori nekoliko stranica, zatim u PaiCLI:
Pomozmi mi da zatvorim karticu Zhishi XingqiuAgent će pokušati pozvati close_page, zatim blokira na sloju politike, vraća "politika odbijena".

08, Nadogradnja prompt-a
Agent-ov sistem prompt takođe treba sinhronizovano nadograditi, ne zna šta treba raditi u shared režimu.
Tri mesta prompt-a (Agent, PlanExecuteAgent, SubAgent) su dodala jedan odeljak:
Prijavljeno stanje pregledača:
- Podrazumevano isolated režim: privremeni user-data-dir, nema cookie / prijavljeno stanje
- Nakon što korisnik izvrši /browser connect ulazi u shared režim: ponovna upotreba debug Chrome-a sa prijavljenim stanjem
- U shared režimu stranice koje vidiš su pravi prikazi korisničkog naloga
- Ne radij pisanje koje korisnik nije eksplicitno zatražio: ne klikni prati/otprati prati/obriši/izloguj/promeni postavke itd dugmad
- Ne popunjavaš u forme podatke koje korisnik nije dao
- Ne izvršavaj evaluate_script da pokrene skriptu koju korisnik nije zatražio
- close_page može samo zatvoriti karticu koju si sam new_page kreirao
- Ako nisi siguran da li neka operacija će uticati na korisničke podatke naloga, prvo pitaj korisnika potvrdu09, Kako PaiCLI napisati na CV-u
Naziv projekta: PaiCLI — Session-Aware Browser Agent CLI
Opis projekta: Komandna linija AI Agent-a bazirana na Javi, podržava Chrome DevTools MCP isolated/shared dvostruki režim rada, dok ponovno upotrebljava korisnički pravi pregledač prijavljeno stanje, kroz mehanizam politike osetljivih stranica i zaštite kartica osigurava bezbednost naloga.
Glavne odgovornosti:
- Dizajn i implementacija
BrowserSessionmenedžera stanja sesije pregledača, podržava isolated/shared dvostruki režim runtime prebacivanje, primenjuje synchronized mehanizam sinhronizacije osigurava konzistentnost stanja više niti - Implementacija CDP automatskog mehanizma povezivanja, Agent detektuje da treba prijavljeno stanje kroz
--autoConnectautomatski otkriva i povezuje lokalnu mašinu uključen remote debug Chrome instancu, neuspešno prebacivanje automatski degradira nazad u isolated režim - Dizajn
BrowserGuardsloja izvršenja politike, na 28 chrome-devtools alata poziv implementira graničnu bezbednosnu proveru, alati za izmenu pri pogodjenoj osetljivoj stranici prisilno korak-po-korak HITL odobrenje, zaobilazi server puno propuštanje dozvolu - Implementacija
SensitivePagePolicymotora prepoznavanja osetljivih stranica, ugrađuje 14 podrazumevanih glob pravila pokriva banku, plaćanje, cloud konzolu itd. visoko rizične scenare, podržava korisnički nivo~/.paicli/sensitive_patterns.txtpravila dodavanje - Dizajn mehanizma praćenja vlasništva kartica, kroz
agentOpenedTabsskup beleži kartice ID koje je Agent sam kreirao, u shared režimuclose_pagetv zaštita blokira operaciju zatvaranja kartica koje nisu samokreirane

