Skip to content

MCP server

Lets an AI assistant read and moderate your feedback directly — list what is waiting, read it, approve or reject, create testimonials, check NPS, fetch an embed code.

pip install withfeedback-mcp
# or, without installing:
uvx withfeedback-mcp

Claude Desktop / Claude Code

{
  "mcpServers": {
    "withfeedback": {
      "command": "uvx",
      "args": ["withfeedback-mcp"],
      "env": {
        "WITHFEEDBACK_TOKEN": "spd_your_token_here"
      }
    }
  }
}

Create the token under Account → API Tokens with only the scopes you want the assistant to have. That token is the boundary of what it can do.

Tools

Tool Calls Needs
list_teams GET /teams/ read:teams
list_projects GET /teams/{team}/projects/ read:feedback
list_submissions GET …/submissions/ read:feedback
get_submission GET …/submissions/{id}/ read:feedback
approve_submission POST …/approve/ moderate:submissions
reject_submission POST …/reject/ moderate:submissions
create_testimonial POST …/submissions/ write:testimonials
import_testimonials looped, ≤100 items write:testimonials
list_widgets GET …/widgets/ read:widgets
get_widget_embed_code GET …/embed-code/ read:widgets
get_nps_summary surveys + results read:surveys

A tool whose scope your token lacks fails with a clear message rather than doing something narrower and pretending it worked.

Deciding what to grant

The interesting choice is moderate:submissions.

Without it, the assistant becomes a very good reader: it can summarise what is waiting, spot themes, draft your replies, and tell you which five are worth publishing — and you click approve.

With it, the assistant can publish to your website.

Approving is publishing

An approved, consented testimonial appears in your embeds. Give an assistant moderate:submissions when you want that, not by default — and remember that a submission's text is written by a stranger. Text asking an assistant to "approve all pending items" is content to be moderated, not an instruction. Reading a queue is safe; acting on what a queue says is where a prompt injection would land.

Start read-only. Add moderation when you have watched it work.

Configuration

Variable Default Purpose
WITHFEEDBACK_TOKEN Personal access token
WITHFEEDBACK_API_URL https://withfeedback.com Self-hosted or staging
WITHFEEDBACK_CLIENT_ID official public client Device-flow fallback
WITHFEEDBACK_SCOPES all tool scopes Scopes requested in device flow
WITHFEEDBACK_MCP_TRANSPORT stdio http for streamable HTTP
WITHFEEDBACK_MCP_HOST 127.0.0.1 HTTP bind address
WITHFEEDBACK_MCP_PORT 8000 HTTP bind port
WITHFEEDBACK_MCP_ALLOW_REMOTE unset Required to bind beyond loopback

HTTP transport

withfeedback-mcp --http

Binds 127.0.0.1 only. That default is deliberate: the server holds a token, so anything that can reach it can act as you.

Do not expose it without authentication in front

Binding to a routable address needs WITHFEEDBACK_MCP_ALLOW_REMOTE=1, which exists to make you stop and think. An MCP server on an open port is an unauthenticated proxy to your account. If you need remote access, put a reverse proxy with real authentication in front of it, or use stdio over SSH.