Skip to content

MCP server

POST https://api.ax1om.ai/mcp · streamable HTTP · 31 tools. Point a client at it, send your credential in the Authorization header, and an agent can run a scoring trial end to end: check fit honestly, prepare a scrubbed export, train a model on your own conversion history, read the results, score records live, and check those scores against what actually converted.

Why this exists: ax1om for AI agents.

What this is

The Model Context Protocol is how an AI agent calls an external tool. A predictive scoring MCP server is one that gives the agent access to a trained model that ranks conversion likelihood, instead of asking the agent to invent a score itself.

That distinction is the whole point. A language model can reason about a lead, summarize it, draft the outreach, and decide what to do next. It should not be the scoring model. Prioritizing on conversion history is a job for a model trained on your outcomes, measured, monitored for stability, and explainable per record. ax1om is that model. The agent consumes the prediction and decides what to do with it.

Most scoring an agent can reach today is a rules engine wearing a different hat: enrichment, signals, and hand-set ICP weights. ax1om trains a dedicated model per customer on that customer's own conversion history, converted and non-converted records alike, and every score carries the factors behind it. Nothing here is shared across customers and no third-party intent data is involved.

Connect an agent

The server is mounted on the main API, so there is nothing to install and nothing to run. For an MCP client that speaks HTTP, including Claude Desktop, Claude Code, and Cursor:

.mcp.json
{
"mcpServers": {
"ax1om": {
"type": "http",
"url": "https://api.ax1om.ai/mcp",
"headers": { "Authorization": "Bearer ax1m_sk_your_key_here" }
}
}
}

For a client that only speaks stdio, bridge it:

stdio bridge
{
"mcpServers": {
"ax1om": {
"command": "npx",
"args": [
"-y", "mcp-remote", "https://api.ax1om.ai/mcp",
"--header", "Authorization: Bearer ax1m_sk_your_key_here"
]
}
}
}

The example uses a v1 scoring key. Mint one in the app under Settings, API keys. The secret (ax1m_sk_...) is shown once. A test key (ax1m_sk_test_...) works the same way and meters against a separate free allowance. For broader access, connect with person OAuth or use an org agent key as described below.

Authentication

There are three agent credential paths. Choose based on who the agent acts for and which tools it needs.

CredentialWhere it comes fromWhat it reaches
Person OAuth grantConnect from an MCP client and approve in the browserThe tools allowed by the scopes that person approved
ax1m_ak_... org agent keyAn org admin creates and revokes it in the consoleThis MCP endpoint only, under the key's own scopes
ax1m_sk_... v1 API keySettings, API keys at app.ax1om.aiscore_records · test_webhook only

An org agent key belongs to the company rather than to a person. It is always MCP-only: sending it directly to a REST route is refused. Because a key is not a person, Require SSO and Require MFA do not apply to it. Revoking the key in the console cuts off its access.

A v1 ax1m_sk_... key carries no scopes and is not extended beyond live scoring. Call any other tool with one and the server returns a plain refusal saying which credential that tool needs.

An authenticated app session token remains supported for manual or raw HTTP access, with the same tool access checks it already had. It is separate from a person OAuth grant, which is limited to the scopes approved in the browser.

The server holds no credentials of its own. Every call it makes carriesyour credential to the real route, which runs its own auth, entitlement checks, rate-limit bucket, and metering. Keys are never logged and never appear in a tool result.

On browser authorization

An agent can now authorize in a browser instead of being handed a token. Point your MCP client at the endpoint above and connect: it registers itself, your browser opens, you sign in (or create an account - connecting starts your trial) and approve exactly what the agent may do - score records · upload data · train models · read model results. Every grant is yours to revoke at any time under Settings · Connected agents in the app, and revoking cuts off the agent immediately.

Accounts with multi-factor authentication approve on an MFA-verified session - the check happens at the moment you authorize the agent, not on every call the agent makes. Header credentials stay fully supported as the fallback for headless and warehouse setups; nothing already configured needs to change.

Scopes

Person OAuth grants and org agent keys use the same four scopes. The approval screen is the source of truth for what each scope allows:

  • Score records (scoring:write) · Send records to your trained models and get conversion-likelihood scores back. Counts against your scored-record allowance.
  • Read model results (models:read) · See your models, their results, and the factors behind a score.
  • Train models (models:write) · Start training runs and create models in your workspace.
  • Upload data (data:write) · Upload CSV files of your records into your workspace.

Creating a model is never automatic, and no scope lets an agent activate one.

Tool reference

The server registers 31 tools. 28 are documented below, 4 of which never touch the network: nothing about your data leaves your machine when you call them.

