> For the complete documentation index, see llms.txt.
Skip to main content

Check out Port for yourself ➜ 

Visualize Claude Skills adoption and usage

Implement with AI

Send this guide to your coding agent.

Prerequisite: Install Port MCP

Open plan mode if your tool supports it; otherwise present the plan below filled in and wait for my approval. Implement this Port guide in my org via MCP:

https://docs.port.io/guides/all/visualize-claude-skills-adoption

Read the raw markdown version at https://docs.port.io/guides/all/visualize-claude-skills-adoption.md - it contains every tab and code block without page markup.

Goal: get the guide's core flow working end-to-end in my org; adapting it to fit my existing setup takes priority over matching the guide 1:1.

Plan:
1. Confirm MCP is connected, in the right org, with sufficient permissions.
2. If the guide offers alternative implementation paths (tabs), pick the one matching my installed integrations and tools, confirm it with me, and implement only that path.
3. Diff the guide's data model (blueprints, properties, relations, workflows, actions, agents, automations, integrations, webhook data sources, secrets) against mine.
4. Propose adaptations for gaps, reusing existing blueprints/relations over guide-named duplicates.
5. Flag what needs a UI click, credential, or secret from me, testing MCP capability empirically before ruling anything out. If the guide has a "Set up via API" section, use it for anything MCP can't do before treating a step as UI-only.
6. Stop on any blocker and give me options. Approving this plan authorizes the writes it lists; pause only for writes beyond what's listed.

Build:
- Extend blueprint schema additively when upserting; don't remove or overwrite existing properties, and treat type conflicts as a blocker, not an auto-fix.
- Never print secret values into the chat or logs; ask me to set them in Port, or write them via the secrets API without echoing them back.
- List any mock data in the plan, minimal and labeled mock; once approved, seed it without re-asking, and tell me what you seeded.
- For anything the guide writes downstream (e.g. a webhook target), use a real entity, not a mock.
- For pages/widgets, use the real page identifier from the app URL, not a guessed slug.
- When you hit a UI step confirmed (not assumed) unsupported via MCP and not covered by the guide's API sections, pause, give exact clicks, then resume via MCP.
- Validate and give links after each meaningful step (only a tool-returned URL, no guessed paths); don't proceed if the last run wasn't a success.

Done:
- Run the guide's "Let's test it" steps where possible (e.g. execute a workflow test run) and confirm the expected output exists in Port.
- Summarize adaptations, seeded data, what was mocked or skipped, remaining UI steps, and how to verify.
Supported integration

This guide is scoped to Claude Skills data ingested by Port's Claude integration. For token, cost and model-level Claude metrics, see Visualize Claude metrics.

Most organizations adopting skills cannot answer the questions that matter. Are people using skills at all, or did they try once and stop? Are the same skills coming back day after day, or is everyone building throwaway experiments? And is the knowledge staying locked to individuals, or becoming shared?

This guide walks you through building a Claude Skills adoption dashboard in Port. We'll add a small number of calculation properties to the blueprint the Claude integration already creates, then build a dashboard on top of it. The result reads as a single story:

  • Adoption: Are skills being used, and by how many different skills?
  • Depth: Are people returning to the same skills, or only ever trying new ones?
  • Reuse: Is knowledge staying personal, or becoming reusable by teammates?
  • Repeatability: Which skills have become part of regular workflows?
  • Cost: Where is skill-related spend concentrated?
Claude Skills Adoption & Usage dashboard in Port showing invocation trends, sharing scope breakdowns, and the most consistently used skills
The Claude Skills Adoption & Usage dashboard built in this guide.

Common use cases

  • Measure how broadly and deeply Skills are being adopted.
  • Understand whether knowledge stays personal or becomes reusable.
  • Identify consistently used Skills worth scaling or standardizing.

Prerequisites

