Oppora MCP server
The Oppora MCP server is a remote Model Context Protocol endpoint for Claude, ChatGPT, Cursor, VS Code and Claude Code. Its 73 tools find companies, people and job posts, find and verify emails and phone numbers, and run outreach: email campaigns, multichannel sequences with LinkedIn steps, workflows and analytics, all inside your Oppora account.
Last updated:
https://api.oppora.ai/mcpStreamable HTTP transport. Authenticate with your API key as Authorization: Bearer, X-API-Key, or ?api_key= in the URL.
Quick start
Create a key
In Oppora, open Integrations > Oppora API and click New key. Copy the opp_live_ secret; it is shown once.
Add the server
Pick your client below and paste the URL or config. Header auth and the ?api_key= URL both work.
Try a tool
Ask "what lists do I have?" and the assistant calls my_lists. Then try one of the example prompts.
Connect a client
Open Settings > Customize > Connectors, click +, choose Add custom connector and paste the URL below. Claude.ai's Free plan allows one custom connector.
https://api.oppora.ai/mcp?api_key=YOUR_KEY
Team and Enterprise: an owner adds it under Organization settings > Connectors > Add > Custom > Web. Members then turn it on under Customize > Connectors.
Claude connects from Anthropic's servers, so the URL must be reachable from the internet. api.oppora.ai is public, so this works as is.
Example prompts
Paste any of these into a connected client. Under each one is the tool chain it usually triggers, so you can see where credits go before you run it.
- 1
Find Series B software companies in Germany with 51 to 500 employees. Save them to a new list called "DACH Series B", then find their VP Sales and Heads of Sales.
Tools:
get_available_countries,get_available_last_funding_round_types,get_available_industries,discover_companies,create_list,add_companies_to_list,get_available_departments,get_available_management_levels,find_leads_for_companies,get_task_status - 2
Find the work email for Priya Shah at acme.com.
Tools:
email_search,get_job_status (only if the lookup is still running) - 3
Check these 20 addresses before I import them and tell me which will bounce. Run the advanced check on any that come back risky.
Tools:
email_verifier (standard, once per address),email_verifier (advanced, for risky ones) - 4
Find emails for everyone in my "DACH Series B" list, then tell me how many are verified.
Tools:
my_lists,find_emails_for_leads,get_task_status,get_list_analytics - 5
Build a draft sequence for "DACH Series B": a LinkedIn connection request, wait 2 days, an intro email, then a follow-up email 4 days later. Send from my Gmail mailbox.
Tools:
list_sequence_templates,create_sequence_campaign,save_sequence,list_email_accounts,attach_sequence_audience,get_sequence - 6
How is the "DACH Series B" sequence doing? Who replied, and who is stuck on a step?
Tools:
get_sequence_campaign_analytics,get_sequence_recipients - 7
Which companies in Texas posted SDR jobs this week? Save them to a list and find their sales leaders.
Tools:
search_jobs,create_list,add_jobs_to_list,find_leads_for_companies,get_task_status - 8
Find 25 companies that match my ICP and add them to my "Q4 targets" list.
Tools:
get_icp_profile,get_available_industries,get_available_countries,discover_companies,my_lists,add_companies_to_list
What you can do that a data-only MCP can't
A data MCP server answers lookups. Oppora's server also acts on the results in the same account, with the same credits and the same lists you see in the app.
Find and verify
- Search companies, people and live LinkedIn job posts.discover_companies, discover_people, search_jobs
- Find work emails through Oppora's email waterfall, then any finder you connected with your own key.email_search, find_emails_for_leads
- Find phone numbers through a phone waterfall. Numbers already in Oppora cost nothing.phone_search
- Verify deliverability, with a catch-all aware advanced mode.email_verifier
- Fill firmographic fields and score leads against your offer.enrich_companies, score_leads
Act on it
- Set up email campaigns with templates, follow-ups, schedules and mailboxes, check readiness and start them.create_or_update_campaign, check_campaign_readiness, start_campaign
- Build multichannel sequences: email, LinkedIn invites, messages, InMail, profile visits, likes, comments and follows, plus waits, conditions, call tasks and CRM pushes.save_sequence, attach_sequence_audience, activate_sequence
- Report on campaigns, sequence steps, each recipient, mailbox health and list quality.get_sequence_campaign_analytics, get_sequence_recipients, get_email_account_health
- Read and update your ICP, and run repeatable workflows that target it.get_icp_profile, update_icp_profile, create_workflow, set_workflow_icp
Tools reference
73 toolsEvery tool returns TOON-encoded text except discover_companies and discover_people, which return JSON. Open a row for arguments, response shape and an example.
Discovery (companies & people)
2Search Oppora's company and people databases. Rows carry an Oppora id you can pass to the add-to-list tools. A call that returns results costs a flat 5 data credits for companies or 10 for people; empty results are free. Reuse next_cursor for the next page.
discover_companiesSearch companies by industry, size, location, revenue, funding, growth and tech stack.5 data credits per call
discover_companiesSearch companies by industry, size, location, revenue, funding, growth and tech stack.organization_name?: string | string[], industry?: string[], category?: string[], location?: string[] (city or state), size?: string[] ("2-10" … "10001+"), hq_country?: string[] (ISO 3-alpha), company_type?: string[], year_founded?: string, revenue_range_min/max?: int (USD), total_funding_range_min/max?: int, latest_funding_amount_range_min/max?: int, last_funding_round_type?: string[], last_funding_date?: string, employee_growth_6m_min / employee_growth_12m_min?: int (percent), acquisition_status?: "acquired" | "not_acquired", technologies?: string[], company_website_domain?: string[], domain?: string, domain_pattern?: string, linkedin_url?: string[], exclude_companies / exclude_industries / exclude_keywords / exclude_domains / exclude_size?: string[], limit?: int (1-100, default 25), next_cursor?: stringJSON { count, credit_charged, credits_remaining, next_cursor, has_more, results: [{ id, name, domain, website, linkedin_url, industry, employee_count, location, country, … , oppora_url }] }. id is set when the company is already in your Oppora database.
discover_companies( hq_country=["USA"], industry=["Software Development"], size=["51-200", "201-500"], revenue_range_min=5_000_000, technologies=["Salesforce"], limit=25, )
discover_peopleSearch people by title, department, seniority, company, location and skills.10 data credits per call
discover_peopleSearch people by title, department, seniority, company, location and skills.title?: string | string[], first_name?: string, last_name?: string, company_name / company_linkedin / company_domain?: string | string[], company_industries?: string[], company_hq_location?: string[], departments?: string[], management_levels?: string[], location?: string | string[], employee_count?: string | string[], years_experience?: string | string[], skills?: string[], recently_changed_jobs?: bool, exclude_companies / exclude_industries / exclude_titles / exclude_keywords / exclude_location?: string[], limit?: int (1-100, default 25), next_cursor?: string
JSON { count, has_more, next_cursor, credit_charged, credits_remaining, results: [{ first_name, last_name, title, department, management_level, company_name, company_domain, location, linkedin_url, … }] }. Running the same search again without next_cursor returns the same rows and is charged again.
discover_people( title=["VP Sales", "Head of Sales"], management_levels=["VP"], company_domain=["stripe.com", "plaid.com"], limit=25, )
Jobs
2The Job Finder over MCP: live LinkedIn job posts, filtered by title, place, date and hiring company size. Saving posts to a list also adds each hiring company.
search_jobsSearch live LinkedIn job posts. Empty pages are free and nothing is saved.1 data credit per page
search_jobsSearch live LinkedIn job posts. Empty pages are free and nothing is saved.job_title?: string[], location?: string[], posted_limit?: "24h" | "week" | "month", company_size?: string[] (buckets to keep), workplace_type?: ("office" | "hybrid" | "remote")[], employment_type?: string[], experience_level?: string[], industry?: string[], job_function?: string[], salary?: "40k+" … "200k+", under_10_applicants?: bool, easy_apply?: bool, sort_by?: "date" | "relevance", next_cursor?: stringTOON { count, total, credit_charged, credits_remaining, next_cursor, has_more, jobs[N]{ job_title, company, company_id, company_size, job_location, posted_date, job_url, company_linkedin } }
search_jobs( job_title=["SDR", "Sales Development Representative"], location=["Texas"], posted_limit="week", )
add_jobs_to_listSave job rows from search_jobs to a list and add each hiring company to it.Free
add_jobs_to_listSave job rows from search_jobs to a list and add each hiring company to it.list_id: int, jobs: list[dict] (1-100 rows from search_jobs), skip_duplicate?: bool (default true: one job per company)
TOON { added_jobs, added_companies, skipped, message, list_id, list_url }
Filter helpers
7Return the exact values the discovery and lead tools accept. Misspelled values match nothing, so assistants call these first. All free.
get_available_industriesAbout 435 LinkedIn industry names.Free
get_available_industriesAbout 435 LinkedIn industry names.get_available_countriesCountry names with ISO 3-alpha codes. Pass iso_alpha3 to hq_country.Free
get_available_countriesCountry names with ISO 3-alpha codes. Pass iso_alpha3 to hq_country.get_available_company_typesPrivately Held, Public Company, Nonprofit and the rest.Free
get_available_company_typesPrivately Held, Public Company, Nonprofit and the rest.get_available_last_funding_round_typesFunding rounds such as seed, series_a, series_b.Free
get_available_last_funding_round_typesFunding rounds such as seed, series_a, series_b.get_available_departmentsValues for departments on discover_people and find_leads_for_companies.Free
get_available_departmentsValues for departments on discover_people and find_leads_for_companies.get_available_management_levelsSeniority values such as C-Level, VP, Director, Manager.Free
get_available_management_levelsSeniority values such as C-Level, VP, Director, Manager.search_locationsAutocomplete up to 20 city and region names for location filters.Free
search_locationsAutocomplete up to 20 city and region names for location filters.Saved companies & leads
8Manage records saved in your Oppora lists.
my_listsYour lists with company and lead counts. The only source of a valid list_id.Free
my_listsYour lists with company and lead counts. The only source of a valid list_id.create_listCreate a list, or return the existing one with that name (case-insensitive).Free
create_listCreate a list, or return the existing one with that name (case-insensitive).name: string (max 200 characters)
TOON { id, name, is_existing, message, list_url }
create_list(name="Top Prospects Q4")
list_my_saved_companiesSaved companies, optionally for one list, filtered by industry and size.Free
list_my_saved_companiesSaved companies, optionally for one list, filtered by industry and size.list_my_saved_leadsSaved leads, filterable by list and lead status.Free
list_my_saved_leadsSaved leads, filterable by list and lead status.add_companies_to_listAdd Oppora company IDs to a list. Companies already in it are skipped free.1 data credit per new company
add_companies_to_listAdd Oppora company IDs to a list. Companies already in it are skipped free.remove_companies_from_listRemove companies from a list. The company records stay.Free
remove_companies_from_listRemove companies from a list. The company records stay.add_leads_to_listAdd Oppora lead IDs to a list. Leads already in it are skipped free.1 data credit per new lead
add_leads_to_listAdd Oppora lead IDs to a list. Leads already in it are skipped free.remove_leads_from_listRemove leads from a list. The lead records stay.Free
remove_leads_from_listRemove leads from a list. The lead records stay.Bulk upsert (external data)
2For data that did not come from discovery: web scrapes, news results, pasted lists, CSV rows. Both tools dedupe against Oppora's database and can add the rows to a list in the same call. Saving is free.
create_companies_bulkUpsert up to 100 companies. Dedupes by name, LinkedIn, website and domain.Free
create_companies_bulkUpsert up to 100 companies. Dedupes by name, LinkedIn, website and domain.companies: list[{ name (required), domain?, website?, linkedin?, industry?, approx_employee_size?, meta? }], list_id?: intTOON { company_ids, added_to_list, list_id, list_url, message }
create_companies_bulk(
companies=[
{"name": "Acme", "domain": "acme.com"},
{"name": "Globex", "linkedin": "https://linkedin.com/company/globex"},
],
list_id=12, # optional: save and add to the list in one call
)create_leads_bulkUpsert up to 100 leads. Dedupes by email, then LinkedIn, then name plus company.Free
create_leads_bulkUpsert up to 100 leads. Dedupes by email, then LinkedIn, then name plus company.leads: list[{ first_name or email (one required), last_name?, linkedin?, title?, phone?, location?, company_name?, company_domain?, company_linkedin?, company_industry? }], list_id?: int. With list_id, rows also accept email_status, ai_recommendation, status, alternate_emails, source, custom_columns.TOON { created, existing, failed, lead_ids, failed_details, list_id, message }
create_leads_bulk(
leads=[
{"first_name": "Alice", "email": "[email protected]", "company_name": "Stripe"},
{"linkedin": "https://linkedin.com/in/bob-smith"},
],
list_id=12,
)Async list operations
4Long-running work on a list. Each call returns a task_id at once and runs in the background; poll it with get_task_status. Every response includes an oppora_url for the list.
enrich_companiesFill firmographic fields (website, industry, size, description and more) for companies in a list.1 data credit per field filled
enrich_companiesFill firmographic fields (website, industry, size, description and more) for companies in a list.list_id: int, company_ids?: int[] (omit for the whole list)
TOON { task_id, message, list_id, list_name, counts, oppora_url }
enrich_companies(list_id=12)
find_leads_for_companiesFind people at the companies in a list from Standard, Premium or Deep sources.1/3/5 data credits per lead
find_leads_for_companiesFind people at the companies in a list from Standard, Premium or Deep sources.list_id: int, departments: string[], management_level: string[], company_ids?: int[], title?: string[], lead_limit?: int (per company, default 10, max 1000), country / country_full_name / location / experience / employee_count?: string[], source_tiers?: ("standard" | "premium" | "deep")[], exclude_location?: string[], main_objective?: stringTOON { task_id, message, list_id, list_name, oppora_url }
find_leads_for_companies( list_id=12, departments=["Sales"], # from get_available_departments management_level=["VP", "Director"], title=["VP Sales", "Head of Sales", "Sales Director"], lead_limit=5, source_tiers=["standard"], )
score_leadsScore each lead in a list Yes or No against your offer, with a reason. Fills gaps from your ICP.1 AI credit per lead
score_leadsScore each lead in a list Yes or No against your offer, with a reason. Fills gaps from your ICP.list_id: int, service_type: string, leads_per_company: int, priority_departments: string, specific_leads_per_department: string, additional_requirements?: string
TOON { task_id, message, list_id, list_name, counts, oppora_url }
score_leads( list_id=12, service_type="Sales automation software for outbound teams", leads_per_company=3, priority_departments="Sales, Marketing", specific_leads_per_department="VP Sales x2, Director of Marketing x1", )
find_emails_for_leadsFind work emails for leads in a list through the email waterfall. Misses are free.Data credits per email found
find_emails_for_leadsFind work emails for leads in a list through the email waterfall. Misses are free.list_id: int, lead_ids?: int[] (omit for the whole list)
TOON { task_id, message, list_id, list_name, counts, oppora_url }
find_emails_for_leads(list_id=12)
Tasks (poll async work)
2Read background tasks started by the list operations and workflows. Each row links to the affected list or workflow.
get_task_statusStatus, progress, summary, credits used and oppora_url for one task.Free
get_task_statusStatus, progress, summary, credits used and oppora_url for one task.task_id: int
TOON { task_id, title, status, progress, summary, credits_used, oppora_url, … }
get_task_status(task_id=1408)
list_my_tasksYour recent tasks, newest first, filterable by status.Free
list_my_tasksYour recent tasks, newest first, filterable by status.status?: "pending" | "in_progress" | "completed" | "stopped", page?: int, limit?: int (max 100)
TOON { total, page, limit, has_more, tasks[N]{ task_id, title, status, progress, summary, oppora_url, … } }
list_my_tasks(status="in_progress", limit=10)
Workflows
3Chain steps (find companies, enrich, find leads, score, find and verify emails, draft a campaign) into a workflow on a list. Run it now or at a scheduled time.
create_workflowCreate a workflow on a list, with an optional one-time schedule.Free
create_workflowCreate a workflow on a list, with an optional one-time schedule.name: string, list_id: int, scheduled_time?: "YYYY-MM-DD HH:MM", timezone_str?: string (IANA, default "US/Eastern")
TOON { workflow_id, message, oppora_url }
create_workflow(name="Weekly outbound", list_id=12)
add_workflow_nodeAppend one or more steps to a workflow, in run order.Free
add_workflow_nodeAppend one or more steps to a workflow, in run order.workflow_id: int, list_id: int, prompt: string (step types plus instructions)
TOON { workflow_id, message, step_count, pipeline, oppora_url }. Step types: company-crawl, company-enrich / ai-enrich, company-filter, job-finder, lead-search, lead-enrichment, ai-recommendation, lead-remover, search-contact, mobile-number, verify-contact, generate-campaign, start-campaign, crm-write, web-search, delay.
add_workflow_node( workflow_id=79, list_id=12, prompt="company-crawl: NYC HR firms, lead-search: HR directors, search-contact, verify-contact", )
start_workflowRun a workflow now. Steps run in order in the background; track them with list_my_tasks.Free (steps bill their own credits)
start_workflowRun a workflow now. Steps run in order in the background; track them with list_my_tasks.workflow_id: int, list_id: int
TOON { message, oppora_url }
start_workflow(workflow_id=79, list_id=12)
ICP
3Read and update your organization's ideal customer profile, and point workflow steps at it. Generating a new ICP happens in the Oppora app.
get_icp_profileYour ICP: target companies, buyer persona, messaging and signals, with a mapping to discovery filters.Free
get_icp_profileYour ICP: target companies, buyer persona, messaging and signals, with a mapping to discovery filters.TOON { status, company_context, target_company, buyer_persona, messaging, signals, summary, confidence_score, refining, can_edit, message, oppora_url }
update_icp_profileChange ICP sections. Owner or admin only; lists are replaced, not appended.Free
update_icp_profileChange ICP sections. Owner or admin only; lists are replaced, not appended.company_context?, target_company?, buyer_persona?, messaging?, signals?: dict, summary?: string (pass at least one)
TOON { status, updated_fields, message, oppora_url }
set_workflow_icpTurn "use my ICP" on or off for a workflow's steps.Free
set_workflow_icpTurn "use my ICP" on or off for a workflow's steps.workflow_id: int, list_id: int, use_icp?: bool (default true), steps?: string[] (omit for every step that supports it)
TOON { message, pipeline, icp_warning, workflow_id, list_id, oppora_url }
set_workflow_icp(workflow_id=79, list_id=12)
Contact resolution
4One-off finders and a verifier. Credits are charged only when a result comes back. A lookup that outlasts the call returns status: "pending" with a job_id; the assistant reads it with get_job_status instead of searching again.
email_searchFind a work email from a name and company domain via Oppora's waterfall, then your own connected finders.1 data credit when found
email_searchFind a work email from a name and company domain via Oppora's waterfall, then your own connected finders.first_name?: string, last_name?: string, full_name?: string, domain: string (required)
TOON { email, status, source, credit_charged, credits_remaining }. Charged only when status is valid or risky.
email_search(first_name="Alice", last_name="Chen", domain="stripe.com")
email_verifierCheck whether an address will bounce. Advanced mode adds a catch-all aware deep check.1 data credit, 2 advanced
email_verifierCheck whether an address will bounce. Advanced mode adds a catch-all aware deep check.email: string, mode?: "standard" | "advanced"
TOON { email, mode, status, credit_charged, credits_remaining } with status valid, invalid, risky, catch-all or unknown.
email_verifier(email="[email protected]", mode="standard")
phone_searchFind a phone number from a LinkedIn URL (best) or name plus company or domain. Numbers already in Oppora are free.1 phone credit when found
phone_searchFind a phone number from a LinkedIn URL (best) or name plus company or domain. Numbers already in Oppora are free.linkedin_url?: string, first_name?: string, last_name?: string, full_name?: string, company?: string, domain?: string
TOON { phone, status, source, credit_charged, credits_remaining }
phone_search(linkedin_url="https://linkedin.com/in/alice-chen")
get_job_statusRead a pending email_search, email_verifier or phone_search lookup.Free
get_job_statusRead a pending email_search, email_verifier or phone_search lookup.job_id: int
TOON { id, kind, status, total, processed, credits_charged, error, results[] }
Campaigns
8Email campaigns: inspect, set up, check readiness and start. Starting runs the readiness check and refuses if setup is incomplete.
list_campaignsCampaigns with sent, opened, clicked, replied and bounced counts and rates.Free
list_campaignsCampaigns with sent, opened, clicked, replied and bounced counts and rates.get_campaignFull setup of one campaign: lists, mailboxes, templates, schedule, stats.Free
get_campaignFull setup of one campaign: lists, mailboxes, templates, schedule, stats.get_campaign_reportFunnel for one campaign over an optional date range.Free
get_campaign_reportFunnel for one campaign over an optional date range.create_or_update_campaignCreate or update a campaign: lists, templates, follow-ups, schedule, mailboxes, limits, tracking.Free
create_or_update_campaignCreate or update a campaign: lists, templates, follow-ups, schedule, mailboxes, limits, tracking.campaign_id?: int (omit to create), name?: string, status?: string, lists?: int[], template_id?: int, linkedin_template_id?: int, follow_up_templates_ids?: int[], schedule_id?: int, accounts?: int[], start_time / end_time?: "YYYY-MM-DD", daily_limit?: int, min/max_time_gap_between_emails?: int (minutes), sending_priority?: string, send_linkedin_invite, open_tracking, click_tracking, stop_tracking_on_reply, is_sent_invalid_emails, delivery_optimization, unsubscribe_header_enabled, skip_dnc_list, skip_rejected_domains, skip_rejected_domains_per_account, send_to_all_emails?: bool
TOON { campaign_id, name, status, created, updated, oppora_url, setup_url, message }. List-type fields replace the current values.
update_campaign_statusSet draft, active, paused or completed. Active runs the readiness check first.Free
update_campaign_statusSet draft, active, paused or completed. Active runs the readiness check first.start_campaignStart a campaign. Refuses and lists the issues if setup is incomplete.Free
start_campaignStart a campaign. Refuses and lists the issues if setup is incomplete.check_campaign_readinessEvery missing setup piece, each with a link to fix it.Free
check_campaign_readinessEvery missing setup piece, each with a link to fix it.list_email_accountsConnected Gmail, Outlook and SMTP mailboxes with status and today's sends.Free
list_email_accountsConnected Gmail, Outlook and SMTP mailboxes with status and today's sends.Sequences (multichannel)
9Sequences mix email and LinkedIn steps with waits, conditions, call tasks and CRM pushes. New sequences start as drafts, and the editing tools refuse while a sequence is sending. activate_sequence and resume_sequence send real email and LinkedIn messages; their instructions limit them to an explicit request from you.
list_sequence_templatesReady-made sequence templates to seed a new campaign from.Free
list_sequence_templatesReady-made sequence templates to seed a new campaign from.include_steps?: bool (default false)
TOON { count, templates[N]{ key, name, flow, … } }
create_sequence_campaignCreate a sequence as a draft, empty or from a template. Contacts nobody.Free
create_sequence_campaignCreate a sequence as a draft, empty or from a template. Contacts nobody.name: string, template_key?: string
TOON { campaign_id, name, status, nodes, revision, requirements, next_step, oppora_url }
create_sequence_campaign(name="DACH Series B")
get_sequenceSteps, settings, audience, and the errors and warnings that affect launch.Free
get_sequenceSteps, settings, audience, and the errors and warnings that affect launch.campaign_id: int
TOON { campaign_id, name, status, nodes, revision, requirements, errors, warnings, enrolled_leads, oppora_url }
save_sequenceReplace a draft's steps. AI comment and auto-reaction steps cost 1 AI credit per enrolled person.Free to save
save_sequenceReplace a draft's steps. AI comment and auto-reaction steps cost 1 AI credit per enrolled person.campaign_id: int, nodes: list (the complete step graph; steps left out are deleted). action_type: send_email, send_connection, send_message, send_inmail, send_follow_up, visit_profile, like_post, comment_post, follow_user, withdraw_request, wait, condition, manual_call, push_to_crm, ai_reply
TOON { campaign_id, nodes, revision, warnings, requirements, paused, oppora_url }
attach_sequence_audienceSet the lead lists, mailboxes and LinkedIn accounts for a draft. Each argument replaces the current set.Free
attach_sequence_audienceSet the lead lists, mailboxes and LinkedIn accounts for a draft. Each argument replaces the current set.campaign_id: int, list_ids?: int[], email_account_ids?: int[], linkedin_account_ids?: int[]
TOON { campaign_id, lists, email_accounts, linkedin_accounts, connected_linkedin_accounts, lead_count, requirements, oppora_url }
update_sequence_settingsChange a draft's name, schedule, dates, daily limit, tracking, CRM push and reply agent.Free
update_sequence_settingsChange a draft's name, schedule, dates, daily limit, tracking, CRM push and reply agent.campaign_id: int, name?: string, schedule_id?: int, start_date / end_date?: "YYYY-MM-DD", daily_limit?: int (1-2000), push_replies_to_crm, stop_tracking_on_reply, open_tracking, click_tracking, skip_dnc, reply_agent_enabled?: bool
TOON { campaign_id, updated[], oppora_url }
activate_sequenceLaunch a sequence. Sends real email and LinkedIn messages; refused while readiness blockers remain.Free
activate_sequenceLaunch a sequence. Sends real email and LinkedIn messages; refused while readiness blockers remain.campaign_id: int
TOON { campaign_id, name, status, enrolled, step_count, warnings, readiness_warnings, oppora_url }
pause_sequencePause a running sequence. Further sends stop at once.Free
pause_sequencePause a running sequence. Further sends stop at once.campaign_id: int
TOON { campaign_id, status, oppora_url }
resume_sequenceResume a paused sequence after a fresh readiness check.Free
resume_sequenceResume a paused sequence after a fresh readiness check.campaign_id: int
TOON { campaign_id, status, readiness_warnings, oppora_url }
Templates & schedules
7Reusable pieces for email campaigns.
list_templatesEmail and LinkedIn templates, filterable by kind.Free
list_templatesEmail and LinkedIn templates, filterable by kind.list_follow_up_templatesFollow-up templates ordered by position and delay.Free
list_follow_up_templatesFollow-up templates ordered by position and delay.list_schedulesSending windows with timezone and days.Free
list_schedulesSending windows with timezone and days.create_email_templateHTML email template with merge variables and fallbacks such as {industry|your industry}.Free
create_email_templateHTML email template with merge variables and fallbacks such as {industry|your industry}.create_linkedin_templatePlain-text LinkedIn message, 200 characters max.Free
create_linkedin_templatePlain-text LinkedIn message, 200 characters max.create_follow_up_templateFollow-up with position, days after the first email and an optional subject.Free
create_follow_up_templateFollow-up with position, days after the first email and an optional subject.create_scheduleSending window: days, start and end time, any IANA timezone.Free
create_scheduleSending window: days, start and end time, any IANA timezone.Analytics
7Read-only reporting across campaigns, sequences, mailboxes and lists. Reply text is not available over MCP; read replies in Oppora.
get_dashboard_analyticsOrg-wide totals: lists, leads, sends, opens, replies, bounces, LinkedIn connections, workflows, top campaigns.Free
get_dashboard_analyticsOrg-wide totals: lists, leads, sends, opens, replies, bounces, LinkedIn connections, workflows, top campaigns.get_campaign_analyticsAll-campaign summary or one campaign, with lead status breakdown and follow-up progress.Free
get_campaign_analyticsAll-campaign summary or one campaign, with lead status breakdown and follow-up progress.campaign_id?: int, campaign_name?: string (omit both for all campaigns)
get_sequence_campaign_analyticsFull sequence analytics: email, LinkedIn, calls, CRM pushes and a per-step table.Free
get_sequence_campaign_analyticsFull sequence analytics: email, LinkedIn, calls, CRM pushes and a per-step table.campaign_id?: int, campaign_name?: string
TOON { campaign, audience funnel, rates, email, linkedin, calls, crm, reply_outcomes, steps, tracking_setup }
get_sequence_recipientsPer-lead sequence status: current step, activity on each channel, reply status.Free
get_sequence_recipientsPer-lead sequence status: current step, activity on each channel, reply status.campaign_id?: int, campaign_name?: string, filter?: string (all, replied, in_progress, queued, completed, failed, paused, waiting_task, email_sent, opened, clicked, bounced, unsubscribed, invite_sent, invite_pending, connected, li_message, inmail_sent, skipped, unreachable, removed), search?: string, limit?: int (1-100, default 25)
get_pipeline_funnelOutbound funnel from contacted to opportunity: open, in progress, won, lost.Free
get_pipeline_funnelOutbound funnel from contacted to opportunity: open, in progress, won, lost.get_email_account_healthPer-mailbox connection, warmup status, daily usage and pause state.Free
get_email_account_healthPer-mailbox connection, warmup status, daily usage and pause state.get_list_analyticsList quality: lead and company counts, email coverage, verified and risk rates.Free
get_list_analyticsList quality: lead and company counts, email coverage, verified and risk rates.list_id?: int, list_name?: string
Research / web
5Web, news, maps and semantic search. web_search and web_scrape are free; the other three cost 1 AI credit per call that returns results.
web_searchGoogle web search: titles, snippets, links and the knowledge graph.Free
web_searchGoogle web search: titles, snippets, links and the knowledge graph.web_scrapeFetch a URL and return its readable text.Free
web_scrapeFetch a URL and return its readable text.smart_web_searchSemantic web search (Exa) for niche companies, people, news, papers and reports.1 AI credit per call
smart_web_searchSemantic web search (Exa) for niche companies, people, news, papers and reports.local_business_searchGoogle Maps businesses with address, phone, website and rating.1 AI credit per call
local_business_searchGoogle Maps businesses with address, phone, website and rating.news_searchRecent news articles, useful for funding, launch and hiring signals.1 AI credit per call
news_searchRecent news articles, useful for funding, launch and hiring signals.End-to-end example
One conversation can take a list from search to a launched sequence. Background steps return a task_id; the assistant polls get_task_status or list_my_tasks.
- 1
get_available_industries + get_available_countries(resolve exact filter values) - 2
discover_companies(industry=[…], hq_country=[…])(rows carry Oppora ids) - 3
my_lists or create_list(pick the target list) - 4
add_companies_to_list(list_id, company_ids=[…])(1 data credit per new company) - 5
enrich_companies(list_id)(background task) - 6
find_leads_for_companies(list_id, departments=[…], management_level=[…], title=[…])(background task) - 7
score_leads(list_id, service_type, leads_per_company, …)(Yes or No per lead) - 8
find_emails_for_leads(list_id)(background task) - 9
get_task_status(task_id) or list_my_tasks(status="completed")(progress and links) - 10
create_sequence_campaign + save_sequence + attach_sequence_audience(draft with email and LinkedIn steps) - 11
get_sequence, then activate_sequence when you say "launch"(sends for real)
create_workflow, then add_workflow_node with steps such as company-crawl, lead-search, ai-recommendation, search-contact and generate-campaign, then set_workflow_icp to target your ICP and start_workflow. For outside data (web scrapes, news, pasted lists): create_companies_bulk and create_leads_bulk save up to 100 rows per call.FAQ
Which MCP clients are supported?
Any client that supports remote MCP servers over Streamable HTTP. The setup tabs above cover Claude.ai, Claude Desktop, Claude Code, Cursor, VS Code and ChatGPT. Clients that only run local servers can connect through the mcp-remote bridge.
Does Oppora's MCP server work with ChatGPT?
Yes. Add it as a custom app in ChatGPT developer mode with the URL https://api.oppora.ai/mcp?api_key=YOUR_KEY and no authentication. Developer mode is a beta feature on paid ChatGPT plans, and workspace admins may need to allow it.
Is the MCP server free?
Yes. Connecting costs nothing and works on every Oppora plan, including the 7-day free trial. Tool calls spend the same credits as the app. Pro allows 300 a minute and Max 1,500.
How much does each tool cost?
Most tools are free, including lists, filters, templates, campaigns, sequences, workflows, ICP, analytics, web search and scraping. Paid tools: discover_companies costs 5 data credits and discover_people 10 per call with results; search_jobs 1 data credit per page; add_companies_to_list and add_leads_to_list 1 data credit per new item; email_search 1 data credit per email found; email_verifier 1 data credit (standard) or 2 (advanced); phone_search 1 phone credit per number found; find_leads_for_companies 1, 3 or 5 data credits per lead saved; find_emails_for_leads data credits per email found; enrich_companies 1 data credit per field filled; score_leads 1 AI credit per lead; smart_web_search, local_business_search and news_search 1 AI credit per call with results. Misses and empty results are free.
Can the AI send emails without asking?
No tool sends on the AI's own initiative. Outreach starts only through a launch call: start_campaign, or a status change to active through update_campaign_status or create_or_update_campaign, for email campaigns, and activate_sequence or resume_sequence for sequences. Each runs a readiness check and refuses if setup is incomplete. The sequence launch tools tell the assistant to call them only when you explicitly ask, and your request is the go-ahead; Oppora does not add a second confirmation. start_campaign, update_campaign_status, activate_sequence and resume_sequence carry the MCP destructive hint, which many clients use to ask before running a tool. create_sequence_campaign and the editing tools only build drafts.
Do MCP and the REST API use the same key?
Yes. One opp_live_ key works for both. Create keys in the app under Integrations > Oppora API > New key; the secret is shown once.
How does authentication work?
With your Oppora API key. Send Authorization: Bearer YOUR_KEY or X-API-Key: YOUR_KEY, or add ?api_key=YOUR_KEY to the URL for clients that cannot set headers. Each key belongs to one user in one workspace.
What format do tool responses use?
TOON, a compact tabular text format, for every tool except discover_companies and discover_people, which return JSON because their rows carry nested fields. TOON spends fewer tokens than JSON on lists of uniform records.
How do I check that my key works?
Run MCP Inspector with npx @modelcontextprotocol/inspector, connect to https://api.oppora.ai/mcp?api_key=YOUR_KEY over Streamable HTTP and list the tools. You should see 73.