Open as a MockFlow board
Add a Connect MockFlow button, then turn each user's roadmap into a board in their account.
A product roadmap tool wants an Open as a MockFlow board button, so its users can discuss and rearrange their roadmap on a visual board with their team. Each user connects their own MockFlow account once; after that, one click creates a board in their account with the milestones as a timeline and the initiatives as a kanban.
This is the most complete of the OAuth examples, and the best one to start from: it covers every step of the OAuth flow.
Download the code (Node.js 18 or later, no packages)
What it does
Shows Connect MockFlow to a user who has not connected, and the board button to one who has.
Creates the board in the user's own account: a timeline of milestones and a kanban of initiatives by status.
Refreshes the user's token when it is close to expiring, notices when they have disconnected the app in MockFlow, and revokes the tokens when they click Disconnect in your product.
How it works
Connect: make a random
stateand a PKCEcode_verifier, keep both in the user's session, and send the user tohttps://mockflow.com/mcp-oauth/with your client ID, redirect URI, the scopesuser:read boards:writeand thecode_challenge.Callback: check that
statematches, then trade thecodefor tokens athttps://mockflow.com/mcp-oauth/tokenwith your secret and the verifier. The code lasts 10 minutes and works once.Store: save the access token, the refresh token and when the access token expires, against your user. Read
GET /meto show who is connected.Call: send the user's access token as a bearer token to
POST /boardsand a batch of items.Refresh: access tokens last 24 hours. Before one runs out, trade the refresh token for a new pair and store both. An
invalid_grantmeans the user disconnected: delete the tokens and show Connect MockFlow again.Disconnect: post either token to
https://mockflow.com/mcp-oauth/revokeand delete your copy.
Run the example
Register an app in the OAuth apps tab of the developer console with the redirect URI http://localhost:3000/oauth/callback and the scopes user:read and boards:write. Then:
cp .env.example .env # paste the client ID and secret into .env
node server.js # open http://localhost:3000
While the app is in development, you and the people in your workspace can connect it. To let anyone connect, submit it for review in the console; a published app needs a description, a logo and an https redirect on your own domain.
The key code
// Connect
s.auth = newAuthRequest(); // state, verifier, challenge
redirect(res, authorizeUrl({ clientId, redirectUri, scope: 'user:read boards:write', state: s.auth.state, challenge: s.auth.challenge }));
// Callback
if (url.searchParams.get('state') !== s.auth.state) return html(res, 'Expired', 400);
const tokens = await exchangeCode({ clientId, clientSecret, redirectUri, code: url.searchParams.get('code'), verifier: s.auth.verifier });
store.set(s.userId, tokens);
// Call, refreshing first when needed
const token = await accessTokenFor(store, s.userId, app); // null when the user disconnected
const board = await new MockFlow({ token }).post('/boards', { title: 'Q1 2027 roadmap' });
The OAuth helpers are in lib/oauth.js in the download, and are reused by every OAuth example.
Adapt it
CRM: "Plan this account" turns an account's open opportunities into a board.
Help desk: "Map this issue" turns a ticket thread into a flowchart of what the customer tried.
Forms and surveys: "Visualise results" turns answers into charts on a board.
What you need
An OAuth app with the scopes user:read and boards:write. The board is created under the connecting user's plan, so a Basic account's three board limit applies to them; the example shows a link to upgrade when the API answers 402.