Every documented tool has its own page: the table is the map, and a tool name links to what it needs, what it returns, which credential reaches it, and an example call.

The remaining 3 are registered and callable, but are not described here yet. They belong to capabilities we have not finished saying anything public about, and we would rather name the gap than let you find it: create_forecasting_model, evaluate_forecast_scenario, check_forecast_validation. Ask us if you need one before it lands here.

Local · nothing leaves your machine

These run entirely inside the agent. They make no network call, need no credential, and send none of what you pass them anywhere. An agent can assess fit and prepare a scrubbed export before your org has an account.

ToolNetworkCredentialWhat it does
assess_fitNononeThe four-point fit checklist: a definable conversion outcome, enough conversions, months of history, and a CRM that can export a CSV. Returns fit, fit_with_caveats, or not_yet. A not_yet comes with next steps that need nothing from ax1om.
generate_export_specNononeWhich columns may leave your org and which never may, how to derive the email domain, and how to build the conversion label. Set warehouse to snowflake or databricks and you get a commented SQL scrub template instead of spreadsheet steps.
validate_csvNononeLints your header row, and any sample values you pass, against the drop rules, then proposes a column mapping for what is left. The report never repeats back a value it flagged. Run it before every upload.
safe_export_policyNononeThe keep and drop tables verbatim, for a security reviewer who would rather read the rules than infer them from a generated query.

Train and read

Upload a scrubbed dataset, train on your own outcomes, and read what the run produced. Training is asynchronous throughout: start a run, then poll for it.

ToolNetworkCredentialWhat it does
upload_csvYesSession tokenUploads a scrubbed CSV as a training dataset and returns the column metadata ax1om read from it. Max 100MB, .csv only.
create_scoring_modelYesSession tokenCreates the conversion model: which leads or contacts convert, learned from your own conversion history. Bind the outcome to a CRM template or, for an uploaded CSV, to your own columns. Field selection is optional, and label, identifier and personal-data columns are never selectable: naming one is refused rather than silently dropped. Returns the model id to train.
train_modelYesSession tokenStarts a training run. Training is asynchronous: this returns a run id, then poll get_model_results.
get_model_resultsYesSession tokenModel state and raw training metadata, including run status.
get_readoutYesSession tokenThe model-quality readout as structured text: AUC named and explained, lift in the top band, what it trained on, the features that drove the score, and the Feature Stability Score. Metrics the model does not have are reported as unavailable rather than guessed.
explain_modelYesSession tokenThe factors behind a trained model as structured data: each one with its direction and its size, the quality summary, and, once the model has retrained at least once, what moved since the last run. It reads what the run already produced and computes nothing new. No language model is involved.
compare_versionsYesSession tokenStructural diff between two versions of the same thing: two versions of a semantic entry, or two models’ saved configurations. Returns what changed, with a summary line per change. Read-only.

Score and check

Score records live, and grade what the scores did against what actually converted. Scoring is metered; the check is read-only.

ToolNetworkCredentialWhat it does
score_recordsYesAPI keyLive scoring through POST /v1/score. Returns a 0-100 score per record plus the conversion likelihood it ranks by, and the factors behind it when explain is on. Max 1000 records per request. Metered.
check_validationYesSession tokenThe scoring-vs-outcomes check-in: cohort conversions by score band for a model’s live scores, with maturity honesty. Cohorts too young to grade say so, showing counts and withholding rates, rather than rendering noise. The natural week-2 and week-4 questions: are the top bands converting, and is it too early to tell?
test_webhookYesAPI keyPosts one sample record to the inbound /v1/webhooks/score endpoint and returns the exact flat response your receiver will get. Use a test key so it meters against the test allowance.

Customer health

The renewal-risk family, on the same rails as scoring. Once a health model is trained you read it, grade it and score with it using the tools above: the readout, the validation check and live scoring all take a health model, and the number comes back labelled as renewal risk rather than conversion.

ToolNetworkCredentialWhat it does
create_health_modelYesSession tokenCreates a customer-health model: which accounts are at risk before renewal, learned from the renewals your own book has won and lost. Pick a template and the connection to train on. Returns the model id to train, then read and grade it with the same tools a conversion model uses. It writes to your workspace, so it needs an owner or admin session rather than an API key.

Timing

The in-market family, and the one place the surface deliberately stops short. An agent can configure timing, start a refresh, read the result horizon by horizon and grade it. It cannot ask for one account on demand: timing refreshes on a dispatched run rather than per request, so live scoring refuses a timing model instead of returning a number that would be stale by construction. One timing model per workspace, and timing is included with Pro and above.

