A coding agent can write a web application in minutes and then has no way to look at it. It cannot open a browser, click through the flow it just built, or notice that the layout breaks at 390 pixels. This project gives it one: a Model Context Protocol server that connects Claude to TestGrid’s device cloud, so the agent can launch the app it just wrote in a real remote browser and explore it, with no deployment step in between.
What the server exposes
MCP is a way for a model to call tools with typed inputs and get structured results back. The server exposes device-cloud sessions as tools: start a browser session, open a URL, interact with the page, read back what happened, end the session. The design decision that mattered was granularity. Tools describe outcomes, not clicks. An agent handed twenty low-level primitives spends its context on choreography; handed a small number of higher-level tools, it spends it on judgement about what to check next.
The tunnel
The application usually runs on the developer’s machine, and a browser in the cloud cannot reach a laptop. The bridge is secure reverse tunnelling: the local app is exposed to TestGrid’s infrastructure over an authenticated tunnel, and the remote browser sees it as if it were deployed. This builds on tunnelling software I had built earlier for the platform, which exposes locally hosted applications to remote test infrastructure with multi-server support so that distributed execution can run against private environments. For the agent it means the loop is write, look, fix, without a build and deploy step breaking the rhythm.
Agent-initiated sessions
The difference from a scripted harness is who decides what happens next. A script executes a fixed sequence; the agent decides what to look at based on what it sees. That changes what the server has to return. State comes back as structured text a model can reason over, not as a screenshot alone. Errors are explained rather than coded, because an agent that reads “session limit reached, end one before starting another” recovers, while one that reads “E429” loops. And the session lifecycle is explicit: everything an agent can start it can stop, and the server stops it anyway after a timeout, because an agent will eventually forget.
What it taught
- Tool granularity is prompt design. The shape of the tools decides what the agent spends its attention on.
- Give the agent the user’s environment. A real browser on a real network finds what a mocked one never will.
- Make failure legible. An error message written for a model is different from one written for a log.
- Bound everything. Sessions, time, retries. An agent without limits will find them for you.