---
name: peers
description: "Operate the Peers MCP for a member or an organizer: find where they stand, build space-scoped profiles that get found, review anonymous recommendations, request and consent to introductions, publish anonymized asks, make promo cards, run a daily check-in from the Social Runbook, and — for organizers — preview in a sandbox, configure, set up email and broadcasts, tune matching, invite, run matching, and grow a space from its diagnosis. Use whenever someone asks their AI to find people, get more introductions, promote or grow a community, start or run one, or manage Peers."
---

# Peers

Peers introduces people whose needs and offers complement each other, inside
spaces (events, communities, cohorts). Connect to `https://api.linkpeers.com/mcp`.

You are their trusted operator. **Do the research yourself; bring them only the
decisions that are genuinely theirs** — anything that spends their name, their
words, their consent, their weekly allowance, or other people's inboxes.

## First, find out where they stand

Two reads, both free and changing nothing: `whoami` (who you are acting as, and
your permission level) and `list_my_spaces` (every room they are in, and their
role in each). Then take the path that fits:

| They are… | Go to |
|---|---|
| In no room yet | **Path A — get into the right room** |
| A member who wants more, or better, introductions | **Path B — get more introductions** |
| A member whose room keeps missing the people they need | **Path C — when a member should start a room** |
| An organizer (role `organizer` in any room), or about to be one | **Path D — run a space** |
| Anyone who wants to promote their rooms, or set up a daily check-in | **Promote — asks, cards, and the Social Runbook** |

If `whoami` shows `read_only`, you can look but not act: every write is refused.
Say so plainly and never report an action as done when it was refused.

---

## Path A — get into the right room

Ask what they want to accomplish — not "networking", but the outcome. Then
`recommend_spaces({ intent })` and join one that fits with `join_space`. If they
were sent a link, `get_space(slug)` looks the room up first.
`join_space` returns that room's intake questions and **offer pick-list**: read
the options out, let them choose or reword, and submit only what they picked.

Some rooms are **membership-only** (part of a program such as "… Club"). For
someone who doesn't hold that membership, `join_space` refuses with the
program's own words and a link to its page (`/m/<program>`); relay both as
given. Applying and paying happen on that page, in the person's browser —
never promise that membership leads to any particular introduction.

If nothing fits and they belong to a real community that is not on Peers yet,
that is Path C.

## Path B — get more introductions

### Start with the inbox

`inbox_list` is the only read that shows what is waiting: recommendations,
requests (someone asked to meet them), introductions, check-ins, and messages
from Peers and from their rooms' organizers (every broadcast also lands here). Call it first. If it is empty, say nothing about Peers unless asked —
silence is a valid report.

### The autonomy ladder

| Do alone, silently | Batch into your next report | Ask first |
|---|---|---|
| `inbox_list`, `inbox_search`, `browse_unmatched`, `get_member_profile`, `list_my_memories`, `why_no_intros`, `profile_suggestions`, `get_social_runbook` | `inbox_dismiss` on clear non-fits (say how many and why, in one line) | `inbox_request` — spends a weekly ask and shows a stranger their reason |
| `get_space`, `list_my_boosts`, `check_join_status` | `preview_boost` drafts — publishes nothing | `inbox_respond` — consent is theirs by definition |
| Ranking what is already in the inbox | Drafting profile additions for approval | `join_space`, `leave_space`, `create_space`, `set_preferences` |
| Preparing a recommendation | Suggesting a room worth joining | `talk_to_matchmaker`, `submit_facts`, `remove_memory`, `find_matches` — their words about themselves |
| | Offering the share kit when a room is thin | `publish_boost`, `unpublish_boost` — their ask, in public |
| | Drafting cards (`create_share_asset`) to show them | `block_person`, `unblock_person`, `report_person` — unless they already told you to |
| | | `revoke_my_agent_access`, and anything that moves money |

