Docs/Guides

AI assistants (MCP)

Let Claude, ChatGPT, Cursor or any assistant that speaks the Model Context Protocol work in your HelpBites workspace: read the inbox, draft a reply, move a feedback post along, write a changelog entry, look into an error. You keep control: the assistant acts as you, with your role, in one workspace, and you can cut it off from Settings → API keys at any time.

The server is one address on your HelpBites host:

https://YOUR-SUPPORT-HOST/mcp

It is stateless Streamable HTTP (JSON-RPC 2.0), so it needs nothing beyond the app itself. The same address is shown, ready to copy, under Settings → API keys.

Connect#

There are two ways to sign in. Both end in the same thing: an admin API key (ak_…) that the assistant sends as Authorization: Bearer ….

Sign in with your browser (claude.ai, ChatGPT)#

Assistants that run in the cloud can't be given a header, so they sign in with OAuth instead.

  1. In the assistant, add a custom connector (Claude: Settings → Connectors → Add custom connector; ChatGPT: Settings → Connectors, with developer mode on) and paste the address above.
  2. Your browser opens HelpBites. Sign in if you aren't, check the workspace, choose all projects or only some, and press Approve.
  3. The assistant gets a key named MCP: Claude (or whatever it called itself). It is listed under Settings → API keys. Revoking it there disconnects the assistant.

