npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@abimaelmartell/pco-cli

v0.1.4

Published

Agent-friendly TypeScript CLI for the Planning Center API.

Readme

pco-cli

Agent-friendly TypeScript CLI for the Planning Center API, intended for npm publishing.

Planning Center exposes APIs for products including Calendar, Check-Ins, Giving, Groups, People, and Services. This CLI focuses on the Services product for worship planning workflows.

Install

From npm (after the package is published):

npm install -g @abimaelmartell/pco-cli
pco health

The registry package is scoped because npm rejects unscoped pco-cli as too similar to existing cp-cli. The installed binaries are still pco and pco-cli.

From this repository:

npm install
npm run build
npm link
pco health

npm install and npm run build alone do not put pco on PATH. Use npm link for a local checkout, or run npm run dev -- health.

Configuration

Copy .env.example to .env and set credentials:

cp .env.example .env

To store credentials once for every working directory, copy the same file to ~/.config/pco/env (or $XDG_CONFIG_HOME/pco/env). Override the path with PCO_CONFIG_PATH if needed.

Supported authentication inputs:

  • PCO_ACCESS_TOKEN for bearer token flows.
  • PCO_CLIENT_ID and PCO_SECRET for basic auth. Planning Center personal access tokens are labeled Client ID + Secret.
  • PCO_APP_ID is a compatible alias of PCO_CLIENT_ID. If both are set to different values, the CLI exits with an error.

You can also pass credentials via CLI flags: --access-token, --client-id (alias --app-id), and --secret. Flags override environment values. Environment values override a project .env, which overrides the global config file. You do not need to pass flags on every command when credentials are in the environment or a config file.

Bearer PCO_ACCESS_TOKEN / --access-token wins over basic auth when both are present.

Agent skill

A portable Agent Skill lives at .agents/skills/pco-cli/SKILL.md. Cursor, Claude Code, Codex, and other compatible agents load it from that path automatically in this repo. The skill is the source of truth for calling the CLI, including the songs + keys + musicians playbook (plan-items add-song with --arrangement-id and --key-id; do not use create-worship-plan when keys matter).

To use the CLI from another project or globally:

mkdir -p ~/.agents/skills/pco-cli
curl -fsSL https://raw.githubusercontent.com/abimaelmartell/pco-cli/main/.agents/skills/pco-cli/SKILL.md \
  -o ~/.agents/skills/pco-cli/SKILL.md

Project copy (Cursor also reads .cursor/skills/):

mkdir -p .agents/skills/pco-cli
curl -fsSL https://raw.githubusercontent.com/abimaelmartell/pco-cli/main/.agents/skills/pco-cli/SKILL.md \
  -o .agents/skills/pco-cli/SKILL.md

Usage

The CLI prints JSON so automation agents can parse output reliably.

Health check

pco health

JSON includes ok, version (from package.json), baseUrl, auth (basic, bearer, or none), and clientReady.

Service Types

List available service types:

pco service-types list
pco service-types list --per-page 10 --offset 0

Songs

Search for songs by title:

pco songs search "Amazing Grace"
pco songs search "How Great" --per-page 5

Create or update library songs (Planning Center assignable fields: title, admin, author, copyright, ccli_number, hidden, themes):

pco songs get <song-id>
pco songs create --title "Holy Forever" --author "Chris Tomlin" --ccli-number 7200535
pco songs update <song-id> --hidden true --themes "Praise"

Tags replace the full set. Look up IDs first:

pco tag-groups list --tags-for song --include tags
pco tag-groups tags <tag-group-id>
pco songs tags <song-id>
pco songs assign-tags <song-id> --tag-ids 5,9

Arrangements and keys

Keys belong to an arrangement, not directly to a song. Creating a song usually adds a default arrangement; list it before adding keys.

pco arrangements list <song-id> --include keys
pco arrangements create <song-id> --name "Default" --meter 4/4 --bpm 72
pco arrangements update <song-id> <arrangement-id> --chord-chart "[G]Holy forever"
pco arrangements assign-tags <song-id> <arrangement-id> --tag-ids 12

pco keys list <song-id> <arrangement-id>
pco keys create <song-id> <arrangement-id> --starting-key G --ending-key G
pco keys update <song-id> <arrangement-id> <key-id> --starting-key A --name "Acoustic"

