Install
$ agentstack add skill-basecamp-basecamp-cli-basecamp ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
/basecamp - Basecamp Workflow Command
Full CLI coverage: 155 endpoints across todos, cards, messages, files, schedule, check-ins, timeline, recordings, templates, webhooks, subscriptions, lineup, chat, gauges, assignments, notifications, and accounts.
Agent Invariants
MUST follow these rules:
- Choose the right output mode —
--jqwhen you need to filter/extract data;--jsonfor full JSON;--mdwhen presenting results to a human (see Output Modes below). Never pipe to externaljq— use--jqinstead. - Parse URLs first with
basecamp url parse ""to extract IDs - Comments are flat - reply to parent recording, not to comments
- Check context via
.basecamp/config.jsonbefore assuming project - Content fields accept Markdown and @mentions — message body and comment content accept Markdown syntax; the CLI converts to HTML automatically. Use Markdown formatting (lists, bold, links, code blocks) for rich content. Four mention syntaxes are available (prefer deterministic for agents):
[@Name](mention:SGID)— zero API calls, embeds SGID directly (preferred for agents)[@Name](person:ID)— one API call, resolves person ID to SGID via pingable set@sgid:VALUE— inline SGID embed for pipeline composability@Name/@First.Last— fuzzy name resolution (may be ambiguous)
For todos, documents, and cards, content is sent as-is — use plain text or HTML directly.
- Project scope is mandatory for most commands — via
--inor.basecamp/config.json. Cross-project exceptions:basecamp reports assignedfor assigned work,basecamp assignmentsfor structured assignment views,basecamp reports overduefor overdue todos,basecamp reports schedulefor upcoming schedule across all projects,basecamp recordingsfor browsing by type,basecamp notificationsfor notifications,basecamp gauges listfor account-wide gauges.
Output Modes
Choosing a mode:
| Goal | Flag | Format | |------|------|--------| | Filter/extract JSON data | --jq '' | Built-in jq filter (no external jq needed). Implies --json; filter runs on the envelope. | | Filter in agent mode | --agent --jq '' | Filter runs on data-only payload (no envelope), matching --agent contract. | | Full JSON output | --json | JSON envelope: {ok, data, summary, breadcrumbs, meta} | | Show results to a user | --md / -m | GFM tables, task lists, structured Markdown | | Automation / scripting | --agent | Success: raw JSON data (no envelope); errors: {ok:false,...} object; no interactive prompts |
Always pass --json or --md explicitly — auto-detection depends on config and may not produce the format you expect. Use --md when composing reports, summarizing data, or displaying results inline. --agent is for headless integration scripts.
Other modes: --quiet (success: raw JSON, no envelope; errors: {ok:false,...}), --ids-only, --count, --stats (session statistics), --styled (force ANSI), -v / -vv (verbose/trace), --jq '' (built-in jq filter — see below).
CLI Introspection
Navigate unfamiliar commands with --agent --help — returns structured JSON describing any command:
basecamp todos --agent --help
{"command":"todos","path":"basecamp todos","short":"...","long":"...","usage":"...","notes":["..."],
"subcommands":[{"name":"sweep","short":"...","path":"basecamp todos sweep"}],
"flags":[{"name":"assignee","type":"string","default":"","usage":"..."}],
"inherited_flags":[{"name":"json","shorthand":"j","type":"bool","default":"false","usage":"..."}]}
Walk the tree: start at basecamp --agent --help for top-level commands, then drill into any subcommand. Commands include notes with domain-specific agent hints (e.g., "Cards do NOT support --assignee filtering").
Pagination
basecamp --limit 50 # Cap results (default varies by resource)
basecamp --all # Fetch all (may be slow for large datasets)
basecamp --page 1 # First page only, no auto-pagination
--all and --limit are mutually exclusive. --page cannot combine with either.
Smart Defaults
--assignee meresolves to current user--due tomorrow/--due +3/--due "next week"- natural date parsing- Project from
.basecamp/config.jsonif--innot specified - Multiple identities use named profiles:
basecamp profile create, then select one with global--profileorBASECAMP_PROFILE=.
Quick Reference
> Note: Most queries require project scope (via --in or .basecamp/config.json). Cross-project exceptions: basecamp reports assigned, basecamp assignments, basecamp reports overdue, basecamp reports schedule, basecamp recordings , basecamp notifications, basecamp gauges list.
| Task | Command | |------|---------| | List projects | basecamp projects list --json | | My todos (in project) | basecamp todos list --assignee me --in --json | | My todos (cross-project) | basecamp reports assigned --json (defaults to "me") | | My schedule (cross-project) | basecamp reports schedule --json (upcoming events across all projects) | | All todos (cross-project) | basecamp recordings todos --json (no assignee data — cannot filter by person) | | Overdue todos (in project) | basecamp todos list --overdue --in --json | | Overdue todos (cross-project) | basecamp reports overdue --json | | Assign todo | basecamp assign [id...] --to --in --json | | Assign card | basecamp assign [id...] --card --to --in --json | | Assign card step | basecamp assign [id...] --step --to --in --json | | Create todo | basecamp todo "Task" --in --list --json | | Create todolist | basecamp todolists create "Name" --in --json | | Complete todo | basecamp done --json | | List cards | basecamp cards list --in --json | | Create card | basecamp card "Title" --in --json | | Move card | basecamp cards move --to [--position N] --in --json | | Move card to on-hold | basecamp cards move --on-hold --in --json | | Post message | basecamp message "Title" "Body" --in --json | | Post with @mention | basecamp message "Title" "Hey @First.Last, ..." --in --json | | Post silently | basecamp message "Title" "Body" --no-subscribe --in --json | | Post to chat | basecamp chat post "Message" --in --json | | Add comment | basecamp comment "Text" --in --json | | List attachments | basecamp attachments list --json | | Download attachments | basecamp attachments download --out /tmp/ | | Show + download | basecamp todos show --download-attachments --json | | Stream attachment to stdout | basecamp attachments download --file --out - | | Search | basecamp search "query" --json | | Parse URL | basecamp url parse "" --json | | Upload file | basecamp files uploads create [--vault ] --in --json | | Download file | basecamp files download --in | | Stream file to stdout | basecamp files download --out - --in | | Download storage URL | basecamp files download "https://storage.3.basecamp.com/.../download/report.pdf" | | My assignments | basecamp assignments --json (priorities + non-priorities) | | Overdue assignments | basecamp assignments due overdue --json | | Completed assignments | basecamp assignments completed --json | | Notifications | basecamp notifications --json | | Mark notification read | basecamp notifications read --json | | Gauges (account-wide) | basecamp gauges list --json | | Gauge needles | basecamp gauges needles --in --json | | Create needle | basecamp gauges create --position 75 --color green --in --json | | Account details | basecamp accounts show --json | | Watch timeline | basecamp timeline --watch |
URL Parsing
Always parse URLs before acting on them:
basecamp url parse "https://3.basecamp.com/2914079/buckets/41746046/messages/9478142982#__recording_9488783598" --json
Returns: account_id, project_id, type, recording_id, comment_id (from fragment).
URL patterns:
/buckets/27/messages/123- Message 123 in project 27/buckets/27/messages/123#__recording_456- Comment 456 on message 123/buckets/27/card_tables/cards/789- Card 789/buckets/27/card_tables/columns/456- Column 456 (for creating cards)/buckets/27/todos/101- Todo 101/buckets/27/uploads/202- Upload/file 202/buckets/27/documents/303- Document 303/buckets/27/schedule_entries/404- Schedule entry 404
Replying to comments:
# Comments are flat - reply to the parent recording_id, not the comment_id
basecamp url parse "https://...messages/123#__recording_456" --json
# Returns recording_id: 123 (parent), comment_id: 456 (fragment) - comment on 123, not 456
basecamp comment 123 "Reply" --in
Decision Trees
Finding Content
Need to find something?
├── Know the type + project? → basecamp list --in --json
│ (some groups have default list behavior; use --agent --help if unsure)
├── My assigned work? → basecamp assignments --json (priorities + non-priorities)
│ Or: basecamp reports assigned --json (traditional view, defaults to "me")
├── My overdue assignments? → basecamp assignments due overdue --json
├── My notifications? → basecamp notifications --json
├── Upcoming schedule? → basecamp reports schedule --json (cross-project)
├── Overdue across projects? → basecamp reports overdue --json
├── Browse by type cross-project? → basecamp recordings --json
│ (types: todos, messages, documents, comments, cards, uploads)
│ Note: Defaults to active status; use --status archived for archived items
│ ⚠ No assignee data — cannot filter by person; use reports assigned instead
├── Full-text search? → basecamp search "query" --json
└── Have a URL? → basecamp url parse "" --json
Modifying Content
Want to change something?
├── Have URL? → basecamp url parse "" → use extracted IDs
├── Have ID? → basecamp update --field value
├── Change status? → basecamp recordings trash|archive|restore
└── Complete todo? → basecamp done
Common Workflows
Link Code to Basecamp Todo
# Get commit info and comment on todo (use printf %q for safe quoting)
COMMIT=$(git rev-parse --short HEAD)
MSG=$(git log -1 --format=%s)
basecamp comment "Commit $COMMIT: $(printf '%s' "$MSG")" --in
# Complete when done
basecamp done
Track PR in Basecamp
# Create todo for PR work
basecamp todo "Review PR #42" --in --assignee me --due tomorrow
# When merged
basecamp done
basecamp chat post "Merged PR #42" --in
Bulk Process Overdue Todos
# Preview overdue todos
basecamp todos sweep --overdue --dry-run --in
# Complete all with comment
basecamp todos sweep --overdue --complete --comment "Cleaning up" --in
Mentioning people (preferred — deterministic)
# 1. Look up the person
basecamp people pingable --jq '.data[] | select(.name == "Jane Smith")'
# => {"id": 42000, "attachable_sgid": "BAh7CEkiCG...", "name": "Jane Smith"}
# 2. Use SGID in Markdown mention syntax (zero API calls during post)
basecamp comment 123 "Hey [@Jane Smith](mention:BAh7CEkiCG...), check this" --in
# Or use person ID (one lookup during post)
basecamp comment 123 "Hey [@Jane Smith](person:42000), check this" --in
Mentioning people (interactive — may be ambiguous)
# Fuzzy matching: use @First.Last to reduce ambiguity
basecamp comment "@Jane.Smith, please review this" --in
basecamp message "Update" "cc @Jane, @Alex" --in
basecamp chat post "@Jane, done!" --in
# Ambiguous names return an error with suggestions
# Use @First.Last for disambiguation
Move Card Through Workflow
# List columns to get IDs
basecamp cards columns --in --json
# Move card to column
basecamp cards move --to --in
# Move card to specific position in column (1-indexed)
basecamp cards move --to --position 1 --in
# Move card to on-hold section of its current column
basecamp cards move --on-hold --in
# Move card to on-hold section of a specific column (numeric ID)
basecamp cards move --to --on-hold --in
# Move card to on-hold section of a named column (requires --card-table)
basecamp cards move --to "Column Name" --on-hold --card-table --in
Download File from Basecamp
basecamp files download --in --out ./downloads
# Download attachment from a storage URL (no --in needed)
basecamp files download "https://storage.3.basecamp.com/123/blobs/abc/download/report.pdf"
# Stream to stdout (for piping)
basecamp files download --out - --in
Working with Attachments (Multimodal Agent Workflow)
Messages, todos, cards, and documents may contain images and file attachments (mockups, screenshots, annotated designs). Show commands surface these as field-scoped collections — content_attachments and/or description_attachments — keyed by which rich-text attribute contained them. The notice field hints at the download command.
Step 1: Fetch the recording and check for attachments
basecamp todos show --json
# Response includes description_attachments when attachments are present
# Messages/documents use content_attachments; cards may have both
# The notice field hints: "3 attachment(s) — download: basecamp attachments download "
Step 2 (one-shot): Download attachments with the show command
# --download-attachments fetches + downloads in one shot
basecamp todos show --download-attachments --json
# content_attachments/description_attachments entries now include "path" pointing to local files
# Downloads to OS temp dir by default, or specify: --download-attachments /tmp/att
Step 2 (two-step alternative): Download separately
# Download all at once (shows progress on stderr)
basecamp attachments download --out /tmp/attachments
Step 3: View images with your native file-read tool For multimodal LLMs (Claude, Gemini), use your file-read tool on the path from the response to view downloaded images directly — no browser needed. This surfaces visual context (mockups, screenshots, annotated designs) that is often the most important part of a Basecamp todo or message.
# Stream a single image to stdout for piping
basecamp attachments download --file mockup.png --out -
# Select by index when names collide
basecamp attachments download --index 2 --out -
Key pattern: When a show command response contains content_attachments or description_attachments, always download and view them — visual context is often more important than the text content. Use --download-attachments for one-shot fetch+download, or follow the breadcrumb hint for two-step control.
Resource Reference
Projects
basecamp projects list --json # List all
basecamp projects show --json # Show details
basecamp projects create "Name" --json # Create
basecamp projects update --name "New" # Update
Todos
basecamp todos list --in --json # List in project
basecamp todos list --assignee me --in # My todos
basecamp todos list --overdue --in # Overdue only
basecamp todos list --status completed --in # Completed
basecamp todos list --list --in # In specific list
basecamp todo "Task" --in --list --assignee me --due tomorrow
basecamp done [id...] # Complete (multiple OK)
basecamp reopen # Uncomplete
basecamp assign [id...] --to --in # Assign to-do (multiple OK)
basecamp unassign [id...] --from --in # Remove to-do assignee (multiple OK)
basecamp assign [id...] --card --to --in # Assign card
basecamp unassign [id...] --card --from --in # Remove card assignee
basecamp assign [id...] --step --to --in # Assign card step
basecamp unassign [id...] --step --from --in # Remove step assignee
basecamp todos position --to 1 #
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [basecamp](https://github.com/basecamp)
- **Source:** [basecamp/basecamp-cli](https://github.com/basecamp/basecamp-cli)
- **License:** MIT
- **Homepage:** https://basecamp.com/cli
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.