Agent connection

MCP for FeatQ boards

The FeatQ MCP server is a standard streamable HTTP endpoint at /api/mcp. It gives an MCP-compatible client a board-scoped connection for reading requests, checking votes and comments, generating implementation specs, and updating request status.

Every request is authenticated with Authorization: Bearer fq_.... The board key determines which board the client can access. FeatQ does not use the older SSE transport, so the client must speak streamable HTTP. Claude Code, Cursor, Codex CLI, and any other client that implements this transport can connect directly.

Get your board key

Open your board admin page and find the Connect your coding agent panel. Copy the bearer key or copy a ready-made client config. Keep the key private; anyone with it can read and update that board through MCP.

Board keys start with fq_. Use the key from the board you want the agent to manage because tools cannot cross from that board into another one. If you maintain separate product or staging boards, configure each as a separate MCP server with its own key.

Claude Code

Run the command from the project where you use Claude Code. The HTTP transport and authorization header are stored with the server definition, so the tools become available to that Claude Code project after a restart.

claude mcp add --transport http featq https://featq.com/api/mcp --header "Authorization: Bearer fq_YOUR_KEY"
  1. Open a terminal in the project where you use Claude Code and run the command above.
  2. The default local-scope connection is stored under that project in ~/.claude.json. Keep the bearer key private.
  3. Exit and restart Claude Code in that project so it reloads the connection.
  4. Verify it by asking: Use FeatQ list_requests to list my board requests.

Cursor

Cursor reads MCP servers from a JSON configuration file. The project file keeps the connection local to one repository, while the home-directory file makes it available across projects opened by your user account.

{
  "mcpServers": {
    "featq": {
      "url": "https://featq.com/api/mcp",
      "headers": {
        "Authorization": "Bearer fq_YOUR_KEY"
      }
    }
  }
}
  1. Save the JSON as .cursor/mcp.json in one project, or as ~/.cursor/mcp.json to use it globally. Do not commit a file containing your bearer key.
  2. Fully restart Cursor after saving the file.
  3. Verify it in Agent chat by asking: Use FeatQ list_requests to list my board requests.

Codex CLI

Codex CLI can connect to FeatQ directly over streamable HTTP. Set FEATQ_BOARD_KEY to your fq_... board key in the environment that starts Codex. A shell startup file or your usual secret manager can provide the variable, but it should not be committed to the repository.

Add the server with the CLI command below. The bearer token flag tells Codex to read the token from the named environment variable instead of storing the key in its configuration file.

codex mcp add featq --url https://featq.com/api/mcp --bearer-token-env-var FEATQ_BOARD_KEY

The command creates this entry in ~/.codex/config.toml. You can also add the same entry by hand. Restart Codex after changing its configuration or environment, then ask it to call list_requests to verify access.

[mcp_servers.featq]
url = "https://featq.com/api/mcp"
bearer_token_env_var = "FEATQ_BOARD_KEY"

Any other MCP client

FeatQ works with any client that implements MCP over streamable HTTP and can send a bearer authorization header. Create a remote HTTP server entry using these values; there is no client marketplace or client-specific approval step.

Endpoint URL
https://featq.com/api/mcp
Transport
Streamable HTTP, not SSE
Auth header
Authorization: Bearer fq_your_key

Client labels vary, but the connection type may be called remote MCP, HTTP MCP, or streamable HTTP. Do not select an SSE-only connection type. After connecting, the client should discover the seven tools listed below during MCP initialization.

Tools reference

All tools run against the board identified by the bearer key. Request IDs from a different board are returned as not found. Tool results are JSON serialized into MCP text content, which lets an agent inspect the fields before deciding on its next call.

list_requests

List requests from the authenticated board. Use it to find the most requested work, review recent submissions, or focus on one stage of the roadmap.

Arguments

status (string, optional)
Filter by new, considering, planned, in_progress, or done.
sort ("votes" | "newest", optional)
Controls request order. Defaults to votes.
limit (integer, optional)
Limits the result to 1 through 50 requests. Defaults to 20.

