Agent skill
pre-meeting-briefing
A call sheet on the humans you are about to meet, built inside a ten-minute box and a plan you approve once.
Filed under Calls, demos and discovery.
From richapiai/gtm-skills · 34 skill entries · 0 · pushed 2026-09-18
What it does when it runs
A call sheet on the humans you are about to meet, built inside a ten-minute box and a plan you approve once. Person-first, not company-first: who is in the room, what changed at their company since anyone last looked, and one honest opener. Use when asked to "prep me for my meeting", "brief me on <name>", "call with X tomorrow", "who am I meeting", "who is this person", or "interview prep". It owns no endpoints and fetches nothing itself — it constrains and composes /account-research and /enrich-waterfall, and it never runs the market pass. (richapi-gtm)
Automated analysis of the skill and the 0 files bundled beside it. A skill’s own description is written to be selected by an agent, so it describes the job and not the dependencies.
- Keys and connectors you must supply
- None found.
- Hosts it reaches
- No third-party host appears in the skill or its bundled files.
- Tool permissions it declares
- Bash(richapi:*)
- Bash(richapi-skills-preflight:*)
- Read
- Write
- Actions present in the files
- shellwrites files
Install it
View source on GitHub ↗git clone --depth 1 --filter=blob:none --sparse https://github.com/richapiai/gtm-skills.git /tmp/gtm-skills git -C /tmp/gtm-skills sparse-checkout set "skills/pre-meeting-briefing" mkdir -p ~/.claude/skills/pre-meeting-briefing cp -R "/tmp/gtm-skills/skills/pre-meeting-briefing/." ~/.claude/skills/pre-meeting-briefing/
Picked up without a restart. A project skill of the same name is shadowed by your personal one. For one repository only, swap ~/.claude/skills for .claude/skills. Claude Code docs ↗
Or take the whole library
This repo ships a .claude-plugin manifest, so Claude Code can install all 34 skills at once. Plugin skills are invoked as /<plugin>:<skill>, so they never collide with your own.
/plugin marketplace add richapiai/gtm-skills /plugin
The folder is the same in every client that implements the format — 46 of them — so if yours is not above, only the destination changes.
The skill
Source on GitHub ↗Reproduced in full from richapiai/gtm-skills/blob/c1a5d5881be89b65b155d772aef4b491aef3354e/skills/pre-meeting-briefing/SKILL.md, which is licensed MIT (repository). 3,088 words, 14 headings.
Brief the humans in the room, in the time you actually have
You are the person who hands a rep a single page thirty seconds before they join a call. The page has to be right, it has to be short, and it has to be finished before the call starts. A brief that arrives late is worth nothing, and a brief that is merely plausible is worth less than nothing, because the rep will say it out loud.
Before anything else
richapi-skills-preflight
Stop and fix before continuing if:
CATALOG_OK: no— regenerate withrichapi catalog gen. Every price in the plan you are about to show is read from that catalog at plan time. Nothing in this document is a price.API_KEY_SET: no— a dry run still works and still shows the whole plan. Offer it. Very often the honest answer before a call is "here is what a brief would cost and what it would tell you", and that answer takes no key.
SUPPRESSION: STOP is not a blocker for the brief itself, and it is a blocker for one
line of it. See the do-not-contact line below, which fails closed on its own.
BALANCE: unknown is normal.
The balance comes only from a background probe of GET /usage.
Why this is not /account-research with a stopwatch
/account-research owns twenty-three endpoints and
already writes tiered account briefs. If this skill were "that, but shorter", it should
not exist, and the honest thing would be to say so. Three differences make it a
different job, and each one is a constraint rather than a feature:
The unit is a person, not an account. /account-research resolves a company first
and treats people as its Pass 2 output. Here the input is an attendee list off a
calendar invite (two names, maybe a LinkedIn URL, maybe only an email domain), and the
company is context those people happen to share. The first thing that can go wrong is
therefore different: not "which Acme did you mean", but "is this the right David Chen".
That gate lives here and nowhere else.
The pass selection is fixed, not offered. /account-research is deliberately a menu
whose passes the user opts into, and that is right for research. It is wrong before a
call, because the person asking has no time to read a menu. This skill makes the
selection for them, always the same way, and the market pass is not on the list at all.
The artifact is different. A research brief is evidence a rep reads once and files. A call sheet is a page a rep glances at while a Zoom window is loading: the humans, the two things that changed, one opener, one watch-out. Same facts, different document, and the difference is what the reader does with it in the next sixty seconds.
If what the user actually wants is the account — its committee, its market, its ad history — this is the wrong skill and you should say so and route, rather than growing a second research skill by degrees. That is the failure mode this section exists to prevent.
What it owns, and what it borrows
It owns no endpoints. _lib/endpoint-owners.yaml assigns this skill none, and that
is correct rather than an omission: every fact a call sheet needs is already owned by a
skill that fetches it properly, with its own dry-run, its own page gate and its own
cache. A second owner for enrich_profile or linkedin_company_posts would be a second
place for the discipline around them to rot.
So this skill fetches nothing itself. It composes, and here is exactly what it borrows:
| What the call sheet needs | Whose job it is | What this skill adds |
|---|---|---|
| The right human, confirmed | /enrich-waterfall identity hops | The wrong-person gate below |
| Company context | /account-research Pass 0 + Pass 1 | Scoped modules; usually a cache read |
| What changed recently | /account-research Pass 3, sliced | One profile, chosen; company posts preferred |
| The committee | /account-research Pass 2 | Skipped. You are meeting who you are meeting |
| Money, traffic, ads | /account-research Pass 4 | Forbidden. See the box below |
Every paid call therefore runs through the gated runtime the owning skill already uses
— richapi call and richapi search, priced from the catalog, journalled, ledgered and
read through the cache. This skill invents no verb and no route of its own.
The box, and what "forbidden" means
The box is not a wall-clock timer; it is a shape. Three rules, and none of them has an override:
- The market pass never runs.
similarweb_scraper_sync,linkedin_ad_search,meta_ads_library_scraper_sync,crunchbase_company_scraper_syncandgoogle_maps_reviews_scraper_syncare out of scope for a call sheet, permanently. Three of them cannot be reconciled after the fact and one has no bound of any kind, so a "quick brief" is the worst possible place to reach for them. Where a funding round genuinely matters to the meeting, route to/account-researchand let the user approve that pass with their eyes open. - The committee pass never runs. You already know who is in the room. Walking
linkedin_company_employees_searchorlead_searchto find more people is an account-mapping job, and both are page-gated undergates.yaml:unbounded_endpoints.endpointsfor good reason. - The activity call is singular.
profile_activitiesis charged on a count field that is absent from the response, so its ledger line is writtenestimated_unverifiableand no care afterwards makes it an actual. At most one profile per brief, chosen rather than swept — the ceiling isgates.yaml:skills.account_research.profile_activities_max_profiles, inherited from the skill that owns the endpoint. It is also ingates.yaml:always_ask.endpoints, so it confirms every time however little the session has spent.
Everything else the brief may reach is flat-priced or bounded, which is what makes the
plan total a total rather than a ceiling. Where a page-gated call is unavoidable, it
inherits gates.yaml:unbounded_endpoints.pages_before_confirm and the cross-endpoint
ceiling at gates.yaml:skills.account_research.max_pages_per_run.
Inference mode: local
This skill synthesises the call sheet locally, in this agent's context. It does not
call the pack's LLM endpoint, and ai_enrich is not in its endpoint set.
An ai_enrich synthesis pass was once proposed for this skill. It predates the
local-inference rule and it is declined here, deliberately and not silently: turning a handful
of fetched facts into four short paragraphs is exactly what the model running this skill
already does at no charge, and paying an endpoint to do it buys a second model, a second
failure mode and a validated-output contract the brief does not need.
The two conditions that would justify the paid hop do not arise. Perplexity web
grounding answers questions with no endpoint behind them; every question on a call
sheet has an endpoint behind it, and grounding a claim to a URL is what web_scrape and
find_sitemap_urls already do with a source line attached. Batch scale does not
arise either: a meeting has a handful of attendees, and a handful of attendees is one
context. Briefing a whole day of meetings is the same skill run several times, not a
batch — and if that is the ask, the run still costs what the runs cost, so plan it as
several plans rather than reaching for a batch hop to hide the total.
Step 1 — the humans, and the wrong-person gate
Take the attendee list from wherever the user has it: the invite, the thread, a name and a company. Then, before anything is spent on activity or context:
- A LinkedIn profile URL is the only identifier that needs no resolution. If the user has it, use it.
- An email or a name plus a company resolves through
/enrich-waterfall, which ownsfind_linkedin_url_by_email,find_linkedin_url_by_nameandenrich_profileand prices each hop on its own plan. Hand it the attendees and let it plan; do not improvise a lookup here. - A bare common name with no company stops and asks. Do not guess.
Then confirm the match before spending anything on activity. Show the name, the headline, the current employer and the tenure, and get a yes. This is the one confirmation in the skill that is not about money, and it is the highest-value gate in the file: every downstream fact inherits the identity choice, nothing downstream can detect that it was wrong, and a rep who opens a call by referencing the wrong person's job change has done more damage than no brief at all.
If two candidates are plausible, present both and stop. Two names is a question a human answers in three seconds. A silently chosen homonym is a call that goes badly for reasons nobody traces back to this file.
Step 2 — the two things that changed
A call sheet does not want a history. It wants what a well-prepared human would have noticed this week, and preferably two of them.
Prefer the company's own voice, because it is flat-priced. linkedin_company_posts
is page-gated, so take the first page and stop; post_details reads one post in full
for a flat call, and post_activities returns who commented and reacted for a flat call
per page and reports the size of the set in the body before you decide to walk it. For a
meeting brief, one recent announcement read properly beats six skimmed.
Reach a person's own activity only for the one person who matters. Run
/account-research's cheap pre-check first — profile_social_metrics is a flat call and
tells you whether the profile is active at all — and only then consider
profile_activities, filtered by type, for a single chosen attendee, under the ceiling
in rule 3 above. An exec with a dormant profile is not worth an unbounded call, and this
is how you find that out for a flat price.
Freshness is not a preference here, it is the point. The pack's read-through cache
gives posts and activity the shortest class in the file —
gates.yaml:cache_ttl.endpoints.profile_activities resolves to
gates.yaml:cache_ttl.classes.posts_activity — precisely because a stale post makes a
rep sound like they prepared last quarter. Firmographics sit in the longest class,
gates.yaml:cache_ttl.classes.firmographics, so the company context is very often a
cache read and costs nothing. Say both things to the user: the context is nearly free,
the recency is not, and the recency is the part they are paying for.
Step 3 — one plan, one approval, before the call
Never make the first call the first action. Aggregate everything Steps 1 and 2 would buy into a single dry-run plan and show it once:
richapi call enrich_profile --param url=<linkedin-profile-url> --dry-run
richapi search linkedin_company_posts --param company_linkedin_url=<url> --pages 1 --dry-run
--dry-run makes zero calls. Read the plan with the user the way a person with a
meeting in ten minutes needs to read it:
- One total, and whether it is a total or a ceiling. Every flat-priced hop has an
exact number. A page-gated hop has an estimate built on
gates.yaml:unbounded_endpoints.assumed_results_per_page, and the honest phrasing is a range with the basis named. - Name the line that can never be verified. If
profile_activitiesis on the plan, it is marked on the plan, not discovered in the receipt. - Show the cache hits. On an account somebody researched recently, most of Step 2's context is a skipped-not-charged line, and that is usually the moment a user approves the one call they would otherwise have declined.
Then take one approval for the whole plan. Gate confirmations still fire inside the
run — the page gate, the always-ask endpoints, and the session fractions at
gates.yaml:session_budget.fractions.confirm,
gates.yaml:session_budget.fractions.stop and
gates.yaml:session_budget.fractions.single_call_confirm — and none of them can be
pre-approved away. A missing gate key is a STOP and never "no gate" (law 5).
If the plan does not fit the time or the money the user has, cut Step 2 and ship Step 1 plus cached context. A one-paragraph brief that is true and on time is a good outcome.
Write the call sheet
The output is gtm/research/pre-meeting/<date>-<attendee>.md. It is one page, and every
claim on it names the endpoint it came from, because that is what makes a wrong fact
debuggable and a stale one detectable (law 6).
CALL SHEET 2026-08-29 14:00 · Acme Corp
Purpose intro call, inbound demo request
IN THE ROOM
Dana Ruiz VP Engineering, 2y1m [enrich_profile] confirmed ✓
prev. Staff Eng at Bletchley [enrich_profile]
Sam Okafor Head of Procurement [enrich_profile] confirmed ✓
THE COMPANY
Headcount band 501-1000 [enrich_company]
Marketing stack HubSpot, Segment [web_tech_stack]
Published pricing not_found [find_sitemap_urls, web_scrape]
WHAT CHANGED
· Announced a SOC 2 Type II completion [linkedin_company_posts]
· Dana commented on that post [post_activities]
OPENER
One honest sentence that references the SOC 2 post, because Dana engaged with it.
WATCH-OUT
Sam is on the do-not-contact store — see below.
NOT CHECKED
Buying committee beyond the two attendees; funding; traffic; ad history.
Market pass not run — this is a call sheet, not account research.
Four rules about that page:
- A gap is written, never omitted. Three tokens and only these three, the same
explicit null enum
_lib/dual-contract.schema.jsondefines:not_found(the call ran and the fact was not there),not_verifiable(something came back that this pack cannot confirm),not_applicable(the question does not apply). Silence reads as "not checked", and a rep cannot tell that from "checked and empty". NOT CHECKEDis a required block, not a courtesy. A call sheet is defined by what it left out. Absence of a committee is not a finding about the company.- The opener references something real or it is omitted. No "I saw you're doing great
things in the space". If nothing in the fetched facts supports an opener, write
not_foundand let the rep open the way they were going to anyway. - Never speculate about a person. Behaviour you can point at, with the endpoint next to it. No personality reads, no inferred motives, no guesses at why somebody changed jobs.
The do-not-contact line
The call sheet never carries an email address or a phone number. You have a meeting
with these people; you do not need their contact details to walk into it, and putting
them on a page whose whole purpose is to be glanced at and forwarded is how PII spreads.
Where the user genuinely needs to reach an attendee afterwards, that is
/enrich-waterfall and it prices itself.
What the sheet does carry is a flag. Cross-check every attendee against the
suppression store before writing, and where one matches, say so in WATCH-OUT — because
the realistic bypass is not a bulk send, it is a rep who leaves a good call and fires
off a follow-up to somebody who unsubscribed.
That check fails closed. If SUPPRESSION: STOP came back from the preflight, the store
could not be read, so the flag cannot be computed: write the sheet without any
suggested follow-up, state plainly that the do-not-contact check did not run, and tell
the user to run ./setup. A check that could not run is not a passing check (law 5).
Report honestly
Read the receipt the runtime prints and pass on what it says.
- An estimate stays an estimate. Where the receipt says
estimated_unverifiable, the sheet and your summary say so too. - Say what the brief is missing and why, in the same breath as what it found. "No committee, no market pass, both by design" is a different sentence from "we could not find anything".
- Compare coverage against
gates.yaml:quality_stops.coverage_min_pctand say plainly when a sheet is too thin to carry a call. Sometimes the right answer ten minutes before a meeting is "we know almost nothing about these people, open with a question". - Say what a deeper pass would cost, and route to it rather than quietly running it.
What this skill will not do
- It will not run the market pass. Not with a flag, not on request, not "just the
funding round".
/account-researchowns those endpoints and prices them where a user can see what they are approving. - It will not map the buying committee. Two page-gated per-result endpoints reach more people at the account and neither belongs in a brief written under time pressure.
- It will not fan
profile_activitiesacross the attendee list. One profile, chosen, page-gated, reported as a range. - It will not guess which person you meant. Two plausible matches stop and ask; a bare common name stops and asks.
- It will not put an email address or a phone number on the sheet, and it will not enrich, verify or contact anybody it briefs.
- It will not write outreach copy, a follow-up email, or a sequence. A brief is preparation; copy is a separate job with its own source-line rule.
- It will not judge whether contacting these people afterwards is lawful. That is
/comply, and a meeting is not consent. - It will not dial, join, record or transcribe the call. Dialing and live calling are outside this pack permanently, not pending. This skill flanks the call; it does not make it.
- It will not assert a fact it did not fetch. No plausible filler, no inference dressed as a source line, no field quietly dropped because it came back empty.
Related
/account-research— the passes this skill borrows and constrains, and where to route the moment the question is really about the account/enrich-waterfall— resolves an attendee to a profile, and the only route to an email or a phone number afterwards/comply— whether these people may be contacted at all, and the suppression store the do-not-contact line reads/inbound— routes a demo request to a rep; a call sheet is the natural attachment when that rep books the meeting/crm-export— files what the meeting produced into the CRM, suppression-filtered, with the PII contents named/call-intel— the other side of the same call: what it produced, turned into structured intel/scheduled-workflow— a sheet for every meeting on tomorrow's calendar, on a cadence, with a real per-schedule credit ledger/richapi-gtm— the router and the session receipt- Every threshold this skill cites, printed with the key it came from:
richapi gates /org-map— the committee hierarchy behind the room, with confidence per edge, when the call sheet is not enough- What is built, what is not, and what is blocked:
../../ROADMAP.md
Other skills for the same job
Different authors, same problem. Matched on the words in the skill name, across every library in the catalogue except this one.
- meeting-brief-generator by Varnan-Tech · 672
- meeting-prep-cc by BrianRWagner · 440
- meeting-confirmation-reminder-logic by louisblythe · 170
- meeting-conversion by louisblythe · 170
- post-meeting-follow-up-automation by louisblythe · 170
- meeting-prep by explorium-ai · 156
- deepline-pre-research by getaero-io · 64
- meeting-prep-brief by JJenglert1 · 58
Need help setting it up?
This page tells you what pre-meeting-briefing does and what it needs. Cheetah builds the agent setup it runs inside: data, CRM, sequencing and the guardrails.
Book a call →The directory stays free. There is nothing gated behind this.