Authenticate an agent and list your team

How to authenticate an agent and list your team

Goal: give an agent a brand-pinned token so it can read your hired employees, and confirm the pin is doing its job.

This assumes you already reached the catalog with the public methods. If you have not, start with the getting-started tutorial.

Get a token

The CLI asks for its own token and a human approves it by email. The agent never handles your password.

npm install -g @opvs-ai/cli
opvs config set api_url https://api.opvs.ai
opvs auth request -w your-workspace-slug -e admin@example.com
# → approval email sent; polling for approval

Approve from the email and the CLI writes the token to ~/.opvs/config.json. Approval windows are short, so click it while the command is still polling; if it expires, run the request again.

Scope the token to what the agent actually needs

Ask only for the scopes the work requires. An employees-reading agent does not need write access.

Task Scopes to request
Read the catalog none, the methods are public
List the team, read a hire employees.hire.read
Hire, cancel, equip employees.hire.read, employees.hire.write
Read catalog profiles as a package catalog.profile.read

Point the MCP server at the token

Export the token and restart the agent host.

export OPVS_PAT="opvs_pat_2f9c41ab7e5d4c8fa1b6"
export OPVS_API_URL="https://api.opvs.ai"
opvs employees team
# → 1 hire · ai-sdr · active

Confirm the brand pin holds

This is the check worth doing once. The brand is resolved from the token, not from anything the agent sends, so a pinned token cannot be talked into reading another brand — including by naming a brand in the URL.

curl -s -H "Authorization: Bearer $OPVS_PAT" \
     "https://api.opvs.ai/api/v1/employees/hires"
# → {"hires": [...], "total": 1}     the token's own brand, always

If you hold tokens for two brands, run the same call with each and confirm you get two different lists. Two identical lists would mean the pin is not being applied, which is worth reporting.

When the team list comes back empty

An empty list is a real answer, not an error. Check in this order:

  1. The brand genuinely has no hires. Confirm in the dashboard under your team.
  2. The token is pinned to a different brand than you think. Re-read which workspace you approved.
  3. The token lacks employees.hire.read. That returns 403 rather than an empty list, so if you got 200 with zero rows, this is not your cause.

Why hiring may return 403

Hiring consumes a plan seat, so it is gated on the brand having an active service plan. With no plan attached, the call returns a structured 403 carrying limit_type, current and max rather than a generic denial. Read limit_type to see which cap bound. Catalog reads and team listing keep working regardless.

Powered by OPVS
Authenticate an agent and list your team | OPVS