Returns

Returns the board slug and name plus a requests array. Each request contains id, title, description, status, votes, comments, and created_at.

Example

list_requests({ status: "planned", sort: "votes", limit: 10 })

get_ranked_requests

Rank the open requests on the authenticated board by demand. The score counts votes plus half a point per comment and fades as a request ages over roughly 90 days, with ties going to the newer request. Requests already marked done are excluded.

Arguments

limit (integer, optional)
Limits the result to 1 through 20 requests. Defaults to 5.

Returns

Returns the board, generated_at, a ranking description, and a requests array. Each request contains id, title, status, votes, comments, created_at, and score.

Example

get_ranked_requests({ limit: 5 })

get_request

Read the full context for one request on the authenticated board before planning or changing it.

Arguments

id (string, required)
The non-empty feature request ID returned by list_requests.

Returns

Returns the board, the request summary with submitter_email, and its comments. Each comment includes id, author_email, author_name, content, is_admin, and created_at.

Example

get_request({ id: "REQUEST_ID" })

generate_spec

Create an agent-ready markdown implementation spec draft from a request and its board context.

Arguments

id (string, required)
The non-empty feature request ID to turn into a draft specification.

Returns

Returns the board, a compact request object with id, title, and status, and the generated markdown. The markdown is a draft that the agent should verify against the codebase.

Example

generate_spec({ id: "REQUEST_ID" })

update_request_status

Move one request to a valid workflow status. Marking it done also makes it appear in the board's public changelog.

Arguments

id (string, required)
The non-empty ID of a request on the authenticated board.
status (string, required)
One of new, considering, planned, in_progress, or done.

Returns

Returns success, the updated request summary, notifications_queued, and changelog_url. The changelog URL is present when status is done and null for other statuses.

Example

update_request_status({ id: "REQUEST_ID", status: "done" })

get_board_stats

Get a compact view of demand and workflow distribution across the authenticated board.

Arguments

No arguments.

Returns

Returns the board, total_requests, total_votes, by_status counts for all five statuses, and top_requests. The top_requests array contains the five highest-voted request summaries.

Example

get_board_stats({})

list_competitor_claims

List the claims FeatQ extracted from the competitor comparison pages this board watches. Read-only. Use it to see what those pages say the product is missing before planning work.

Arguments

state (string, optional)
Filter by new, added, or dismissed. Defaults to new.
limit (integer, optional)
Limits the result to 1 through 100 claims. Defaults to 25.

Returns

Returns a claims array. Each claim contains id, feature, summary, quote, claim_type, competitor, source_url, first_seen_at, state, and request_id.

Example

list_competitor_claims({ state: "new", limit: 25 })

An agent workflow that ships

Start by asking the agent to call list_requests with sort: "votes". The response ranks requests by demonstrated demand and gives the agent the request IDs it needs for deeper calls. The agent can choose the top item, or you can tell it which status to filter and how many candidates to compare. Calling get_request next adds the complete description, submitter email, and discussion context before implementation decisions are made.

With a request selected, generate_spec produces a markdown implementation draft. The coding agent should reconcile that draft with the actual repository, identify affected files, implement the change, and run the project checks. FeatQ supplies the feedback context and proposed scope; the agent still verifies technical assumptions against the code it is changing.

After the work is complete, the agent calls update_request_status with status: "done". FeatQ queues the applicable voter notifications and publishes the completed request on the board's public changelog. The response includes the changelog path, so the agent can report where users can see the shipped update.

Security notes

  • A key is scoped to one board. It permits MCP tools to read that board and update its request statuses, but it does not grant access to other FeatQ boards.
  • Treat the key as a secret. Keep it in environment variables, secret managers, or private client configuration. Never put it in browser code, public logs, or a file committed to source control.
  • Per-board rate limits apply. When a board exceeds its MCP limit, FeatQ responds with HTTP 429 and a Retry-After header. Wait for the number of seconds in that header before retrying instead of immediately repeating the call.

Curious how other feedback tools compare on this? See which feedback tools have MCP servers.