Skip to content
Merged
15 changes: 15 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "freeticket",
"description": "Official FreeTicket plugin: run and grow ticketed events from your agent — CLI, MCP server and brand-voice copy.",
"owner": {
"name": "FreeTicket",
"url": "https://github.com/AppFreeticket"
},
"plugins": [
{
"name": "freeticket",
"source": "./",
"description": "Skills for the ft CLI, the MCP server and event copy, plus the freeticket MCP server wired in."
}
]
}
20 changes: 20 additions & 0 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "freeticket",
"displayName": "FreeTicket",
"version": "0.1.1",
"description": "Operate FreeTicket from your agent: skills for the ft CLI, the MCP server and event copy, plus the freeticket MCP server (B2B, superadmin and public contracts as tools).",
"author": {
"name": "FreeTicket",
"url": "https://freeticket.co"
},
"homepage": "https://freeticket.co",
"repository": "https://github.com/AppFreeticket/agent-skills",
"license": "MIT",
"keywords": ["freeticket", "ticketing", "events", "latam", "mcp", "cli"],
"mcpServers": {
"freeticket": {
"type": "http",
"url": "https://mcp.appfreeticket.com/mcp"
}
}
}
28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,27 @@ Claude Code, Cursor, and any agent that reads markdown skills.
```bash
# Install a specific skill (recommended)
npx skills add AppFreeticket/agent-skills@freeticket-cli
npx skills add AppFreeticket/agent-skills@freeticket-mcp
npx skills add AppFreeticket/agent-skills@freeticket-eventos

# List what's in the repo
npx skills add AppFreeticket/agent-skills -l
```

