Skip to main content
Glama
featurejet

featurejet-mcp

Official
by featurejet
README.md
# FeatureJet MCP Server

The official [Model Context Protocol](https://modelcontextprotocol.io) server for
[FeatureJet](https://featurejet.com), a hosted customer-feedback board with
verified-email voting, a public roadmap, and a changelog.

It lets an MCP-compatible agent — Claude, Cursor, Codex, or anything else that
speaks the protocol — read a board and act on it: list and search posts, read
votes and analytics, file feature requests, and pull the top-voted planned item
to work on it.

## Hosted endpoint

Most people should use the hosted server rather than run this themselves:

```
https://mcp.featurejet.com/mcp
```

Transport is Streamable HTTP with Bearer authentication. API keys are minted in
the FeatureJet dashboard and begin with `fj_live_`.

Example client configuration:

```json
{
  "mcpServers": {
    "featurejet": {
      "url": "https://mcp.featurejet.com/mcp",
      "headers": {
        "Authorization": "Bearer fj_live_REPLACE_ME"
      }
    }
  }
}
```

Full setup instructions live at
[featurejet.com/docs/mcp](https://featurejet.com/docs/mcp).

## Running it yourself

```bash
uv sync
uv run featurejet-mcp
```

Configuration is read from the environment:

| Variable | Default | Purpose |
|---|---|---|
| `FEATUREJET_API_BASE` | `http://featurejet-api:8000` | Base URL of the FeatureJet API |
| `MCP_PORT` | `8080` | Port to listen on |
| `MCP_HOST` | `127.0.0.1` | Interface to bind |
| `MCP_DNS_REBINDING_PROTECTION` | `true` | Validate the `Host` header |

Point `FEATUREJET_API_BASE` at `https://api.featurejet.com` to talk to
production.

## How it works

This server is a thin, typed proxy over FeatureJet's public REST API. Every tool
it exposes maps to an endpoint documented at
[featurejet.com/docs/api](https://featurejet.com/docs/api), so anything an agent
can do here can also be done with the
[Python and Node.js SDKs](https://github.com/featurejet/featurejet-sdks) or a
plain HTTP client.

Two deliberate constraints:

- **The key's scope decides whether a human confirms.** These are two different
  grants, and you choose which one an agent holds:
  - A **propose-scoped** key cannot change a post's status directly. It calls
    `propose-status`, nothing changes on the public board, and no voter is
    notified until a human confirms in the dashboard. That confirmation applies
    the change through the same path as a direct admin edit.
  - A **write-scoped** key *can* change status immediately, including to
    statuses that notify voters. That is the point of the scope, and it is the
    one to withhold from an agent you don't want announcing things to your
    users.

  If you want an agent that can do the work and attach its receipts but cannot
  tell your customers something shipped, give it a propose-scoped key.
- **The API key scopes what is reachable.** The server holds no ambient
  authority of its own; it forwards the caller's key and nothing more.

## Development

```bash
uv sync
uv run pytest
uv run ruff check
```

## Feedback

We run our own roadmap on FeatureJet. Requests and bugs are welcome at
[feedback.featurejet.com](https://feedback.featurejet.com), or open an issue
here.

## License

MIT. See [LICENSE](LICENSE).