Aito
PYPI · AITO-MCP
Predictions over your own data with $p and $why, no model training; says when Aito does not fit.
Available components
Last scanned (4 hours ago)
Scores higher than 71% of PyPI servers
Category AI and Machine Learning
How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →
Supply Chain Security100
- No malware found by supply-chain analysis.Pass
- No known CVEs affecting this package version or its production dependencies.Pass
- Runs setuptools.build_meta at install time, a recognised build step with no custom scripting around it. View diagnostics → Pass
- 1 of 22 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency97
- Source repository is publicly reachable at the declared URL. View diagnostics → Pass
- Cryptographically verified build provenance (signed, bound to AitoDotAI/aito-python-tools). View diagnostics → Pass
- Clear OSI-approved license (MIT).Pass
- Actively maintained (last published 11 days ago).Pass
- Disclosure check failed: no security disclosure policy was found in the source repository. See how to fix → Fail
Schema Quality & AI Usability55
- AI-judged instruction clarity (good).Pass
- Context-footprint check failed: tool/resource definitions use about 3351 tokens (~335/item across 10 items; 10 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management0
- Stability not yet verified: not enough scan history yet (needs a 30-day window).Unverified
Tool Coverage67
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 0% of tool parameters carry a description.Fail
Tool Safety100
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- We read all 10 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
- An AI judge read all 11 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a current MCP spec version (2026-07-28).Pass
Unverified: 1 category
A category scored 0 because we could not verify it: a data source with nothing on this package, evidence we could not reach, or a check we could not run. We only credit what we can confirm.
Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 31 Oct 26 0
- Security disclosure: unverified → fail ▼ functional
- 30 Oct 26 0
- Security disclosure: fail → unverified ▼ functional
- 28 Oct 26 0
- Package version: 1.2.0 → 1.2.1 functional
- 25 Oct 26 +15
- Malware scan: unverified → pass ▲ security
- 24 Oct 26 +21
- Malware scan: pass → unverified ▼ security
- Injection markers: unverified → pass ▲ security
- Provenance: fail → pass ▲ security
- First check of Judged manipulation: pass security
- Stability: Stability not yet verified: not enough scan history yet (needs a 30-day window). security
- The attested source repository moved: AitoDotAI/aito-python-tools security
- Tool coverage: unverified → 100 ▲ functional
- MCP protocol: unverified → pass ▲ functional
- First check of Tool coverage: 0 functional
- First check of Schema quality: fail functional
- First check of Destructive annotations: pass functional
- First check of Schema quality: fail functional
- First check of Schema quality: good functional
- Package version: 1.2.0 → 1.2.1 functional
- 14 Oct 26 0
- Stability: Stability not yet verified: this server's registry entry declares environment variables (an API key or similar), and its server did not start in our sandbox, so we have no schema to compare. security
- Tool safety: Tool safety not yet verified: this server's registry entry declares environment variables (an API key or similar), and its server did not start in our sandbox, so we have no tool text to scan. security
- Schema quality: Schema quality not yet verified: this server's registry entry declares environment variables (an API key or similar), and its server did not start in our sandbox, so we have no schema to assess. functional
- Capabilities: Protocol version not yet verified: this server's registry entry declares environment variables (an API key or similar), and its server did not start in our sandbox, so we never saw its MCP handshake. functional
- Tool coverage: Tool coverage not yet verified: this server's registry entry declares environment variables (an API key or similar), and its server did not start in our sandbox, so we have no tool definitions to assess. functional
- 12 Oct 26 39
First indexed and scored.
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 5 Nov 2026 · Analysed pypi/aito-mcp@1.2.1
Provenance Verified
A signed build attestation was found and verified, binding this exact artifact to the source repository it claims to come from.
| Result | Verified |
|---|---|
| Ecosystem | pypi |
| Reason | Verified |
| Discovered via | Registry attestation endpoint |
| Source repo | AitoDotAI/aito-python-tools |
| Certificate issuer | https://token.actions.githubusercontent.com |
| Certificate SAN | https://github.com/AitoDotAI/aito-python-tools/.github/workflows/release.yml@refs/tags/1.2.1 |
| Rekor log index | 3440917892 |
| Predicate type | PyPI publish attestation https://docs.pypi.org/attestations/publish/v1 |
| Subject digest | sha256:878fde1c53fc73d9d012cfb12d06bffb130aa90fcf2ba9541e573aab080f869c |
Background: How many MCP packages publish verified provenance →
Install scripts 1 script
| Hook | Tier | Command |
|---|---|---|
| build_backend | allowlisted | setuptools.build_meta |
Background: Why install scripts are a supply-chain risk →
Dependencies 22 packages
| Packages resolved | 22 |
|---|---|
| Stale | 1 |
| Tree resolution | Complete |
Background: SBOMs and build attestations, explained →
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
evaluate ~386
Measure how good a prediction is on the user's own data before anyone acts on it: Aito holds out the test rows, predicts them from the rest, and reports accuracy and how the predicted $p compare with what happened. Use when: before wiring a prediction into an app or an automation, and to choose the confidence threshold for act / suggest / ask a person. Run it once per use case, and again when the data changes a lot. Don't use when: you only need one prediction now (use predict). The answer leads with a summary: accuracy against always guessing the most common value (the honest comparison: report both), the calibration error (ECE, 0 is perfect), the number of held-out rows and the time per prediction. The engine's full metrics follow; `raw: true` returns only those. On personal data, prefer answers that aggregate (predict, relate, evaluate without cases) over tools that return rows (search, query, evaluate cases): every row you fetch enters the conversation. `query` is a v2 _evaluate body: {"test": <which rows to hold out>, "evaluate": <a _predict body>}, e.g. {"test": {"$index": {"$mod": [4, 0]}}, "evaluate": {"from": "invoices", "where": {"vendor": {"$get": "vendor"}, "description": {"$get": "description"}}, "predict": "gl_account"}}. Add "select": ["accuracy", "cases"] to get each held-out row's top $value and $p and whether it was right: sort the cases by $p and pick the lowest threshold whose accuracy above it meets the user's target. Hold out only rows whose outcome is known. It can take minutes on a large table.
| Name | Type | Req | Description |
|---|---|---|---|
| query | object | yes | – |
| raw | boolean | – | – |
No output schema declared.
No examples provided.
get_schema ~47
Read the schema: every table with its columns, types and links, or one table's. Start here to see what the data holds and which fields can be predicted.
| Name | Type | Req | Description |
|---|---|---|---|
| table | – | – | – |
No output schema declared.
No examples provided.
match ~227
Find the rows of a linked table that best match a row, learned from how such rows were linked before, e.g. which product an invoice line refers to. Returns ranked candidates with $p and $why. Use when: the matching repeats against the user's own labelled history (the history is the signal). Don't use when: matching records with no shared history to a catalogue (current state): a search engine (BM25) currently ranks better. Data separation between your customers: use a separate instance or collection per customer. Do not rely on a customer id in a query condition, and for now do not rely on a population-restricting query (a nested `from`) either, to keep customers' data apart. `query` is a v2 _match body, e.g. {"from": "invoice_lines", "where": {"text": "toner cartridge black"}, "match": "product", "limit": 5}. If `select` is omitted, $value and $p are returned, and $why on the top hit.
| Name | Type | Req | Description |
|---|---|---|---|
| query | object | yes | – |
No output schema declared.
No examples provided.
predict ~346
Predict the most likely value of one field for a row, learned from the table's own history. Returns each candidate value with $p (its probability) and $why (the base rate and the lift of each piece of evidence). Use when: the decision repeats and the user's own records know the answer, e.g. which GL account an invoice goes to, which category a ticket belongs to, who approves it. For "which X fits this record", prefer this tool over recommend. Don't use when: the task is open-ended language understanding or generation (use a language model); the case is genuinely new with no history (_predict will give a low probability, which is honest but not useful); one large, flat, stable dataset with one decision to optimise for years (consider a trained model). $p is a probability you can set a threshold on; check it on your own data with the evaluate tool before you act on it: act above the threshold, suggest in the middle, ask a person below. Data separation between your customers: use a separate instance or collection per customer. Do not rely on a customer id in a query condition, and for now do not rely on a population-restricting query (a nested `from`) either, to keep customers' data apart. `query` is a v2 _predict body, e.g. {"from": "invoices", "where": {"vendor": "Acme Oy", "description": "printer toner"}, "predict": "gl_account", "limit": 3}. If `select` is omitted, $value and $p are returned, and $why on the top hit.
| Name | Type | Req | Description |
|---|---|---|---|
| query | object | yes | – |
No output schema declared.
No examples provided.
put_schema ~256
Create a table (a v2 collection) from a schema. A WRITE: refused unless the user started the server with AITO_MCP_ALLOW_WRITES=1. Derive the schema from the user's existing table: one column per field, with type String for ids and categories, Text for free text (with an analyzer, e.g. "english"), Int / Decimal for numbers, Boolean for flags, and "link": "<table>.<column>" where a field refers to another table's row. Data separation between your customers: use a separate instance or collection per customer. Do not rely on a customer id in a query condition, and for now do not rely on a population-restricting query (a nested `from`) either, to keep customers' data apart. `schema` is a v2 schema body, e.g. {"type": "collection", "columns": {"invoice_id": {"type": "String"}, "vendor": {"type": "String"}, "description": {"type": "Text", "analyzer": "english"}, "amount": {"type": "Decimal"}, "gl_account": {"type": "String"}}}.
| Name | Type | Req | Description |
|---|---|---|---|
| schema | object | yes | – |
| table | string | yes | – |
No output schema declared.
No examples provided.
query ~266
Run any v2 query body on the general _query endpoint: search, predict, recommend, relate and match combined, including select expressions and nested queries. Use it when a specific tool does not take the shape you need; prefer the specific tools otherwise, since their descriptions say when they fit. Check the evidence on every answer: each result carries `$p` and `$why`. For "which X fits this record", prefer _predict. When you rank linked items with _recommend, check that the top candidates have supporting history before you act on them. On personal data, prefer answers that aggregate (predict, relate, evaluate without cases) over tools that return rows (search, query, evaluate cases): every row you fetch enters the conversation. Data separation between your customers: use a separate instance or collection per customer. Do not rely on a customer id in a query condition, and for now do not rely on a population-restricting query (a nested `from`) either, to keep customers' data apart. `query` is a v2 _query body, e.g. {"from": "deals", "where": {"stage": "lead"}, "select": ["deal_id", "value_eur"], "limit": 20}.
| Name | Type | Req | Description |
|---|---|---|---|
| query | object | yes | – |
No output schema declared.
No examples provided.
recommend ~294
Rank the values of a field by how likely they make a goal true, e.g. which product to offer so that the customer buys, learned from the history. Returns each option with $p and $why. Use when: the user wants options ranked toward an outcome (next product, best channel, the lever that moves a rate). Don't use when: the question is "which X fits this record" (use predict); the candidates have no history behind the goal. Caveat: when you rank a LINK target (rows of another table), candidates with no supporting history can rank high. Check each top candidate's $p and $why for supporting evidence before you act on it, and prefer predict for "which X for this row". Data separation between your customers: use a separate instance or collection per customer. Do not rely on a customer id in a query condition, and for now do not rely on a population-restricting query (a nested `from`) either, to keep customers' data apart. `query` is a v2 _recommend body, e.g. {"from": "impressions", "where": {"customer": "c42"}, "recommend": "product", "goal": {"purchased": true}, "limit": 5}. If `select` is omitted, $value and $p are returned, and $why on the top hit.
| Name | Type | Req | Description |
|---|---|---|---|
| query | object | yes | – |
No output schema declared.
No examples provided.
relate ~242
Find which conditions statistically go together with a given condition, with their lift and counts, e.g. what is typical of deals that were won. Descriptive statistics over the history, not a prediction for one row. Use when: the user asks why, or what drives an outcome, or which features matter. Don't use when: you need a value for one row (use predict) or a ranked choice (use recommend). Data separation between your customers: use a separate instance or collection per customer. Do not rely on a customer id in a query condition, and for now do not rely on a population-restricting query (a nested `from`) either, to keep customers' data apart. `query` is a v2 _relate body, e.g. {"from": "deals", "where": {"won": true}, "relate": "industry"}. Each hit comes back as the related value, its lift, and the counts behind it; small_sample marks a lift resting on fewer than 10 rows. `raw: true` returns the engine's response unchanged.
| Name | Type | Req | Description |
|---|---|---|---|
| query | object | yes | – |
| raw | boolean | – | – |
No output schema declared.
No examples provided.
search ~213
Find, filter and sort rows: an ordinary database lookup, no inference. Use it to look at the data before predicting, or to fetch rows to act on. Don't use when: raw full-text search at very large scale is the whole job (a dedicated search engine is faster). On personal data, prefer answers that aggregate (predict, relate, evaluate without cases) over tools that return rows (search, query, evaluate cases): every row you fetch enters the conversation. Data separation between your customers: use a separate instance or collection per customer. Do not rely on a customer id in a query condition, and for now do not rely on a population-restricting query (a nested `from`) either, to keep customers' data apart. `query` is a v2 _search body, e.g. {"from": "invoices", "where": {"vendor": "Acme Oy"}, "orderBy": {"$desc": "date"}, "limit": 10}.
| Name | Type | Req | Description |
|---|---|---|---|
| query | object | yes | – |
No output schema declared.
No examples provided.
upload_rows ~199
Add rows to a table. A WRITE: refused unless the user started the server with AITO_MCP_ALLOW_WRITES=1. The rows count in the very next query; there is no training step. A local `aito start` instance runs free mode: 10,000 rows per table and 50,000 in total. Past that the engine answers row_limit_exceeded with a link to a licence; for more data, use a licensed or hosted instance (https://aito.ai). Data separation between your customers: use a separate instance or collection per customer. Do not rely on a customer id in a query condition, and for now do not rely on a population-restricting query (a nested `from`) either, to keep customers' data apart. `rows` is a list of objects matching the table's schema, at most a few thousand per call.
| Name | Type | Req | Description |
|---|---|---|---|
| rows | array | yes | – |
| table | string | yes | – |
No output schema declared.
No examples provided.
How do I install the Aito MCP server?
Aito runs locally as a PyPI package, launched with uvx aito-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
pypi · aito-mcp
claude mcp add aitodotai-aito -- uvx aito-mcp
What is the Aito MCP server?
Aito is an MCP server listed in the public MCP registry as io.github.AitoDotAI/aito. Predictions over your own data with $p and $why, no model training; says when Aito does not fit. This page covers its PyPI package (aito-mcp).
Is the Aito MCP server safe to use?
Aito scores 75 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 5 November 2026. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the Aito MCP server expose?
Aito exposes 10 tools: predict, recommend, relate, match, search, and 5 more. Their descriptions and schemas cost roughly 2,476 tokens of context every time the server is loaded.
Is the Aito MCP server still maintained?
Aito is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.
What licence is the Aito MCP server under?
Aito declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.