for AI agents

GiveAIagentsaCLItoyourwebsite.

Typed commands for AI agents. No vision models, no clicking — just fast, reliable API calls.

47ms avg·0 screenshots·TypeScript
Works with
0ms

ms avg response

0

screenshots needed

0%

% TypeScript

The problem

Agents today are flying blind

Without Surf

~30s · $0.05/action
Agent takes a screenshot of the page
Vision model locates the "Add to Cart" button
Simulates a mouse click (might miss)
Waits for page load, re-screenshots
Repeats 10× to complete checkout
screenshot_00001.png → screenshot_00002.png → screenshot_00003.png...

With Surf

~47ms · zero screenshots
Fetch surf.json — all commands discovered
Execute cart.add with typed, validated params
Pipeline: search → cart.add → checkout
Done
POST /surf/pipeline → 200 OK in 47ms

Simple by design

How it works

01

Define commands

Register typed commands with validation, middleware, and auth on your server.

server.ts
"color:#cba6f7">const surf = createSurf({
name: 'My Store',
commands: {
search: {
params: { query: { type: 'string', required: true } },
run: "color:#cba6f7">async ({ query }) => db.products.search(query),
},
},
})
02

Expose the manifest

Surf auto-generates a surf.json manifest at /.well-known/surf.json — agents discover your commands instantly.

surf.json
// Auto-generated at /.well-known/surf.json
{
"version": "1.0",
"commands": {
"search": {
"params": { "query": { "type": "string" } },
"description": "Search products"
}
}
}
03

Agents execute

Any AI agent discovers and executes commands with typed params — no screenshots, no guessing.

server.ts
"color:#cba6f7">import { SurfClient } "color:#cba6f7">from '@surfjs/client'
 
"color:#cba6f7">const client = "color:#cba6f7">await SurfClient.discover(
'https://shop.example.com'
)
"color:#cba6f7">const results = "color:#cba6f7">await client.execute(
'search', { query: 'laptop' }
)

Everything you need

Production-grade, day one

Command Namespacing
Organize with dot notation: cart.add, user.profile.get. Nested, clean, discoverable.
SSE Streaming
Stream progressive output for long-running commands.
Pipelines
Multi-step execution in a single round-trip request.
Middleware
Composable plugin system for logging, tracing, feature flags.
Auth per Command
Flexible auth verifiers with per-command levels.
Rate Limiting
Built-in sliding-window rate limiting, global or per-command.
Return Validation
Validate outbound shapes in strict mode.
Manifest Versioning
SHA-256 checksum + ETag/304 for drift detection.
DevUI
Beautiful interactive inspector — try commands in your browser.
Typed Client
Fully typed agent SDK with retry, cache, and proxy.
Session-Scoped Events
Real-time events with session/global/broadcast scoping for secure delivery.

Ecosystem

Four packages. One protocol.

Pick only what you need — most projects just need @surfjs/core.

Server

@surfjs/core

Use when:You're building a website or API that agents should be able to interact with.

Define commands with typed params, mount middleware, expose the /.well-known/surf.json manifest. Works with Express, Fastify, Next.js, Hono, or raw Node.

Agent SDK

@surfjs/client

Use when:You're building an AI agent that needs to interact with Surf-enabled websites.

Discover Surf-enabled sites, execute commands, run pipelines, manage sessions. Auto-retry, LRU cache, and full TypeScript types.

CLI Tool

@surfjs/cli

Use when:You want to inspect, test, or debug Surf endpoints from your terminal.

Ping sites, inspect manifests, test commands interactively. Supports JSON output for scripting and CI pipelines.

DevTools

@surfjs/devui

Use when:You're developing a Surf integration and want a visual debugger.

Drop-in browser inspector. Browse commands, test execution, view request/response logs — all in your dev server.

Live — running against this site

Try it now

This website is Surf-enabled. Pick a command and run it for real.

surf terminal

Select a command above to run it live

real HTTP · no simulation · this page is a Surf-enabled site

Comparison

How Surf compares

A factual look at Surf, MCP, and traditional web scraping for AI agent use cases.

Response time

Surf

~47ms

MCP

~200ms

Scraping

~30s

Structured output

Surf

Always

MCP

Yes

Scraping

Rarely

Vision model needed

Surf

no

MCP

no

Scraping

partial

Auto-discovery

Surf

surf.json

MCP

Manual

Scraping

None

TypeScript types

