---
title: "Review the theme taxonomy"
description: "Find duplicate, vague, oversized and stale themes in Deck, propose fixes, and apply them after the user approves."
url: "/docs/agents/workflows/taxonomy-review"
---

This page is an agent-readable workflow for Deck. Humans can follow along. Coding agents should treat the steps as the source of truth.

# Review the theme taxonomy — agent workflow

* **Use it when:** the user asks "clean up our themes", "we have duplicate themes", "review the taxonomy" or "which themes are stale?", or after a large import.
* **Outcome:** each problem theme has a decision. Duplicates are merged, vague themes have clear names and descriptions, oversized themes are split, and stale themes are kept or archived by the user's choice.
* **Needs:** Deck MCP. Every member with MCP access can use the theme write tools. They spend no credits. Subthemes, which help to split a theme, need the Starter plan or higher.

## 1. Probe Deck MCP

Call `get_user_context`. This must be a real tool call.

* 401 Unauthorized: tell the user to connect Deck MCP in this client (Settings → Connections). Stop.
* No Deck tools: fetch and follow [https://docs.getdeck.io/docs/agents/getting-started/prompts/ai-pm.md](https://docs.getdeck.io/docs/agents/getting-started/prompts/ai-pm.md). Stop this workflow until the tools work.

## 2. List every theme

Call `explore_themes` with `limit` set to 100 and `include_empty` set to `true`. Page with `offset` until you have every theme. Keep the ID, name, description, `insight_count`, `recent_insights` and `latest_insight_at` of each theme.

Make these calls at the same time, to find stale themes:

* `explore_themes` with `sort` set to `latest_insight_at` and `direction` set to `asc`. The first rows had no new insights for the longest time.
* `explore_themes` with `window_days` set to 180 and `limit` set to 100. Page with `offset` until `hasMore` is `false`. A theme of the full list that is in no page of this list had no insights in the last 180 days.

## 3. Find the problems

Check each theme against these four tests. A theme can fail more than one.

* **Duplicate:** two themes cover the same product area. Look for similar names, and call `explore_themes` with a `query` word to find themes whose name or description match. Compare a sample of their insights with `explore_insights` and `theme_id`. An insight that is in both themes shows the overlap: `explore_insights` with `insight_id` lists its `theme_associations`.
* **Vague:** the name does not say a product area, for example "General", "Other", "Issues" or "UX". Or the name says a feeling or a solution. Or the description is empty.
* **Oversized:** the theme is at the top of Deck's `insight_count` order and holds several product areas. Call `explore_subthemes` with its `theme_id` and `segment_scope: "all_customers"`. Subthemes that belong to different product areas show where to split.
* **Stale:** step 2 shows no recent insights, or `insight_count` is 0. The area can still be valid: a fixed problem also stops new feedback.

## 4. Propose the fixes

Show the user one table: theme, problem, Deck's evidence (counts and dates), proposed fix. Use these fixes:

| Problem               | Fix                                 | Tools                                              |
| --------------------- | ----------------------------------- | -------------------------------------------------- |
| Duplicate             | Merge into the clearest theme       | `merge_themes`, then `update_theme` for the target |
| Vague                 | New name and description            | `update_theme`                                     |
| Oversized             | Split one area into a new theme     | `create_theme`, then `move_theme_insights`         |
| Stale with insights   | Keep, or merge into a broader theme | `merge_themes`                                     |
| Stale with 0 insights | Keep, or archive                    | `archive_theme`                                    |

Name and description rules:

* A name has 1 to 120 characters and must be unique in the organization, without case. Archived themes keep their names. A taken name returns `CONFLICT`. When the conflict is an archived theme, the message gives its ID for `restore_theme`.
* To give a merge target the name of a source, first rename the source with `update_theme`, then merge, then rename the target.
* A description has at most 1000 characters. It says what belongs in the theme and what does not.
* When PII redaction is on, Deck masks the emails and phone numbers in the theme descriptions that it returns, for example `j***@acme.com`. Never send a masked description back: Deck refuses it with `VALIDATION_ERROR`. Write a new description without the masked text, or do not change the description.

Ask: "Apply these fixes?" Wait for a yes. Then get an explicit yes for each merge and each archive.

## 5. Apply the fixes

* **Merge:** `merge_themes` with `target_theme_id` and 1 to 10 `source_theme_ids`. Deck moves every insight link to the target, removes duplicate links and archives the sources. Read `links_moved` and `archived_theme_ids`. It cannot be fully undone: `restore_theme` brings back an empty source theme.
* **Rename or describe:** `update_theme` with `theme_id` and one or more of `name`, `description` and `color`.
* **Split:** `create_theme` with `name` and `description`. Then `move_theme_insights` with `source_theme_id`, `target_theme_id` and up to 100 `insight_ids` for each call. Get the IDs from `explore_subthemes` with a `subtheme_id` and `view` set to `insights`, or from `explore_insights` with `theme_id`. Read `moved` and `not_linked`.
* **Archive:** `archive_theme` with `theme_id`. `restore_theme` with the same `theme_id` undoes it.

One unknown insight ID fails the whole call with `NOT_FOUND`. The missing IDs are in `error.details.details.missing_insight_ids`. Remove them and call again.

## 6. Check the result

* Call `explore_themes` with each changed `theme_id`. For a merge, use the target ID.
* Call `explore_themes` for the full list again. Show the user the changed themes with Deck's counts and their `deck_url`.
* Tell the user that subthemes do not change now. Deck rebuilds them on the next synthesis run.

For a full redesign of the themes, fetch and follow [https://docs.getdeck.io/docs/agents/workflows/design-taxonomy.md](https://docs.getdeck.io/docs/agents/workflows/design-taxonomy.md).

## Rules

* Base each finding on Deck's data: counts, dates, subthemes and sample insights. Do not guess from names alone.
* Quote Deck's numbers. Do not compute your own.
* Show the plan and get a yes before you call write tools. `merge_themes` is a sensitive write: get an explicit yes for each merge, every time. Do the same for each `archive_theme` call.
* Do not archive a theme that still has insights. Merge it into the theme that should hold them.
* After each write, check for a top-level `error` key. When `idempotency.replayed` is `true`, Deck did not run the write again. See [Write responses and retries](/docs/integrations/mcp#write-responses-and-retries).
* If the user has more than one Deck organization, call `select_organization` first and pass `org_id` on every call.

## Done when

* Each problem theme has a fix that the user approved or declined.
* Each approved fix returned success, and `explore_themes` shows the result.
* The user knows that subthemes refresh on the next synthesis run.

---

[View full sitemap](/docs/sitemap)