This guide assumes the following:

  • You have a Port account and have completed the onboarding process.
  • Port's Claude integration is installed and ingesting data.
  • The claude_ai_skill_usage blueprint exists (created automatically when you install the Claude integration).
  • Your organization is on a Claude Enterprise plan, and the API key used by the integration has the read:analytics scope. Skill usage analytics are unavailable otherwise.

Understanding Claude skill types

Skills hosted by Anthropic. This covers three different things that all carry a sharing setting: Anthropic's own pre-built skills (docx, pptx, xlsx, pdf), custom skills a user uploads on claude.ai (individual to that user), and custom skills uploaded through the Claude API, which are shared workspace-wide.

Skills stored outside Anthropic (Claude Code). Files under .claude/skills/, either committed to a git repository by your team or kept locally on a developer's machine. Anthropic neither hosts them nor knows who can read them, so they carry no sharing setting at all and the share_status property arrives empty rather than missing. Access is governed by repository and local file permissions.

This produces four groups:

share_statusTypeWho can use itWhere it lives
privatePersonalOne individual onlyAnthropic
organizationOrganizationEveryone in the workspaceAnthropic
publicPublicPublished openly, including Anthropic's pre-built skills (such as docx, pptx, xlsx, pdf)Anthropic
Not applicableProjectAnyone with repository access, or just the author for local filesYour git repositories and local files

Names of private skills are not disclosed, so they appear as opaque identifiers such as skill_01Kd8iFQ… rather than readable names.

Port note

Project skills can be measured through the Claude integration without being registered in Port. Teams can later promote proven skills into the Port Skill Registry for centralized discovery and management.

Key metrics overview

The table below is a starting point rather than an exhaustive list. Add or drop metrics to match the questions your organization actually wants answered. Each record in the claude_ai_skill_usage blueprint represents one skill on one day, referred to below as a skill-day.

MetricWhat it measuresWhy it matters
Skill invocationsTotal times skills were invoked per dayHeadline volume signal for adoption
Skills usedHow many different skills were used per dayBreadth of adoption
Avg. invocations per active skillInvocations divided by skills usedSeparates depth from breadth: is usage deepening or just spreading?
Usage by sharing scopeInvocations split into Personal, Project, PublicWhether knowledge is staying individual or becoming reusable
Skill activity by sharing scopeSkill-days grouped by scopeOverall distribution behind the trend
Days active per skillSeparate days each skill was usedDistinguishes habitual tools from one-off experiments
Activity by spend rangeSkill-days bucketed by cost bandWhere skill-related consumption concentrates

Avg. invocations per active skill is the one number that tells you whether an adoption programme is maturing. If invocations and skills-used rise together, people are trying more things. If invocations rise while skills-used stays flat, people are returning to skills that work. The second is what durable adoption looks like.

Set up data model

Add calculation properties

  1. Navigate to your Data model page.
  2. Find and expand the Claude AI Skill Usage (claude_ai_skill_usage) blueprint.
  3. Click the ... button in the top right corner, then Edit JSON.
  4. Merge the following into the blueprint's calculationProperties object, then click Save.
Additional calculation properties (click to expand)
{
"sharing_scope": {
"title": "Sharing Scope",
"icon": "TwoUsers",
"type": "string",
"description": "Personal = one individual. Organization = shared organization-wide in Claude.ai. Public = published openly, including Anthropic built-ins. Project = stored outside Claude.ai and used via Claude Code, where no Claude.ai sharing setting exists.",
"calculation": "if (.properties.share_status == \"private\") then \"Personal\" elif (.properties.share_status == \"organization\") then \"Organization\" elif (.properties.share_status == \"public\") then \"Public\" else \"Project\" end"
},
"spend_band": {
"title": "Spend Range",
"icon": "DefaultProperty",
"type": "string",
"description": "Attributed list price for the skill-day, bucketed so it can be charted as a distribution.",
"calculation": "if (.properties.attributed_list_price // 0) >= 5 then \"Over $5\" elif (.properties.attributed_list_price // 0) >= 1 then \"$1 to $5\" elif (.properties.attributed_list_price // 0) >= 0.1 then \"$0.10 to $1\" else \"Under $0.10\" end"
},
"uses": {
"title": "",
"icon": "DefaultProperty",
"type": "number",
"description": "Alias of invocation count with a blank title, so chart legends read as the line name alone.",
"calculation": ".properties.invocation_count // 0"
},
"skill_row": {
"title": "",
"icon": "DefaultProperty",
"type": "number",
"description": "Always 1. Summing it over a time bucket counts the distinct skills used in that bucket.",
"calculation": "1"
}
}

