> ## Knowledge Base Index
> Fetch the complete knowledge base index at: https://help.feedbucket.app/sitemap.xml
> Use this file to discover available pages before exploring further.
> Pure-Markdown content can be obtained by appending a '.md' suffix to the content URLs listed in the sitemap (without the trailing slash).

# Feedbucket MCP Server

# Feedbucket MCP

|| The Feedbucket MCP no longer is in beta. You can freely access it from your Feedbucket Admin via your Profile icon in the upper right > Account > MCP

## Table of Contents

* [What is Feedbucket MCP?](#2-what-is-feedbucket-mcp)
* [Tool List](#2-tool-list)
  * [projects-list](#3-projects-list)
  * [projects-create](#3-projects-create)
  * [project-archive](#3-project-archive)
  * [project-get](#3-project-get)
  * [project-update](#3-project-update)
  * [feedback-list](#3-feedback-list)
  * [feedback-get](#3-feedback-get)
  * [feedback-update](#3-feedback-update)
  * [attachment-create](#3-attachment-create)
  * [comment-create](#3-comment-create)
  * [comment-update](#3-comment-update)
  * [comment-delete](#3-comment-delete)
  * [feedback-get-console-log](#3-feedback-get-console-log)
* [How to Connect](#2-how-to-connect)
  * [Cursor](#3-cursor)
  * [VS Code](#3-vs-code)
  * [Claude Code](#3-claude-code)
  * [Claude Desktop](#3-claude-desktop)
  * [Claude.ai](#3-claudeai)
  * [ChatGPT](#3-chatgpt)
  * [Codex](#3-codex)
* [Access Tokens](#2-access-tokens)
  * [Create a token](#3-create-a-token)
  * [Use a token](#3-use-a-token)
  * [Connected apps](#3-connected-apps)

## What is Feedbucket MCP?

[MCP](https://modelcontextprotocol.io/) (Model Context Protocol) is an open standard that lets AI assistants — Cursor, Claude, ChatGPT, Codex, and others — securely call tools exposed by external services. Instead of copying data back and forth by hand, the assistant can query and act on your product data in place.
Feedbucket MCP connects those assistants to your Feedbucket account. From the editor or chat, an assistant can:

* List, create, archive, and update projects
* Read feedback (including annotated screenshots and browser console logs)
* Resolve or reopen feedback
* Comment on feedback threads, including file attachments
* Edit or delete comments
* Change project settings (widget visibility, tags, language, and more)

The server is a Streamable HTTP MCP endpoint at:

```
https://dashboard.feedbucket.app/mcp
```

All tools operate on the authenticated user's current team. Authentication uses either a [personal access token](#2-access-tokens) (Bearer header) or OAuth (browser sign-in), depending on the client.

## Tool List

### projects-list

**Tool name:** `projects-list`

**What it does:** List projects for the authenticated user's current team. Read-only and idempotent. Results are ordered by creation date (newest first).

#### Input schema

| Parameter | Type | Required | Default | Description |
| ---- | ---- | ---- | ---- | ---- |
| `search` | string (nullable) | optional | — | Filter projects by name or URL (partial match). Max 255 characters. |
| `archived` | boolean | optional | `false` | When `true`, include archived projects alongside active ones. |
| `limit` | integer | optional | `10` | Maximum number of projects to return. Minimum 1. |

#### Output

```
{
  "projects": [
    {
      "id": 1,
      "name": "Acme Marketing Site",
      "url": "https://example.com",
      "imageUrl": "https://...",
      "type": "website",
      "key": "abc123",
      "lastActivityAt": "2026-07-01T12:00:00+00:00",
      "lastFeedbackAt": "2026-07-01T11:30:00+00:00",
      "createdAt": "2026-01-15T09:00:00+00:00",
      "archived": false
    }
  ]
}
```

#### Errors

* `No team found for the authenticated user.`

### projects-create

**Tool name:** `projects-create`

**What it does:** Create a new project for the authenticated user's current team.

#### Input schema

| Parameter | Type | Required | Default | Description |
| ---- | ---- | ---- | ---- | ---- |
| `type` | string | **required** | — | Project type. Values: `website`, `asset`. |
| `name` | string | **required** | — | The project name. Max 256 characters. |
| `url` | string (nullable) | required when `type` is `website` | — | Website URL where Feedbucket will be installed. Must be an `http`/`https` URL. Max 999 characters. |

#### Output

```
{
  "project": {
    "id": 1,
    "name": "Acme Marketing Site",
    "url": "https://example.com",
    "imageUrl": null,
    "type": "website",
    "key": "abc123",
    "lastActivityAt": null,
    "lastFeedbackAt": null,
    "createdAt": "2026-07-17T10:00:00+00:00",
    "archived": false
  }
}
```

#### Errors

* `No team found for the authenticated user.`
* `Project limit reached for your plan.`

### project-archive

**Tool name:** `project-archive`

**What it does:** Archive or restore a project by ID for the authenticated user's current team. By default the project is archived; set `archived` to `false` to restore it (subject to your plan's active project limit).

#### Input schema

| Parameter | Type | Required | Default | Description |
| ---- | ---- | ---- | ---- | ---- |
| `projectId` | integer | **required** | — | The ID of the project to archive or restore. |
| `archived` | boolean | optional | `true` | When `true`, archive the project. When `false`, restore an archived project if your plan allows. |

#### Output

```
{
  "success": true
}
```

#### Errors

* `No team found for the authenticated user.`
* `Project not found.`
* `You do not have access to this project.`
* `Active project limit reached for your teams plan.` (on restore)

### project-get

**Tool name:** `project-get`

**What it does:** Get full details for a single project by ID, including all settings. Read-only and idempotent.

#### Input schema

| Parameter | Type | Required | Default | Description |
| ---- | ---- | ---- | ---- | ---- |
| `projectId` | integer | **required** | — | The ID of the project to retrieve. |

#### Output

```
{
  "project": {
    "id": 1,
    "name": "Acme Marketing Site",
    "url": "https://example.com",
    "imageUrl": "https://...",
    "type": "website",
    "key": "abc123",
    "lastActivityAt": "2026-07-01T12:00:00+00:00",
    "lastFeedbackAt": "2026-07-01T11:30:00+00:00",
    "createdAt": "2026-01-15T09:00:00+00:00",
    "archived": false,
    "settings": {
      "visibility": "all",
      "theme": "default",
      "widgetVisible": true,
      "feedbackSubmissionOpen": true,
      "controlsPlacement": "bottom-right",
      "showPins": "always",
      "enabledFeatures": ["record", "view_feedback", "comment", "resolve", "tag", "mention"],
      "pinColor": "theme_primary",
      "onboardingEnabled": true,
      "onboardingWelcomeHeading": null,
      "onboardingWelcomeBody": null,
      "language": "en",
      "embedImages": false,
      "embedCSS": false,
      "queryTriggerSecret": null,
      "basicAuth": false,
      "basicAuthUsername": null,
      "basicAuthPassword": null,
      "notifications": {
        "enabledFor": ["comment", "resolve"]
      },
      "textOverrides": {
        "feedbackDescriptionPlaceholder": null
      },
      "tags": [
        {
          "name": "Bug",
          "syncsWith": null
        },
        {
          "name": "Design",
          "syncsWith": "jira"
        }
      ]
    }
  }
}
```

#### Errors

* `No team found for the authenticated user.`
* `Project not found.`
* `You do not have access to this project.`

### project-update

**Tool name:** `project-update`

**What it does:** Update a project's name, URL, and/or settings. Only provided fields are changed. At least one of `name`, `url`, or `settings` must be provided.

#### Input schema

| Parameter | Type | Required | Default | Description |
| ---- | ---- | ---- | ---- | ---- |
| `projectId` | integer | **required** | — | The ID of the project to update. |
| `name` | string | optional | — | The project name. |
| `url` | string (nullable) | optional | — | Website URL where Feedbucket is installed. Required for website projects when provided. |
| `settings` | object | optional | — | Project settings to update. Only provided keys are changed. See below. |

**`settings`** **properties** (all optional):

| Key | Type | Description |  |
| ---- | ---- | ---- | ---- |
| `visibility` | string | Who can see the widget. Values: `all`, `membersOnly`, `queryTrigger`. |  |
| `theme` | string | Widget theme. Use `default` or a numeric ID for a custom team theme. |  |
| `widgetVisible` | boolean | Whether the widget appears on the website. |  |
| `feedbackSubmissionOpen` | boolean | Whether clients can submit new feedback. |  |
| `controlsPlacement` | string | Widget controls position. Values: `middle-left`, `bottom-left`, `bottom-middle`, `bottom-right`, `middle-right`. |  |
| `showPins` | string | When feedback pins are visible. Values: `always`, `interact`, `never`. |  |
| `enabledFeatures` | string[] | Widget features available to clients. Values: `record`, `view_feedback`, `comment`, `resolve`, `tag`, `mention`. |  |
| `pinColor` | string | Feedback pin color. Values: `theme_primary`, `light_gray`. |  |
| `onboardingEnabled` | boolean | Show onboarding tour to clients on first visit. |  |
| `onboardingWelcomeHeading` | string (nullable) | Custom onboarding welcome heading. `null` uses default. |  |
| `onboardingWelcomeBody` | string (nullable) | Custom onboarding welcome body text. `null` uses default. |  |
| `language` | string | Widget UI language. Values: `en`, `fr`, `es`, `sv`, `de`, `nl`. |  |
| `embedImages` | boolean | Embed images in feedback screenshots when Feedbucket cannot access the site. May increase submission time. |  |
| `embedCSS` | boolean | Embed CSS in feedback screenshots when Feedbucket cannot access the site. |  |
| `queryTriggerSecret` | string (nullable) | Secret for the `feedbucketKey` query param when visibility is `queryTrigger`. Auto-generated if omitted when setting visibility to `queryTrigger`. |  |
| `basicAuth` | boolean | Use Basic Auth credentials when generating screenshots on protected sites. |  |
| `basicAuthUsername` | string (nullable) | Basic Auth username. `null` when `basicAuth` is false. |  |
| `basicAuthPassword` | string (nullable) | Basic Auth password. `null` when `basicAuth` is false. |  |
| `notifications` | object | Client email notification settings. Shape: `{ "enabledFor": string[] }` where values are `comment`, `resolve`. |  |
| `textOverrides` | object | Custom widget text. Shape: `{ "feedbackDescriptionPlaceholder": string | null }`. |
| `tags` | string[] | Full tag list to set on the project. Replaces existing tags — include every tag to keep (by name), omit to remove. New names become native tags. Tags cannot be linked to integrations via MCP, but listing an existing synced tag by name keeps its sync intact. |  |

Some settings (for example `enabledFeatures`, custom onboarding welcome text, and `textOverrides`) are plan-gated and are silently ignored if your plan does not include them.

#### Output

Same full `project` object as [`project-get`](https://markdownlivepreview.com/#project-get), including the updated `settings`.

#### Errors

* `No team found for the authenticated user.`
* `Project not found.`
* `You do not have access to this project.`
* `At least one of name, url, or settings must be provided.`
* Validation errors for invalid settings values

### feedback-list

**Tool name:** `feedback-list`

**What it does:** List feedback for a project. Read-only and idempotent. Results are ordered by creation date (newest first). Defaults to open feedback only.

#### Input schema

| Parameter | Type | Required | Default | Description |
| ---- | ---- | ---- | ---- | ---- |
| `projectId` | integer | **required** | — | The ID of the project to list feedback for. |
| `search` | string (nullable) | optional | — | Filter feedback by title or description (partial match). |
| `status` | string | optional | `open` | Filter by resolution status. Values: `all`, `open`, `resolved`. |
| `tags` | string[] | optional | — | Filter feedback that has at least one of these tags. Case-sensitive. |
| `limit` | integer | optional | — (all) | Maximum number of feedback items to return. When omitted, returns all matching feedback. |
| `createdAfter` | string (nullable) | optional | — | Only include feedback created at or after this ISO8601 date or datetime. |
| `createdBefore` | string (nullable) | optional | — | Only include feedback created at or before this ISO8601 date or datetime. |
| `changedAfter` | string (nullable) | optional | — | Only include feedback that was created, commented on, or updated (title/tags/resolve/etc.) at or after this ISO8601 date or datetime. |
| `changedBefore` | string (nullable) | optional | — | Only include feedback that was created, commented on, or updated (title/tags/resolve/etc.) at or before this ISO8601 date or datetime. |

**Date filters**

* Values may be a date (`2026-08-01`) or a full datetime (`2026-08-01T14:30:00+02:00`).
* `createdAfter` / `createdBefore` filter only on when the feedback was submitted.
* `changedAfter` / `changedBefore` match feedback if **any** of these happened in the range:
  * the feedback was created
  * a comment was added
  * an activity happened (title/description/tags/members-only change, resolve, reopen)
* Filters combine with AND. Example: `status: open` + `changedAfter: <timestamp>` returns open feedback that was created or changed since that time.
* Date-only values are treated as midnight at the start of that day.

Example: to sync only what moved since the last automation run, call feedback-list with `status: open` and  `changedAfter` set to the timestamp of the previous run.

#### Output

```
{
  "feedback": [
    {
      "id": 42,
      "title": "Logo is blurry on mobile",
      "description": "The logo looks pixelated on iPhone.",
      "descriptionTruncated": false,
      "tags": ["Bug", "Design"],
      "status": "open",
      "reporter": {
        "type": "reporter",
        "name": "Jane Client",
        "email": "jane@client.com"
      },
      "membersOnly": false,
      "page": "https://example.com/about",
      "createdAt": "2026-07-10T14:22:00+00:00",
      "changedAt": "2026-07-10T15:00:00+00:00"
    }
  ]
}
```

**Output details**

`changedAt` is always returned (not only when date filters are used). It is the latest of:

* `createdAt`
* the latest comment time
* the latest activity time (title/tags/resolve/etc.)
If nothing has happened since creation, `changedAt` equals `createdAt`.

When `reporter.type` is `member`, an `id` field is also included on the reporter object.

`description` is a preview of the feedback text, truncated to 500 characters (with `...` when cut). `descriptionTruncated` is `true` when the preview was truncated — call `feedback-get` for the full description.

#### Errors

* `No team found for the authenticated user.`
* `Project not found.`
* `You do not have access to this project.`

### feedback-get

**Tool name:** `feedback-get`

**What it does:** Get full details for a single feedback item. Read-only and idempotent. When the feedback type is `screenshot` and the annotated image is ready and ≤ 3 MB, the screenshot is also returned inline as an image in the response. If the image is still generating, too large, or missing, only the JSON payload is returned (`resource` may be `"generating"` while processing).

#### Input schema

| Parameter | Type | Required | Default | Description |
| ---- | ---- | ---- | ---- | ---- |
| `feedbackId` | integer | **required** | — | The ID of the feedback item to retrieve. |

#### Output

```
{
  "feedback": {
    "id": 42,
    "title": "Logo is blurry on mobile",
    "description": "The logo looks pixelated on iPhone.",
    "tags": ["Bug", "Design"],
    "attachments": [
      {
        "type": "image",
        "name": "extra.png",
        "url": "https://..."
      }
    ],
    "type": "screenshot",
    "resource": "https://...",
    "status": "open",
    "membersOnly": false,
    "createdAt": "2026-07-10T14:22:00+00:00",
    "changedAt": "2026-07-10T15:00:00+00:00",
    "reporter": {
      "type": "reporter",
      "name": "Jane Client",
      "email": "jane@client.com"
    },
    "comments": [
      {
        "id": 7,
        "creator": {
          "type": "member",
          "name": "Alex",
          "email": "alex@agency.com",
          "id": 3
        },
        "body": "Looking into this.",
        "attachments": [],
        "membersOnly": false,
        "createdAt": "2026-07-10T15:00:00+00:00"
      }
    ],
    "sessionDetails": {
      "page": "https://example.com/about",
      "device": "mobile",
      "system": "iOS",
      "browser": "Safari",
      "screenWidth": 390,
      "screenHeight": 844,
      "viewportWidth": 390,
      "viewportHeight": 664,
      "devicePixelRatio": 3,
      "selector": "#logo"
    },
    "integrations": [
      {
        "slug": "jira",
        "url": "https://..."
      }
    ],
    "customMetadata": {},
    "console": {
      "error": 2,
      "warn": 1,
      "info": 0,
      "log": 5
    }
  }
}
```

**Output details**

`changedAt` is the latest of the feedback’s creation time, latest comment, or latest activity (title/tags/resolve/etc.).

Comments may also include a `fromIntegration` string when the comment originated from a synced integration.

Each comment includes an `id`. Pass that value as `commentId` to `comment-update` and `comment-delete`. `attachments` lists files on the comment. For files attached with `attachment-create`, each item has `type` (a MIME type such as `image/png` or `text/plain`), `name` (the original filename), and `url` (the file). An empty `attachments` array means the comment has no files.

#### Errors

* `No team found for the authenticated user.`
* `Feedback not found.`
* `You do not have access to this feedback.`

### feedback-update

**Tool name:** `feedback-update`

**What it does:** Update a feedback item's title, description, tags, visibility, and/or status. Use `status` to resolve or reopen feedback. Only provided fields are changed. At least one of `title`, `description`, `tags`, `membersOnly`, or `status` must be provided.

#### Input schema

| Parameter | Type | Required | Default | Description |
| ---- | ---- | ---- | ---- | ---- |
| `feedbackId` | integer | **required** | — | The ID of the feedback item to update. |
| `title` | string | optional | — | New title for the feedback. Max 255 characters. |
| `description` | string (nullable) | optional | — | New description for the feedback. |
| `tags` | string[] | optional | — | Full tag list to set on the feedback. Replaces existing tags. Tags must already exist on the project (case-sensitive). |
| `membersOnly` | boolean | optional | — | Whether the feedback should only be visible to team members. |
| `status` | string | optional | — | Set to `resolved` to mark resolved, or `open` to reopen. |

#### Output

```
{
  "feedback": {
    "id": 42,
    "title": "Logo is blurry on mobile",
    "description": "The logo looks pixelated on iPhone.",
    "tags": ["Bug"],
    "status": "resolved",
    "membersOnly": false
  }
}
```

#### Errors

* `No team found for the authenticated user.`
* `Feedback not found.`
* `You do not have access to this feedback.`
* `At least one of title, description, tags, membersOnly, or status must be provided.`
* `Invalid tag(s): {tags}. Tags must exist on the project. Use the ProjectGet tool with projectId {id} to see available tags. Case sensitive.`

### Attaching files to a comment

Comment tools do not accept file bytes. Upload the file first, then pass the returned key when creating or updating the comment.

1. Call `attachment-create` once per file, with the original filename (including the extension).
2. PUT the file to the returned `uploadUrl`. Use the returned `curl` command and replace `/path/to/local/file` with the local path. The upload URL expires after 5 minutes. If it expires before the PUT succeeds, call `attachment-create` again and use the new URL and key.
3. Pass every returned `key` in the `attachmentKeys` array on `comment-create` or `comment-update`.

`attachmentKeys` values are UUIDs. Each key can be used once, and only by the same user on the same current team that created it. If a key is unknown, already used, expired, or belongs to someone else, the tool returns `Invalid attachment key.` and the comment is not created or changed.

There is no way to remove or replace files already on a comment. On `comment-update`, `attachmentKeys` only appends new files.

### attachment-create

**Tool name:** `attachment-create`

**What it does:** Mint a short-lived upload URL for one comment attachment. PUT the file to `uploadUrl`, then pass `key` to `comment-create` or `comment-update` as `attachmentKeys`. This tool does not accept file bytes. Call it once per file. See Attaching files to a comment above.

#### Input schema

| Parameter | Type | Required | Default | Description |
| ---- | ---- | ---- | ---- | ---- |
| `name` | string | **required** | — | The original filename, including the extension (for example `notes.txt` or `shot.png`). Max 255 characters. The extension sets the attachment MIME type. |

#### Output

```
{
  "key": "2e2cdb8b-9897-4a6c-a935-82922b1cfb87",
  "uploadUrl": "https://...",
  "curl": "curl -X PUT -T /path/to/local/file 'https://...'"
}

```

**Output details**

`key` is the value to pass in `attachmentKeys` after the file has been PUT to `uploadUrl`.

`uploadUrl` is a presigned URL. PUT the file bytes there. Do not POST them to Feedbucket. The URL expires after 5 minutes.

`curl` is ready to run. Replace `/path/to/local/file` with the local file path, then run it.

#### Errors

* `No team found for the authenticated user.`

### comment-create

**Tool name:** `comment-create`

**What it does:** Create a new comment on a feedback item. If the feedback was resolved, commenting automatically reopens it. To attach files, follow [Attaching files to a comment](#3-attaching-files-to-a-comment) above, then pass the keys as `attachmentKeys`

#### Input schema

| Parameter | Type | Required | Default | Description |
| ---- | ---- | ---- | ---- | ---- |
| `feedbackId` | integer | **required** | — | The ID of the feedback item to comment on. |
| `body` | string | **required** | — | The comment body text. |
| `membersOnly` | boolean | optional | `false` | Whether the comment should only be visible to team members |
| `attachmentKeys` | string[] | optional | — | Keys from `attachment-create` after PUTting each file to its `uploadUrl`. Each item is a UUID. Omit to create a comment with no files. |

#### Output

```
{
  "comment": {
    "id": 8,
    "creator": {
      "type": "member",
      "name": "Alex",
      "email": "alex@agency.com",
      "id": 3
    },
    "body": "Fixed on staging — please recheck.",
    "attachments": [
      {
        "type": "image/png",
        "name": "shot.png",
        "url": "https://..."
      }
    ],
    "membersOnly": false,
    "createdAt": "2026-07-17T10:30:00+00:00"
  }
}
```

**Output details**

`attachments` is `[]` when the comment has no files. Each item has:

* `type` — MIME type from the filename extension, such as `image/png` or `text/plain`. Unknown extensions use `application/octet-stream`.
* `name` — the original filename.
* `url` — URL of the uploaded file.

When `creator.type` is `member`, `creator` also includes `id`.

#### Errors

* `No team found for the authenticated user.`
* `Feedback not found.`
* `You do not have access to this feedback.`
* `Invalid attachment key.`

### comment-update

**Tool name:** `comment-update`

**What it does:** Update a comment on a feedback item. Only provided fields are changed. Get `commentId` from the comment `id` returned by `feedback-get`. `attachmentKeys` appends new files and does not replace existing ones. Editing a comment does not reopen resolved feedback. Any member of the feedback’s current team can update the comment, including a comment written by someone else. To attach files, follow Attaching files to a comment above.

#### Input schema

| Parameter | Type | Required | Default | Description |
| ---- | ---- | ---- | ---- | ---- |
| `commentId` | integer | **required** | — | The ID of the comment to update. Use `feedback-get` to find comment IDs. |
| `body` | string | optional | — | New comment body text. Omit to leave the body unchanged. |
| `membersOnly` | boolean | optional | — | Whether the comment should only be visible to team members. Omit to leave visibility unchanged. |
| `attachmentKeys` | string[] | optional | — | Keys from `attachment-create` after PUTting each file to its `uploadUrl`. Appends to existing attachments. Each item is a UUID. |

At least one of `body`, `membersOnly`, or `attachmentKeys` must be provided.

#### Output

Same comment object as `comment-create`. Existing files stay first in `attachments`. Newly appended files follow them.

```
{
  "comment": {
    "id": 8,
    "creator": {
      "type": "member",
      "name": "Alex",
      "email": "alex@agency.com",
      "id": 3
    },
    "body": "Updated: please recheck the logo.",
    "attachments": [
      {
        "type": "image/png",
        "name": "shot.png",
        "url": "https://..."
      },
      {
        "type": "text/plain",
        "name": "notes.txt",
        "url": "https://..."
      }
    ],
    "membersOnly": false,
    "createdAt": "2026-07-17T10:30:00+00:00"
  }
}

```

**Output details**

#### Errors

* `No team found for the authenticated user.`
* `Comment not found.`
* `You do not have access to this comment.`
* `At least one of body, membersOnly, or attachmentKeys must be provided.`
* `Invalid attachment key.`

### comment-delete

**Tool name:** `comment-delete`

**What it does:** Delete a comment by ID. Get `commentId` from the comment `id` returned by `feedback-get`. Any member of the feedback’s current team can delete the comment, including a comment written by someone else. This does not delete the feedback item.

#### Input schema

| Parameter | Type | Required | Default | Description |
| ---- | ---- | ---- | ---- | ---- |
| `commentId` | integer | **required** | — | The ID of the comment to delete. Use `feedback-get` to find comment IDs. |

#### Output

```
{
  "success": true
}

```

#### Errors

* `No team found for the authenticated user.`
* `Comment not found.`
* `You do not have access to this comment.`

### feedback-get-console-log

**Tool name:** `feedback-get-console-log`

**What it does:** Get browser console log entries captured with a feedback item. Read-only and idempotent. Requires a plan that includes console logs.

#### Input schema

| Parameter | Type | Required | Default | Description |
| ---- | ---- | ---- | ---- | ---- |
| `feedbackId` | integer | **required** | — | The ID of the feedback item to retrieve console logs for. |

#### Output

```
{
  "consoleLog": [
    {
      "type": "error",
      "arguments": ["Uncaught TypeError: Cannot read property 'x' of undefined"],
      "captured_at": "2026-07-10T14:21:58+00:00"
    },
    {
      "type": "warn",
      "arguments": ["Deprecated API usage"],
      "captured_at": "2026-07-10T14:21:59+00:00"
    }
  ]
}
```

**Output details**

`type` is one of: `log`, `warn`, `error`, `info`.

#### Errors

* `No team found for the authenticated user.`
* `Feedback not found.`
* `You do not have access to this feedback.`
* `Console log is not available on your plan.`

## How to Connect

Feedbucket MCP supports two authentication methods:

1. **Personal access tokens** — send as an `Authorization: Bearer` header. Used by Cursor and VS Code. See [Access Tokens](#2-access-tokens) to create one manually.
2. **OAuth** — browser sign-in with dynamic client registration. Used by Claude Code, Claude Desktop, Claude.ai, ChatGPT, and Codex.
You can also follow the guided setup for each client in the dashboard at [https://dashboard.feedbucket.app/account/mcp](https://dashboard.feedbucket.app/account/mcp).
MCP endpoint used in all examples below:

```
https://dashboard.feedbucket.app/mcp
```

### Cursor

Cursor connects with a personal access token.

**Add to Cursor (one-click):** On the [MCP settings page](https://dashboard.feedbucket.app/account/mcp/cursor), the **Add to Cursor** button creates an access token labeled "Cursor" and opens a deeplink (`cursor://anysphere.cursor-deeplink/mcp/install?...`) that installs the Feedbucket MCP server into Cursor with the token already configured.

**Manual setup:**

1. Create an access token (see [Access Tokens](#2-access-tokens)).
2. In Cursor, open **Settings → Tools & MCPs → New MCP Server**.
3. Paste the following into `mcp.json`, replacing `YOUR_TOKEN` with your token:

```
{
  "mcpServers": {
    "feedbucket": {
      "url": "https://dashboard.feedbucket.app/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_TOKEN"
      }
    }
  }
}
```

### VS Code

VS Code connects with a personal access token.

**Add to VS Code (one-click):** On the [MCP settings page](https://dashboard.feedbucket.app/account/mcp/vscode), the **Add to VS Code** button creates an access token labeled "VS Code" and opens a deeplink (`vscode:mcp/install?...`) that installs the Feedbucket MCP server into VS Code with the token already configured.

**Manual setup:**

1. Create an access token (see [Access Tokens](#2-access-tokens)).
2. In VS Code, open the Command Palette and run **MCP: Add Server**, then choose HTTP — or paste the following into `mcp.json`, replacing `YOUR_TOKEN` with your token:

```
{
  "servers": {
    "feedbucket": {
      "type": "http",
      "url": "https://dashboard.feedbucket.app/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_TOKEN"
      }
    }
  }
}
```

### Claude Code

Claude Code connects with OAuth by default.
**CLI (recommended):**

```
claude mcp add --transport http feedbucket https://dashboard.feedbucket.app/mcp
claude mcp login feedbucket
```

The login command opens a browser (or prints a URL) for Feedbucket sign-in and authorization. If the redirect fails, paste the callback URL when prompted.
**Token alternative:** You can also use a personal access token via `.mcp.json`:

```
{
  "mcpServers": {
    "feedbucket": {
      "type": "http",
      "url": "https://dashboard.feedbucket.app/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_TOKEN"
      }
    }
  }
}
```

### Claude Desktop

Claude Desktop connects with OAuth.

1. Open **Settings → Connectors**.
2. Choose **Add Custom Connector**.
3. Name: `Feedbucket`.
4. URL: https://dashboard.feedbucket.app/mcp.
5. Add the connector and complete Feedbucket authorization in the browser.

Connectors are tied to your Claude account. If you already connected Feedbucket on Claude.ai, it will appear in Claude Desktop as well.

### Claude.ai

Claude.ai connects with OAuth, using the same Custom Connector flow as Claude Desktop.

1. Open **Settings → Connectors**.
2. Choose **Add Custom Connector**.
3. Name: `Feedbucket`.
4. URL: https://dashboard.feedbucket.app/mcp.
5. Add the connector and complete Feedbucket authorization in the browser.

### ChatGPT

ChatGPT connects with OAuth.

1. Open **Settings → Apps → Advanced settings** and enable **Developer mode**.
2. Go to **Settings → Apps → Create**.
3. Name: `Feedbucket`.
4. URL: https://dashboard.feedbucket.app/mcp.
5. Auth: **OAuth**.
6. Create the app and complete Feedbucket authorization.
7. In a new chat, enable Feedbucket from the **+** menu.

### Codex

Codex connects with OAuth via the CLI.

```
codex mcp add feedbucket --url https://dashboard.feedbucket.app/mcp
codex mcp login feedbucket
```

The login command opens a browser (or prints a URL) for Feedbucket sign-in and authorization.
## Access Tokens

Personal access tokens let clients authenticate to the MCP server with a Bearer header. Cursor and VS Code use this method (and their **Add** buttons create a token for you automatically). Claude Code can also use a token as an alternative to OAuth.

### Create a token

1. Go to [https://dashboard.feedbucket.app/account/access-tokens](https://dashboard.feedbucket.app/account/access-tokens).
2. Create a token with a label (for example, `Cursor` or `Local testing`).
3. Copy the token immediately — it is shown only once and cannot be retrieved later.

Tokens are scoped to `mcp:use` and expire after one year.

### Use a token

Send the token as an `Authorization` header on requests to the MCP endpoint:

```
Authorization: Bearer YOUR_TOKEN
```

Example MCP config (Cursor-style):

```
{
  "mcpServers": {
    "feedbucket": {
      "url": "https://dashboard.feedbucket.app/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_TOKEN"
      }
    }
  }
}
```

Requests without a valid token receive `401 Unauthorized`. Tokens that are missing the `mcp:use` scope receive `403 Forbidden`.

### Connected apps

The same Access Tokens page also lists applications you have connected via MCP using OAuth, so you can see and manage both token-based and OAuth clients in one place.