ToolNetworkCredentialWhat it does
create_timing_modelYesSession tokenConfigures the in-market timing model: for each account, when it is likely to enter a buying window, learned from your own account event history. One per workspace, so calling it again reconfigures the existing model rather than creating a second. Returns the model id and the resolved configuration.
train_timing_modelYesSession tokenStarts a timing refresh. It takes no model id, because there is one timing model per workspace, and it dispatches the same run the Timing page runs rather than training in the request. Returns a run id and a pending status, then poll get_timing_readout.
get_timing_readoutYesSession tokenThe timing readout, horizon by horizon, plus how much of your book the last run actually covered. Timing is graded per horizon rather than on one number, so no single figure is synthesized across them. The score ranks the likelihood of entering a buying window within a horizon. It is not a conversion score and not a predicted close date.
check_timing_validationYesSession tokenGrades the timing model per horizon on its own holdout evaluation. Deliberately not the forward backtest check_validation runs for a scoring model: what you get is what the engine computed, with the horizons it could not grade named as such rather than filled in.

Discover

Read-only orientation. What exists in this workspace, what it is made of, and which of it is worth acting on, so an agent does not have to guess before it acts.

ToolNetworkCredentialWhat it does
list_connectionsYesSession tokenThe data connections this workspace can train on, and the ids the model constructors take. Each row carries the connection id, its provider, its status and a display name. Never credentials. Read-only.
describe_connectionYesSession tokenThe columns of one object on a connection: each with its type, the role schema discovery graded it, whether it reads as personal data, and how populated it is; the other objects you can describe; and, for the uploaded-CSV workspace, its upload history. Read-only. This is the read that lets an agent learn a workspace's schema without provoking a validation error to see it.
list_modelsYesSession tokenWhat this workspace already has, so an agent can triage from the listing instead of pulling full results for every model: status, the run currently serving, whether a quality reading exists yet, where the training data came from, and how many warnings the last run raised. Status is a workflow state a person set, not a quality verdict, and a row that looks approved while carrying warnings says so. Read-only.
recommend_modelYesSession tokenRoutes a population or a plain-language intent to the model that fits it, then lists this workspace’s own models of that kind so an agent can act, and names how to create one when there is none. Read-only.

Data semantics

What ax1om knows about the meaning of your data, and how an agent proposes an addition. A proposal changes no number until a person confirms it in the app.

ToolNetworkCredentialWhat it does
get_dictionaryYesSession tokenThe data dictionary: field meanings and caveats, metric notes, and analysis memos, plus the field roles and known nuance shapes ax1om brings by default. The first read to make before building analysis on a workspace’s data. Honest about coverage: it describes what is held today rather than fabricating a catalog for fields nobody has described. Read-only.
list_nuancesYesSession tokenWhat ax1om knows about this workspace’s data semantics, merged across two tiers: universal CRM truths, and this workspace’s own entries. Every entry is labeled with its tier and status, and only confirmed entries ever affect a number. A fresh workspace sees the base tier rather than an empty list. Read-only.
propose_nuanceYesSession tokenProposes one nuance about your data, such as a boolean that means a record should be excluded from metrics, in the words of whoever knows it. Creates a proposed entry only: nothing a proposal says changes a number anywhere until a person confirms it in the app.

The governed passthrough

One escape hatch, under your own grant. It is permission parity rather than gate removal: the call runs as you, so your role, your plan entitlements and the agent-compute consent gate all still apply, and an agent can do nothing here that you could not do in the app.

ToolNetworkCredentialWhat it does
describe_workspace_apiYesSession tokenWhat the workspace API can do: the route families an agent may call, and for one family the exact paths, parameters and payload shapes. Generated from the API’s own schema and the parity manifest, so it describes what the routes actually accept rather than a hand-written summary that goes stale. A route the door refuses is either absent or marked not callable, with the reason. Read-only, and it reads no data of yours.
call_workspace_apiYesSession tokenCalls one workspace route under your own grant. Run describe_workspace_api first for the exact path and shape. Anything that ends at a consent screen, that is a human ceremony, or that governs agents themselves (spend, keys, grants, members, payment) is refused with the reason, and a path outside the parity manifest is refused outright. JSON in, JSON out: no downloads, no streaming.

On test_webhook

ax1om does not deliver outbound webhooks to a url you supply, so there is no delivery endpoint to ping. /v1/webhooks/score is aninbound endpoint: Marketo, Zapier, or your own service posts a record and gets a score back in the response. That is the path an integration actually exercises, so that is the one this tool tests. It takes a model_id, not a url.

A trial, end to end