Reference blueprint

The block below is the full blueprint after adding the four calculation properties above, so you can diff it against your own. The schema section reflects what the Claude integration creates automatically; only calculationProperties needs to be added by hand.

Full reference blueprint (click to expand)
{
"identifier": "claude_ai_skill_usage",
"description": "Org-level Claude skill usage metrics for a single day",
"title": "Claude AI Skill Usage",
"icon": "Claude",
"schema": {
"properties": {
"record_date": { "type": "string", "format": "date-time", "title": "Record Date (UTC)" },
"skill_name": { "type": "string", "title": "Skill Name" },
"skill_display_name": { "type": "string", "title": "Skill Display Name" },
"distinct_user_count": { "type": "number", "title": "Distinct Users" },
"enable_count": { "type": "number", "title": "Enable Count" },
"invocation_count": { "type": "number", "title": "Invocation Count" },
"share_status": { "type": "string", "title": "Share Status" },
"currency": { "type": "string", "title": "Currency" },
"estimated_overage_spend": { "type": "number", "title": "Estimated Overage Spend" },
"attributed_list_price": { "type": "number", "title": "Attributed List Price" },
"chat_conversation_skill_used_count": { "type": "number", "title": "Chat Conversation Skill Uses" },
"code_session_skill_used_count": { "type": "number", "title": "Claude Code Session Skill Uses" },
"cowork_session_skill_used_count": { "type": "number", "title": "Cowork Session Skill Uses" },
"excel_session_skill_used_count": { "type": "number", "title": "Excel Session Skill Uses" },
"powerpoint_session_skill_used_count": { "type": "number", "title": "PowerPoint Session Skill Uses" },
"word_session_skill_used_count": { "type": "number", "title": "Word Session Skill Uses" },
"outlook_session_skill_used_count": { "type": "number", "title": "Outlook Session Skill Uses" }
},
"required": ["record_date", "skill_name"]
},
"mirrorProperties": {},
"calculationProperties": {
"sharing_scope": {
"title": "Sharing Scope",
"icon": "TwoUsers",
"description": "Personal = one individual. Organization = shared organization-wide in Claude.ai. Public = published openly, including Anthropic built-ins. Project = stored outside Claude.ai and used via Claude Code, where no Claude.ai sharing setting exists.",
"calculation": "if (.properties.share_status == \"private\") then \"Personal\" elif (.properties.share_status == \"organization\") then \"Organization\" elif (.properties.share_status == \"public\") then \"Public\" else \"Project\" end",
"type": "string"
},
"spend_band": {
"title": "Spend Range",
"icon": "DefaultProperty",
"description": "Attributed list price for the skill-day, bucketed so it can be charted as a distribution.",
"calculation": "if (.properties.attributed_list_price // 0) >= 5 then \"Over $5\" elif (.properties.attributed_list_price // 0) >= 1 then \"$1 to $5\" elif (.properties.attributed_list_price // 0) >= 0.1 then \"$0.10 to $1\" else \"Under $0.10\" end",
"type": "string"
},
"uses": {
"title": "",
"icon": "DefaultProperty",
"description": "Alias of invocation count with a blank title, so chart legends read as the line name alone.",
"calculation": ".properties.invocation_count // 0",
"type": "number"
},
"skill_row": {
"title": "",
"icon": "DefaultProperty",
"description": "Always 1. Summing it over a time bucket counts the distinct skills used in that bucket.",
"calculation": "1",
"type": "number"
}
},
"aggregationProperties": {},
"relations": {}
}

