@port-labs/port-plugins-cli
v0.0.6
Published
CLI for uploading and managing plugins in Port (beta)
Keywords
Readme
@port-labs/port-plugins-cli
CLI for uploading and managing plugins in Port.
Requirements
- Node.js 22+ — Required by
engines.nodein the package. Dependencies rely on APIs available in Node 22+.
Install and use
From npm:
npm install -g @port-labs/port-plugins-cli(Yarn 2+ removed yarn global; use npm install -g for a global install, or run via npx @port-labs/port-plugins-cli without installing.)
Then run port-plugins from any directory:
port-plugins --help
port-plugins list --token YOUR_TOKENOr run without installing:
npx @port-labs/port-plugins-cli --helpAuthorization
Provide credentials in one of these ways (precedence order):
Token (direct)
--token <token>PORT_TOKENorPORT_ACCESS_TOKEN- Config file:
~/.port/configor project.port/config
Client ID + client secret
--client-idand--client-secretPORT_CLIENT_IDandPORT_CLIENT_SECRET- Config file (after
port-plugins config)
The CLI exchanges these for an access token (e.g. for CI).
All requests send Authorization: Bearer <token>.
When you use client ID + secret, the CLI caches the access token in ~/.port/token_cache.json so later commands skip the auth round-trip. If the server rejects the cached token (e.g. after a restart), the CLI clears the cache, gets a new token, and retries automatically.
Where to store credentials: Use a config file (see port-plugins config below), not .zshrc or other shell config. That keeps secrets out of shell history and avoids leaking them if you share or commit shell config. For CI, use environment variables.
Commands
Config (save credentials so you do not paste them every time)
Save client ID + secret or token to a config file. Prefer this over putting secrets in .zshrc.
- Project (default):
port-plugins config— writes.port/configin the current directory. - Global:
port-plugins config --global— writes~/.port/config.
Interactive (terminal only, TTY stdin, and no credential flags on the command): the CLI first asks for region (Port API base URL):
e— EU —https://api.port.iou— US —https://api.us.port.ioo— other — you type the base URL
Enter (empty) is the same ase(EU).
Then it asks whether to use a token (t) or client ID + secret (c); Enter counts as c.
Non-interactive: pass --client-id and --client-secret, or --token; optional --port-api-base-url. Combine with --global when you want the user-level file. Example:port-plugins config --client-id <id> --client-secret <secret>port-plugins config --global --token <token>
Each successful port-plugins config run rewrites the target config file with only the keys from that run (it does not merge with the previous file). That avoids leaving a stale token next to new client credentials, or the reverse.
After config, you can run port-plugins list (and other commands) without passing --token or --client-id / --client-secret each time.
Upload
port-plugins upload --file <path> --title <title> [--params <json>] [--identifier <id>] [--description <text>] [--upsert]--description— Optional description for the plugin.--upsert— Create or replace for this identifier: if the plugin already exists, refresh it instead of failing with a conflict; if not, behave like a normal upload.- Uses the same steps as
port-plugins update <identifier> --file …: presigned HTML upload, then finalize. - Title is always applied on finalize. Description and params change only when you pass
--description/--params; omitting those flags leaves the current values on the server.
- Uses the same steps as
- Identifier, title, description, and
paramslimits — see Plugin metadata reference.
List
port-plugins list— List all plugins for the org.
Get
port-plugins get <identifier>— Get a plugin by identifier.port-plugins get-url <identifier>— Get the URL for a plugin.
Update
port-plugins update <identifier> [--file <path>] [--title <title>] [--description <text>] [--params <json>]- With
--file, re-uploads HTML; without--file, updates metadata only.--descriptionis optional; omit to leave the existing description unchanged. - Field limits and
paramsJSON shape — see Plugin metadata reference.
- With
Delete
port-plugins delete <identifier>
Plugin metadata reference
Use these constraints for upload and update:
| Field | Type / limit | Example |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| identifier | string, 1–100 chars; only A-Za-z0-9@_.+:\/=- (not . or ..) | my-custom-widget |
| title | string, 1–100 chars, required | My Custom Widget |
| description | string, 0–2000 chars, optional | Shows a chart on the dashboard |
| params | JSON object; each key is a param name, value is { type, isRequired, label? }. type is one of: string, number, boolean, array, object, blueprint. At most 5 params can have type: "blueprint". | {"theme":{"type":"string","isRequired":false,"label":"Theme"}} |
Options (global)
--port-api-base-url <url>— Port API base URL when not set in config orPORT_API_BASE_URL(default: https://api.getport.io)
Config file
Created by port-plugins config or manually. Locations (first found wins): project .port/config, then ~/.port/config. Format: key=value, one per line:
token=your-token
# or
client_id=your-client-id
client_secret=your-client-secret
port_api_base_url=https://api.port.io