World's Best Sales CLI
Project description
World's Best Sales CLI
████████╗██╗ ██╗███████╗ ██████╗ ███████╗███████╗██╗ ██████╗███████╗
╚══██╔══╝██║ ██║██╔════╝ ██╔═══██╗██╔════╝██╔════╝██║██╔════╝██╔════╝
██║ ███████║█████╗ ██║ ██║█████╗ █████╗ ██║██║ █████╗
██║ ██╔══██║██╔══╝ ██║ ██║██╔══╝ ██╔══╝ ██║██║ ██╔══╝
██║ ██║ ██║███████╗ ╚██████╔╝██║ ██║ ██║╚██████╗███████╗
╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝
██████╗██╗ ██╗
██╔════╝██║ ██║
██║ ██║ ██║
██║ ██║ ██║
╚██████╗███████╗██║
╚═════╝╚══════╝╚═╝
[paces at the front of the conference room]
Listen up. I got us a new tool. It's called The Office CLI.
60 sales commands. You can combine them however you want. You can create any sales play.
Runs in your terminal, Claude Code, Claude Cowork, or Codex. Connects to LinkedIn and HubSpot.
The point is: this is how we beat Staples.
[looks directly at camera]
Alright — let me show you how to get it.
Install
For users:
pipx install the-office-cli
For contributors (develop on the latest source):
git clone https://github.com/your-org/the-office-cli.git && cd the-office-cli
python3 -m venv venv && source venv/bin/activate
pip install -e .
Use it where you work
Claude Code — run Claude Code, then:
pipx install the-office-cli
Codex — run Codex, then:
pipx install the-office-cli
Claude Cowork
Claude Cowork → Settings → Connectors → Add custom connector → The Office
Quick start
This is some examples how you can use it:
Understand
the-office tour # menu of every command + description
the-office <command> --schema # full JSON contract + example
the-office <command> --dry-run # preview
Create an account
the-office create-account \
--company-name "Dunder Mifflin" \
--website dundermifflin.com \
--email michael@dundermifflin.com \
--password thatsWhatSheSaid2026
Log in
the-office login \
--email michael@dundermifflin.com \
--password thatsWhatSheSaid2026
Connect LinkedIn
the-office linkedin connect account
Search for accounts
echo '{
"keywords": "print shop",
"industry": "Printing Services",
"headcount": "51-200",
"location": "Scranton, PA",
"limit": 25
}' | the-office linkedin search classic accounts
Search for leads
echo '{
"job_position": ["Founder", "Co-Founder", "CEO", "CSO", "VP of Sales", "Director of Sales"],
"current_company": ["Lackawanna Printing", "Electric City Press", "Scranton Print Works", "Keystone Graphics", "Pocono Press", "NEPA Printing Co", "Steamtown Print Shop", "Valley Print & Copy", "Wyoming Avenue Printers", "Dickson City Press"],
"location": "Scranton, PA",
"limit": 175
}' | the-office linkedin search classic leads
Create campaign
echo '{
"name": "Lackawanna County Blitz",
"note": "Hi {first_name}, Michael Scott from Dunder Mifflin — same-day paper delivery with a dedicated rep. Open to exploring?",
"follow_up_note": "{first_name}, our clients save 15-20% vs big box suppliers.",
"follow_up_delay": 3,
"daily_outreach_limit": 25,
"filters": {
"job_position": ["Founder", "Co-Founder", "CEO", "CSO", "VP of Sales", "Director of Sales"],
"current_company": ["Lackawanna Printing", "Electric City Press", "Scranton Print Works", "Keystone Graphics", "Pocono Press", "NEPA Printing Co", "Steamtown Print Shop", "Valley Print & Copy", "Wyoming Avenue Printers", "Dickson City Press"],
"location": "Scranton, PA"
},
"total_leads_to_source": 175
}' | the-office campaign create custom
Send invite
the-office linkedin send invitation \
--provider-id ACoAABxyz123 \
--message "Hi Jan, Michael Scott from Dunder Mifflin — same-day paper delivery with a dedicated rep. Open to exploring?"
Combine commands
Combine any command with any other. JSON in, JSON out. Ask an agent. Build the sales plays no other sales tool could.
Find a job posting for an Office Manager and send an invite
echo '{"keywords": "office manager scranton"}' \
| the-office linkedin search classic jobs \
| jq -r '.items[0].poster.provider_id' \
| xargs -I {} the-office linkedin send invitation \
--provider-id {} \
--message "Saw you'"'"'re hiring an Office Manager — Dunder Mifflin handles the paper, same-day delivery. Happy to get you set up before day one."
Find someone asking about paper suppliers and send an invite
echo '{"keywords": "best paper supplier scranton"}' \
| the-office linkedin search classic posts \
| jq -r '.items[0].author.provider_id' \
| xargs -I {} the-office linkedin send invitation \
--provider-id {} \
--message "Saw your post asking about paper suppliers — Dunder Mifflin delivers same-day in Lackawanna County. Happy to chat."
Find top 5 campaigns by booked meeting rate
for id in $(the-office campaign list | jq -r '.items[].id'); do
the-office dashboard conversations --campaign $id \
| jq --arg id "$id" '
([.links[] | select(.target == "Outreached") | .value] | add // 0) as $out |
([.links[] | select(.target == "Booked Meeting") | .value] | add // 0) as $booked |
{campaign_id: $id, outreached: $out, booked: $booked,
rate: (if $out > 0 then ($booked / $out * 100 | floor) else 0 end)}'
done | jq -s 'sort_by(-.rate) | .[0:5]'
Find top 5 job positions by booked meeting rate
# Pull lead IDs that reached "Booked Meeting" in the conversations Sankey
BOOKED=$(the-office dashboard conversations \
| jq -c '[.links[] | select(.source == "Booked Meeting") | .target | tonumber]')
# Group leads by position, count bookings, compute rate
the-office lead list \
| jq --argjson booked "$BOOKED" '.items
| group_by(.position)
| map({
position: .[0].position,
total: length,
booked: ([.[] | select(.id as $id | $booked | any(. == $id))] | length),
rate: (([.[] | select(.id as $id | $booked | any(. == $id))] | length) / length * 100 | floor)
})
| sort_by(-.rate)
| .[0:5]'
Commands
60 commands across 12 groups:
info — 1 command
tour
auth — 5 commands
loginlogoutwhoamicreate-accountfire-drill
campaign — 8 commands
listgetupdatedeletestatuscreate customcreate aicreate signals
lead — 6 commands
listgetcreateupdatedeleteimport
linkedin — 20 commands
meconnect accountreconnect accountcheck accountretrieve profileretrieve companysend invitationsend messagestart chatlist relationslist chatslist messageslist user messagessearch parameterssearch classic leadssearch classic accountssearch classic postssearch classic jobssearch sales navigator leadssearch sales navigator accounts
account — 6 commands
listgetcreateupdatedeleteimport
dashboard — 2 commands
funnelconversations
report — 1 command
generate
outreach — 1 command
list
user — 5 commands
listgetcreateupdatedelete
settings — 2 commands
getupdate
task — 3 commands
sync acceptedsync conversationsstatus
Layout
the-office-cli/
├── pyproject.toml
├── README.md
├── CLAUDE.md
├── src/the_office_cli/
│ ├── main.py
│ ├── config.py
│ ├── cli/
│ │ ├── main.py
│ │ ├── decorators.py
│ │ └── flags.py
│ ├── commands/
│ │ ├── auth.py
│ │ ├── campaign.py
│ │ ├── lead.py
│ │ ├── linkedin.py
│ │ ├── account.py
│ │ ├── dashboard.py
│ │ ├── report.py
│ │ ├── outreach.py
│ │ ├── user.py
│ │ ├── settings.py
│ │ ├── task.py
│ │ └── info.py
│ ├── network/
│ │ ├── session.py
│ │ └── errors.py
│ └── utils/
│ ├── output.py
│ ├── schema.py
│ └── registry.py
└── tests/
Tech stack
- Status: stable (v1.0.0)
- Language: Python 3.11+
- CLI: Click 8+
- HTTP: httpx 0.27+
- Auth: JWT in
~/.the-office/session.json - Config:
~/.the-office/config.json - Build: setuptools, entry
the-office - Tests: pytest
Contributing
PRs welcome. Here's the dev flow:
git clone https://github.com/your-org/the-office-cli.git && cd the-office-cli
python3 -m venv venv && source venv/bin/activate
pip install -e .
pytest
License
MIT
Contact
Email:
Website:
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file the_office_cli-1.0.2.tar.gz.
File metadata
- Download URL: the_office_cli-1.0.2.tar.gz
- Upload date:
- Size: 51.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
65ab0da7e5b9375d2a75d488179e13b74609eeb90c65b3387b5ca03c07e077c0
|
|
| MD5 |
2720455e9ac93a37973fb3b6e2d2af91
|
|
| BLAKE2b-256 |
d6b141c9fa0bb25a1b299488f2ed87437dd4b6dd2fffbaaa1b9c6a3a7abf0b03
|
File details
Details for the file the_office_cli-1.0.2-py3-none-any.whl.
File metadata
- Download URL: the_office_cli-1.0.2-py3-none-any.whl
- Upload date:
- Size: 52.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
291704e333b6c32efc9a5e34f102a088dcbf5420a605ef9bbb74408028950161
|
|
| MD5 |
baaa1f507cbe20274bbcddd1eb66a47c
|
|
| BLAKE2b-256 |
9b23bda3f48d7860cb91685305d2535206635845f29f33f6710640b4ed25e0a4
|