Look up your contacts from Claude Code
A contact is one person across everything Launch knows about them. With the MCP server connected, the agent can answer questions that otherwise mean exporting three CSV files and matching emails by hand.
Claude Code connects to remote MCP servers over HTTP directly. One command registers the server under the name nordva.
Setup
You need a secret key (nv_live_…) from Dashboard → API keys.
01Register the server
claude mcp add --transport http nordva https://mcp.nordva.dev \
--header "Authorization: Bearer nv_live_..."The name comes before the URL. By default the server is added for the current project only and stored outside the repository; add --scope user to make it available in every project.
02Or share it with the team without sharing the key
.mcp.json
{
"mcpServers": {
"nordva": {
"type": "http",
"url": "https://mcp.nordva.dev",
"headers": {
"Authorization": "Bearer ${NORDVA_API_KEY}"
}
}
}
}Claude Code expands ${NORDVA_API_KEY} from the environment, so the file can be committed while each developer keeps their own key in their shell profile.
03Check the connection
Run claude mcp list, or type /mcp inside a session. nordva should show as connected. Then ask Claude to run setup_check: it reports the project, the plan and which features are unlocked.
Then ask Claude Code
- Which of my waitlist signups are paying customers now?
- What has [email protected] asked for, and is she paying?
- List paying customers who came from Product Hunt.
- Mark [email protected] as in talks and note that she wants SSO.
For “Which paying customers left feedback?” Claude Code calls list_contacts with:
{
"paying": true,
"has_feedback": true,
"limit": 10
} Returned: Contacts with id, email, source, waitlist status, subscriber flag, feedback count, Stripe status, plan, MRR and stage, plus a cursor when there are more.
Contacts tools and arguments
list_contacts
Read-onlyList people across waitlist, feedback, subscribers and Stripe
| paying | optional | boolean | |
| has_feedback | optional | boolean | |
| status | optional | "waiting" | "invited" | "unsubscribed" | |
| source | optional | string, max 255 | |
| stage | optional | "potential" | "in_talks" | "customer" | "recurring" | "not_a_fit" | "inactive" | |
| q | optional | string, max 254 | Part of an email address. |
| limit | optional | number, 1–100 | |
| cursor | optional | string |
get_contact
Read-onlyGet one person across every primitive
| contact_id | required | string, max 64 | Contact id, e.g. "ct_...". |
update_contact
Set a contact's stage or note
| contact_id | required | string, max 64 | |
| stage | optional | "potential" | "in_talks" | "customer" | "recurring" | "not_a_fit" | "inactive" | |
| note | optional | string, max 5,000 |
Behaviour worth knowing
- People are matched on normalised email: lowercase, +alias removed, dots ignored on Gmail.
- update_contact changes only the stage and the note. It cannot change an email, a waitlist status or anything in Stripe, and a new note replaces the old one.
- It works without Stripe connected; every contact then has Stripe status none.
- On the Free plan only waitlist people are listed, in a single page.
- A contact is removed when the person no longer exists in any source, for example after their signup is deleted.
- Tools appear to the model as mcp__nordva__<tool>, which is the form to use in permission allowlists.
- Read-only tools are marked as such by the server; Claude Code still asks before the first call to each tool unless you allow it.