Skip to main content

withfeedback-mcp

MCP (Model Context Protocol) server for withfeedback.com: lets AI assistants (Claude, Cursor, …) list and moderate feedback submissions, create and bulk-import testimonials, inspect widgets and embed codes, and read NPS survey results.

Transports: stdio (default) and streamable HTTP (withfeedback-mcp --http or WITHFEEDBACK_MCP_TRANSPORT=http). HTTP mode binds 127.0.0.1 only — see the security note below before changing that.

Install

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

Quick start with a personal access token (PAT)

The recommended setup for a local/stdio MCP server:

  1. Log in at your withfeedback.com instance and open Account → API Tokens (/accounts/tokens/).
  2. Create a token with the scopes you need (see the table below). Copy it — it is shown only once.
  3. Configure your MCP client with WITHFEEDBACK_TOKEN (examples below).

API access requires a plan that includes the API/CLI/MCP feature (Pro and above). Requests from lower plans return HTTP 403.

Claude Desktop / Claude Code configuration

Claude Desktop (claude_desktop_config.json):

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

Prefer the OAuth2 device flow over a PAT? Omit WITHFEEDBACK_TOKEN — the official public client id 7yQMsnY2Is2f5tCuwwgItoQu3fRkEX2wnzIRj0Vh is the built-in default (shown here explicitly; only needed to override):

{
  "mcpServers": {
    "withfeedback": {
      "command": "uvx",
      "args": ["withfeedback-mcp"],
      "env": {
        "WITHFEEDBACK_CLIENT_ID": "7yQMsnY2Is2f5tCuwwgItoQu3fRkEX2wnzIRj0Vh"
      }
    }
  }
}

Claude Code:

claude mcp add withfeedback --env WITHFEEDBACK_TOKEN=spd_your_token_here -- uvx withfeedback-mcp

Cursor configuration

~/.cursor/mcp.json (or the project's .cursor/mcp.json):

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

OAuth2 device flow (alternative to a PAT)

If WITHFEEDBACK_TOKEN is not set, the server falls back to the OAuth2 device flow using the official public client id 7yQMsnY2Is2f5tCuwwgItoQu3fRkEX2wnzIRj0Vh (public by design — device-flow clients carry no secret). Set WITHFEEDBACK_CLIENT_ID to use a different client (e.g. on a self-hosted instance). On the first tool call the server prints a verification URL and a short code on stderr (and tries to open your browser):

  1. The server calls POST /o/device-authorization/ with the client id.
  2. You open the printed URL, enter the code, and approve the requested scopes.
  3. The server polls POST /o/token/ until approval and then uses the access token for all API calls.

Request a custom scope set with WITHFEEDBACK_SCOPES (space-separated).

Note on Dynamic Client Registration: open DCR (POST /o/register/) is disabled in production (DCR_ENABLED=False is the production default) — the endpoint is unauthenticated and unthrottled, so withfeedback.com does not expose it. Use the published official client id (or a PAT); self-hosted instances can register additional clients via Django admin or the create_oauth2_app management command.

Environment variables

Variable Default Purpose
WITHFEEDBACK_API_URL https://withfeedback.com API base URL (self-hosted/staging override)
WITHFEEDBACK_TOKEN Personal access token (primary auth for stdio)
WITHFEEDBACK_CLIENT_ID official public client id OAuth2 client id for the device-flow fallback
WITHFEEDBACK_SCOPES all tool scopes Scopes requested during device flow
WITHFEEDBACK_MCP_TRANSPORT stdio Set to http for streamable HTTP
WITHFEEDBACK_MCP_HOST 127.0.0.1 HTTP bind address (loopback only by default)
WITHFEEDBACK_MCP_PORT 8000 HTTP bind port
WITHFEEDBACK_MCP_ALLOW_REMOTE unset Must be 1 to allow a non-loopback HTTP bind (read the security note first)

On startup the server checks GET /.well-known/speedpy.json once and warns (never fails) when the manifest is unreachable or the API is older than the minimum this client expects.

HTTP transport security

The streamable HTTP transport has no per-caller authentication: the process holds a single account token (your PAT or device-flow grant), and every HTTP caller acts as that account. Therefore:

  • HTTP mode binds 127.0.0.1 by default and is intended for local clients on the same machine.
  • Binding a non-loopback address is refused unless you explicitly set WITHFEEDBACK_MCP_ALLOW_REMOTE=1, and even then the server prints a prominent warning: only do this behind a reverse proxy that authenticates callers before they can reach the port.
  • A properly multi-tenant remote MCP server with per-user OAuth is a future server-side deployment of withfeedback.com — it is not something this package provides. Do not expose this process to the internet.

Tools and required scopes

Give your PAT (or device-flow grant) the scopes for the tools you plan to use:

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

Notes:

  • Moderation is explicit and audited. approve_submission / reject_submission call the dedicated action endpoints; write:* scopes cannot approve — only moderate:submissions can. Responses include the submission id, status, moderated_by_id, and moderated_at, so agent actions stay attributable in the moderation audit trail.
  • Nothing is auto-published. create_testimonial and import_testimonials always create pending submissions that a moderation step (human or explicit approve call) must publish.
  • API errors surface as readable tool errors: HTTP 402 = plan quota/billing block, HTTP 403 = missing scope/role/plan feature, HTTP 409 = invalid moderation state transition.

Development

uv run --with pytest --with httpx --with mcp pytest packages/withfeedback-mcp/

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

withfeedback_mcp-0.1.0.tar.gz (20.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

withfeedback_mcp-0.1.0-py3-none-any.whl (13.9 kB view details)

Uploaded Python 3

File details

Details for the file withfeedback_mcp-0.1.0.tar.gz.

File metadata

  • Download URL: withfeedback_mcp-0.1.0.tar.gz
  • Upload date:
  • Size: 20.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for withfeedback_mcp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d0704eda8a1463f9fe1b9f578d076ad3f03e7162329bcf71a08ef0fa2e9d62a6
MD5 4e1bb023075286fa227a38a5a34f1f66
BLAKE2b-256 94ee90ebb32b32d141cba0093517f7ee68d36ad72179ccd242391a35c6d8925e

See more details on using hashes here.

File details

Details for the file withfeedback_mcp-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: withfeedback_mcp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 13.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for withfeedback_mcp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e616815bc5dd0427b8ba8311f8686f5cddd364b02d2d85117ec48b1d02ff75a8
MD5 b68557c46ea8a925c81674783a46aa4a
BLAKE2b-256 fc70905bc50dc22f098ca8aed3228458b46c213c54f606bc5bc8cffc2f051087

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page