Ptally
ai.ptally/ptallyVersion 1.0.0Insurance pricing: build, validate and test rating models, then price quotes from your AI client.
Status
Responds93 msAnswered our handshake without sign-in.- Last checked
- Nov 14, 2026, 13:32 UTC
- Latency
- 93 ms
- Remotes responding
- 1 of 1
- Sign-in
- No sign-in
- Hosting
- EU hosting detected (detected, not a legal statement)
- Registry data as of
- Nov 14, 2026, 22:14 UTC
Data from the official MCP Registry, checked by run.zero. How we check
Connect
Streamable HTTP
https://app.ptally.ai/mcpResponds93 msNo sign-in
Claude Code
claude mcp add --transport http ptally https://app.ptally.ai/mcpClaude Desktop and claude.ai
Settings > Connectors > Add custom connector
Name: ptally
Remote MCP server URL: https://app.ptally.ai/mcpCursor
{
"mcpServers": {
"ptally": {
"url": "https://app.ptally.ai/mcp"
}
}
}VS Code
code --add-mcp '{"name":"ptally","type":"http","url":"https://app.ptally.ai/mcp"}'Built your own server? run.zero hosts MCP servers on European infrastructure.
Tools
16 tools
Read-only | Idempotent | Open world | ||
|---|---|---|---|---|
amend_quoteAmend a SAVED quote (a quote_reference from get_quotes): its price (`result`), and optionally `valid` or `sold`, with a required `reason`. Logged in the quote's audit trail under the signed-in user, with the time, the old and new values, source "mcp" and the reason. The engine's own result, valid and output are never changed — the amended values sit beside them, and setting price or validity back to the engine's value clears that amendment (still logged).
BEFORE CALLING
1. Call get_quote (or get_quotes) for the quote's current price, validity and sold flag.
2. Tell the user exactly what will change (old → new) and the reason that will be logged, and get their go-ahead.
RULES
- At least one of result, valid, sold, and each must differ from what the quote is now (else an error says nothing changed).
- result is a number; valid and sold are booleans; reason is a non-empty sentence.
- A sold quote is locked. The only change it accepts is `sold: false` on its own (marking it unsold, with a reason); after that it can be amended and marked sold again — three calls, each logged. Check get_quote first, and tell the user when a change means unselling the quote. A price change can go in the same call that marks it sold.
- Refused in read-only mode.
RESULT
{ quote_reference, engine: { result, valid }, now: { result, valid, sold }, amended, logged: { amendment_reference, by, at, source, result: { from, to }, valid, sold, reason }, quote_url, next_steps }. | No | No | No | No |
get_docRead consecutive passages of an indexed document: the passage numbered `chunk` (a search_docs result's chunk) plus `before` and `after` passages either side (default 1 each, max 10). Use it when a search hit is cut off mid-clause, refers to another clause, or uses a defined term you need to read. Returns `{ document: { document_reference, title, filename, pages, chunk_count, status, … }, from, to, chunks: [{ chunk, page, section, text }] }`. chunk 0 with a larger `after` reads a document from the start. A document that isn't indexed yet is a tool error. Nothing is changed. | Not declared | Yes | Yes | No |
get_docsFetch Ptally documentation by topic. Call BEFORE building or editing a config to load the rules and reference material you need. Topics: "rules" = agent rules, constraints, expression syntax, quality gates, and debugging guidance (start here); "readme" = full engine reference with step types, query language, input/output blocks, and code examples. | Not declared | Yes | Yes | No |
get_healthDiagnostic snapshot of the deployed MCP server plus a live probe of its store (sqlite or Postgres). Returns server name and version, protocol version, root, boot time, advertised tool names and count, a hash of the tool surface, and `store` — `{ ok, latency_ms, counts: { projects, quotes } }` from counting rows in the projects table (one row per version) and the quotes table, or `{ ok: false, latency_ms, error }`. | Not declared | Yes | Yes | No |
get_projectFetch a project by `project_reference` from the self-host store. Optional `version_reference` pins to a specific version of that project (a version from another project is a tool error); otherwise the latest live (published or approved) version is used, or the latest non-archived version of any status if none is live. Returns `{ project_reference, version_reference, version, name, description, status, summary, created_at, updated_at, project_url, version_url, latest_draft, clipped_collections, documents, next_steps, model }`. `documents` lists the indexed project documents that apply to this version (`[{ document_reference, title, pages }]`) — search them with search_docs. The model is a summary for reading, never a file to hand back. Every `collection` step is stamped with `__context` (`total_rows`, `shown_rows`, `columns`, `shape`, `truncated`, `patchable`; an empty table gets `total_rows: 0`, `columns: []`, `patchable: true`): tables of up to 100 rows are shown whole and can be changed with patch_version; bigger ones are clipped, listed in `clipped_collections`, and can only change by the user downloading the model from `version_url`, you amending it, and the user uploading it. `latest_draft` is the newest draft version (null if none) — patches go there, so call get_project again with its version_reference before patching. Follow `next_steps` and tell the user which route applies before making changes. All other model content — input.format, steps, expressions, output — is returned verbatim so an LLM caller can understand what the project does and how to build a valid input payload. Precursor to run_quote and patch_version. | Not declared | Yes | Yes | No |
get_projectsList every project stored on this self-host instance. Returns `{ count, projects: [{ project_reference, name, description }] }`. Descriptions are truncated to 100 characters so the response stays compact — call get_project for the full record. Archived projects are excluded. | Not declared | Yes | Yes | No |
get_quoteReview one quote in a standard shape, from a stored `quote_reference` (get_quotes) or a pasted `quote` — the dashboard's Copy JSON, a POST /quotes or run_quote response, or a bare engine output with `debug` (`quote_gz`: base64 gzip of the same JSON, for big pastes). Pass exactly one. Returns `{ source, quote_reference, project_reference, project_name, version_reference, version, created_at, outcome: { decision (quoted | declined | referred | error), result, valid, status, error, exec_time_ms, engine_time_ms, steps, slowest_steps }, input, output, rules: { exclusions, refers, excesses, endorsements: { fired_count, checked_count, fired: [{ step, name, exp, values, result }] } }, result_build: { formula, values, result }, valid_rule: { exp, values, result }, build: [{ order, id, name, type, description, ms, logic: [{ name, exp | formula, values, result }], lookups, table_rows, output, errors }], errors, has_trace, truncated, amendment, quote_url, version_url, replay, how_to_explain, next_steps }`. `outcome` is always what the engine priced. `amendment` (stored quotes only; null when never touched) is `{ result, valid, sold, amended_at, log: [{ when, who, via (dashboard | api | mcp), result: { from, to }, valid, sold, note }] }`: the price, validity or sold flag someone set afterwards (dashboard, API or amend_quote), and the log of who changed what. Step names, types, descriptions and collection lookups come from the version's model when it is on this instance. A quote without a step trace is re-priced against its version (`replay: true` forces it); `replay` reports the replayed vs stored result and whether they match. Nothing is saved. Responses are kept under ~80 KB: large quotes come back clipped or as an overview (`truncated` says which) — pass `steps: [<id>, …]` for those steps in full. If even the overview is too big the result is `{ too_large: true, outcome, rules counts, next_steps }`: review a few steps at a time, or ask the user to paste the part they want exp | Not declared | Yes | Yes | No |
get_quotesList quotes stored on this self-host instance, newest first (`direction: "asc"` for oldest first). Filter by `project_reference` (from get_projects), `version_reference`, `since` (ISO date) or `search` (text match on indicators). Paged with `limit` (default 25, max 100) and `offset`; `has_more` says whether another page exists. Returns `{ count, limit, offset, has_more, quotes: [{ quote_reference, project_reference, project_name, version_reference, version, created_at, status, valid, result, indicator, client_ref, exec_time_ms, error, amended_result, amended_valid, sold, quote_url }], next_steps }` — `result` and `valid` are what the engine priced; `amended_result` / `amended_valid` (null when not amended) are what someone changed them to in the dashboard, and `sold` (null when never set) whether it sold. No input or output payloads; call get_quote for one quote's full review. Dry runs (run_quote without save, run_version_tests) are never stored, so they never appear here; run_quote with save: true does. | Not declared | Yes | Yes | No |
get_schemaFetch the full JSON schema for Ptally project config files. Use to check exact field requirements, allowed step types, and property constraints. | Not declared | Yes | Yes | No |
get_starterFetch a worked-example Ptally project for a common line of business. Each example is a small, fully valid project with realistic collection tables, calculations, exclusions and refers, plus an embedded tests[] suite for reference. Use as a template — copy and adapt rather than authoring from scratch. Pass no arguments (or `list: true`) to get the catalog. | Not declared | Yes | Yes | No |
list_docsList the documents uploaded to a project (policy wordings, product guides, underwriting guidelines or anything else), newest first, with their indexing status. Takes `project_reference` and optional `version_reference` (only documents that apply to that version: those for every version plus any pinned to it; without it, every document on the project). Returns `{ project_reference, version_reference, count, indexed, pending, failed, documents: [{ document_reference, title, filename, status, error, pages, chunk_count, bytes, version_reference, created_at }], next_steps }`. `status` is `indexed` (searchable with search_docs), `pending` or `indexing` (not searchable yet), or `failed` (with the reason in `error`, e.g. a scanned PDF with no text). `chunk_count` is how many searchable passages the document has. Documents are uploaded and deleted in the dashboard, not over MCP. Nothing is changed. | Not declared | Yes | Yes | No |
patch_versionChange a DRAFT version's stored model with an RFC 6902 JSON Patch, merged on the server. Use it for targeted edits; any change to a clipped collection (__context.patchable: false) goes through download and upload instead (see next_steps in get_project).
BEFORE CALLING
1. The version must be a draft: use get_project's latest_draft. If it is null, ask the user to click New Version on the project page (it copies the live model), then call get_project again.
2. Call get_project with the draft's version_reference and build every path from that response. Pass its updated_at as base_updated_at.
3. Tell the user what you will change (old → new) and get their go-ahead.
PATHS (JSON Pointer)
- Name steps, tests and other id'd array elements by id (else key) instead of index: /steps/<step id>/... and /tests/<test id>/... Ids survive other steps being inserted or removed in the same patch.
- Model layout: /meta/..., /input/format/<input key>/... (format is an object keyed by input key), /steps/<id>/..., /output/format/<key>/..., /tests/<id>/...
- Collection rows by index. Compressed collection ([[col1, col2, ...], [v1, v2, ...], ...]): index 0 is the header row, so the first data row is /collection/1, and a cell is /collection/<row>/<column index>. Uncompressed collection (array of row objects): the first row is /collection/0, and a cell is /collection/<row>/<column name>. Check __context.shape and __context.columns.
- Append with "-" (/steps/-, /steps/<id>/collection/-). Insert at a numeric index; step order is execution order, so a new step goes after the steps whose outputs it reads.
- Escape "~" as ~0 and "/" as ~1 inside a segment.
EXAMPLES
- Change a rate cell: {"op":"replace","path":"/steps/region_rates/collection/1/1","value":4.5}
- Guard then change: [{"op":"test","path":"/steps/base_premium/formula","value":"<current formula>"},{"op":"replace","path":"/steps/base_premium/formula","value":"<new formula>"}]
- Add a table row: {"op":"add","path":"/steps/type_factors/co | No | No | No | No |
run_quotePrice a quote against a stored project: a dry run by default, saved only with `save: true`. Takes `project_reference`, an optional `version_reference` (defaults to the latest live version; there is no fallback to drafts, so pass `version_reference` to price one — it must belong to the project and not be archived, else a tool error), and an `input` payload that matches the project's input schema. Runs the pricing engine and returns the quote envelope — `output`, `result`, `valid`, `status`, `error`, the engine's `errors` log, `exec_time_ms`, `dry_run: true`, a null `quote_reference`, and `documents` (the indexed project documents for the version that priced it, `[{ document_reference, title, pages }]`, to answer questions about cover with search_docs) — WITHOUT persisting a quotes row. With `save: true` the quote is stored like a POST /quotes, under the signed-in user (an engine error is stored as an error quote), and the envelope carries `dry_run: false`, its `quote_reference`, `created_at` and `quote_url`; it then shows in get_quotes and the dashboard and can be amended with amend_quote. Only save when the user asks for the quote to be kept, not to try inputs. Saving is refused in read-only mode. Call get_project first to inspect `input.format` and build a valid input. | No | No | No | No |
run_version_testsPrice every test in a version's tests[] against that version's stored model and compare each with its expected output. Takes `version_reference` (any status but archived — a draft after patch_version, or a live version for a baseline). Runs against the stored model, so a patch saved a moment ago is included. A test passes when its result is within 0.005 of the expected result and its valid flag equals the expected valid. Expectations are read from output { result, valid }, or, when output has neither (tests imported from the hosted service), from result { result, valid }; `expected_from` says which. A test with neither is priced but unchecked (passed: null). Returns `{ project_reference, version_reference, version, status, updated_at, total, passed, failed, unchecked, results: [{ id, name, passed, expected: { result, valid }, expected_from, actual: { result, valid }, problems, errors }], version_url, next_steps }` — `problems` says why a test failed, `errors` is up to 5 of the engine's step errors for that run. Nothing is persisted. Use after patch_version, after adding or changing tests, or before a change to record the baseline. To change a test's expected output, patch_version on /tests/<test id>/output/result (drafts only) — output takes precedence over result. | Not declared | Yes | Yes | No |
search_docsSearch the documents uploaded to a project (policy wordings, product guides, underwriting guidelines or anything else) for the passages that answer a question about the product: what is covered or excluded, excesses, conditions, definitions, claims notice, eligibility. Takes `project_reference`, `query` (the question in plain words, or an exact term like "Section 4" or a defined term), optional `version_reference` (default: the latest live version, else the latest of any status; pass the version that priced a quote so the wording matches it), optional `k` (passages to return, default 5, max 20) and optional `document_references` to search only some documents. Every passage is scored by meaning (a local embedding model) and by keywords, blended 70/30. Returns `{ project_reference, version_reference, query, documents: { indexed, pending, failed }, results: [{ document_reference, title, filename, version_reference, chunk, page, section, text, score, similarity, keyword }], next_steps }`. `score` is relative to this search (the best passage scores near 1); `similarity` is the cosine similarity to the question (below about 0.5 is rarely relevant). Answer only from the returned text, citing title, section and page; read around a passage with get_doc. Nothing is changed. | Not declared | Yes | Yes | No |
validate_projectServer-side schema validation of a project config. Returns { valid: true/false, errors: [...] } with the JSON path, keyword, and message for each issue. Prefer local validation against get_schema during authoring; use this as a ground-truth check, including on an amended model before handing it back to the user as a file. Pass exactly one of inline `project` or a base64-gzipped `project_gz` (if the inline form is too large for your client); passing neither or both returns an error result. | Not declared | Yes | Yes | No |
Details
- Registry status
- Active
- Published
- Nov 4, 2026
- Updated
- Nov 4, 2026
- Repository
- Not given
- Categories (suggested)
- Project managementKnowledge and notesSuggested categories are assigned automatically from the registry text and may be wrong. Verified operators can correct them.
- GDPR
- Not declared