Add Claude Console plugin#73
Conversation
The APIs generally do not allow filtering by the default workspace, so we have to use scripts to enable this
📝 WalkthroughWalkthroughClaude Console v1 adds plugin metadata, required Admin API key configuration and validation, object type and scope definitions, data streams for organization data, spend, usage, API keys, default dashboards, index mappings, and documentation. ChangesClaude Console v1 plugin rollout
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Comment |
|
@clarkd something to consider, is what this plugin should be called. As mentioned, this only api key usage data, not users using Claude Teams/Pro or Enterprise. |
There was a problem hiding this comment.
Actionable comments posted: 10
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@plugins/ClaudeConsole/v1/dataStreams/scripts/workspaces.js`:
- Line 7: The workspace import logic is spreading data.data directly into
result, which can throw if the response body is missing the array or it is
empty. Update the workspaces handling in the scripts/workspaces.js flow to
safely guard the spread in the data.data path, using a fallback empty array or a
presence check before building result. Keep the fix localized around the result
assignment so the import degrades gracefully when the response shape is
unexpected.
In `@plugins/ClaudeConsole/v1/dataStreams/usage.json`:
- Around line 174-188: The usage report schema includes dimensions that will
always be empty with the current grouping, so fix the data definition in
usage.json by either adding service_tier, context_window, and account_id to the
report’s group_by configuration or removing those columns from the selected
fields. Use the existing usage report dimension definitions around service_tier,
context_window, and account_id to align the columns with the grouping behavior
so only non-null fields are exposed.
In `@plugins/ClaudeConsole/v1/dataStreams/workspaces.json`:
- Around line 48-52: The archived_at field is declared with the wrong shape in
the workspaces JSON schema, so it won’t be treated as a date in the UI. Update
the archived_at entry in workspaces.json to use shape: "date", matching the
created_at field and other ISO 8601 date-time values. Keep the change scoped to
the archived_at schema definition so sorting/parsing behavior is corrected
without affecting other fields.
In `@plugins/ClaudeConsole/v1/defaultContent/apiKey.dash.json`:
- Line 58: The dashboard tile title is not using title case; update the “Token
usage” label in the relevant tile definition to “Token Usage” to match the
dashboard naming guideline. Locate the tile config by its title field in the
dashboard JSON and change only the displayed title text.
In `@plugins/ClaudeConsole/v1/defaultContent/member.dash.json`:
- Line 67: The dashboard tile titles in member.dash.json are not following the
title-case guideline. Update the tile title strings for the affected entries,
including the ones currently labeled Account usage and API keys created by this
member, so they match the title case used by the other dashboard tile names.
In `@plugins/ClaudeConsole/v1/defaultContent/overview.dash.json`:
- Line 21: The dashboard tile titles in overview.dash.json are using sentence
case instead of title case. Update the affected tile name fields (including the
ones for Spend (this month), Cost by model, Top workspaces by cost, and Token
usage by model, plus the other referenced entries) to use title case
consistently, and use the surrounding dashboard tile definitions to locate the
relevant title properties.
In `@plugins/ClaudeConsole/v1/defaultContent/workspace.dash.json`:
- Line 67: Normalize the dashboard tile names in the workspace.dash.json content
to title case: update the tile entries for Cost over time, Usage by model, and
API keys in this workspace so their title strings use proper title
capitalization. Keep the change limited to the affected tile title fields so the
dashboard naming aligns with the title case guideline.
In `@plugins/ClaudeConsole/v1/docs/README.md`:
- Line 1: The README top-level heading in the Claude Console docs repeats the
plugin name, so update the first heading to a neutral title that matches the
docs guideline. Change the heading in the README file to something like “Before
you start” or “Prerequisites” so it no longer duplicates the plugin name and
better reflects the section’s purpose.
In `@plugins/ClaudeConsole/v1/indexDefinitions/default.json`:
- Around line 13-14: The index mapping source type names in default.json are
plugin-prefixed and should be renamed to match the upstream entity names
instead. Update the ClaudeConsole/v1 indexDefinitions entries referenced by the
source type values used for the workspace, API key, and member mappings so they
read as upstream names like workspace, api key, and member rather than Claude
Workspace or similar. Make the change consistently across all affected mapping
objects in the default definition so the source type labels follow the existing
naming guidelines.
In `@plugins/ClaudeConsole/v1/ui.json`:
- Around line 5-10: The UI copy for this field needs to follow the plugin text
rules: update the label in the ClaudeConsole v1 UI config to sentence-style
casing rather than title case, and rewrite the help text in the same config so
it does not start with “Your” and instead begins with a verb while staying
concise and neutral. Use the existing field entry in ui.json (the Admin API key
field) as the target for these copy-only changes.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 4ac7bbb8-6b7b-449b-8cf0-8f0b45eb2acd
⛔ Files ignored due to path filters (1)
plugins/ClaudeConsole/v1/icon.svgis excluded by!**/*.svg
📒 Files selected for processing (22)
plugins/ClaudeConsole/v1/configValidation.jsonplugins/ClaudeConsole/v1/custom_types.jsonplugins/ClaudeConsole/v1/dataStreams/apiKeys.jsonplugins/ClaudeConsole/v1/dataStreams/cost.jsonplugins/ClaudeConsole/v1/dataStreams/members.jsonplugins/ClaudeConsole/v1/dataStreams/organization.jsonplugins/ClaudeConsole/v1/dataStreams/scripts/apiKeys.jsplugins/ClaudeConsole/v1/dataStreams/scripts/cost.jsplugins/ClaudeConsole/v1/dataStreams/scripts/usage.jsplugins/ClaudeConsole/v1/dataStreams/scripts/workspaces.jsplugins/ClaudeConsole/v1/dataStreams/usage.jsonplugins/ClaudeConsole/v1/dataStreams/workspaces.jsonplugins/ClaudeConsole/v1/defaultContent/apiKey.dash.jsonplugins/ClaudeConsole/v1/defaultContent/manifest.jsonplugins/ClaudeConsole/v1/defaultContent/member.dash.jsonplugins/ClaudeConsole/v1/defaultContent/overview.dash.jsonplugins/ClaudeConsole/v1/defaultContent/scopes.jsonplugins/ClaudeConsole/v1/defaultContent/workspace.dash.jsonplugins/ClaudeConsole/v1/docs/README.mdplugins/ClaudeConsole/v1/indexDefinitions/default.jsonplugins/ClaudeConsole/v1/metadata.jsonplugins/ClaudeConsole/v1/ui.json
clarkd
left a comment
There was a problem hiding this comment.
A few CodeRabbit comments to address here.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
plugins/ClaudeConsole/v1/docs/README.md (1)
36-40: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winDocument the actual graph object type names.
Lines 38-40 call these types
Claude Workspace,Claude API Key, andClaude Member, butplugins/ClaudeConsole/v1/custom_types.jsonregisters them asWorkspace,API Key, andMember. Keeping the README aligned with the real type names avoids confusion in scope pickers and object drilldowns.Proposed fix
-| **Claude Workspace** | `GET /v1/organizations/workspaces` | A workspace in your organization — the container for API keys and the primary cost/usage attribution dimension. | -| **Claude API Key** | `GET /v1/organizations/api_keys` | An API key, including its status, partially-redacted hint, creating user, and owning workspace. | -| **Claude Member** | `GET /v1/organizations/users` | An organization member, including email, name, and organization role. | +| **Workspace** | `GET /v1/organizations/workspaces` | A workspace in your organization — the container for API keys and the primary cost/usage attribution dimension. | +| **API Key** | `GET /v1/organizations/api_keys` | An API key, including its status, partially-redacted hint, creating user, and owning workspace. | +| **Member** | `GET /v1/organizations/users` | An organization member, including email, name, and organization role. |🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@plugins/ClaudeConsole/v1/docs/README.md` around lines 36 - 40, The README’s object type table uses display names that do not match the registered graph types. Update the entries in the object type section to use the exact names defined in custom_types.json and referenced by the ClaudeConsole type system, specifically the types surfaced by the workspace/API key/member mappings. Keep the API source and description text, but align the object type labels so scope pickers and drilldowns show the same names as the actual registered types.plugins/ClaudeConsole/v1/defaultContent/overview.dash.json (1)
42-42: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winScalar
labelstill uses sentence case.The tile
titlewas corrected to "Spend (This Month)" (line 21), but the visualisationlabelhere is still "Spend (this month)". Align it with title case for consistency.✏️ Proposed fix
- "label": "Spend (this month)" + "label": "Spend (This Month)"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@plugins/ClaudeConsole/v1/defaultContent/overview.dash.json` at line 42, The visualisation label is still using sentence case while the tile title uses title case; update the `label` value in the same overview dashboard content to match the corrected `title` formatting. Locate the scalar configuration in `overview.dash.json` and change the `label` for the Spend tile so it consistently reads in title case alongside the existing `title` field.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@plugins/ClaudeConsole/v1/dataStreams/usage.json`:
- Around line 27-30: The usage stream grouping still leaves account_id
ungrouped, so any emitted account_id field will remain null. Update the
group_by[] definition in usage.json (the same place that already includes
workspace_id, api_key_id, model, service_tier, and context_window) to either add
account_id or remove it from the output if it is not needed. Make sure the
change matches how usage.js builds the member filter and grouped dimensions.
---
Outside diff comments:
In `@plugins/ClaudeConsole/v1/defaultContent/overview.dash.json`:
- Line 42: The visualisation label is still using sentence case while the tile
title uses title case; update the `label` value in the same overview dashboard
content to match the corrected `title` formatting. Locate the scalar
configuration in `overview.dash.json` and change the `label` for the Spend tile
so it consistently reads in title case alongside the existing `title` field.
In `@plugins/ClaudeConsole/v1/docs/README.md`:
- Around line 36-40: The README’s object type table uses display names that do
not match the registered graph types. Update the entries in the object type
section to use the exact names defined in custom_types.json and referenced by
the ClaudeConsole type system, specifically the types surfaced by the
workspace/API key/member mappings. Keep the API source and description text, but
align the object type labels so scope pickers and drilldowns show the same names
as the actual registered types.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 45f8cb0f-5e21-46d5-8273-236049ff07a7
📒 Files selected for processing (14)
plugins/ClaudeConsole/v1/custom_types.jsonplugins/ClaudeConsole/v1/dataStreams/apiKeys.jsonplugins/ClaudeConsole/v1/dataStreams/cost.jsonplugins/ClaudeConsole/v1/dataStreams/scripts/workspaces.jsplugins/ClaudeConsole/v1/dataStreams/usage.jsonplugins/ClaudeConsole/v1/dataStreams/workspaces.jsonplugins/ClaudeConsole/v1/defaultContent/apiKey.dash.jsonplugins/ClaudeConsole/v1/defaultContent/member.dash.jsonplugins/ClaudeConsole/v1/defaultContent/overview.dash.jsonplugins/ClaudeConsole/v1/defaultContent/scopes.jsonplugins/ClaudeConsole/v1/defaultContent/workspace.dash.jsonplugins/ClaudeConsole/v1/docs/README.mdplugins/ClaudeConsole/v1/indexDefinitions/default.jsonplugins/ClaudeConsole/v1/ui.json
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
plugins/ClaudeConsole/v1/dataStreams/cost.json (2)
87-94: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winMove
patternonto thedescriptioncolumn definition.Lines 92-94 currently add a separate metadata entry with only
"pattern": ".*". That leaves an unnamed column descriptor inmetadatainstead of constrainingdescription, which is likely to break schema parsing or silently drop the validation you intended.Proposed fix
{ "name": "description", "displayName": "Description", - "shape": "string" - }, - { + "shape": "string", "pattern": ".*" }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@plugins/ClaudeConsole/v1/dataStreams/cost.json` around lines 87 - 94, The metadata entry for the `description` column is split incorrectly: the standalone object with `pattern` should be attached to the existing `description` column definition in the same metadata item. Update the `description` object in `cost.json` so it includes the `pattern` constraint alongside `name`, `displayName`, and `shape`, and remove the separate unnamed pattern-only entry.
23-30: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy liftExpose a
modelcolumn or the overview contract breaks.The overview dashboard groups
{{dataStreams.cost}}bymodel, but this stream only requestsworkspace_idanddescription, and its schema never declares amodelfield. As-is, the “Cost By Model” tile has nothing valid to group on. Parsedescriptioninto amodelproperty incost.jsand add it tometadata, or change the dashboard to group bydescriptioninstead.Also applies to: 55-95
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@plugins/ClaudeConsole/v1/dataStreams/cost.json` around lines 23 - 30, The cost data stream is missing the field the overview expects for grouping by model, so update the cost stream contract in cost.js/cost.json to expose a model property derived from description and include it in metadata, using the existing cost stream parsing and schema definitions. If model cannot be added, then change the overview dashboard’s grouping to use description consistently, but keep the identifiers in the cost stream and dashboard aligned so the “Cost By Model” tile has a valid group-by field.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@plugins/ClaudeConsole/v1/docs/README.md`:
- Line 57: The README wording for default-workspace attribution is inaccurate
because the usage stream maps missing workspace IDs into the synthetic default
bucket while only api_key_id remains nullable. Update the text in the
default-workspace attribution section to distinguish the default workspace
bucket from a null api_key_id, and make sure the wording aligns with the
normalization behavior in usage.js.
---
Outside diff comments:
In `@plugins/ClaudeConsole/v1/dataStreams/cost.json`:
- Around line 87-94: The metadata entry for the `description` column is split
incorrectly: the standalone object with `pattern` should be attached to the
existing `description` column definition in the same metadata item. Update the
`description` object in `cost.json` so it includes the `pattern` constraint
alongside `name`, `displayName`, and `shape`, and remove the separate unnamed
pattern-only entry.
- Around line 23-30: The cost data stream is missing the field the overview
expects for grouping by model, so update the cost stream contract in
cost.js/cost.json to expose a model property derived from description and
include it in metadata, using the existing cost stream parsing and schema
definitions. If model cannot be added, then change the overview dashboard’s
grouping to use description consistently, but keep the identifiers in the cost
stream and dashboard aligned so the “Cost By Model” tile has a valid group-by
field.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 8a57c72f-7690-49b5-9085-91221cc8e5fe
📒 Files selected for processing (5)
plugins/ClaudeConsole/v1/dataStreams/cost.jsonplugins/ClaudeConsole/v1/dataStreams/scripts/cost.jsplugins/ClaudeConsole/v1/dataStreams/scripts/usage.jsplugins/ClaudeConsole/v1/defaultContent/overview.dash.jsonplugins/ClaudeConsole/v1/docs/README.md
💤 Files with no reviewable changes (1)
- plugins/ClaudeConsole/v1/dataStreams/scripts/usage.js
🧩 Plugin PR Summary📦 Modified Plugins
📋 Results
🔍 Validation Details✅
|
🔌 Plugin overview
sk-ant-admin…) sent via thex-api-keyheader (with a staticanthropic-versionheader) againsthttps://api.anthropic.com. Validated on setup viaGET /v1/organizations/me.🖼️ Plugin screenshots
Plugin configuration
Default dashboards
🧪 Testing
Built and tested end-to-end against a live, authenticated tenant (not just file validation):
configValidationprobe (GET /v1/organizations/me) returns 200.squaredup objects.squaredup test):usage— flattens the nesteddata[].results[]time-buckets into rows; auto-selectsbucket_width(1m/1h/1d) from the timeframe and sizeslimitto stay within the API's per-bucket caps; bracketed array params (group_by[],workspace_ids[],api_key_ids[],account_ids[]) verified in the resolved request URL.cost— daily USD;amountunit verified empirically by computing implied $/token against Claude's published list prices — they match exactly only whenamountis treated as cents (/100), catching a would-be 100× error.workspaces/apiKeys/members— return one flat row per object; double-as import streams and visible dashboard tables; optional API-side scope filters (workspace_id,created_by_user_id) tested with a two-object proof.squaredup validatepasses clean (data streams, import definition, UI, icon, default content, config validation, custom types all present).nullworkspace/API-key, it also can't be used in some apis to filter by, so we have to do it via thepostRequestScript🔮 Future work
This does not query individual workspace settings, i.e. to list what skills, files, models, and managed agents are on a workspace.
This can come in an updated version of the plugin, but requires us to get the user to provide individual api keys for each workspace they want to access so we can see their details.
Similar to the Sanity plugin with how it handles dataset queries (Although that is blocked by needing dependant imports)
📚 Checklist
Summary by CodeRabbit