The four local tools exist so an agent can do the preparation work before anything is sent anywhere. A typical run:

  1. Check fit first. assess_fit is deterministic and answers honestly, including when the answer is no. A first model trains on as few as 50 conversions, and if you are below that the tool says so and gives you next steps that need nothing from ax1om.
  2. Generate the export spec.generate_export_spec returns exactly which columns may leave and which never may. In the warehouse lane it returns SQL instead, so the scrub runs where the data lives.
  3. Lint the file locally. validate_csv checks the header row against the drop rules and proposes a column mapping. No file, header, or value is sent anywhere.
  4. Upload, train, read. upload_csv, thentrain_model, then poll get_model_results and read get_readout for AUC, lift, the driving features, and the Feature Stability Score. The readout is structured text; there is no PDF export of it.
assess_fit
assess_fit({
conversion_outcome_defined: true,
conversion_count: 340,
months_of_history: 18,
crm_exports_csv: true,
crm: "salesforce"
})
result
{
"verdict": "fit",
"checks": [
{ "name": "conversion_outcome_defined", "pass": true },
{ "name": "conversion_count", "pass": true },
{ "name": "months_of_history", "pass": true },
{ "name": "crm_exports_csv", "pass": true }
]
}

Scoring inside an agent

Once a model is trained, score_records is the tool an agent calls in normal operation. Set explain to true and each score comes back with the factors behind it, which is what lets the agent explain its own prioritization to a human instead of asserting it.

score_records
score_records({
model_id: "mdl_abc123",
records: [
{ "Title": "VP of Revenue Operations", "Industry": "Software", "LeadSource": "Webinar" }
],
explain: true
})
result
{
"model_id": "mdl_abc123",
"scores": [
{
"score": 87,
"conversion_likelihood": 0.871,
"top_reason_1": "Title seniority",
"top_reason_2": "Industry: Software",
"top_reason_3": "Webinar source"
}
],
"records_scored": 1,
"usage": { "current": 151, "limit": 10000, "remaining": 9849 }
}

The score is a 0-100 ranking of conversion likelihood. It is not a percentage chance of conversion, and the per-record factors do not sum to it. A prospecting agent uses it to choose target accounts, an SDR agent to order outreach, a routing agent to set priority. In each case the model supplies the prediction and the reasons; the agent decides the action.

Compare it to what you run today

A readout tells you how the model scored itself. It does not tell you whether it beats the process you already run. That question has one honest answer and it is arithmetic on your own historical months: the leads your team treated as qualified, against the leads ax1om would have ranked at the top, over the same records, at the same volume.

The comparison needs a column you should never send us. Whatever your CRM calls it - MQL, qualified, lead grade, your current score - it is your estimate of who was worth working, and it stays on your machine. So does the comparison itself. Your agent already holds the export locally,score_records returns the ax1om side, and the arithmetic happens where both already sit. Nothing about how you qualify today reaches ax1om. That is the same reason thescrubbed export works: the fewer approvals a trial needs, the sooner it happens.

Paste this at an agent that has your export and this server connected:

head-to-head prompt
You have my CRM export on this machine and the ax1om MCP server connected.
Run a head-to-head between ax1om and the way my team qualifies leads today.
Ground rules, before anything else:
- My qualification column, my current score, and my conversion outcomes stay
on this machine. Never send them to a tool or to any network call.
- The only thing that goes to ax1om is what score_records needs: the feature
columns the export spec allows. Call generate_export_spec if you are not
sure which those are.
- Do the arithmetic locally. Report it to me, not to anyone else.
Then:
1. Read the export and ask me two questions before assuming anything: which
column marks the leads my team treated as qualified, and which column marks
a conversion. Name the candidates you found and let me choose.
2. Call get_readout and note the months the model trained on. Keep the
comparison to records outside that window. If that leaves too few records
to work with, tell me the comparison is in-sample and that it flatters
ax1om.
3. Keep only matured records: scored long enough ago that an outcome has had
time to land. Use 30 days unless I tell you my sales cycle is longer. Tell
me how many records you dropped as too recent.
4. Score what is left with score_records, 1000 records per call.
5. Count my side: how many records my qualification column marks, and how many
of those converted.
6. Count ax1om's side at the same volume: the top N by ax1om score, where N is
the count from step 5, and how many of those converted.
7. Report counts first, then rates. Withhold the rates if either set has fewer
than 50 matured records. Below that the gap is noise, and a percentage
reads as a finding it is not.
8. List the conversions my rules did not mark that ax1om's top N did, with the
factors behind each score, so I can see why it ranked them.
9. Close by saying what this is not: one historical read on my own data, not a
forecast.