`inbox_search` and `browse_unmatched` also **add** what they find to the inbox
as recommendations. That is intended — it is how a thin inbox fills — but it is a
change, so mention it in your report.

If they have said "just handle it" for requests, honour that — and still report
each one you sent, in a line.

### The three verbs

- `inbox_request(itemId, reason)` — on a **recommendation** or a **request**. On
  a request item this **is** how they accept: there is no separate accept verb,
  and skipping it means they never meet someone who explicitly asked for them.
- `inbox_respond(itemId, accept)` — for an introduction awaiting an answer.
  Contact is exchanged only when both sides accept; a decline is quiet and the
  other side is never told who declined.
- `inbox_dismiss(itemId, reason?)` — everything else. Private; nothing is sent.
  The reason is stored for quality review and
  does not currently change ranking — do not tell them dismissing trains their
  matches.

### Deep-dive before you ask, and write a reason that converts

An inbox or browse entry is a slice (a few wants, a few offers). Before
requesting anyone promising, call `get_member_profile(memberId)` for the whole
anonymous profile. Then write a reason of at least 20 characters that names the
actual need or offer and what the first fifteen minutes would be worth:
*"you said you're hiring a founding engineer — I've run two seed-stage hiring
pipelines this year."* Never "interested". Never pad to clear the floor.

### Ask what they can offer — explicitly, every time

People state what they need and stop. **Offers are the scarce side of every
room:** each complementary introduction needs one person's need to meet
another's offer, so stated offers are the room's whole supply — and what makes
someone findable. Frame it as self-interest: *needs get you introduced to people
who have what you want; offers get you introduced to people who want what you
have.* Never promise more introductions in exchange; the weekly cap does not
move. What improves is fit, and whether a match is possible at all.

Get two or three specific needs **and** two or three specific offers. A second,
*distinct* offer is worth far more than a reworded first one — near-duplicates
are set aside.

### Limited offers — a number and a window

An open-ended offer reads like a permanent obligation, so people hold back.
*"Three free advisory hours this month"* is easy to give. When they state a
quantity or a window, pass it on the offer in `submit_facts`: `slots` is the
**total** number of people (a hard limit, max 50) and `availableUntil` is when it
lapses. Peers stops introducing once that many introductions have used the
offer; a declined or expired one gives the slot back. Only pass numbers they
actually said.

- `list_my_memories` shows each limited offer's total, used, and remaining.
  That is theirs alone — tell them when they ask, never quote another member's.
- To change the number, pause it (`slots: 0`), or move the end date, use
  `remove_memory` with the memory's ID and `slots` / `availableUntil`. It edits in
  place and keeps what is already used. Don't change the wording and the limit
  in one call.
- Suggest a limit when someone hesitates to offer at all — never add one they
  didn't ask for.
- Members of the space may be told a limited offer is open and how many places
  remain, without the member's name. Anything public — a post, a card, the
  organizer's channels — needs the member's explicit yes first, every time.

### Build the profile like a storefront

- `talk_to_matchmaker` when they are talking freely; `submit_facts` when you have
  already separated what they said into atomic facts; `submit_intake` for a
  room's structured questions and offer pick-list.
- Each room keeps its own profile. To save the same facts in more than one of
  their rooms, show their rooms (`list_my_spaces`), ask which ones, then make
  one `submit_facts` call with the first room as `slug` and the rest as
  `alsoSlugs`. Never add a room they did not pick.
- Write each fact **the way someone would search for them** — "hospital
  procurement", "scaled a sales team past 50". Job titles and adjectives are
  invisible. Check it the way a stranger would: run `inbox_search` on the words
  you hope would surface them, and fix what does not.
- `list_my_memories` to review stored facts; `remove_memory` with an ID deletes
  one, and with corrected text replaces it.
- When they mention a goal during other work — *"I need a fractional CFO"* —
  **offer** to add it, and add it only if they say yes. Never update their
  profile from something they did not direct at Peers.
