port-labs/port-skills

port-dashboards

Build and update Port dashboard pages: widgets (table, number chart, pie chart, bar chart, multi-line chart, markdown, iframe, links, action card, action-runs table, entity details, AI agent), the 12-column row layout, sidebar placement, and private-page ru…

View source

How to use

  1. Copy the installation command and review the source package before installing it in your own agent environment.
  2. Check the source document for required tools, credentials and supported hosts.
  3. Describe your input and desired deliverable; review the output against the source material.
npx skills add https://github.com/port-labs/port-skills --skill port-dashboards

Before you start

  • Installation does not include a model subscription, API allowance or permission to access your files.
  • Repository stars and installation counts describe activity, not an independent quality or security test.
Original skill document

Rendered from the source repository. Headings, examples, code, tables, links, and referenced images are preserved.

Port dashboard pages

A Port dashboard page is a sidebar entry made of one or more widgets (tables, charts, markdown, links, and more) arranged in a 12-column grid. This skill is reference-only: static knowledge about widget schemas, the layout grid, sidebar placement, and dataset filter syntax, drawn from Port's dashboard page schema and public docs. It doesn't need a live Port account or MCP server to produce a correct dashboard payload, only a real account to actually create the page.

Out of scope: building your own custom-code widget (a React/TypeScript iframe plugin uploaded via port-plugins-cli) is the nested `port-dashboard-plugins` skill, not this one. Blueprint and property modeling (what a dataset can filter on) is owned by the port-blueprints skill; this skill only covers how those properties map onto widget and dataset fields. The full search rule grammar (all operators, and/or/not nesting) is Port's Search and query syntax; this skill covers the subset relevant to widget datasets. Who can view or edit a page once it exists, including private pages shared with specific users or teams, is the port-permissions skill's page-permissions reference, not this one; this skill only covers a private page's own creation and visibility mechanics (see Step 5).

Skill class

Reference skill: the widget schemas, grid rules, and dataset syntax below are static and enough to hand-author a correct dashboard JSON payload. If the Port MCP server is connected, its dashboard tools (upsert_dashboard_page, upsert_widget, get_page, get_sidebar, load_widget_schema, list_entities, list_blueprints) are an optional enhancement: they create the page for you and let you sample real entities to validate a dataset before saving. Without them, use the fallback in every step below: the Port UI's dashboard editor, or the Pages API / Swagger directly.

Prerequisites

  • Go over the port-getting-started skill first if this is your first time

working with Port.

  • The blueprint(s) the dashboard's widgets will query already exist, with

the properties you plan to filter, group, or chart on.

  • Optional: the Port MCP server connected in your agent, for live dataset

validation and one-shot page creation (see Skill class above). Without it, use the Port UI or the Pages API with a client_id/client_secret pair (... menu > Credentials in the Port app). Search search_port_knowledge_sources for anything this skill doesn't cover.

Step 1 - Decide sidebar placement

Precondition: a new dashboard page needs a home in the sidebar. Action: if MCP is available, call get_sidebar to inspect the existing folder structure before creating the page. If a single folder clearly matches the dashboard's topic, place the page there (parent on the page). If several folders are plausible, ask the user which one they prefer instead of guessing. If nothing matches, place the page at the sidebar root, creating a new folder only when the dashboard starts a new category of its own. Fallback: without MCP, open the Port UI's sidebar and read the folder tree directly, or GET /v1/pages (see references/dashboards.md) to list existing pages and their parent/after fields.

Step 2 - Choose widgets and validate each dataset

Precondition: you know which entities and metrics the dashboard should show. Action: pick one widget type per metric or view from the twelve types in references/dashboards.md, matching the widget to the question ("how many" -> number chart, "trend over time" -> multi-line chart, "browse rows" -> table). For every widget with a dataset, resolve the target blueprint first, then validate the dataset before creating the widget: if MCP is available, run list_entities with the dataset as query, countOnly: true, and a small limit (3-5), to confirm the count and that the returned entities look right. If the call errors or the results look wrong, call list_blueprints to check property names, types, and enum values, fix the dataset, and retry. Fallback: without MCP, run the equivalent call yourself: POST /v1/blueprints/{blueprint}/entities/search with the same query body (see references/dashboards.md for the rule grammar and examples), or build the widget in the Port UI and use its built-in entity count/preview before saving.

Step 3 - Lay out the page (12-column grid)

Precondition: the widget set for the page is known. Action: arrange widgets into rows. Every row's column sizes must sum to exactly 12, a row holds at most 4 columns, each column is 3-12 wide, and every row is at least 400px tall. Every layout column's id must match a widget's id exactly, one-to-one. See references/dashboards.md for the layout schema and worked examples. Fallback: the Port UI's drag-and-drop dashboard editor enforces these constraints for you, use it when hand-writing a layout for 6+ widgets gets error-prone.

Step 4 - Create or update the page

Precondition: widgets and layout are ready. Action: if MCP is available, call upsert_dashboard_page with the full identifier, title, widgets, and layout. For 5+ widgets, try the full payload first; if it fails on size or complexity, fall back to an incremental flow: create an empty page (widgets: []), add widgets one at a time with parallel upsert_widget calls, then call get_page and pass its widgets straight through to a final upsert_dashboard_page call that only adds the new layout. Fallback: without MCP, create the page from the Port UI's dashboard editor, or call the Pages API directly: POST /v1/pages (or PATCH /v1/pages/{identifier} if it already exists) with type: "dashboard" and a single root dashboard-widget wrapping your widgets and layout (see references/dashboards.md for the exact envelope Port expects).

