Use Stacktree from a Vercel app or agent.
Stacktree is a connector in the Vercel Connect catalog. Your code asks Vercel for a Stacktree token at the moment it needs one, then publishes HTML to a private link, updates it in place and reads client feedback, with no Stacktree key in your environment variables.
No card · 3 pages free · about a minute
How do you call Stacktree from a Vercel app?
Create the Stacktree connector with vercel connect create stacktree, then call getToken from @vercel/connect when your code runs. Each person who uses your app connects their own Stacktree account once. The token works on the MCP server at api.stacktr.ee/mcp and on the REST API at api.stacktr.ee.
Create the connector
From the project that will use it. Pick any name; the examples below use acme-stacktree, which makes the connector stacktree/acme-stacktree.
vercel link
vercel connect create stacktree --name acme-stacktree
vercel env pull Or in the dashboard: open Stacktree in the Vercel Connect catalog and press Create Connector. Vercel reads Stacktree's OAuth metadata, registers the client and keeps the tokens.
Give a model the Stacktree tools
An AI SDK agent that publishes as the person using your app. Each user connects their own Stacktree account once: they sign in to Stacktree, see what your app is asking to do, and press Allow.
// agent.ts
import { getToken } from '@vercel/connect';
import { createMCPClient } from '@ai-sdk/mcp';
import { generateText, isStepCount } from 'ai';
const userId = 'user_123'; // from your own session, never from the request body
const token = await getToken('stacktree/acme-stacktree', {
subject: { type: 'user', id: userId },
});
const client = await createMCPClient({
transport: {
type: 'http',
url: 'https://api.stacktr.ee/mcp',
headers: { Authorization: `Bearer ${token}` },
},
});
try {
const { text } = await generateText({
model: 'openai/gpt-5.4',
tools: await client.tools(), // publish_html, update_site, list_feedback, ...
stopWhen: isStepCount(10),
prompt: 'Write the weekly report as one HTML page and publish it to a private link.',
});
} finally {
await client.close();
} In an eve agent
Add one connection file. eve asks each user to authorize Stacktree in their browser the first time a tool needs it, and keeps a separate grant per person.
// agent/connections/stacktree.ts
import { defineMcpClientConnection } from 'eve/connections';
import { connect } from '@vercel/connect/eve';
export default defineMcpClientConnection({
url: 'https://api.stacktr.ee/mcp',
description: 'Publish HTML to private Stacktree links, update them in place, and read client feedback.',
auth: connect('stacktree/acme-stacktree'),
}); Without a model: one REST call
The same token works as a Bearer token on the REST API, for a route or a cron job that already has the HTML.
import { getToken } from '@vercel/connect';
export async function publishReport(userId: string, html: string) {
const token = await getToken('stacktree/acme-stacktree', {
subject: { type: 'user', id: userId },
});
const res = await fetch('https://api.stacktr.ee/sites', {
method: 'POST',
headers: { Authorization: `Bearer ${token}`, 'content-type': 'application/json' },
body: JSON.stringify({ html }),
});
if (!res.ok) throw new Error(`Stacktree publish failed: ${res.status}`);
const { url } = await res.json();
return url; // a private, unguessable link
} What a token can do
- Everything the Stacktree account can do through the API: publish, update a page in place on the same link, set a passcode or an expiry, read and resolve viewer feedback, and delete pages. Stacktree lists two scopes,
sites:writeandsites:read, but neither narrows a token today, so treat any Stacktree token as full access to that account. - Access tokens last 30 days. Vercel Connect renews them with a refresh token, so a connection in regular use does not lapse.
- To remove access, delete the connector or revoke its token in Vercel.
Related guides
Give your Vercel agent a publish step.
Connect Stacktree once. Every page your agent makes gets a private link.
Sign up free →