Or install **all three skills plus the MCP server at once** — this repo is also a
plugin under the [Agent Plugins 1.0.0](https://agent-plugins.org) standard
(`plugin.json` + `skills/` + `mcp.json` at the root):

```bash
# Claude Code
/plugin marketplace add AppFreeticket/agent-skills
/plugin install freeticket@freeticket
```

Any Agent-Plugins-compatible client can read the same manifests. The plugin
wires the `freeticket` MCP server over its hosted endpoint and authorizes in the
browser on first use — no keys to paste, nothing to install.

Skills install into `~/.claude/skills/` (global) or the project's `.claude/skills/`.
The agent loads each skill's `name` + `description` and opens the body only when
your prompt matches it ([progressive disclosure](https://agentskills.io/specification)).
Expand Down Expand Up @@ -63,12 +78,15 @@ The only requirement is a terminal where the agent (or you) can run `npx`.

## Skills Overview

**2 skills.** They compose: `freeticket-eventos` calls `freeticket-cli` to pull
live data before it audits.
**3 skills.** They compose: `freeticket-eventos` pulls live data before it
audits, through `freeticket-cli` in a terminal or `freeticket-mcp` in a chat
client. `freeticket-cli` and `freeticket-mcp` are the same B2B contract from two
directions — the CLI for terminals and scripts, the MCP server for chat clients.

| Skill | Scope | Install |
|---|---|---|
| [`freeticket-cli`](./skills/freeticket-cli) | Drive the official `ft` CLI (`@freeticket/cli`): log in (browser device flow), list/inspect **and** create/update/delete events, dates, ticket types, sales, membership plans, venues, staff; publish events; cancel/refund sales; run CFO reconciliation; export anything to CSV. Superadmin via `ft admin …`. `--json`/`--csv` for automation. | `npx skills add AppFreeticket/agent-skills@freeticket-cli` |
| [`freeticket-mcp`](./skills/freeticket-mcp) | Connect to and operate the official MCP server (`@freeticket/mcp`): local stdio setup, remote connectors on claude.ai via the embedded OAuth 2.1 server, the three credential layers (anonymous B2C → workspace B2B → superadmin), all 87 tools, and the MCP Apps view that renders lists and reports inside the host. | `npx skills add AppFreeticket/agent-skills@freeticket-mcp` |
| [`freeticket-eventos`](./skills/freeticket-eventos) | Event & community advisor: applies FreeTicket's brand voice and real product rules (visibility, member-gated presales, platform fee, time zone, required ticket fields), and **audits events with live data** (via `ft`) to recommend sales and retention improvements. | `npx skills add AppFreeticket/agent-skills@freeticket-eventos` |

---
Expand All @@ -83,6 +101,8 @@ Ask your agent in natural language — it picks the right skill. Examples:
| "Create an event" / "Publish it" / "Refund sale X" / "Raise a ticket price" | `freeticket-cli` |
| "Run the CFO reconciliation" / "Suspend a tenant" / "Set a feature flag" | `freeticket-cli` (incl. `ft admin …`) |
| "Automate this report" / "Give me `--json` for `jq`" / "Configure my API key" | `freeticket-cli` |
| "Add FreeTicket to Claude Desktop" / "Set up the MCP connector on claude.ai" | `freeticket-mcp` |
| "Why do I only see the public tools?" / "Which MCP tool refunds a sale?" | `freeticket-mcp` |
| "Write the description for this event" / "Improve my event copy" | `freeticket-eventos` |
| "Why isn't this event selling?" / "Audit my event" | `freeticket-eventos` (pulls data via `ft`) |
| "How do I grow and retain my audience?" / "Recommend a presale strategy" | `freeticket-eventos` |
Expand All @@ -106,6 +126,9 @@ agent-skills/
├── freeticket-cli/
│ ├── SKILL.md
│ └── references/commands.md
├── freeticket-mcp/
│ ├── SKILL.md
│ └── references/tools.md # 87 tools + what is deliberately absent
└── freeticket-eventos/
├── SKILL.md
└── references/
Expand All @@ -118,6 +141,7 @@ agent-skills/
## Related

- CLI: [`@freeticket/cli`](https://github.com/AppFreeticket/freeticket-cli) (binary `ft`)
- MCP server: [`@freeticket/mcp`](https://github.com/AppFreeticket/freeticket-mcp)
- B2B API v1: OpenAPI 3.1 contract at `GET /api/v1/openapi.json`

## License
Expand Down
9 changes: 9 additions & 0 deletions mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
"mcpServers": {
"freeticket": {
"type": "streamable-http",
"url": "https://mcp.appfreeticket.com/mcp"
}
}
}
14 changes: 14 additions & 0 deletions plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "freeticket",
"version": "0.1.1",
"description": "Operate FreeTicket from any agent: skills for the ft CLI, event copy, and the MCP server that exposes the B2B, superadmin and public contracts as tools.",
"author": {
"name": "FreeTicket",
"url": "https://freeticket.co"
},
"homepage": "https://freeticket.co",
"repository": "https://github.com/AppFreeticket/agent-skills",
"license": "MIT",
"keywords": ["freeticket", "ticketing", "events", "latam", "mcp", "cli"]
}
39 changes: 33 additions & 6 deletions skills/freeticket-cli/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: freeticket-cli
description: Drive the official FreeTicket CLI (binary `ft`, npm `@freeticket/cli`) to operate a workspace from the terminal — log in through the browser (device flow), list/inspect AND create/update/delete events, dates, ticket types, sales, membership plans, venues, staff, discount codes and webhooks; publish events; create/cancel/refund sales; check tickets in at the door and resend QRs; list a sale's tickets, a plan's subscribers, cancel subscriptions; run reports (summary, by-event, timeseries, inventory, CFO reconciliation); and export buyers/attendees/subscribers to CSV. Superadmin (`ft admin …`) manages tenants, users, platform plans, feature flags and impersonation. Use it when the user wants to read OR mutate their FreeTicket account from the terminal, run `ft <command>`, automate with `--json`/`jq` or `--csv`, manage the session/workspace, send feedback/suggestions (filed as GitHub issues on the right repo), or when another skill needs live data or actions on the B2B v1 backend.
description: Drive the official FreeTicket CLI (binary `ft`, npm `@freeticket/cli`) to operate a workspace from the terminal — log in through the browser (device flow), list/inspect AND create/update/delete events, dates, ticket types, sales, membership plans, venues, staff, discount codes and webhooks; publish events; create/cancel/refund sales; check tickets in at the door and resend QRs; list a sale's tickets, a plan's subscribers, cancel subscriptions; run reports (summary, by-event, timeseries, inventory, per-function financials, CFO reconciliation); read settlements paid to the organizer; mint headless service API keys; and export buyers/attendees/subscribers to CSV. Superadmin (`ft admin …`) manages tenants, users, platform plans, feature flags and impersonation. Use it when the user wants to read OR mutate their FreeTicket account from the terminal, run `ft <command>`, automate with `--json`/`jq` or `--csv`, manage the session/workspace, send feedback/suggestions (filed as GitHub issues on the right repo), or when another skill needs live data or actions on the B2B v1 backend.
---

# FreeTicket CLI (`ft`)
Expand Down Expand Up @@ -39,9 +39,20 @@ npm install -g @freeticket/cli@latest && ft whoami
> the CLI is installed globally. Pinning `@latest` matters: a user on an older
> version (e.g. before the device-flow login) breaks otherwise.
>
> This skill documents **`ft` ≥ 0.7.0**. A globally-installed `ft` that's behind
> prints an `⚠ Update available` line on *stderr*; when you see it, tell the user
> to run `npm i -g @freeticket/cli@latest`. `npx …@latest` always runs the newest.
> This skill documents **`ft` ≥ 0.9.0** (skill revision 2026-08-03). A
> globally-installed `ft` that's behind prints an `⚠ Update available` line on
> *stderr*; when you see it, tell the user to run
> `npm i -g @freeticket/cli@latest`. `npx …@latest` always runs the newest.
>
> **If the skill is the stale one** — `ft --help` lists a command this file does
> not, or a documented flag is rejected — trust the CLI, not this file, and
> update the installed copy:
>
> ```bash
> npx skills add AppFreeticket/agent-skills # reinstalls from source
> ```
>
> Then say so, so the drift gets fixed upstream instead of silently repeating.

`ft login` uses the OAuth 2.0 Device Authorization Grant: it shows a short code
and a URL, opens your browser, and once you approve it stores the session in
Expand Down Expand Up @@ -97,6 +108,9 @@ Config lives in `~/.freeticket/config.json` (mode `0600`). Precedence:
| `ft staff list\|create\|set-role` | Workspace staff (`set-role --data '{"role":"…"}'`) | ADMIN |
| `ft reports summary` | KPIs (`--period 7d\|30d\|90d\|1y`) | VIEWER |
| `ft reports by-event\|timeseries\|inventory` | Revenue/tickets by event · over time (`--interval`) · capacity/availability | VIEWER |
| `ft reports financials` | Per-function P&L: gross, platform fee, facial, payment fee, 4x1000, net to settle (`--event`, `--past`) | ADMIN |
| `ft settlements list` | What FreeTicket pays the organizer: amount, status, event (`--event`, `--status`) | ADMIN |
| `ft api-keys create\|list\|revoke` | Headless service credentials — plaintext shown once on `create` (`--scope read\|write`) | VIEWER |
| `ft reports reconciliation` | CFO: cross-check Mercado Pago ↔ sale ↔ Siigo invoice (`--from` `--to`, `--match`, `--provider`) | ADMIN |
| `ft reports export buyers\|attendees\|subscribers\|reconciliation` | Export to CSV (buyers/attendees take `--event` `--event-date` `--from` `--to` `--status`) | ADMIN |

Expand All @@ -106,12 +120,24 @@ Common flags on all: `--json` (raw output for `jq`), `--workspace <id>`
**`--data <json>`** (inline JSON or `@file.json`); `delete` asks for confirmation
unless `--yes`.

**Confirmation and exit codes.** A refused confirmation exits **1**, and without
a TTY a destructive command fails immediately instead of prompting — so
`ft … delete && next-step` never runs `next-step` on an abort. In scripts pass
`--yes` deliberately, not as a habit.

**Money questions go to `reports financials`, not to arithmetic over `sales`.**
It returns the authoritative breakdown FreeTicket already computed (the same
numbers as the Liquidaciones dashboard). `settlements list` then says what was
actually paid out. The proof PDF is panel-only — the API exposes `hasDocument`
and file names, not a download URL.

### Superadmin (`ft admin …`) — cross-tenant, separate contract

Superadmin commands hit a **different contract** (`/api/admin`) with **different
auth**: a SUPER_ADMIN better-auth session, *not* an API key. Save it once with
`ft admin login` — it validates against `/api/admin/me` before storing (MVP — a
service token is coming, see free-admin#157):
`ft admin login` — it validates against `/api/admin/me` before storing. For CI,
mint a platform service token from that session with `ft admin tokens create`
instead of shipping the cookie around:

```bash
# copy the `better-auth.session_token` cookie from an authenticated admin browser session
Expand All @@ -132,6 +158,7 @@ ft admin me # confirm identity
| `ft admin feature-flags list` · `set <key> --data '{"scope":"…","enabled":true}'` | Feature flags |
| `ft admin audit-log list` | Audit log (`--actor`, `--action`, `--from`, `--to`) |
| `ft admin impersonate --data '{"targetUserId":"…"}'` · `impersonate-stop` | Impersonation |
| `ft admin tokens list\|create\|revoke` | Platform service tokens (PAT) for headless `ft admin` — plaintext shown once |

Admin lists also take `--csv`. Writes take `--data <json>`.

Expand Down
34 changes: 33 additions & 1 deletion skills/freeticket-cli/references/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ minimum role; insufficient → `403`.

| Command | Own flags | Role |
|---|---|---|
| `ft events list` | `--limit` `--cursor` | VIEWER |
| `ft events list` | `--q <text>` (search) `--limit` `--cursor` | VIEWER |
| `ft events get <id>` | — | VIEWER |
| `ft ticket-types list` | `--event-date-id <id>` `--limit` `--cursor` | VIEWER |
| `ft ticket-types get <id>` | — | VIEWER |
Expand All @@ -45,7 +45,10 @@ minimum role; insufficient → `403`.
| `ft webhooks list` | `--limit` `--cursor` | ADMIN |
| `ft venues list` · `get <id>` | `--limit` `--cursor` | VIEWER |
| `ft staff list` | `--limit` `--cursor` | ADMIN |
| `ft settlements list` | `--event` `--status SENT\|AWAITING_PAYMENT\|PAID` `--limit` `--cursor` | ADMIN |
| `ft api-keys list` | `--limit` `--cursor` | VIEWER |
| `ft reports summary` | `--period 7d\|30d\|90d\|1y` | VIEWER |
| `ft reports financials` | `--event` `--past`, `--csv` \| `--json` | ADMIN |
| `ft reports by-event` | `--from` `--to` `--status` | VIEWER |
| `ft reports timeseries` | `--interval day\|week\|month` (req), `--from` `--to` `--event` | VIEWER |
| `ft reports inventory` | `--event-id` `--event-date-id` `--from` `--to` `--include-drafts` `--group-by ticketType\|date\|event` | VIEWER |
Expand All @@ -54,6 +57,18 @@ minimum role; insufficient → `403`.
| `ft reports export subscribers` | `--csv` \| `--json` | ADMIN |
| `ft reports export reconciliation` | `--from` `--to` (req), `--match` `--provider`, `--csv` \| `--json` | ADMIN |

`settlements` = what FreeTicket pays the organizer (authoritative, already
computed): `reference`, `status`, `amount`, `currency`, event/function,
`hasDocument`, `paymentProofs[].fileName`, `requestedAt`/`paidAt`. The proof PDF
is **not** downloadable through the API — it lives in the panel.

`reports financials` = one row per function with the full breakdown: `gross`,
`platformFee`, `facial`, `paymentFee`, `gmf` (4x1000), `net`, plus the linked
`settlementStatus`/`settlementId`/`settlementAmount`. Use it instead of
recomputing margins from `sales list` + payment-provider data — same numbers as
the Liquidaciones dashboard. `--past` narrows to functions that already happened
(the settleable ones).

`reconciliation` `--match` / `match_status` enum: `OK` · `MISSING_INVOICE`
(payment without invoice) · `MISSING_CUFE` (invoice without DIAN stamp) ·
`AMOUNT_MISMATCH` (MP amount ≠ sale) · `MISSING_PAYMENT`.
Expand Down Expand Up @@ -94,6 +109,20 @@ matching endpoint in the OpenAPI contract — when unsure, check the spec, don't
| `ft staff create` | `--data` (`{"email","role"}`) | ADMIN |
| `ft staff set-role <id>` | `--data` (`{"role"}`) | ADMIN |

## Service credentials (`ft api-keys …`)

Headless credential for CI / cron — no browser, no device flow. The plaintext
(`ft_live_…`) is shown **once**, in the `create` response.

```bash
ft api-keys create --name "finance-sync" --scope read # scope: read (default) | write
ft api-keys list
ft api-keys revoke <id> --yes
```

`read` allows GET/HEAD only; `write` enables mutations subject to the user's
role. Use it with `--key ft_live_…` or `FT_API_KEY`.

## Admin (`ft admin …`) — separate contract `/api/admin`

A **second contract**, not `/api/v1`. It is **cross-tenant** (not workspace-scoped)
Expand Down Expand Up @@ -127,6 +156,9 @@ ft admin login --session <better-auth.session_token> # validates vs /api/admin
| `ft admin audit-log list` | `--actor` `--action` `--from` `--to` `--limit` `--cursor` | SUPER_ADMIN |
| `ft admin impersonate` | `--data` (`{"targetUserId","workspaceId?"}`) | SUPER_ADMIN |
| `ft admin impersonate-stop` | — | SUPER_ADMIN |
| `ft admin tokens list` | — (no pagination) | SUPER_ADMIN |
| `ft admin tokens create` | `--data` (`{"name","expiresAt?"}`) — plaintext shown once | SUPER_ADMIN |
| `ft admin tokens revoke <id>` | `--yes` to skip confirm | SUPER_ADMIN |
Comment on lines +159 to +161

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Admin token docs inconsistent 🐞 Bug ≡ Correctness

skills/freeticket-cli/references/commands.md still says a revocable admin service token is
“coming”, but this PR also adds the ft admin tokens list|create|revoke commands, which contradicts
the earlier guidance and can mislead CI/auth setup. The docs also don’t state (based on the actual
CLI interface) how to provide the newly minted plaintext token to later ft admin … commands.
Agent Prompt
### Issue description
The admin authentication section still frames service tokens as future work, but the same reference now documents `ft admin tokens …`. This creates contradictory guidance and also leaves out the critical “how to use the created token” step for headless `ft admin`.

### Issue Context
- The reference currently says tokens are “coming”, while listing the token commands.
- `SKILL.md` advises using `ft admin tokens create` for CI, but neither doc shows (per the real CLI contract/help) how the minted token is supplied to future admin commands.

### Fix Focus Areas
- skills/freeticket-cli/references/commands.md[126-138]
- skills/freeticket-cli/references/commands.md[159-165]
- skills/freeticket-cli/SKILL.md[123-129]
- skills/freeticket-cli/SKILL.md[137-138]

### What to change
1. Remove or rewrite the stale “MVP — a revocable service token replaces this …” wording so it matches the now-documented `ft admin tokens …` feature.
2. Add a short, **verified** snippet showing how the minted admin token is used for subsequent `ft admin` calls (confirm the exact env var / flag from the CLI’s actual behavior/help, then document that mechanism explicitly).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Without an admin session (`ft admin login` or `FT_ADMIN_SESSION`) the command
fails fast with a clear message. A missing/expired session returns `401`; a
Expand Down
Loading