Overview
Primary Portal MCP lets you query Primary Portal’s ECM deal data directly from your own AI assistant (Claude, ChatGPT, or any other MCP-compatible tool) using natural language instead of the web UI. It exposes deal search, filtering, aggregated metrics, deal lookups, lock-up expiries and bookbuild messages over the Model Context Protocol, scoped to whatever your account and organisation are entitled to see.
Before you start
You’ll need:
- An existing Primary Portal investor account. This surface is investor-only.
- A Priced or Live entitlement on your organisation. Live includes everything Priced does, plus announced/live deals and bookbuild messages (see Entitlements). If you’re not sure which you hold, ask your Primary Portal account team.
- For announced or in-flight (not yet priced) deals from a specific bank, an active connection to that bank. Without one, you’ll only see the priced-deal universe your entitlement covers.
Connecting your AI assistant
Endpoint. Primary Portal MCP is reached at:
https://mcp.live.ai.primaryportal.com/mcpAuthentication. OAuth 2.1, with no API key or personal access token to generate or store. When you add Primary Portal MCP as a remote server in your AI assistant, it will redirect you to sign in with your existing Primary Portal investor credentials and ask you to authorise access.
Steps (exact menus vary by client):
- Open your AI assistant’s connector or integrations settings.
- Add a new MCP server and paste the endpoint URL above.
- Sign in with your Primary Portal credentials when prompted.
- Approve the permissions request.
Once connected, the tools your assistant can see are filtered live to your organisation’s entitlements, so what you’re offered may differ from a colleague’s, even at the same firm.
Entitlements
Access comes in two tiers, and Live is a superset of Priced:
| Entitlement | What it covers |
|---|---|
| Priced | All priced and withdrawn deals, plus lock-ups. |
| Live | Everything in Priced, plus announced and in-flight (live) deals and bookbuild messages. |
Your entitlement decides both the deal universe you can query and which tools your assistant is offered. The catalogue is filtered live at connection time, so a Live user sees more tools than a Priced user, and what you’re offered may differ from a colleague’s, even at the same firm.
Available tools
Every tool Primary Portal MCP can expose is listed below. The Access column shows the minimum entitlement. A Priced tool is also available to Live users, since Live includes Priced.
| Tool | What it does | Access |
|---|---|---|
get_deals_data_coverage |
Dataset metadata: pricing-date and withdrawal-date spans, deal count by state, and every available field with a plain-language description | Priced |
get_available_deals_filters |
Valid filter values for deal searches: regions, offering types, sectors, market-cap bands, states, countries and the pricing-date range. Pass includePublishingBanks=true for the full list of bank names |
Priced |
search_deals |
Search deals by region, offering type, sector, market-cap band, state, pricing-date or withdrawal-date range, issuers, countries, publishing banks or minimum deal size (at least one filter required) | Priced |
get_aggregated_deals_metrics |
Deal count, total volume or average performance, grouped by sector, region, offering type, market-cap band, state, country or publishing bank | Priced |
get_deal |
Full detail on up to 50 deals at once, by deal ID | Priced |
search_lockups |
Search the upcoming lock-up expiries calendar | Priced |
search_bookbuild_messages |
Search bookbuild messages by deal, issuer or bank | Live |
get_available_bookbuild_filters |
Valid issuer, bank and country values for bookbuild search | Live |
All tools are read-only. Rather than treating this table as fixed, ask your assistant to list its available tools after connecting, or call get_deals_data_coverage.
Deal tools
Five tools cover the deals dataset. Most questions follow the same path:
get_available_deals_filtersto find valid filter values.search_dealsto find deals, orget_aggregated_deals_metricsto summarise them.get_dealfor the full record of specific deals.
get_deals_data_coverage explains what each field means and how often it’s filled.
Filters
search_deals and get_aggregated_deals_metrics take the same filters. All are optional, and they combine with AND.
| Filter | Values | Matching |
|---|---|---|
region |
EMEA, APAC or AMRS |
Exact, any case |
offeringType |
IPO, ABO, EQL, RI, SPAC or OTH |
Exact, any case |
sector |
A sector name | Partial, any case |
marketCapBand |
micro, small, mid, large or mega |
Exact, any case |
state |
PRICED, ANNOUNCED, LIVE or WITHDRAWN. Omit it for every state |
Exact, any case |
pricingDateFrom / pricingDateTo |
Dates as YYYY-MM-DD |
Inclusive. Only priced deals have a pricing date |
withdrawnDateFrom / withdrawnDateTo |
Dates as YYYY-MM-DD |
Inclusive. Only withdrawn deals have a withdrawal date |
issuers |
Up to 50 issuer names | Partial, any case; any name matches |
countries |
Up to 50 country codes (see Countries) | Exact; any code matches |
publishingBanks |
Up to 50 bank names (see Publishing banks) | Partial, ignoring case, punctuation and spacing; any name matches |
minDealSizeUSD |
A deal size in US dollars | Deal size at or above this |
search_deals
Finds deals that match your filters, most recently priced first. Withdrawn deals are ordered by withdrawal date.
- Needs at least one filter.
state=PRICEDon its own doesn’t count, butANNOUNCED,LIVEorWITHDRAWNdoes. - Returns 20 deals per page by default and up to 50, with the total count, whether there are more, and the offset of the next page.
- Each deal carries every field in What a deal contains except
stateandmarketCapBand. Useget_dealfor those.
Examples: offeringType IPO, countries ["IND"] and pricingDateFrom 2026-01-01 lists IPOs listed in India and priced in 2026. state WITHDRAWN and withdrawnDateFrom 2026-01-01 lists deals withdrawn this year.
get_aggregated_deals_metrics
Groups deals by one dimension and returns one metric for each group.
-
groupBy:sector,region,offeringType,marketCapBand,state,countryorpublishingBank. -
metric: one of the following.Metric What it returns dealCountNumber of deals totalVolumeUSDTotal deal size, in US dollars avgPerf1d/avgPerf1w/avgPerf1mAverage share price move one day, one week or one month after pricing, in percentage points -
Filters: the same as
search_deals. For dates, use one of the pricing-date range,lookbackDays(days back from the latest pricing date in the data) or the withdrawal-date range. -
States: without a
stateor date filter, groups include announced, live and withdrawn deals as well as priced ones. SetstatePRICED, or a pricing-date range, to count completed deals only. -
Returns one row per group: the group value, its deal count and the metric. Check the deal count before trusting an average.
Example: groupBy country, metric totalVolumeUSD, offeringType IPO and lookbackDays 90 gives IPO volume by listing country over the last 90 days.
get_deal
Returns the full record for up to 50 deals at once.
dealIds: an array of 1 to 50 deal IDs. IDs fromsearch_deals,search_lockupsandsearch_bookbuild_messagesall work.- Returns the deals in the order you asked for, every field in What a deal contains, plus a list of any IDs that matched no deal.
get_available_deals_filters
Returns the valid values for every filter above, worked out from the data, plus the earliest and latest pricing dates. Pass values to the filters exactly as returned. Bank names are a long list, so they’re only included when you pass includePublishingBanks=true.
get_deals_data_coverage
Describes the dataset: the pricing-date and withdrawal-date ranges, deal counts by state, and every field the deal tools return, with what it means, its possible values and how often it’s filled. It also lists the dataset’s limits. Ask your assistant to call it when you need to know how far an answer can be trusted.
Publishing banks
You can filter and group deals by the banks on them, in any role: bookrunners and coordinators, but also sponsors, co-managers, placing agents and advisers.
- Any bank name containing your term counts, so “Morgan Stanley” also matches “MUFG Morgan Stanley”, and a broad term such as “Bank” pulls in several banks.
- If a name matches no bank, you get no deals back, plus a list of similar bank names to try instead.
- Grouping by
publishingBankuses the bank names as they appear on each deal, so one bank can show up under several name variants. Check the groups before comparing two banks.
Countries
countries filters on the country of the listing exchange, not the issuer’s home country. Values are three-letter ISO 3166 codes, for example IND, JPN or GBR. A dual-listed deal matches each of its countries.
What a deal contains
get_deal returns every field below. search_deals returns all of them except state and marketCapBand. Not every field is filled for every deal: announced and live deals have no pricing date, prices or performance yet, withdrawn deals never get them, and EQL deals have no prices, performance or market cap.
| Field | What it is |
|---|---|
dealId |
Primary Portal’s ID for the deal. |
issuer |
The issuer’s name. |
ticker |
The ticker, with its exchange code, for example 658A JP. |
state |
PRICED, ANNOUNCED, LIVE or WITHDRAWN. |
offeringType |
IPO, ABO, EQL, RI, SPAC or OTH. |
region |
EMEA, APAC or AMRS. |
sector |
The issuer’s sector. |
dealSizeUSD |
The deal size, in US dollars. |
marketCapBand |
The issuer’s market cap at the time of the deal, as a band: micro (under USD 250m), small (250m to 2bn), mid (2bn to 10bn), large (10bn to 200bn) or mega (200bn and above). Filled only when marketCapUSD is. |
marketCapUSD |
The issuer’s market cap at the time of the deal, in US dollars. It’s fixed then and never refreshed, so it isn’t today’s market cap. For IPOs it’s the low end of the implied range. Often empty outside IPOs. |
announcementDate |
The date the deal was announced. Filled on almost every deal, including announced and live ones. |
pricingDate |
The date the deal priced. |
withdrawnDate |
The date the deal was withdrawn. Filled only on withdrawn deals. |
offeringCurrency |
The currency the deal was offered in, as a three-letter ISO 4217 code, for example JPY. Both prices below are in this currency. Often empty on announced and live deals. |
finalPriceLocal |
The final offer price per share, in the offering currency. |
latestPriceLocal |
The latest daily closing price per share, in the offering currency. It’s refreshed once a day, not a live quote, and isn’t adjusted for splits or rights issues. |
timeToBooksCoveredMin |
Minutes from books opening to books covered. Filled on only a minority of deals. An ABO usually covers in minutes and an IPO over a day or more, so only compare it within one offering type. |
performance |
The share price move in percentage points: oneDay, oneWeek, oneMonth and sincePricing. sincePricing compares the latest price with the final price. |
publishingBanks |
Every bank on the deal, with its role. |
url |
A link to the deal in Primary Portal (see What data you’ll see). |
Sample prompts
- “What deal data do I have access to?”
- “Show me IPOs priced in the technology sector in EMEA over the last 6 months.”
- “What’s the average one-week aftermarket performance for healthcare IPOs this year, by region?”
- “Show me the deals Nomura was on in the last six months.”
- “Compare Goldman Sachs and Morgan Stanley on healthcare IPOs this year by deal count.”
- “List IPOs listed in India in 2026.”
- “Which country had the highest total ECM volume in APAC this year?”
- “Which IPOs were withdrawn in EMEA this year?”
- “Give me full details on these three deals: [deal IDs].”
- “What filters can I use to narrow a deal search?”
- “Which IPO lock-ups are expiring in the next month in EMEA?”
- “Which lock-ups expire in Japan in the next two weeks?”
- “Show me the bookbuild messages from JP Morgan for [issuer name].”
Lock-ups
search_lockups queries an upcoming lock-up expiries calendar: a forward-looking view of when share lock-ups on recent deals are due to expire. It’s available on the Priced entitlement, and therefore to Live users too.
Filters:
dealTypes(required): one or more offering types.issuer(optional): partial and case-insensitive; matches on both the issuer name and the ticker.region(optional): a specific deal region.countries(optional): one or more listing countries (see Countries).expiryFrom/expiryTo(optional): bound the results to a lock-up expiry date range.- Results are ordered by expiry date, nearest first, and paginated.
Each row also lists the deal’s bookrunners and a link to the deal in Primary Portal.
The dataset is a rolling snapshot of upcoming expiries (currently around a month ahead), not a full history. Depending on when it was last loaded, it can also include expiries from the past few days. Every response reports the expiry window it currently holds, so an empty result tells you whether nothing matched your filters or you simply queried outside the loaded window.
Bookbuild messages
If your organisation holds the Live entitlement, two additional tools let you search bookbuild messages.
search_bookbuild_messages: filter bydealIds(exact match),issuers(partial, case-insensitive) orbankNames(partial, case-insensitive). At least one of these is required. Each takes up to 50 values: values within a filter are combined with OR, and different filters with AND. You can narrow further withcountries, but it doesn’t count as the required filter on its own. Results are paginated (up to 50 per page), ordered most recent first, and message bodies are returned in full. Each message carries its deal’s state, including withdrawn, and a link to the deal.get_available_bookbuild_filters: takes no input and returns the issuer names, bank names and listing countries present in the messages you can see, so you can discover valid filter values instead of guessing (the bookbuild equivalent ofget_available_deals_filters).
You only see messages for deals you can see through the deal tools. A deal ID you can’t see returns an empty list rather than an error, as does a search with no matches.
What data you’ll see
Announced and live deals. Priced users see the priced-deal universe. Live users additionally see announced and in-flight deals, but only where there’s an active connection to the relevant bank, and further filtered by country and regulatory-status rules (REG_S vs QIBS). If a connection is revoked, it takes effect on your very next query.
Deal states. Deals are PRICED, ANNOUNCED, LIVE or WITHDRAWN. Withdrawn deals were cancelled before pricing. They’re included on the Priced entitlement, and get_deals_data_coverage reports the span of withdrawal dates available.
Links to Primary Portal. Every deal, lock-up and bookbuild result includes a link to the deal in Primary Portal: the termsheet for announced and live deals, and the deal page otherwise. Your assistant should pass the link on unchanged rather than build its own.
Input rules.
- Fixed values such as region, offering type, market-cap band, state and deal type are accepted in any case, so
ipoworks as well asIPO. - Filters that take a list (issuers, countries, banks, deal IDs) accept up to 50 values. More than that is rejected with an input error.
Fair use thresholds
Primary Portal MCP isn’t charged by volume, but use must stay within these thresholds, under clause 5.2 of the Data MCP Terms of Use.
| Term | Meaning |
|---|---|
| Data object | A single deal, bookbuild message or lock-up record |
| Tool call | A single call to one of the MCP tools |
| Threshold | Limit |
|---|---|
| Data objects per minute per authorised user | 2,000 |
| Data objects per month per authorised user | 100,000 |
| Tool calls per minute per authorised user | 30 |
Use above any threshold is presumed to be outside interactive sessions, unless you can show otherwise.
Security and data handling
- No API keys or personal access tokens: you sign in with your existing Primary Portal account (OAuth), and access ends as soon as your account, connection or entitlement changes.
- Every query is checked against your current entitlements and connections, so a change applies from your next query.
- You only ever see the deals your organisation is entitled to.
- Every tool is read-only: none can create, change or delete anything.
- Access is logged for usage and audit purposes.