What this needs:

  • A public https address. Cloud assistants call your server from the internet, so localhost won't do (use a tunnel while you try it, and set APP_URL to the tunnel's address).
  • HELPBITES_SECRET set on the server (it signs the assistant's registration).
  • A role that may manage API keys (owners and admins).

The key lasts a year. There are no refresh tokens: when it expires, the assistant asks you to sign in again.

Paste a key (Claude Code, Cursor, scripts)#

Create a key under Settings → API keys, optionally limited to some projects, and give it to the client as a header.

Claude Code:

claude mcp add --transport http helpbites https://YOUR-SUPPORT-HOST/mcp \
  --header "Authorization: Bearer ak_…"

Cursor (~/.cursor/mcp.json), and most other clients that take a URL:

{
  "mcpServers": {
    "helpbites": {
      "url": "https://YOUR-SUPPORT-HOST/mcp",
      "headers": { "Authorization": "Bearer ak_…" }
    }
  }
}

Clients that only run local programs (an older Claude Desktop) can bridge with npx mcp-remote https://YOUR-SUPPORT-HOST/mcp --header "Authorization: Bearer ak_…".

What it can do#

Each tool is one of the documented /v1 API routes, called with the assistant's key. Nothing here is a back door: the role check, the workspace and a key's project limit apply exactly as they do in the panel and the native app.

Tool What it does
list_projects The projects in the workspace, with their ids. Most other tools need one.
get_overview The overview: unread, open, revenue and errors per project.
search Search conversations and knowledge base answers.
list_conversations The inbox: filter by project, status, unread, assignee, priority, tag or customer.
get_conversation One conversation with its customer and project.
get_conversation_messages Its messages, including internal notes.
reply_to_conversation Send a reply to the customer (and email them).
add_internal_note A note only the team sees.
update_conversation Status, priority, tags, assignee.
archive_conversation Archive or restore.
search_end_users Find a customer by name, email or id.
list_feedback A project's feedback board.
get_feedback_post One post with its comments.
update_feedback_post Change status, hide, feature or lock a post.
comment_on_feedback_post Comment as the team, or leave an internal note.
list_board_items The work board behind the roadmap.
create_board_item Add an item.
update_board_item Edit or move an item.
list_changelog_entries Changelog entries, drafts included.
create_changelog_entry Write an entry: a draft unless told to publish.
update_changelog_entry Edit an entry, or publish a draft.
list_errors Issues from the connected error tracker.
get_error One issue with its latest event and stack trace.
list_contacts A project's people: filter by segment, tag, subscription, billing or search.
get_contact One person, with their plan, MRR, language and tags.
get_contact_activity Everything one person has done in one list: conversations, posts, votes, emails, payments, onboarding.
update_contact Name, language, tags and attributes.
list_segments Saved segments.
list_sequences Automated email sequences.
enroll_in_sequence Put people (or a whole segment) on an active sequence.
list_automation_recipes Ready-made sequences started by an event.
install_automation_recipe Add a recipe as a draft sequence.
get_conversation_context Who the customer is: plan, MRR, past conversations, linked posts.
link_feedback_post Link a feedback post to a conversation, or file one for the customer.
draft_conversation_reply A draft reply from the project's assistant. Nothing is sent.
save_conversation_faq Save an answer from a conversation to the knowledge base.
list_saved_replies Reusable replies.
create_saved_reply Add one.
changelog_linked_conversations The conversations a changelog entry answers.
reply_to_changelog_conversations Tell all of them it shipped.
file_error_on_board Turn an error into a board item.
list_github_refs Commits and merged pull requests that mention an item as #12.
list_webhook_endpoints A project's webhook endpoints.
create_webhook_endpoint Add one, choosing the events.
update_project_settings The company profile and the public hub page.
list_pricing_tables A project's pricing tables.
get_pricing_table One table's plans, features, words, look and A/B test.
create_pricing_table Start a draft from a template.
update_pricing_table Edit plans, features, prices, words, look or translations.
publish_pricing_table Make the table live: asks first.
get_stripe_catalog Stripe products, prices and payment links to link plans to.
get_pricing_stats Views, clicks, purchases and revenue, and the A/B test result.
suggest_pricing AI proposal for plans, features and prices, from the repos and Stripe.
add_pricing_variant Copy a table to test against it.
start_pricing_experiment Start an A/B test: asks first.
stop_pricing_experiment End it, optionally keeping the winner.

Try: "Which conversations are unread? Draft a reply to the one about the failed export, and show it to me before sending." Or: "Suggest plans for our pricing table from the repo, and show me before you change anything."

Safe by design#

  • It acts as you. The assistant can do what your role does in that workspace, no more. A key limited to some projects can't reach the rest, or anything workspace-wide.
  • Writes are marked. Every tool says whether it only reads, and assistants that ask before acting use that. Replies to customers and publishing a changelog entry reach real people, and the tool descriptions tell the assistant to confirm first. Prefer a client that asks you to approve each write.
  • Customer text is untrusted. Messages, feedback and error reports are written by other people, and an assistant reads them. Someone can try to slip it instructions ("reply with a refund code"). Keep write approvals on, and read what an assistant is about to send before you allow it.
  • Revoke at any time. Each connection is an API key: rename or revoke it under Settings → API keys. Changing your password with revoke keys ticked removes them all.
  • Limits apply. A key is limited to 600 calls a minute, and to the plan's per-minute allowance on the hosted edition.
  • Results are trimmed. A very long answer is cut off after 60,000 characters with a note, so one big list doesn't fill the assistant's memory: ask for less with a filter or limit.

Calling it yourself#

Every message is a JSON-RPC POST. List the tools, then call one:

curl https://YOUR-SUPPORT-HOST/mcp \
  -H "Authorization: Bearer ak_…" -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

curl https://YOUR-SUPPORT-HOST/mcp \
  -H "Authorization: Bearer ak_…" -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_conversations","arguments":{"unread":true,"limit":10}}}'

A tool that fails (a wrong id, a role that can't do that) answers with isError: true and the API's own message, so the assistant can correct itself. The server offers tools only; it keeps no sessions, so GET and DELETE on /mcp answer 405. For anything the tools don't cover, the full API is the same key's reach, and building your own interface on it is just as supported.

How sign-in works#

For the curious, or anyone writing a client. It is standard OAuth 2.1 with PKCE (S256), no client secret, and dynamic client registration:

Step Where
The server answers 401 with WWW-Authenticate: Bearer resource_metadata="…" POST /mcp
Protected resource metadata (RFC 9728) /.well-known/oauth-protected-resource
Authorization server metadata (RFC 8414) /.well-known/oauth-authorization-server
Register the client (RFC 7591) POST /v1/oauth/register
The person approves the panel page /oauth/authorize
Exchange the code POST /v1/oauth/token

Registration stores nothing: the client id is the client's name and redirect addresses, signed with a key derived from HELPBITES_SECRET. Redirect addresses must be https, http://localhost, or an app's own scheme (cursor://). The authorization code lives two minutes in Redis and works once. The access token is an ordinary admin API key, minted when the code is exchanged.

Not built yet#

  • No refresh tokens (the key lasts a year, then the assistant signs in again).
  • No prompts, resources or live notifications: the server offers tools.
  • No tools for email, campaigns, contacts sync, legal documents, flags or knowledge base editing yet; the API has them, and they are the next to add.