--starting-key / --ending-key use Planning Center values (C, Cm, F#, …). --alternate-keys is a JSON array of {"name":"Capo 3","key":"A"}.

Keys do not have their own tags in the Services API. Tag songs and arrangements instead.

People

Search for people by name:

pco people search "John Smith"
pco people search "Sarah" --per-page 10

Teams

List teams for a service type, and positions for a team:

pco teams list <service-type-id>
pco teams positions <team-id>

Plans

Create and manage service plans:

# List plans
pco plans list <service-type-id>
pco plans list <service-type-id> --filter future --order sort_date

# Get a specific plan (includes planning_center_url for the Services web UI)
pco plans get <service-type-id> <plan-id>

# Create a plan with optional service time (returns plan_time id for reminders)
pco plans create <service-type-id> \
  --title "Sunday Worship" \
  --series-title "Summer Series" \
  --public \
  --starts-at "2026-08-30T10:00:00Z" \
  --ends-at "2026-08-30T11:30:00Z"

`--starts-at` and `--ends-at` must be ISO 8601 datetimes with a timezone. `--ends-at` requires `--starts-at` and must be later than the start time.

# List times on a plan
pco plan-times list <service-type-id> <plan-id>

Plan Items (Songs)

Add songs to a plan:

# List items in a plan
pco plan-items list <service-type-id> <plan-id>

# Add a song by ID
pco plan-items add-song <service-type-id> <plan-id> --song-id <song-id>

# Add a song by title (must match exactly one song across every search page)
pco plan-items add-song <service-type-id> <plan-id> --title "Amazing Grace"

# Add with arrangement and key
pco plan-items add-song <service-type-id> <plan-id> \
  --song-id <song-id> \
  --arrangement-id <arrangement-id> \
  --key-id <key-id>

Song items always send title from the song resource (same as the Planning Center UI) plus song_id. Without title, Services shows "New Item".

Team Member Assignments

Assign people to plans:

# List team members on a plan
pco plan-team-members list <service-type-id> <plan-id>

# See who still needs the first Accept/Decline scheduling email (all assigned members)
pco plan-team-members notify-status <service-type-id> <plan-id>

# Assign a person to a plan
pco plan-team-members assign <service-type-id> <plan-id> <person-id> <team-id> \
  --position "Worship Leader" \
  --prepare-notification

Team Reminders

Set automated reminder emails for teams:

# Set team reminders (days before service)
pco plan-reminders set <service-type-id> <plan-time-id> \
  --team-reminders '{"<team-id>": 7, "<team-id-2>": 3}'

The team_reminders object maps team IDs to the number of days (0-7) before the service time to send automated reminder emails.

Complete Worship Planning Workflow

Create a full worship plan in one command:

pco create-worship-plan <service-type-id> \
  --title "Sunday Morning Service" \
  --starts-at "2026-08-30T10:00:00Z" \
  --ends-at "2026-08-30T11:30:00Z" \
  --series-title "Summer Worship" \
  --public \
  --songs "Amazing Grace" "How Great Thou Art" "Oceans" \
  --assignments '[{"person_id":"123","team_id":"10","position":"Worship Leader"}]' \
  --team-reminders '{"10": 7, "11": 3}'

This command:

  1. Validates assignment JSON and reminder offsets, then looks up each song title in the church library (fails before creating anything if a title is missing or not unique)
  2. Creates a plan with the specified title and series
  3. Adds a service time, including team_reminders when provided
  4. Adds the matched songs in order (song_id and title — Planning Center default arrangement/key)
  5. Assigns team members with their positions
  6. Returns planning_center_url from the plan resource (the Services web UI URL, not the API links.self)

When the setlist includes specific keys, do not use create-worship-plan. Follow the Worship plan with keys and musicians playbook in .agents/skills/pco-cli/SKILL.md (keys create if needed, then plan-items add-song with --arrangement-id and --key-id).

Important API Limitations

Scheduling Email ("Accept/Decline") Not Supported

Planning Center's "Send scheduling email" button (the one that sends Accept/Decline links to team members) is NOT available via the API. This was confirmed by Planning Center in planningcenter/developers#1475.

Workarounds:

  1. Automated Reminders: Use team_reminders when creating or updating plan times. This sends automated reminder emails to teams at a specified number of days before the service.

  2. Manual Sending: After creating a plan via the CLI, use the returned planning_center_url to open the plan in the Planning Center web UI and manually send scheduling emails.

  3. Check Notification Status: Use plan-team-members notify-status (or list) to see notification_sent_at, prepare_notification, and notification_prepared_at and who still needs the first scheduling email.

Project layout

  • src/cli.ts wires the command-line interface.
  • src/client.ts contains the reusable Planning Center API client.
  • src/helpers.ts maps CLI arguments and JSON:API resources.
  • src/config.ts loads and validates environment configuration.
  • src/index.ts exports library primitives for programmatic use.

Publishing

Releases are automated with semantic-release and Conventional Commits. On every push to main, .github/workflows/publish.yml runs tests and then publishes only when the commits since the last release include a feat or fix (semver). npm authenticates with trusted publishing (GitHub OIDC). There is no NPM_TOKEN secret.

Use a Conventional Commit PR title and squash-merge. CI rejects titles that do not match. Do not bump version in package.json or push v* tags by hand — semantic-release publishes to npm, tags vX.Y.Z, and commits the new version back to package.json / package-lock.json.

| PR title | Semver bump | Example | | --- | --- | --- | | feat: add song tags | minor (0.1.2 → 0.2.0) | new command or capability | | fix: handle empty search | patch (0.1.2 → 0.1.3) | bug fix | | feat!: drop Node 18 or a BREAKING CHANGE: footer | major (0.1.2 → 1.0.0) | breaking change | | docs:, chore:, ci:, test:, refactor: | no publish | docs and tooling |

perf: also publishes a patch. A GitHub Release and git tag (vX.Y.Z) are created with the npm publish. The release commit is chore(release): X.Y.Z [skip ci] so it does not start another publish.

The workflow filename must stay publish.yml so it matches the trusted publisher on npmjs.com. Do not set NODE_AUTH_TOKEN or NPM_TOKEN on that job, and do not pass registry-url to actions/setup-node — both make npm skip OIDC trusted publishing.

One-time setup on npmjs.com

  1. Sign in as the npm user abimaelmartell (the scope must match your npm username).
  2. On npmjs.com open @abimaelmartell/pco-cli → Settings → Trusted Publisher.
  3. Choose GitHub Actions and set:
    • Organization or user: abimaelmartell
    • Repository: pco-cli
    • Workflow filename: publish.yml (filename only, including .yml)
    • Environment name: leave blank
    • Allowed actions: npm publish
  4. After a successful OIDC publish, optionally set Publishing access to require 2FA and disallow tokens.

You can do the same attach step from a local npm 11.5.1+ CLI:

npm trust github @abimaelmartell/pco-cli --repo abimaelmartell/pco-cli --file publish.yml --allow-publish

Local dry run (does not publish):

npm run check
npm run build
npm pack --dry-run
npx semantic-release --dry-run