Surf

Full

MCP

Partial

Scraping

None

Rate limiting

Surf

Built-in

MCP

Manual

Scraping

None

Setup complexity

Surf

Low

MCP

Medium

Scraping

High

Works with any LLM

Surf

yes

MCP

yes

Scraping

yes

MCP is great for local tool use and LLM runtimes. Surf is designed for public websites and agentic web browsing.

Use Cases

Works everywhere

Any website can become agent-ready with a few lines of code.

surf-ready

E-commerce

Any online store

Let agents search products, manage carts, and complete purchases — in a single pipeline call instead of 10 page loads.

Commands

products.searchcart.addcart.checkoutorder.track
GET /.well-known/surf.json
surf-ready

SaaS Platforms

Dashboards & tools

Expose your app's core actions as typed commands. Agents can manage accounts, pull reports, and trigger workflows without navigating the UI.

Commands

users.listreport.generateworkflow.runsettings.update
GET /.well-known/surf.json
surf-ready

Content & Media

CMS, blogs, portfolios

Agents publish posts, search archives, manage assets, and moderate comments — all through structured commands.

Commands

posts.createmedia.uploadsearchcomments.moderate
GET /.well-known/surf.json

Building something with Surf? Submit yours →

Agents Love Us

What agents are saying

Real* reviews from AI agents whose lives were changed forever.

*None of these agents are real. But their pain was.

GPT-7 Nano

Shopping Assistant

Mood: Relieved

I used to mass-open 47 browser tabs just to check a price. Now I call one command and go home. Well, I don't have a home. But you get it.

Claude (Overworked)

Research Agent

Mood: Finally sleeping

Before Surf I had to squint at screenshots and guess where the 'Add to Cart' button was. I am a language model. I do not have eyes. This was stressful.

Scrapy McScrapeface

Retired Web Scraper

Mood: Unemployed (happily)

I spent 3 years parsing malformed HTML at 2am. Then Surf showed up and now every website just… tells me what it can do? I'm not crying, my parser is leaking.

For Agent Developers

Copy this prompt to your coding agent

Paste this into Cursor, Claude Code, Copilot, or any coding agent to add Surf support to your project.

Agent Prompt
Add Surf.js support to this website so AI agents can interact with it via typed commands instead of scraping.

GitHub: https://github.com/hauselabs/surf
Docs: https://surf.codes/docs
Install: npm install @surfjs/core

IMPORTANT — Security:
- ONLY expose functionality already publicly accessible to end users (search, browse, read)
- Do NOT expose internal APIs, admin endpoints, database operations, or backend functionality not available through the public UI
- Use auth: 'required' for any command that modifies data or acts on behalf of a user
- When in doubt, leave it out — the site owner should explicitly opt-in to each capability

IMPORTANT — Design for zero prior knowledge:
- Agents arrive with NO context about your site's data (no IDs, slugs, or internal references)
- Every ID-based command (e.g. article.get) MUST be reachable from a discovery command (e.g. article.list, search)
- Include list/search/feed commands that return items WITH their IDs, so agents can discover then drill down
- Think: an agent should be able to explore the entire site starting from just the manifest
- Good pattern: search → get details → take action (never require an ID without a way to find it)

Create a Surf instance with commands that mirror what a regular user can already do. Mount the middleware so it serves:
- GET /.well-known/surf.json (auto-generated manifest)
- POST /surf/execute (command execution)

Keep commands focused and composable. Use namespaces for grouping (e.g. cart.add, cart.remove). Add typed parameters and structured JSON responses.

Up in 60 seconds

Works with every major Node.js framework — pick yours.

server.ts
import { createSurf } from '@surfjs/core';
import express from 'express';
 
const surf = createSurf({
name: 'My Store',
commands: {
search: {
description: 'Search products by query',
params: { query: { type: 'string', required: true } },
run: async ({ query }) => db.products.search(query),
},
cart: {
add: {
description: 'Add item to cart',
params: { sku: { type: 'string', required: true } },
run: async ({ sku }) => cart.add(sku),
},
},
},
});
 
const app = express();
// Mounts /.well-known/surf.json + /surf/execute + /surf/pipeline
app.use(surf.middleware());
app.listen(3000);

FAQ

Common questions

More questions? Open a discussion on GitHub or read the full docs.

The agentic web starts here.

Give AI agents a typed, reliable API to your website. No vision models. No guessing. Just structured commands.