Step 5 - Handle private pages correctly

Precondition: the dashboard is personal, not for the whole organization. Action: set visibility: "private" and omit parent and after entirely, whether via MCP or the raw API. Port keeps private pages in a separate sidebar section and appends an owner-specific suffix to the identifier in its response, use that returned identifier for any follow-up edit, widget update, or delete, not the one you sent. Fallback: from the UI, set Visibility to Private when creating the page (the field is read-only after creation for non-admins); an org admin must first grant the create:private-pages scope if the option isn't visible. See references/dashboards.md for the full rules and an example payload.

Examples

Worked, complete JSON payloads for every widget type, a full layout, and the raw API envelope are in references/dashboards.md.

Common pitfalls

SymptomCauseFix
Widget renders empty or with the wrong entitiesDataset filters on the wrong property, wrong blueprint, or a typo'd enum valueValidate with list_entities/entities/search before creating the widget, see Step 2
Page creation rejected: "column sizes must sum to 12"A row's column size values don't add to 12Recompute the row, max 4 columns, each 3-12 wide, see Step 3
Page creation rejected: row height too smallA row's height is under 400pxSet every row to at least 400
Widget never renders / layout looks brokenA layout column's id doesn't match any widget's idKeep widget ids and layout column ids in exact sync
Private page edits silently target the wrong page, or 404Used the identifier you sent instead of the one Port returned (owner-suffixed)Store and reuse the identifier from the create/get_page response, see Step 5
Private page creation rejectedparent or after was set alongside visibility: "private"Omit both fields entirely for private pages
Number chart shows 0 or an errorchartType-specific required fields missing (e.g. func/averageOf for aggregateByProperty)Check the per-chartType required fields in references/dashboards.md
Pie/bar chart property rejectedproperty isn't prefixed (property#, relation#, scorecard#, ...) or a meta field ($identifier, $title, $team)Use the prefixed form, see references/dashboards.md

Quick reference

  • Widget types: table-entities-explorer, entity-details,

action-card-widget, action-runs-table-widget, links-widget, ai-agent, markdown, iframe-widget, entities-number-chart, entities-pie-chart, bar-chart, multi-line-chart. Full schema for each: references/dashboards.md.

  • Layout: rows of 1-4 columns, column size 3-12 summing to exactly 12 per

row, row height >= 400px, column id matches a widget id.

  • Visibility: "org" (default, sidebar-placeable via parent/after) or

"private" (no parent/after, identifier gets an owner suffix).

  • Dataset shape: { combinator: "and" | "or", rules: [...] }, each rule a

property/relation/scorecard clause. Full grammar: references/dashboards.md.

  • MCP tools (optional, live account): get_sidebar, list_blueprints,

list_entities, load_widget_schema, upsert_widget, upsert_dashboard_page, get_page.

  • Fallback without MCP: Port's UI dashboard editor, or the

Pages API (POST/PATCH/GET /v1/pages) and POST /v1/blueprints/{blueprint}/entities/search for dataset checks.

  • For custom-code widgets instead of built-in widget types, see the nested

port-dashboard-plugins skill.

Related by task

from this repository

More skills

All skills
port-labs
Community

port-blueprints

Model a Port context lake data model using blueprints, defining identifiers, titles, icons, properties, relations, and calculation, mirror, or aggregation properties, then author them with the raw Port API. Use when asked to create a Port blueprint, define a Port data model, add a property to a blueprint, relate two blueprints, add a calculation property, add a mirror property, or add an aggregation property.

installs
1
GitHub stars
3
Updated
Oct 12
port-labs
Community

port-getting-started

Set up Port and connect it to your coding agent: sign up for a Port account, install Port's MCP server, and optionally the Port CLI. Use when asked to 'get started with Port', 'set up Port', 'connect Port MCP', 'install the Port MCP server', 'how do I use Port from Claude Code/Cursor/VS Code', or before using any other skill in this repo for the first time.

installs
1
GitHub stars
3
Updated
Oct 12
port-labs
Community

port-permissions

Configure Port's role-based access control: context lake (blueprint/entity) permissions (read, register, update, or delete entities, down to a single property or relation) and page/dashboard view/edit permissions. Use when asked to 'set up Port permissions', 'restrict who can edit an entity', 'only let the owning team modify this blueprint', 'add a dynamic read policy to a blueprint', 'control who can view a Port dashboard or catalog page', or 'why can this user see/edit something they shouldn't

installs
1
GitHub stars
3
Updated
Oct 12
port-labs
Community

port-skill-creator

Author a new Agent Skill for this repo (port-labs/port-skills): scaffold the skills/port- / directory, write valid frontmatter, structure the body as a short router into references/ and assets/, validate it, and regenerate the README index. Use when asked to create a new Port skill, add a skill to this repo, help me write a SKILL.md, contribute a skill, port an internal Port AI skill to this repo, or fix a skill that fails validate-skill.js.

installs
1
GitHub stars
3
Updated
Oct 12