Agent integration rules
Paste this into AGENTS.md, Cursor rules, or your agent system prompt when adding Bootstrapware Feedback. The same concepts ship inside the npm package as AGENTS.md.
What the package does
Embeddable feature-request board for SaaS: list, submit, vote, status badges.
After 4 characters in the compose title, similar requests search beyond the loaded page: Hosted and BYO debounce listPosts({ q }); local uses in-memory substring/token overlap. Up to 3 clickable matches jump to the post and focus Vote.
Two modes
- BYO ($9.99): you own posts. Pass a
FeedbackAdapter(or callbacks wrapped withcreateByoAdapter). Bootstrapware only hosts board config. - Hosted ($19.99): omit adapter; pass
boardId+publishableKey. Posts/votes live on Bootstrapware. Customer moderates in the dashboard.
Never send post title/body through MCP. MCP configures boards only.
Install
pnpm add @bootstrapware/feedback
import { Feedback, createLocalAdapter } from "@bootstrapware/feedback";
import "@bootstrapware/feedback/styles.css";Identity
Bootstrapware does not authenticate end users. Your app asserts:
user={{ id: "opaque-stable-id", name: "Ada" }}id is opaque. Optional email / avatarUrl are display metadata only.
Optional authorToken: mint with POST /api/v1/author-tokens (secret key). Required when the board enables requireAuthorToken. See Identity.
Local / demo
<Feedback
user={{ id: "user_1", name: "Ada" }}
adapter={createLocalAdapter({ storageKey: "demo-feedback" })}
/>BYO adapter
<Feedback
boardId="brd_..."
user={currentUser}
adapter={{
listPosts: async ({ boardId, status, cursor, q }) => {
const params = new URLSearchParams({ boardId });
if (status) params.set("status", status);
if (cursor) params.set("cursor", cursor);
if (q) params.set("q", q);
return fetch(`/api/feedback?${params}`).then((r) => r.json());
},
createPost: async (input) =>
fetch("/api/feedback", { method: "POST", body: JSON.stringify(input) }).then((r) => r.json()),
vote: async ({ postId, author }) => {
await fetch(`/api/feedback/${postId}/vote`, { method: "POST", body: JSON.stringify({ author }) });
},
unvote: async ({ postId, author }) => {
await fetch(`/api/feedback/${postId}/unvote`, { method: "POST", body: JSON.stringify({ author }) });
},
}}
/>Honor optional q on listPosts so similar-request search can look past the loaded page.
Hosted
<Feedback
boardId="brd_..."
publishableKey="bsw_live_pub_..."
user={currentUser}
/>Optional apiBaseUrl defaults to https://feedback.bootstrapware.co.
Hosted management (secret key)
Secret keys (bsw_test_sec_ / bsw_live_sec_) must stay server-side. Use them as Authorization: Bearer against https://feedback.bootstrapware.co to create, draft, and publish boards without the dashboard.
# Create
curl -s -X POST https://feedback.bootstrapware.co/api/v1/boards \
-H "Authorization: Bearer $BSW_SECRET" \
-H "Content-Type: application/json" \
-d '{"name":"Product ideas"}'
# Save draft (replace BOARD_ID)
curl -s -X PATCH https://feedback.bootstrapware.co/api/v1/boards/BOARD_ID \
-H "Authorization: Bearer $BSW_SECRET" \
-H "Content-Type: application/json" \
-d '{"name":"Product ideas","config":{"submissionsEnabled":true,"votingEnabled":true,"showVoteCounts":true,"allowAnonymous":false,"emptyState":"No requests yet. Suggest one."}}'
# Publish
curl -s -X POST https://feedback.bootstrapware.co/api/v1/boards/BOARD_ID \
-H "Authorization: Bearer $BSW_SECRET" \
-H "Content-Type: application/json" \
-d '{"action":"publish"}'Also available: GET /api/v1/boards, GET /api/v1/boards/:id, GET /api/v1/usage.
Hosted MCP (Cursor)
HTTP MCP endpoint: https://feedback.bootstrapware.co/mcp. Prefer OAuth Connect (no secret in mcp.json). Secret Bearer keys remain a fallback. Never send post title/body through MCP tools.
Cursor plugin: github.com/BootstrapWare/bootstrapware-cursor. Use Keys → Add to Cursor (OAuth), then Connect and sign in.
Tools:
- list_boards
- get_board
- create_board
- update_draft (does not publish)
- publish_board
- get_published_config
- list_capabilities
Dashboard-only: API key mint/revoke, webhooks, board delete, branding, billing, Hosted inbox. Prefer list_capabilities before inventing endpoints.
Publishing stores hosted board config. Live bsw_live_pub_ config fetch needs BYO ($9.99) or Hosted ($19.99). Live Hosted post storage needs Hosted ($19.99). Test publishable keys work without that.
Revoke Cursor OAuth grants under Keys → Active Cursor connections. Marketplace listing may still be pending.
First-run setup
- Open Feedback → Keys and click Add to Cursor (OAuth) (or install the plugin).
- In Cursor, click Connect, sign in on Bootstrapware, and Allow.
- Secret fallback: mint a test secret and paste the Keys-page
mcp.jsonsnippet if OAuth is unavailable.
{
"mcpServers": {
"bootstrapware-feedback": {
"type": "http",
"url": "https://feedback.bootstrapware.co/mcp"
}
}
}Statuses and toggles
Fixed statuses: open | planned | in_progress | shipped | declined.
Published config toggles: submissionsEnabled, votingEnabled, showVoteCounts, allowAnonymous, requireAuthorToken, emptyState.
Security
- Secret keys stay server-side.
- Publishable key + host-asserted
author.idcan be forged if the key leaks; mitigate with origins andrequireAuthorToken+ secret-mintedauthorToken. - Plain text only. Customer moderates Hosted content.
Related: API overview · Quickstart · Modes · Cursor guide