S22 Web Agent MCP Server
Allows integration with ChatGPT Custom App through OpenAI Secure MCP Tunnel, enabling AI agents to perform web scanning and browser inspection via MCP tools.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@S22 Web Agent MCP Serverscan example.com"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
S22 Web Agent
S22 Web Agent repurposes a Samsung Galaxy S22 into a controlled, self-hosted MCP and browser-automation execution node.
Samsung S22
-> Termux
-> Node.js API and MCP servers
-> SQLite local persistence
-> Debian proot
-> Playwright + Chromium
-> VNC/noVNC for human-controlled login
-> controlled tunnels when intentionally enabledThe project is a learning and portfolio proof for applied AI automation, MCP tool development, secure browser workflows, and constrained-device engineering.
Current status
Latest completed runtime proof:
Phase 7O-E — long-gap session continuity: PASSThe real GitHub dummy profile github-manual-local remained authenticated after a full S22 power-off/restart and approximately one week offline. It was reused headlessly without starting VNC/noVNC and without logging in again.
Current engineering phase:
Phase 7P — operator-quality profile lifecycle helpersImplementation status:
session:profile:status: addedsession:profile:probe: addedsession:profile:ensure: addedsession:profile:self-test: addedstatic JavaScript and shell syntax checks: PASS
local file-state classifier test: PASS
live S22 Debian/Chromium verification: pending operator run
Phase 7P is therefore implemented but not yet marked fully PASS.
Related MCP server: Playwright MCP
Current capabilities
CLI and HTTP webpage scanning
SQLite-backed scan history
Markdown report generation
MCP stdio and Streamable HTTP
stateful MCP HTTP sessions
optional bearer-token protection
Cloudflare Route A public MCP proof
OpenAI Secure MCP Tunnel proof
Debian proot Playwright/Chromium worker
browser-rendered inspection through MCP
manual login through VNC
stable tmux-held VNC
local noVNC gateway
temporary public noVNC proof protected by Cloudflare Access
Playwright
storageStatecapturenamed local session profiles
domain-allowlisted authenticated scans
MCP
browser_scan_with_profilereal GitHub dummy-account login and reuse
session continuity after S22 restart and a long offline gap
explicit saved-profile lifecycle states
Project positioning
S22 Web Agent is not intended to become a broad personal-agent framework. It is a controlled execution node that exposes approved MCP tools while keeping local services and browser session artifacts private.
ChatGPT / Codex / another MCP client
-> approved MCP tools
-> S22 Web Agent
-> local scanner or browser workflowSee docs/why-custom-s22-web-agent.md for the detailed rationale.
Architecture
Scanner path
CLI or local HTTP request
-> scanner module
-> SQLite
-> Markdown reportBrowser path
MCP browser tool or local helper
-> Termux wrapper
-> Debian proot Playwright worker
-> ChromiumAuthenticated session path
Human-controlled login through VNC/noVNC
-> Playwright storageState saved under .runtime/
-> named profile with domain allowlist
-> future headless authenticated scansPasswords, cookies, tokens, MFA codes, and storageState contents are not passed to the AI assistant.
Route A public MCP path
Remote MCP client
-> https://s22agent.aidesk.rest/mcp
-> Cloudflare Named Tunnel
-> 127.0.0.1:3003/mcpOnly the MCP HTTP server is exposed in Route A.
Temporary public noVNC path
Remote browser
-> Cloudflare Access protected temporary hostname
-> cloudflared connector on S22
-> 127.0.0.1:6080 noVNC
-> 127.0.0.1:5901 VNC
-> Debian ChromiumThis route is separate from the MCP hostname. It must remain temporary, protected, human-controlled, and intentionally started.
Ports and exposure policy
Port | Service | Exposure rule |
| Local HTTP API | Never public |
| Debian Playwright worker | Never public |
| MCP Streamable HTTP | Intentional protected MCP route only |
| Raw VNC | Local-only; never public |
| noVNC/websockify | Local-only by default; temporary protected route only |
| Demo login server | Local-only |
Security boundary
Never request or print passwords.
Never request or print cookies.
Never request or print session tokens.
Never request or print MFA codes.
Never print or paste
storageState.jsoncontents.Keep
.runtime/sessions/out of Git.Keep ports
3001,3002, and5901local-only.Expose port
3003only through an intentional controlled MCP route.Keep public noVNC temporary and intentionally started.
Never auto-start public noVNC as a fallback.
Keep tunnel tokens and MCP tokens out of the repository.
Rotate the Cloudflare tunnel token before future public tests because it appeared in early raw logs before helper hardening.
Do not upgrade npm to a new major version during this phase merely because an update notice appears.
The current Termux installation is from Google Play; do not propose F-Droid migration by default.
Runtime artifacts ignored by Git:
.runtime/
data/
reports/
*.log
.envMain operating modes
Local CLI/API
node src/index.js scan example.com
npm run api:start
npm run api:status
npm run api:stopDefault API endpoint:
http://127.0.0.1:3001MCP stdio
npm run mcpMCP Streamable HTTP
npm run mcp:http:start
npm run mcp:http:status
npm run mcp:http:stopDefault endpoint:
http://127.0.0.1:3003/mcpRoute A Cloudflare MCP
npm run route:a:start
npm run route:a:status
npm run route:a:stopPublic endpoint:
https://s22agent.aidesk.rest/mcpOpenAI Secure MCP Tunnel
npm run openai:tunnel:start
proot-distro login debian
cd /data/data/com.termux/files/home/projects/mobile-job-radar-agent
npm run openai:tunnel:client:debianStatus and stop:
npm run openai:tunnel:status
npm run openai:tunnel:stopThe runtime key is prompted locally and is not stored in the repository.
Session helpers
VNC and noVNC
npm run session:vnc:start
npm run session:vnc:status
npm run session:vnc:stop
npm run session:vnc:start:stable
npm run session:vnc:stop:stable
npm run session:novnc:start:local
npm run session:novnc:status:local
npm run session:novnc:stop:localHuman-controlled local login
SESSION_LOGIN_TIMEOUT_MS=1200000 npm run session:manual-login:novnc:start -- <profile> <login-url>
npm run session:manual-login:novnc:status -- <profile>
SESSION_SCAN_SUPPRESS_EXCERPT=1 npm run session:manual-login:novnc:complete -- <profile> <authenticated-url> "<expected-text>"
npm run session:manual-login:novnc:cancel -- <profile>Existing profile scan
SESSION_SCAN_SUPPRESS_EXCERPT=1 npm run session:profile:scan -- <profile> <url> "<expected-text>"Phase 7P profile lifecycle
A profile file existing locally does not prove that the remote website session is still authenticated.
States
missing
present_unverified
valid
expired_or_logged_out
domain_mismatch
runtime_errorExit codes:
State | Code |
|
|
|
|
|
|
|
|
|
|
|
|
Lightweight status
Does not launch Chromium:
npm run session:profile:status -- <profile> [target-url]An existing readable profile normally returns:
present_unverifiedLive authenticated probe
Launches headless Chromium inside Debian proot and requires an authenticated marker:
npm run session:profile:probe -- <profile> <authenticated-url> "<expected-text>"marker found -> valid
marker not found -> expired_or_logged_outPage text excerpts are suppressed by design.
Reuse-first ensure
npm run session:profile:ensure -- <profile> <authenticated-url> "<expected-text>" [login-url]ensure checks local status first and then performs a live probe. When refresh is required, it prints safe local manual-login guidance with URL placeholders. It does not echo supplied URLs and does not start VNC, noVNC, Cloudflare, or any public route.
Local self-test
npm run session:profile:self-testThe disposable test covers:
missing
present_unverified
domain_mismatch
runtime_errorIt does not touch a real profile.
Detailed implementation and test instructions:
docs/phase-7p-profile-lifecycle-helpers.mdRequired S22 verification
After pulling the latest main branch:
cd ~/projects/mobile-job-radar-agent
git pull --ff-only
npm run session:profile:self-test
npm run session:profile:status -- github-manual-local https://github.com/settings/profile
npm run session:profile:probe -- github-manual-local https://github.com/settings/profile "Public profile"
npm run session:profile:ensure -- github-manual-local https://github.com/settings/profile "Public profile" https://github.com/login
git status --shortExpected while the GitHub dummy session remains authenticated:
self-test -> PASS
status -> present_unverified
probe -> valid
ensure -> valid
git status --short -> no outputThese checks do not require VNC, noVNC, or a public tunnel.
MCP tools
job_radar_health
job_radar_scan
job_radar_list_pages
job_radar_get_page
job_radar_get_report
browser_inspect_url
browser_scan_url
browser_scan_with_profile
browser_start_manual_login
browser_manual_login_status
browser_complete_manual_login
browser_cancel_manual_loginThe authenticated profile MCP tool accepts only a named profile, target URL, and optional expected text. It does not accept passwords, cookies, tokens, or an arbitrary storageState path.
Session-gateway milestones
Phase | Result |
7A | Session gateway design documented |
7B | Cookie JSON path deferred |
7C | VNC baseline, capture, and local reuse passed |
7D | Profile-aware headless scan passed |
7E | Proof guard hardening passed |
7F | MCP profile scan integration passed |
7G | Pre-login security cleanup completed |
7H | Real GitHub dummy login and scan passed |
7I | Stable tmux VNC and repeated verification passed |
7J | Remote login gateway design documented |
7K | Local noVNC proof passed |
7L | Public HTTPS noVNC design documented |
7M | Local noVNC-assisted manual login passed |
7N | Cloudflare Access public noVNC demo proof passed |
7O | Saved-profile continuity passed |
7O-E | Full restart plus approximately one week offline passed |
7P | Implemented; live S22 verification pending |
Important documentation
docs/phase-7o-e-long-gap-session-continuity.md
docs/phase-7p-profile-lifecycle-helpers.md
docs/phase-7o-agent-continuity-proof.md
docs/phase-7n-temporary-cloudflare-access-novnc-proof.md
docs/phase-7m-local-novnc-assisted-manual-login.md
docs/session-gateway-design.md
docs/why-custom-s22-web-agent.mdFor AI-assisted repository navigation, see llm-index.yaml.
Known limitations
Android may kill Termux under heavy runtime load.
tmux protects against SSH disconnect but not Android terminating Termux.
AnyDesk, SSH, VNC, noVNC, and Chromium together can make the S22 unstable.
A saved profile may exist while the remote session is expired.
Websites can revoke or challenge sessions independently.
An absent expected marker can also mean the target page content changed;
expired_or_logged_outis deliberately a fail-safe classification.Browser performance is limited by phone hardware, thermal behavior, and proot overhead.
The project is a controlled engineering proof, not a production-grade managed server.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/amir89hamzah/s22-web-agent'
If you have feedback or need assistance with the MCP directory API, please join our Discord server