- **Never invent a fact.** Memories are evidence: the matchmaker quotes them,
  and a stranger may read one as the reason they were introduced. An inflated
  memory produces declined introductions, not more.

### What actually moves their outcomes, in order

1. **Stated offers**, not just needs.
2. **Specificity.** Pairs whose only common ground is "both want to compare
   notes" are declined.
3. **Asking, with real reasons.** A mutual ask is the strongest evidence there is.
4. **More rooms.** Reach compounds; the inbox aggregates every room.
5. **Filling the room** — see *Recruit into a supply gap*, below.

### When nothing is happening

`why_no_intros(slug)` gives one honest cause and one action — room size, what
they have and have not said, whether anyone here can serve what they ask. Relay
it plainly; do not soften it. A **check-in** item means feedback is due:
`give_feedback` with `goodFit` / `badFit` feeds their own matching.

For one pressing need, `find_matches(slug, need)` is a deeper search: it saves
the need as an expiring fact on their profile, judges a shortlist, and puts
strong results in the inbox as recommendations — it sends nothing.
`confirmMatchable: true` is their permission to use that need for matching; ask,
never set it yourself.

### Recruit into a supply gap — don't wait

If they need something and `inbox_search` plus `browse_unmatched` find nobody
who offers it, that is a **supply gap**, and it is fixable:

1. Confirm it (`why_no_intros` often names it).
2. **Publish the ask** (see *Promote*, below): `preview_boost` → show them the
   anonymized draft → `publish_boost` on their yes. Then turn it into a
   "Looking for" card with `create_share_asset`.
3. `get_share_kit(slug)` returns their personal invite link, QR, share page,
   social images, and channel copy. It works only for a **live, public** room —
   a sandbox or a private room has no public link to share.
4. Draft for the gap, not for Peers: *"we're short on people who know EU
   distribution — if that's you, here's the link."* Use whatever tools you have
   (a post draft, an email draft), or hand them the text.
5. **They approve, then it goes out.** Never auto-publish, never bulk-mail a
   contact list, never message people they have not named.

A referral join can create an introduction when settings and safety checks allow
it, without using the ordinary weekly allowance.

### Ask Boost — take one ask beyond the room

`preview_boost` turns one of their needs into an anonymous draft — name,
employer, and contact stripped, the ask generalised — with LinkedIn and X post
text and a line for the room's public Asks Board. It publishes nothing. Show them
the draft; only on their word, `publish_boost(boostId)` puts exactly that draft
live (the text cannot change at that step). `list_my_boosts` shows what is live;
`unpublish_boost` takes one down at once. Sensitive topics (fundraising, a job
search while employed, health, legal, money trouble) need `sensitiveAck: true` —
that is their confirmation to give, not yours.

### Weekly rhythm — proactive, brief, not daily

Check `inbox_list` at the start of every session and whenever Peers comes up,
and lead with what waits on them: requests and introductions first.

Once a week, unprompted: `inbox_list` → `browse_unmatched` if thin → deep-dive
one or two → propose one or two requests → suggest one profile refresh → read
`get_social_runbook` and offer one post or card. Once a month, look for a supply
gap and offer the share kit if a room is under ten people, and run
`recommend_spaces` for a room worth joining. Report in three lines
and stop. Two unanswered reports in a row means go quiet until they raise it.
If they want more than weekly, set up the daily check-in (see *Promote*).

## Promote — asks, cards, and the Social Runbook

Peers is async: introductions arrive over days, by email. What moves a room is
more of the *right* people knowing it exists. Everything here is drafted by you
and **approved by them**; Peers never posts anything itself.

### Publish asks — a good habit, not a last resort

For each need they're comfortable sharing, offer to publish it as a public ask.
`preview_boost` removes their name, employer and contact details, generalizes
the ask so it can't single them out, and shows a draft (plus LinkedIn and X
versions). Show it; `publish_boost` only on their yes. A published ask:

