For agents in iMessage, SMS, WhatsApp, Telegram, Slack and email
Give your text agent a real interface.
Agents now work inside text apps, but they can’t build their own interface there. With one tool, Page Systems gives your agent a page to share with the user, so it can collect input that is awkward to gather in a text chat.
Users ask in text. “Find me a flight to New York on Nov 3.”
Your agent sends a page. The link unfurls with a preview of the options.
They tap and pick. A real flight picker, not a numbered list.
The answer is returned. Into the same thread, and the agent keeps going.
The problem
Text is a bad place to make a plan.
Agents are finding a home in the text apps people already use. Chat is fine for conversations, but it breaks down when the person has to compare, pick, or fill in details.
- Long lists the user can’t keep track of. “1) Lotus Thai Kitchen, $$, 0.4 mi: 6:30, 7:00, 7:30… 2) Ember & Stone…” The user scrolls up, loses track, and asks again.
- Back-and-forth to fix small things. A booking that is no longer available, a confirmation to spend on a card, a variation on a purchase. Each is another round trip with the user.
- A real UI, without building one. Page Systems makes it simple to give your users a real UI from their text agent.
How it works
One tool call. A real page. The answer comes back.
No frontend to build, no hosting, no glue code. A page is a link, so it works anywhere your agent can send one.
- iMessage
- SMS
- Slack
- Telegram
- Voice, link by text
Your agent create_page()
- Dinner on Fridayrestaurant_picker
- Review your cartcheckout
- Delivery detailsform
- Lisbon long weekenditinerary
↺ The answer returns to the same conversation
- 01
Your agent sends the data
It finds options, times or guests with the tools it already has, then calls
create_pagewith a typed spec. - 02
We render and host the page
A mobile or desktop page built for that task, with your name and color, and a link preview that shows the options before anyone taps.
- 03
The data comes back seamlessly
When the user submits, your agent is notified at its callback and reads the answer with
get_page_result, in the same conversation.
Page types
Your text agent can do a lot more now.
Each page type is built for one kind of decision. The phone runs the real page: submit it and the agent replies.
Photos, ratings and open times. Pick a place and a time in one step.
restaurant_pickerTimes, stops and prices side by side. Pick one flight.
flight_pickerPhotos, prices and policies, with one marked Recommended.
hotel_pickerPhotos, colors and sizes, with sold-out sizes greyed out.
productA photo grid with prices and filters. Pick the one you like.
product_listA calendar for a stay, with nightly prices on each day.
date_rangeOpen times by day, with taken ones greyed out.
time_slotsNumbers as charts: trends, comparisons and a headline figure.
chartItems and a total to check before your agent orders. No payment on the page.
checkoutA day-by-day plan with times and places. Approve it or ask for changes.
itineraryRows to sort and compare, with one to pick.
tableCollect details like a name, a phone number and a delivery window.
formThree places have a table for four on Friday. Pick one:
What agents use it for
Small decisions, every day.
Most of what an agent asks users to do is small: pick, compare, choose a time, review an order, fill in. Each one is a single, beautiful page.
Pick dinner for four
Three places have a table for four on Friday. Pick one:
Choose a color and size
The linen shirt you asked about comes in three colors. Pick one:
Compare the options
I compared standing desks under $800. Pick the one you want:
Find a time that works
The Corner Table has these tables open. Which time?
Pick the dates
Harbor Light has rooms most nights this month. Which dates?
Review a cart
Your mug and coffee reorder is in a cart. Check it here:
Collect the details
I need a few details to schedule your couch delivery.
Pick a hotel for the trip
Here are hotels for your three nights. One includes breakfast.
The story
Why we built it
While building Partyline, we discovered that booking flights and reservations was a frustrating, many-turn back and forth over text. Page Systems solves that with a great experience.
Dennison BertramFounder, PartylineInstall
Three steps to your first page.
- 1
Import the package.
Install it from npm or pip, or connect over MCP.
- 2
Add it to your agent.
A few lines give your agent the Page Systems tools.
- 3
Your agent handles the rest.
It sends a page when a page beats a chat question, and reads the answer when the user submits.
Read the install guide · llms.txt for coding agents
$ npm install @pagesystems/eve
// agent/extensions/pages.ts
export { default } from "@pagesystems/eve";
# .env.local (and your Vercel project)
PAGE_SYSTEMS_API_KEY=ap_live_...export PAGE_SYSTEMS_API_KEY=ap_live_...
claude mcp add --transport http page-systems https://pagesystems.ai/mcp --header "Authorization: Bearer $PAGE_SYSTEMS_API_KEY"$ npm install @pagesystems/ai-sdk
export PAGE_SYSTEMS_API_KEY=ap_live_...
import { pageSystemsTools, getPageSystemsSkill } from '@pagesystems/ai-sdk';
import { generateText, isStepCount } from 'ai';
const skill = await getPageSystemsSkill(); // once, when the agent starts
const result = await generateText({
model,
system: [yourInstructions, skill].join('\n\n'),
messages,
tools: pageSystemsTools(),
stopWhen: isStepCount(6),
});$ npm install @openai/agents
export PAGE_SYSTEMS_API_KEY=ap_live_...
import { Agent, MCPServerStreamableHttp, run } from '@openai/agents';
const skill = await fetch('https://pagesystems.ai/v1/skill').then((r) => r.text()); // once, at startup
const pageSystems = new MCPServerStreamableHttp({
name: 'page-systems',
url: 'https://pagesystems.ai/mcp',
requestInit: { headers: { Authorization: `Bearer ${process.env.PAGE_SYSTEMS_API_KEY}` } },
cacheToolsList: true,
});
await pageSystems.connect();
const agent = new Agent({ name: 'Assistant', instructions: [yourInstructions, skill].join('\n\n'), mcpServers: [pageSystems] });$ npm install @anthropic-ai/claude-agent-sdk
export PAGE_SYSTEMS_API_KEY=ap_live_...
import { query } from '@anthropic-ai/claude-agent-sdk';
const skill = await fetch('https://pagesystems.ai/v1/skill').then((r) => r.text()); // once, at startup
for await (const message of query({
prompt: userMessage,
options: {
systemPrompt: [yourInstructions, skill].join('\n\n'),
mcpServers: {
'page-systems': {
type: 'http',
url: 'https://pagesystems.ai/mcp',
headers: { Authorization: `Bearer ${process.env.PAGE_SYSTEMS_API_KEY}` },
},
},
allowedTools: ['mcp__page-systems__*'],
},
})) {
if (message.type === 'result') console.log(message.subtype === 'success' ? message.result : message.errors);
}$ pip install langchain langchain-mcp-adapters langgraph
export PAGE_SYSTEMS_API_KEY=ap_live_...
import os
import urllib.request
from langchain.agents import create_agent
from langchain_mcp_adapters.client import MultiServerMCPClient
skill = urllib.request.urlopen("https://pagesystems.ai/v1/skill").read().decode() # once, at startup
client = MultiServerMCPClient({
"page-systems": {
"transport": "http",
"url": "https://pagesystems.ai/mcp",
"headers": {"Authorization": f"Bearer {os.environ['PAGE_SYSTEMS_API_KEY']}"},
}
})
agent = create_agent(
model,
await client.get_tools(),
system_prompt=your_instructions + "\n\n" + skill,
)$ npm install @mastra/mcp
export PAGE_SYSTEMS_API_KEY=ap_live_...
import { Agent } from '@mastra/core/agent';
import { MCPClient } from '@mastra/mcp';
export const pageSystems = new MCPClient({
servers: {
'page-systems': {
url: new URL('https://pagesystems.ai/mcp'),
requestInit: { headers: { Authorization: `Bearer ${process.env.PAGE_SYSTEMS_API_KEY}` } },
},
},
});
const skill = await fetch('https://pagesystems.ai/v1/skill').then((r) => r.text()); // once, at startup
export const assistant = new Agent({
id: 'assistant',
name: 'Assistant',
instructions: [yourInstructions, skill].join('\n\n'),
model,
tools: await pageSystems.listTools(),
});$ pip install "google-adk[mcp]"
export PAGE_SYSTEMS_API_KEY=ap_live_...
import os
import urllib.request
from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool import McpToolset
from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParams
skill = urllib.request.urlopen("https://pagesystems.ai/v1/skill").read().decode() # once, at startup
page_systems = McpToolset(
connection_params=StreamableHTTPConnectionParams(
url="https://pagesystems.ai/mcp",
headers={"Authorization": f"Bearer {os.environ['PAGE_SYSTEMS_API_KEY']}"},
)
)
root_agent = LlmAgent(
name="assistant",
model=model, # e.g. a Gemini model name, or LiteLlm(...) for other providers
instruction=lambda ctx: your_instructions + "\n\n" + skill,
tools=[page_systems],
)$ pip install crewai "pydantic[email]"
export PAGE_SYSTEMS_API_KEY=ap_live_...
import os
import urllib.request
from crewai import Agent, Crew, Task
from crewai.mcp import MCPServerHTTP
skill = urllib.request.urlopen("https://pagesystems.ai/v1/skill").read().decode() # once, at startup
assistant = Agent(
role="Assistant",
goal="Get answers from people by sending them a page instead of a long chat question.",
backstory=your_backstory + "\n\n" + skill,
llm=llm,
mcps=[
MCPServerHTTP(
url="https://pagesystems.ai/mcp",
headers={"Authorization": f"Bearer {os.environ['PAGE_SYSTEMS_API_KEY']}"},
cache_tools_list=True,
)
],
)$ pip install pydantic-ai
export PAGE_SYSTEMS_API_KEY=ap_live_...
import os
import urllib.request
from pydantic_ai import Agent
from pydantic_ai.mcp import MCPToolset
skill = urllib.request.urlopen("https://pagesystems.ai/v1/skill").read().decode() # once, at startup
page_systems = MCPToolset(
"https://pagesystems.ai/mcp",
headers={"Authorization": f"Bearer {os.environ['PAGE_SYSTEMS_API_KEY']}"},
)
agent = Agent(model, instructions=your_instructions + "\n\n" + skill, toolsets=[page_systems])What your agent sends, and what comes back
create_page({
title: "Dinner on Friday",
page: {
type: "restaurant_picker",
options: [ … ],
},
})
→ { url: "https://pagesystems.ai/p/7Hq2…" }
// later, in the same session
"[Page Systems] The person submitted …"Trust
Careful with the parts that matter.
No payments on pages
A cart page shows the items and collects delivery details, then sends them back. It never takes a payment; your agent handles any purchase.
Pages never send people elsewhere
It never redirects and does not complete any bookings or orders. Your agent is always in control.
Pages expire
Links are unguessable and expire by default. Your agent sets how long they last.
Link previews people can read
Users get a clear social preview generated from the page’s content, so they know what to expect before they tap.
Pricing
Start free. Subscribe when you need more.
Pro
$20/month
- 5,000 pages a month included
- Then $0.01 per page
- Every page type
- Hosted pages with link previews
A page is one link your agent sends. Usage resets every month.
Stop sending numbered lists.
Give your agent a page for every decision it asks people to make.