The rules that keep it honest

Four of the steps above exist to stop the comparison flattering us. They are the same rules ax1om applies to its own numbers, and an agent that drops them produces a result you should not believe:

  • Matured records only. A record scored last Tuesday has not had time to convert. Counting it as a non-conversion punishes both sides at random. The recipe uses the same 30-day maturity window ax1om uses internally, widened to your sales cycle if yours is longer, and says out loud how many records it set aside.
  • Historical months, not last week. The whole method depends on records old enough to have outcomes. Run it over the months you already know the answer to; running it over recent leads measures nothing but how recently they arrived.
  • Counts before rates, and no rates on thin sets. Below about 50 matured records in either set, the difference between the two is noise wearing a percent sign. The recipe reports the counts and withholds the rates rather than printing a number that reads as a finding.
  • The same volume on both sides. Any model looks better if you let it pick fewer records. Taking exactly as many ax1om-ranked records as your rules marked removes that move from the argument, in either direction.

The last step matters most and it is the one a comparison usually skips. The list of conversions your rules did not mark is thewhy these leads? answer in its most useful form: real records, with real outcomes you can look up, and the factors that ranked each one. If those factors are not ones you would have named yourself, that is worth knowing before you route anything on the score.

What comes back has the shape below. Every number in it is invented. It is there to show the format, not to report what any comparison returned - ax1om publishes no result it has not measured on a customer's own data, and your own run is the only number that means anything here.

shape of the output · invented numbers, not an ax1om result
Head-to-head · records scored on or before 2026-06-30
Matured records 4,120
Dropped as too recent 860 inside the 30-day window
Excluded as in-sample 1,240 inside the training months
Your qualified set 412 records · 57 conversions · 13.8%
ax1om top 412 412 records · 91 conversions · 22.1%
Rates shown: both sets clear the 50-record floor.
Conversions your rules did not mark, that ax1om's top 412 ranked (44)
rank score factors
7 94 Title seniority · Industry: Software · Webinar source
23 88 Title seniority · Repeat pricing-page visits
41 85 Industry: Software · Demo request
...
Conversions ax1om's top 412 did not rank, that your rules marked (10)
Read these before you trust the rest. If they share something the model
never saw, that is a field to add, not a reason to discard the comparison.
This is one historical read on your own records. It is not a forecast.

Checking in once the model is live

The head-to-head is a one-off: it settles the question at the start, on records that already have outcomes. Once ax1om is scoring for real, the same question comes back on a schedule, and it no longer needs your export.check_validation reads cohort conversions by score band for the scores the model has already written, with the maturity window applied. Cohorts too young to grade say so and return counts with the rates withheld, rather than rendering noise as a trend.

That is the week-2 and week-4 check-in: are the top bands converting, and is it too early to tell? Both are real answers. A model two weeks into a trial has usually not had time to be right yet, and a tool that says so is more useful than one that draws a line through four points.

What leaves your org

Scrub the direct identifiers before the data leaves, then trial on the scrubbed file. A dataset that never contained direct identifiers usually does not need an infosec review, a DPA, or procurement, so you can evaluate on real data without asking anyone's permission first.

generate_export_spec is the machine-readable form of that policy and safe_export_policy returns the rules verbatim. The CSV instructions and the warehouse SQL both compile from one definition, so they cannot drift apart. Two details in the generated SQL are deliberate and commented inline:

  • The record id is hashed; the email domain is not. Hashing is deterministic, so you hash your own ids the same way and the returned scores still join back to your CRM. The domain stays legible because it is a company identifier rather than personal data, and because business-versus-personal email is one of the strongest features. The local part is stripped in the query and the full address never leaves.
  • Dates are truncated to the calendar day, never jittered.Truncation drops the time of day, which is the part that behaves like a fingerprint, and costs the model nothing. Jitter on a conversion date would corrupt the label.

Limits and metering

  • score_records takes up to 1000 records per request and meters against your monthly plan allowance, exactly like any other call to the scoring API. Test keys meter against the separate test allowance instead.
  • upload_csv accepts .csv only, up to 100MB.
  • train_model is asynchronous. It returns a run id; pollget_model_results rather than waiting on the call.
  • Sessions are stateless and responses are JSON, so the server scales horizontally without session affinity.
  • The four local tools have no limits and no metering. They never leave your machine.

The same predictions are available over plain HTTP if you would rather not run an agent: see the API reference. For how the model is trained and what the score means, seehow it works and thelearn center.

Need help?Contact supportLatest changes?See the changelog
Something wrong?Check system statusComing soon