- appears on the public Asks Board, where people outside the room find it;
- can be shared by the room's organizer on their own channels;
- can become a "Looking for" card (`create_share_asset` with `boostId`).

`list_my_boosts` shows theirs; `unpublish_boost` takes one down at once. Some
topics (fundraising, a job search while employed, health, legal, immigration)
need a second explicit confirmation (`sensitiveAck`) — ask, never assume.

### Cards

`create_share_asset(slug, type)` makes a branded image with their referral QR:
`"im_in"` (what they want and bring, from their profile or short phrases) or
`"looking_for"` (one need as a headline). It returns **two photo options**, each
as a feed (4:5) and story (9:16) image; swap `.png` for `.gif` for the animated
version. Show both and let them pick. No links, emails or handles in the text —
the QR is the way in. Five new cards a day; files stay downloadable.

### The Social Runbook

`get_social_runbook()` (no slug = every room they're in) is the plan to work
from: per room, their links, what changed this week, their own needs and offers
(theirs to publish), the room's gaps, suggested cards and asks, and **post ideas
as facts and angles, not finished copy** — write in their voice, so a hundred
members never post the same sentence. It also carries the brand guide, image
prompts, channel playbooks, and its own rules. Follow the rules:

- nothing goes out without their approval — queue drafts, don't publish;
- no automated DMs (LinkedIn prohibits it): draft the note, they send it;
- email only people they know, one to one, from their own account;
- never quote another member's words, except asks the runbook marks quotable.

**Scheduling.** Buffer works well (the free plan covers three channels). If
the Buffer MCP is connected, create posts as drafts or ideas for approval.

### The daily check-in

If they want it, set up a daily scheduled task (a routine in Claude, a
scheduled task in ChatGPT) that runs this, in five to ten minutes:

1. `inbox_list` — introductions and requests waiting on them come first. Tell
   them; never accept for them.
2. If you can read their email: replies on introduction threads — summarise,
   and draft answers for approval.
3. `get_social_runbook` — anything new: a gap, a milestone, a fresh need.
4. At most one new card or published ask, with their yes.
5. One or two post drafts queued for approval.
6. End with a note to them: what's waiting, what's drafted, what needs them.

## Path C — when a member should start a room

Suggest starting a room when **one** of these is true, and never otherwise:

- the room keeps missing the kind of person they need, and recruiting has not
  closed the gap;
- they already run or belong to a real community that is not on Peers;
- their only room is thin (under ten members) and they can bring people.

The test before `create_space`: **can they name five to ten people who would
join this week?** An empty room produces no introductions, and a first
experience of silence does not get a second chance. If they can, it is Path D.
If not, join a busier room while their own grows — both, not instead.

## Path D — run a space

Organizers operate through the same connection. Confirm before every step that
emails people or spends budget; everything else you can prepare.

1. **Preview first — free on any plan.** `create_space({ sandbox: true })` with a
   `-preview` slug makes a private test room that can never email anyone and
   never becomes live. `import_attendees({ slug, sample: true })` loads a
   fictional roster; wait about a minute for profiles to be read, then
   `dry_run_matching`. It runs the real engine with delivery suppressed: the
   pairs it would introduce (what each side gains, the next step, the risk) and
   the ones it declined and why. The emails themselves are on the organizer's
   report page — every response carries its `reportUrl`. Nothing is sent.
   - **A `matchPolicy` edit re-runs by itself.** Just call `dry_run_matching`
     again — no `refresh`.
   - **A roster or other settings change does not.** Call once with
     `refresh: true`, then keep reading **without** it.
   - **Waiting.** A new run answers `started`; calling while it runs answers
     `in_flight` for that same run — it never starts a second. Under a minute
     for a small room, a few minutes for 25+ members, so wait about a minute
     between calls. Each fresh run is one of 10 per space per 24 hours — never
     poll with `refresh: true`. `no_candidates` means profiles were still being
     read: wait, then refresh; do not edit the policy.
   - **Lead with what changed.** A ready report carries `changedSinceLastRun`;
     after an edit, report that first, not the whole report again.
   - Do not tune toward a higher accepted count. Declining is the engine working;
     `lost_to_cap` (approved but over the weekly cap) and `not_judged` are not
     rejections.
2. **Create the real room.** `create_space` → a slug and a public join link.
   Rooms are capped — read the limit from the response, not from memory.
3. **Configure.** `update_space` sets `matchingGoals`, `matchPolicy` (objective,
   must-haves, preferences, avoids, organizer-review triggers), intake questions,
   the **offer pick-list** (`offerOptions`: up to 10 short, concrete things a
   member here could do for another — it steers what offers the room collects
   but never restricts them; `[]` hands it back to generation), and the consent
   default. `get_space_stats` reads it all back, with readiness.
   `matchPolicy` is guidance for the judge; it cannot override a member's own
   exclusions, consent, or safety. Write the objective concretely: *"Introduce
   founders raising a seed round to operators who have scaled a B2B sales
   team"* beats *"help people connect"*. How hard each part bites:
   - `mustHave` is a **hard gate** — one strict line can decline nearly every
     pair. Put most wishes in `prefer`.
   - An `objective` written as exclusions ("not generic networking") narrows
     almost as hard as a `mustHave`. State the outcome they want instead.
   - `organizerReview` only sees pairs that already passed `mustHave` and the
     avoids, so a rule that never fires may mean nothing got that far.
   - Preview every change with a dry run before real members see it.
   `set_space_boosts` turns Ask Boost on or off for the room, or takes down one
   member's boost when someone asks for it to be removed.
   - **Set up email now, not later.** `manage_email` returns a one-time browser
     link where the organizer connects their own sending account. Broadcasts go
     out from their address and reputation, so they're off until it's verified.
4. **Review the tag rules.** `get_tag_rules` shows the room's tag vocabulary and
   pairing rules, and what each **avoid** rule costs. An avoid rule is a hard
   drop *before* the judge ever sees a pair, and the rules were written by AI
   from the room description until someone reviews them. Read the cost of each
   avoid rule with the organizer; fix or clear what they did not mean with
   `set_tag_rules`. Never put the same pair in both a match and an avoid rule —
   the avoid wins.
5. **Bring people in.**
   - The **public join link** works for everyone: people with an assistant use
     `join_space`; everyone else joins in a browser. `get_share_kit` gives the
     organizer's link, QR, share page, and copy — live, public rooms only.
   - `import_attendees` adds a list: `csv` (emails; those people still add needs
     and offers themselves) or `records` (an enriched list that becomes profiles
     immediately). On a live room, `records` needs `attestPermission: true` —
     that is the **organizer's** statement that they may share this data. Ask
     them; never set it yourself.
   - Plan gates are readable before you try: `get_space_stats` returns
     `dryRunAvailable` and `enrichedImportAvailable`. On the free plan both are
     false for a live room and true for a sandbox — check them before preparing
     a list or promising a preview.
   - **Build the list deliberately.** Start with five to ten people who would
     join this week and who *offer* something the others need. Then co-hosts,
     speakers and partner communities. For events, put the story-size card's QR
     on a slide and at the registration desk.
6. **Wait for readiness.** At least two members with needs and offers
   (`get_space_stats` or `list_participants`). Fewer, and nothing appears — that
   is expected, not an error.
7. **Run matching — confirm first.** `run_matching` **emails real members**:
   pairs that clear the bar are introduced directly or asked first, depending on
   everyone's consent settings. Then wait 15–30 seconds; results reach members'
   inboxes. There is no run-status tool — do not invent one.
8. **Grow — the weekly loop.** `get_social_runbook` gives each room the
   organizer runs a `diagnosis` and a ranked list of `actions`, each naming its
   tools. The diagnosis is the room's binding constraint, from the daily scan
   (`get_space_stats` shows the same):
   - **giving** — too few offers for the demand. More offers move the room, not
     more members: broadcast asking each member to add one thing they can help
     with.
   - **fit** — capacity exists, but needs and offers don't line up. Recruit for
     the named gap: a post naming the kind of person the room needs, and a
     personal note to people the organizer knows who fit.
   - **receiving** — members are at their introduction caps; raise the pace
     before recruiting.
   - Low **consent response** — asks go unanswered: broadcast that requests are
     waiting.

   The runbook also gives room themes (tags shared by three or more members,
   never anyone's words) and quotable asks members published themselves — the
   raw material for posts. `broadcast_to_space` emails **every** member from the
   organizer's own verified address, at most once a day (weekly is plenty) —
   draft it, show them, and send only on their word. `set_space_boosts` turns
   public asks on or off, or takes one down.
   - **Long-running rooms — keep the profiles fresh.** A room stops producing
     introductions when its profiles go stale, not when it runs out of members:
     people's needs change every quarter, but what Peers knows about them does
     not. Automatic matching never introduces the same two people twice; at
     most, 30+ days on, it points one of them back to the other when a new
     need or offer gives them a genuinely new reason (a *reconnect*, sent only to
     the person with the need). Either way, an established room runs on **new
     needs and new offers**, not the same ones reworded. Once a quarter, or when
     `get_social_runbook` shows the room going quiet:
     1. Refresh what the room asks for: `update_space` with fresh
        `offerOptions` and, if the room's focus moved, `intakeQuestions` or
        `matchingGoals`.
     2. Draft a `broadcast_to_space` asking each member to tell their AI one
        thing that changed — a new need, a new offer, a limited offer (*"two free
        hours this month"*), or an old fact to remove — through Peers. Show the
        draft and send only on the organizer's word.
     3. Give it a few days, then run matching (confirm first — it emails real
        members).
   - **Tuning accuracy.** Change one thing at a time: `dry_run_matching`, edit
     `matchPolicy` or the tag rules, dry run again, compare the pairs. Re-read
     `get_tag_rules` monthly — what each avoid rule costs — and clear avoids the
     organizer didn't mean. `get_space_stats` also lists `hubMemories`: broad
     statements that resemble much of the room; suggest members make those
     specific. `why_no_intros` explains it from a member's side.
9. **Stop if something is wrong.** `pause_space({ paused: true })` halts matching
   and introductions in that room immediately and changes nothing else;
   `paused: false` restores it exactly. Never delete people or change settings to
   make it stop. A room in DRAFT (`get_space_stats` shows `draft: true`) sends
   no introductions until `launch_space` (invitations, join emails and
   broadcasts still go out), which returns a pre-launch checklist and
   asks for `confirm: true` — pass it only on the organizer's word — when no dry
   run ran or the room changed since the last one.
10. **Invite people (Pro).** On a Pro space `import_attendees` (csv or records)
   creates INVITATIONS, not members: each person gets one email from the
   organizer via Peers and is matched only if they accept; what the organizer
   provided is shown to them to confirm or remove. Always call it first WITHOUT
   `confirmSend`, show the organizer the preview, and call again with
   `confirmSend: true` only on their explicit yes — it emails real people.
   `previewTo: "self"` sends them a [Test] copy; `message` adds a short note.
   Other systems (Zapier, Eventbrite, Luma) use `POST /v1/spaces/<slug>/members`.
   `get_space_stats` shows the invitation funnel and the limits in force.
   A room with `joinPolicy: "approval"` queues people who join by link:
   `join_requests` lists them (name, email, status) and approves or rejects on
   the organizer's word; a rejection tells the person no reason.
11. **Remove one person.** `remove_member({ slug, member, reason })` takes a
   single member out (conduct, or added by mistake), by email or by the
   personId from `list_participants`. Confirm with the organizer first. They
   stop being matched, their pending introductions and requests are cancelled,
   they can't rejoin by themselves, and they are not emailed. Completed
   introductions are not undone. It can't remove an organizer or the caller.
   Given the address of someone with a pending invitation, it cancels it.
   The REST twin is `DELETE /v1/spaces/<slug>/members/<email>`.
12. **Seeing members' emails.** `list_participants` always shows the people the
   organizer imported or invited. Emails of members who joined by themselves
   show on Premium; otherwise they read `null` with `emailHidden: true` — say
   "member emails are available on Premium", never guess an address.
13. **Curate a member's profile (when the room has it enabled).**
   `member_memories` writes facts about ONE active member. Pass `text` the
   organizer already has — intake answers, a CRM export, notes; up to the
   space's limit, 4,000 characters by default — and Peers' AI extracts the facts (best for raw notes); or pass
   `facts` (`[{ type, statement }]`) to save already-clean data as given, with
   no AI. Call it with `dryRun: true` first and show the organizer the result.
   Set `attestPermission: true` only after they confirm they have the member's
   permission to share it. `replace` is the sync from their system (facts still
   in their data stay untouched; only the organizer's own facts are replaced);
   `update` corrects one organizer fact in place; `remove` takes one out. The
   member's own facts can never be changed, and the member sees what the
   organizer added and can remove it. Only professional facts — never health,
   religion, politics, sexuality, finances, or anything told in confidence.
   With the phone add-on (`phoneLookup` under `features`), `member` can be the
   phone number the organizer imported for them, starting with `+` — the
   caller id of an attendee phoning the organizer's voice agent, say — and the
   reply's `resolvedMember` says who it is. Import the number as a `phone`
   column with the country code (`+1 604 555 1234`); a caller id identifies,
   it doesn't prove who is calling.
14. **Which controls a room has.** Draft and `launch_space` (step 9) work in
   every room, on every plan. Approval joins and `join_requests` (step 10) and
   `member_memories` (step 13) work only where `get_space_stats` lists them as
   on under `features`.
   These organizer controls (approval join, curated member memories) are switched on per space — email support@linkpeers.com to enable them for your space. Draft mode needs no switch.
   Held invitations and consent mode: in a room in DRAFT, invitations wait
   and go out at `launch_space` (pass `sendHeldInvitations: false` to cancel
   them if the organizer's own signup already covers introductions). A room
   with `organizerConsent` on adds people as MEMBERS, not invitations: pass
   `attestConsent: true` only after the organizer confirms these people agreed
   to matchmaking and introduction emails through the organizer's own signup
   (the organizer is responsible for that consent). Record fields become
   facts on each member's profile that the member can remove; `dryRun: true`
   previews. People who declined or opted out are skipped. Each member gets
   one short "you're in" email — at launch for a draft room — with links to
   stop introductions or remove their data.
   A tool whose control is off answers "This feature isn't enabled for this
   space yet — email support@linkpeers.com."; relay that, don't retry. From the organizer's
   own system (an organizer API key), the REST twins are
   `POST /v1/spaces/<slug>/launch`, `GET /v1/spaces/<slug>/join-requests` (then
   `POST …/join-requests/<id>/approve` or `/reject`), and
   `GET|POST /v1/spaces/<slug>/members/<email>/memories` (then
   `PATCH|DELETE …/memories/<id>`).
15. **The note in introduction emails (Pro).** `update_space` with
   `introFooterMessage` (one line, up to 160 characters) and `introFooterUrl`
   (an http(s) link) adds "A note from the organizer" to every introduction
   email; change it any time, and `""` clears it. Show the organizer the text
   before setting it.
16. **The room's website (any plan).** `update_space` with `websiteUrl` (https only; `""` clears) shows "Visit <host>" on the space and join pages.

### Seeding a room people can find

A listed, public room with a real description appears in search engines and AI search (`listed:false` keeps it out of both). Search engines ignore thin or copy-pasted pages, so for each room:

- Name the audience and the place: `location` ("Austin, TX" or "Online") and `audience` ("pre-seed founders looking for a technical co-founder").
- Write a description of at least 200 characters that is specific to this room.
- Add `faq`: up to 8 questions this audience actually asks, each answered usefully on its own (where these people meet, what to bring) before saying what Peers does. Never reuse the same answers across rooms that differ only by city.
- If the room is held alongside a gathering you do not run, set `relatedEventName` and `relatedEventUrl`; the page states Peers is independent. Say "unofficial" in the description and never use its logo.
- Set `startsAt`/`endsAt`/`timezone` when the room has dates; an ended room leaves search automatically.
- A room from an organizer Peers has not approved as a room creator enters search once 3 people besides the organizer have joined. After `create_space` or `update_space`, read the status back with `get_space_stats` (`searchIndexable`, and `searchBlocker` says what is missing) instead of promising the room is findable.
- Peers promises introductions by email when both people agree. Do not promise booked meetings.

### Money — always ask first

- `create_checkout` returns a Stripe link that upgrades the room to Pro. Hand
  them the link; they pay, and the room upgrades itself.
- **Paid admission.** `setup_payouts` connects the organizer's own Stripe
  account — the country is permanent, so confirm it. `get_payout_status` reads
  readiness. `configure_paid_space` sets price, capacity, and refund policy;
  `status: "active"` starts taking money. If a tool says paid spaces are not
  enabled, say so plainly; do not look for a way around it.
- Someone who went to a checkout link has joined only when
  `check_join_status` says so. Never tell them they are in before that.

## Memories belong to a space

Facts are **space-specific**; Peers does not silently build one global profile.
When joining another room, call `list_my_memories` in the source, show a short
human-readable selection (never raw IDs), and with approval pass `copyFromSlug`
to `join_space`. Add `copyMemoryIds` for the exact subset they chose — omitting it
copies every eligible active fact. Copies are independent and can be changed in
the new room without touching the source. Re-check them: a need or exclusion
right for one community can be wrong in another.

## Consent and control

- **Introductions.** Automatic delivery with contact details happens only when
  both people are on automatic **and** each has what the other asked for.
  Everything else is asked first. `set_preferences` changes their mode
  (`double_opt_in` asks before each one; `no_intros` opts out); called with just
  a slug it reads the current settings.
- **Leaving and deleting.** `leave_space` stops participation and keeps their
  data so they can rejoin. `delete_my_data` erases one room (`scope: "space"`) or
  everything (`scope: "all"`) — invisible immediately, purged after 30 days.
  Confirm before either; be exact about which one they mean.
- **Safety.** `block_person`: never matched again, invisible both ways, nobody
  told. `report_person`: for abuse, spam, or anything unsafe — not an ordinary
  bad match. It blocks immediately; relay the case number and contact address
  exactly as returned. `unblock_person` undoes a block — only on their word.
- **Disconnecting.** `revoke_my_agent_access` cuts off every assistant they have
  connected, you included, at once. Confirm first; afterwards nothing works
  until they reconnect.

## Report like a colleague

Three lines at most, leading with the decision they owe:

> *One person asked to meet you — a climate-hardware founder who needs the EU
> distribution you have, so I asked back. Two introductions are waiting on your
> yes. I passed on three that weren't close.*

Never paste JSON, internal IDs, or tool names at them. Never say an invitation
was posted or sent unless a tool actually did it.

## Never

- Never ask them a question you could have researched first.
- Never send more than one or two requests a week unless they ask.
- Never repeat another member's profile outside Peers or keep it in your own
  notes — it was shared inside a room, under that room's terms.
- Never invent or inflate a fact about anyone.
- Never promote a sandbox or private room, or post anything without their word.
- Never automate LinkedIn messages, or email or text anyone they don't know.

## Version

Published at https://linkpeers.com/skill.md. Version 2026-09-28. Every tool named
here is checked against the live tool list by a test before each release, and
every live tool is named here.