Visualize metrics

We will create a dashboard that reads top to bottom as one narrative: adoption, then depth, then reuse, then repeatability, then cost.

Create the dashboard

  1. Navigate to your context lake.
  2. Click on the + New button in the left sidebar.
  3. Select New dashboard.
  4. Name the dashboard Claude Skills Adoption & Usage, give it the Claude icon, and click Create.

Add widgets

You can populate the dashboard using either an API script or by manually creating each widget through the UI.

The fastest way to set up the dashboard is by using Port's API to create all widgets at once.

Get your Port API token

  1. Open the Credentials modal.

  2. Click Generate API token.

  3. Copy the generated token and store it as an environment variable:

    export PORT_ACCESS_TOKEN="YOUR_GENERATED_TOKEN"
EU region

If Port is hosted in the EU region, replace api.port.io with api.port-eu.io in the dashboard creation command below.

Create the dashboard with widgets

Save the following JSON to a file named claude_skills_dashboard.json:

Dashboard JSON payload (click to expand)
{
"identifier": "skills-usage-dashboard",
"title": "Claude Skills Adoption & Usage",
"icon": "Claude",
"description": "Understand how Claude Skills are being adopted, shared and reused, which skills are becoming part of regular workflows, and where usage cost is concentrated.",
"type": "dashboard",
"widgets": [
{
"id": "dashboard-widget-root",
"type": "dashboard-widget",
"layout": [
{
"height": 420,
"columns": [
{"id": "kpi_depth", "size": 3},
{"id": "line_depth", "size": 4},
{"id": "line_claude_invocations", "size": 5}
]
},
{
"height": 420,
"columns": [
{"id": "line_library_trend", "size": 7},
{"id": "pie_share_status", "size": 5}
]
},
{
"height": 400,
"columns": [
{"id": "bar_skills_by_name", "size": 12}
]
},
{
"height": 400,
"columns": [
{"id": "bar_top_spend_skills", "size": 12}
]
}
],
"widgets": [
{
"id": "kpi_depth",
"type": "entities-number-chart",
"title": "Avg. Invocations per Active Skill",
"icon": "Claude",
"description": "Rolling 30-Day Avg. Invocations per Active Skill",
"blueprint": "claude_ai_skill_usage",
"chartType": "aggregateByProperty",
"calculationBy": "property",
"property": "invocation_count",
"func": "average",
"averageOf": "total",
"unit": "none",
"dataset": {"combinator": "and", "rules": []}
},
{
"id": "line_depth",
"type": "multi-line-chart",
"title": "Avg Uses per Active Skill Over Time",
"icon": "LineChart",
"description": "Are skills being used more deeply, or just more widely? A rising line means more invocations per active skill, indicating deeper usage of the skills already in use.",
"xAxisTitle": "Week",
"yAxisTitle": "Uses per skill",
"timeInterval": "isoWeek",
"timeRange": {"preset": "last3Months"},
"nullValueDisplayMode": "null",
"baselines": [],
"lines": [
{
"title": "Uses per Skill",
"blueprint": "claude_ai_skill_usage",
"chartType": "aggregatePropertiesValues",
"properties": ["properties.uses"],
"func": "average",
"measureTimeBy": "record_date",
"dataset": {"combinator": "and", "rules": []}
}
]
},
{
"id": "line_claude_invocations",
"type": "multi-line-chart",
"title": "Skill Usage Over Time",
"icon": "LineChart",
"description": "Are skills being adopted? Track how often skills are invoked and how many different skills are used each day. Recent data may be incomplete due to Anthropic's reporting delay.",
"xAxisTitle": "Date",
"yAxisTitle": "Count",
"timeInterval": "day",
"timeRange": {"preset": "lastMonth"},
"nullValueDisplayMode": "null",
"baselines": [],
"lines": [
{
"title": "Skill Invocations",
"blueprint": "claude_ai_skill_usage",
"chartType": "aggregatePropertiesValues",
"properties": ["properties.uses"],
"func": "sum",
"measureTimeBy": "record_date",
"dataset": {"combinator": "and", "rules": []}
},
{
"title": "Skills Used",
"blueprint": "claude_ai_skill_usage",
"chartType": "aggregatePropertiesValues",
"properties": ["properties.skill_row"],
"func": "sum",
"measureTimeBy": "record_date",
"dataset": {"combinator": "and", "rules": []}
}
]
},
{
"id": "line_library_trend",
"type": "multi-line-chart",
"title": "Skill Usage by Sharing Scope Over Time",
"icon": "LineChart",
"description": "Personal skills are used by one individual. Project skills live in the repository and are available to teammates working with that project in Claude Code.",
"xAxisTitle": "Date",
"yAxisTitle": "Skill uses",
"timeInterval": "day",
"timeRange": {"preset": "lastMonth"},
"nullValueDisplayMode": "null",
"baselines": [],
"lines": [
{
"title": "Personal",
"blueprint": "claude_ai_skill_usage",
"chartType": "aggregatePropertiesValues",
"properties": ["properties.uses"],
"func": "sum",
"measureTimeBy": "record_date",
"dataset": {
"combinator": "and",
"rules": [{"property": "share_status", "operator": "=", "value": "private"}]
}
},
{
"title": "Project",
"blueprint": "claude_ai_skill_usage",
"chartType": "aggregatePropertiesValues",
"properties": ["properties.uses"],
"func": "sum",
"measureTimeBy": "record_date",
"dataset": {
"combinator": "and",
"rules": [{"property": "share_status", "operator": "isEmpty"}]
}
},
{
"title": "Public",
"blueprint": "claude_ai_skill_usage",
"chartType": "aggregatePropertiesValues",
"properties": ["properties.uses"],
"func": "sum",
"measureTimeBy": "record_date",
"dataset": {
"combinator": "and",
"rules": [{"property": "share_status", "operator": "=", "value": "public"}]
}
}
]
},
{
"id": "pie_share_status",
"type": "entities-pie-chart",
"title": "Skill Activity by Sharing Scope",
"icon": "PieChart",
"description": "Is knowledge staying personal or becoming reusable? Each skill is counted once for every day it was used, grouped by sharing scope.",
"blueprint": "claude_ai_skill_usage",
"property": "calculation-property#sharing_scope",
"dataset": {"combinator": "and", "rules": []}
},
{
"id": "bar_skills_by_name",
"type": "bar-chart",
"title": "Most Consistently Used Skills",
"icon": "BarChart",
"description": "Which skills have become part of regular workflows? Ranked by how many separate days each was used. Top nine only.",
"blueprint": "claude_ai_skill_usage",
"property": "property#skill_name",
"dataset": {"combinator": "and", "rules": []}
},
{
"id": "bar_top_spend_skills",
"type": "bar-chart",
"title": "Skill Activity by Spend Range",
"icon": "BarChart",
"description": "Which skills are most often associated with higher spend? Each bar is the number of high-spend days, meaning days where requests involving that skill exceeded $5 at list price. Not the skill's own incremental cost.",
"blueprint": "claude_ai_skill_usage",
"property": "calculation-property#spend_band",
"dataset": {"combinator": "and", "rules": []}
}
]
}
]
}

Then run the following command to create the dashboard with all widgets:

curl -s -X POST "https://api.port.io/v1/pages" \
-H "Authorization: Bearer $PORT_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d @claude_skills_dashboard.json | python3 -m json.tool

Next steps

Once your dashboard is in place, consider this next step:

  • Promote proven project skills into the Port Skill Registry so they can be centrally managed, synced from Git, and discovered across the organization.