portco-mcp
portco-mcp is a governed private-equity data-onboarding server: an agent profiles a registered source, proposes canonical mappings, generates and sandbox-tests a dbt project, and only publishes a bundle certified by a separate human reviewer principal.
Profile a source read-only (
profile_schema) — row counts, null rates, distinct counts, patterns and PII classes; aggregates only, no sample rows.Run the onboarding pipeline (
start_onboarding_run) — connection validation → profiling → entity/join inference → canonical mapping, stopping at the first human review gate and returning pending items.Propose canonical mappings (
propose_canonical_mapping) — deterministic scoring; uncertain, PII-bearing, metric-bearing or conflicting columns are routed to review rather than guessed.Track and resume runs (
get_run_status,resume_run) — status, step history, gate and pending items; resume reuses completed steps and re-checks approvals.List what needs deciding (
list_pending_reviews) — items with gate, kind, summary, reason codes, alternatives and subject hash.Submit a review (
submit_mapping_review, reviewer principals only) — approve / reject / approve_with_override bound to the exactsubject_hash; stale packets rejected.Generate dbt + semantic layer (
generate_dbt_artifacts) — requires an existing, unrevokedapproval_idbound to the current mapping content.Sandbox-test and reconcile (
run_sandbox_tests) — dbt build in a disposable sandbox with exact metric reconciliation; pauses at the certification gate or the test-failures gate.Certify (
certify_run, reviewer principals only) — approve/reject individual metrics; rejected metrics and their dependents are not published.Publish certified artifacts (
publish_run) — fails closed without valid certification; returns version, path, published and excluded metrics.Check service health (
healthcheck) — status, version, database and schema version.
Generates a tested dbt project and semantic layer for onboarded portfolio company data, including staging, intermediate and mart models, MetricFlow semantic models and metrics, and runs dbt builds and tests in disposable sandboxes.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@portco-mcponboard Acme's data, infer entities, and send mappings for review"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Portfolio Company Data Onboarding Agent
One company records invoice lines in cents and invoice headers in dollars. Another calls a CRM
opportunity column rev, although it represents potential bookings, not recognized revenue.
A plausible column match can quietly turn either into the wrong financial report.
This system profiles sources, proposes evidence-linked mappings to a private-equity reporting model, generates dbt and semantic definitions, and reconciles the results before a separate reviewer can certify publication.
Scope: an AI-assisted portfolio prototype with synthetic financial workflows, typed CSV and read-only PostgreSQL snapshots, and local publication; no production customers or measured savings.
Project page and replay · Case study · Architecture · Evaluation and limitations · Release status
Run the demo
Requires Python 3.12 and uv. The demo needs no Docker or API keys.
uv sync --all-extras --frozen
uv run poe demoThe synthetic SaaS fixture catches both traps, denies agent self-approval, and publishes nine reconciled metrics after scripted reviewer decisions. The other paths demonstrate malformed source data, a retried timeout and an instruction planted in a table comment.
== 1. Success path: fixture A (synthetic B2B SaaS company)
agent profiled, inferred entities/joins and proposed mappings -> paused at 'mapping_review' with 28 review items
trap caught -> billing.invoice_lines.amount -> invoice_line.amount (suggest cents_to_major) [UNIT_MISMATCH]
trap caught -> crm.opportunities.rev -> opportunity.amount [LOW_CONFIDENCE, SEMANTIC_TRAP]
agent tried to approve its own proposals -> Forbidden
generated dbt + semantic layer; sandbox build exit 0; 27/27 reconciliation checks passed (money exact to the cent)See the recorded replay and
full transcript. Reviewers in this demo are automated test identities. Diagnostic logs are saved beside the reports
in var/demo/diagnostics.log; use uv run portco demo --verbose to show them.
Related MCP server: RecoSearch
How it works
flowchart LR
S[Read-only source] --> P[Aggregate profile]
P --> M[Evidence-linked mapping]
M --> R{Mapping review}
R --> D[Generated dbt + metrics]
D --> T[Sandbox + reconciliation]
T --> C{Separate certification}
C --> V[Versioned publication]
O[Canonical ontology] -.-> M
F[Independent reference calculations] -.-> TThe workflow is available through a CLI and typed MCP capabilities. An agent can discover and propose; deterministic code calculates; reviewer principals decide. Database state records every step, finding, approval and audit event so a conversation is never the source of truth.
Control | What it enforces |
Explicit source contracts | Profiling exposes aggregates and approved category domains. Units, financial classifications and relationships require evidence. |
Review gates | Ambiguous, metric-bearing, PII and unit-mismatched proposals require review. Unsupported metrics remain |
Bound approvals | A reviewer approves a specific content hash. Changes, revocation and expiry invalidate authority; the run starter cannot approve its own run. |
Independent reconciliation | Generated metrics execute in a disposable sandbox and are compared with Python reference calculations, with monetary values exact to the cent. |
Recoverable publication | Execution leases fence stale workers; publication verifies the certified files and recovers across filesystem/database failure windows. |
Architecture and design decisions explain the implementation and its trust boundaries.
What the October audit changed
A ten-agent audit found 23 numbered findings, including a case where account_type='Revenue'
turned a 100.00 credit into 0.00 recognized revenue while every check passed. The SQL and Python
calculators agreed because both assumed lowercase canonical categories. Independent arithmetic
had not provided an independent check of accounting meaning.
The remediation makes financial categories executable contracts: unknown or null classifications block affected metrics, and case normalization requires a reviewed transform. It also repairs rejected relationships resurfacing in generated SQL, cached steps bypassing revoked approvals, and stale-worker publication. The remediation record maps the findings to fixes and regression coverage, including tests that reproduce the financial failure through actual dbt execution. The original audit and probes remain available.
Passing a fixture suite was not enough to catch those boundary failures. The release status identifies which revision and checks verify the repairs.
My role
I wanted to explore how AI-assisted data onboarding can remain auditable when financial definitions, source schemas and units disagree. I chose the portfolio direction, reviewed recommendations and decided which capabilities to pursue. I used AI coding tools extensively for implementation, tests, audits and documentation. I present the resulting prototype with its evidence and failures visible, and distinguish automated review from independent human validation.
Develop and operate
uv run poe fixtures # synthetic source databases
uv run poe test # general suite; PostgreSQL tests run separately
uv run poe eval # pinned golden evaluation cases
uv run poe cov-metrics # reference-calculator branch coverage
uv run poe lint
uv run poe typecheckIf uv is installed as a Python module but unavailable on PATH, use python -m uv.
For a manual run, export the review packet, record decisions as a separate reviewer, then resume:
uv run portco run --fixture portco_a
uv run portco review <run_id> --export review.yaml
uv run portco review <run_id> --import review.yaml --reviewer alice --default approve
uv run portco resume <run_id>The blanket approval flag above is for the supported synthetic walkthrough. Inspect and edit individual decisions for other inputs. Certification is a separate gate before publication; the agent walkthrough and operations guide cover the complete workflow, MCP setup, identity, recovery and deployment configuration. Source contracts: CSV · PostgreSQL.
Evaluation and limits
Supported-fixture results demonstrate the workflow and its checks. Unfamiliar-schema experiments also preserve failed safety gates, wrong proposals and substantial review effort. The original probe matched 0/10 targets; later remediation on a frozen corpus is feedback-informed, not fresh held-out validation. Evaluation and limitations brings the results, denominators and evidence boundaries together.
The financial demonstration uses synthetic data. A real historical retail exercise proves bounded ingestion/profiling only. There is no accepted live backend, warehouse publication, independent human usability study or measured business impact. The optional LLM judge defaults off; the local semantic executor supports a bounded subset rather than full MetricFlow compatibility. The project runs locally with a free GitHub Pages presentation; paid hosting remains optional.
Release status is the source for version-specific verification. Documentation gives the reading path and operator references; the archive retains historical planning and acceptance records.
Available Tools
12 toolscertify_runA
Certify the generated bundle and its metrics. Reviewer principals only.
`subject_hash` is the `subject_hash` of the pending certification items: it binds the approval to the
exact packet under review (bundle, tests, waivers, open findings). `metric_decisions` maps
metric -> approve|reject; unknown metric names are rejected, unlisted metrics are approved. Rejected
metrics (and metrics derived from them) are not published.
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes | ||
| comment | No | ||
| subject_hash | Yes | ||
| bundle_decision | No | approve | |
| metric_decisions | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| gate | Yes | |
| run_id | Yes | |
| reviewer | Yes | |
| decisions | Yes | |
| approval_id | Yes | |
| next_action | Yes | |
| subject_hash | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses the default-approve semantics for unlisted metrics, the rejection of unknown metric names, and the consequence that rejected metrics and their derivatives are not published. It also flags the authorization requirement. These are exactly the behavioral facts an agent needs before invoking a non-idempotent mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads action and authorization in the first two sentences, then details the two parameters that carry the real semantics. Dense but every clause adds information; no filler or restatement of the name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with an output schema (so return values need no explanation), the description covers the critical decision semantics and side effects. The remaining gap is the unexplained run_id, comment, and bundle_decision parameters, which leaves the argument surface partly opaque.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does well for two of five parameters: subject_hash (binds approval to the exact packet under review) and metric_decisions (map of metric -> approve|reject, with rejection cascade). run_id, comment, and bundle_decision (default 'approve') are never explained, so coverage remains partial.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('certify the generated bundle and its metrics') and adds an authorization scope ('Reviewer principals only'). An agent can distinguish it from most siblings, though it never explicitly contrasts with publish_run, which is the nearest neighbor semantically.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'reviewer principals only' clause is a real eligibility constraint, and the metric_decisions paragraph implies usage context (acting on pending certification items). However, there is no explicit when-to-use/when-not guidance and no routing to publish_run or list_pending_reviews, leaving the workflow position to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_dbt_artifactsA
Generate the dbt project and semantic layer from the reviewed mapping.
Requires `approval_id` from submit_mapping_review; the server verifies it exists, is not revoked
or expired, belongs to this run, and is bound to the current mapping content (no boolean flags).
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes | ||
| approval_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| files | Yes | |
| models | Yes | |
| run_id | Yes | |
| status | Yes | |
| resource_uri | Yes | |
| manifest_hash | Yes | |
| not_generated | Yes | |
| generated_metrics | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare the generic write profile (readOnlyHint=false, idempotentHint=false); the description goes further by disclosing the server-side gate: the approval must exist, be unrevoked, unexpired, scoped to this run, and content-bound. It does not say what files/artifacts get written, where, or whether existing output is overwritten, which is the main remaining behavioral gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded: the action and its output are stated first, then the precondition. The second sentence is dense but every clause is load-bearing; the parenthetical '(no boolean flags)' is slightly cryptic but adds an anti-pattern warning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
A write tool with a real prerequisite is documented adequately, and an output schema exists so return values need not be explained. The only missing pieces are artifact destination/overwrite behavior, which are minor given annotations and output schema coverage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the two params have only titles, so the description must carry the load. It substantially defines approval_id (provenance and the four validation checks it must pass) but says nothing about run_id beyond the implicit; the coverage of one of two parameters is rich, so this lands above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Generate) and two concrete artifacts (dbt project and semantic layer) plus the input they derive from (the reviewed mapping). An agent can distinguish this from propose_canonical_mapping, submit_mapping_review, or publish_run without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear precondition and names the upstream sibling that produces it: approval_id comes from submit_mapping_review. It does not state when NOT to use the tool (e.g., versus publish_run or run_sandbox_tests as a next step), so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_run_statusCRead-onlyIdempotent
Current status, step history, gate and pending review items of a run.
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| gate | Yes | |
| error | No | |
| steps | Yes | |
| run_id | Yes | |
| status | Yes | |
| resources | Yes | |
| company_id | Yes | |
| next_action | Yes | |
| current_step | Yes | |
| connection_id | Yes | |
| pending_items | Yes | |
| pending_review_count | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is fully covered. The description adds no behavioral context beyond that — nothing about how fresh the status is, whether it should be polled, or any access constraints — and the returned fields it names are already captured by the output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short fragment with zero filler, and the most important element (current status) is front-loaded. It is efficient, though it reads as a noun phrase rather than a complete statement.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema describing the return shape and annotations covering safety, the description does not need to explain returns or side effects. However, it omits any usage routing and any explanation of the one required identifier, leaving gaps an agent must guess at.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is one required parameter, run_id, with 0% schema description coverage, and the description does not explain what a run_id is, where it comes from, or how to obtain it. Referencing "a run" is the only implicit connection, which is a weak substitute for real parameter guidance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific resource (a run) and enumerates the exact contents returned: current status, step history, gate, and pending review items. It clearly reads as a retrieval tool, though it never explicitly differentiates itself from the overlapping sibling list_pending_reviews.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites, and no mention of alternatives such as list_pending_reviews for review items or resume_run/certify_run for run lifecycle actions. The agent must infer all routing from the name and the sibling list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
healthcheckARead-onlyIdempotent
Return service health for diagnostics.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| status | Yes | |
| version | Yes | |
| database | Yes | |
| schema_version | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, and openWorldHint=false, so the safety profile is fully covered. The description adds little behavioral detail beyond the return purpose and does not mention auth, rate limits, or return format. It does not contradict annotations, but it mostly restates the obvious.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence with no filler, and the core action is front-loaded. It is appropriately sized for a zero-parameter health check.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only diagnostic with no inputs and an output schema, the description is largely sufficient. Annotations cover behavior and the output schema can describe return values, though adding auth or usage prerequisites would make it complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the schema baseline is 4. There are no parameter semantics for the description to clarify, and schema coverage is already 100%.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Return service health.' It is clear what the tool does and is implicitly distinct from the workflow-oriented siblings. It does not explicitly name an alternative, but no sibling overlaps with its diagnostic purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'for diagnostics' gives an implied usage context, suggesting it should be called when checking service health. However, it does not state when-not to use it, prerequisites, or alternatives, so guidance is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_pending_reviewsCRead-onlyIdempotent
Review items a human must decide before the run can continue.
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint=false, so the safety profile is fully covered by structured data. The description does add domain context — these are approval/decision items that block run progression — which is genuinely useful beyond the annotations, but it discloses nothing about ordering, counts, or what happens after a decision.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler, which is structurally fine. However, brevity here comes at the cost of under-specification rather than economy — there is no wasted wording, but not enough wording either.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the annotations cover the safety profile. Even so, for a run-scoped read tool the description omits the run_id scoping and any usage cue, leaving it minimally adequate but with clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the only parameter is required (run_id), documented solely by its title. The description never mentions run_id or explains that the listing is scoped to one run, so it fails to compensate for the schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description conveys what the items are — human decisions that gate the run — but never states the action the tool performs (list/return pending review items). It is inferable from the name list_pending_reviews, yet the sentence alone could be read as describing a review workflow rather than a retrieval call. It also never ties the items to a specific run, so differentiation from siblings like get_run_status is only partial.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites, and no mention of alternatives such as get_run_status or submit_mapping_review. The phrase 'before the run can continue' hints at the blocking context but stops short of saying when an agent should call this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
profile_schemaA
Profile a source read-only: row counts, null rates, distinct counts, patterns, PII classes.
Aggregates only (`sample_rows=0` by construction); values never leave the source adapter.
Starts a run that pauses after profiling; continue it with propose_canonical_mapping.
| Name | Required | Description | Default |
|---|---|---|---|
| schemas | No | ||
| connection_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| run_id | Yes | |
| status | Yes | |
| tables | Yes | |
| findings | Yes | |
| profile_id | Yes | |
| resource_uri | Yes | |
| pii_column_count | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds real behavioral context beyond the annotations: aggregates only, sample_rows=0 by construction, and values never leaving the source adapter — important data-governance behavior. It also discloses the run-state side effect (pauses after profiling). The only friction is the word "read-only", which sits in mild tension with readOnlyHint=false; the description resolves this by explicitly stating it starts a run, but the phrasing could momentarily mislead.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight lines, front-loaded with the purpose, then privacy behavior, then workflow — order is sensible and there is no filler. Minor deduction because `sample_rows=0` references a parameter that does not exist in the input schema, which adds a small decoding cost for the agent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described. The description covers purpose, data-handling constraints, and the required next step for a run-based tool, which is most of what an agent needs. The remaining gap is the undocumented `schemas` parameter, which is the one thing a caller needs in order to control scope.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and neither of the two parameters (connection_id, schemas) is explained in the description. In particular the optional `schemas` scoping parameter — which lets the caller narrow profiling to specific schemas — is never mentioned, so an agent could miss that it can limit scope.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Profile a source") and enumerates the exact outputs computed — row counts, null rates, distinct counts, patterns, PII classes. It also positions itself in the pipeline by naming propose_canonical_mapping as the follow-up step, which distinguishes it from siblings like generate_dbt_artifacts or run_sandbox_tests.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clearly says the tool "starts a run that pauses after profiling" and that the agent must "continue it with propose_canonical_mapping", which is actionable sequencing guidance. However, it never states when NOT to use it or what prerequisites exist (e.g., whether an onboarding run must be started first), so it stops short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
propose_canonical_mappingA
Infer entities and joins and propose canonical mappings for a profiled run.
Deterministic scoring; anything uncertain, PII-bearing, metric-bearing or conflicting is routed to human review rather than guessed. Stops at the mapping-review gate.
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| joins | Yes | |
| run_id | Yes | |
| status | Yes | |
| proposals | Yes | |
| row_filters | Yes | |
| mapping_hash | Yes | |
| resource_uri | Yes | |
| review_items | Yes | |
| auto_accepted | Yes | |
| requires_review | Yes | |
| unmapped_required | Yes | |
| metrics_needing_evidence | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations establish this is a non-read-only, non-idempotent, non-destructive write, so the safety bar is partly met. The description adds real value beyond that: deterministic scoring, routing of uncertain/PII-bearing/metric-bearing/conflicting cases to human review instead of guessing, and halting at the mapping-review gate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action, followed by two focused clauses on scoring behavior and the stopping point. Slightly padded by line-break formatting, but every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the description covers the action, its determinism policy, and its terminal gate. The remaining gap is the run_id contract and any prerequisite that the run be profiled first, which is only hinted at.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and the single run_id parameter has no schema description, so the description must carry the burden. 'For a profiled run' adds a useful constraint (the run must already be profiled), but format, source, or expected value of run_id is never explained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States specific verbs (infer, propose) and resources (entities, joins, canonical mappings) tied to a profiled run. The 'stops at the mapping-review gate' clause distinguishes it from the downstream submit_mapping_review, though that routing is implied rather than named as a sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: the tool operates on a profiled run and hands off at the mapping-review gate, so the agent can infer it precedes submit_mapping_review. However, there is no explicit when-to-use, when-not, or named alternative, leaving pipeline positioning to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
publish_runADestructiveIdempotent
Publish certified artifacts. Fails closed without a valid certification bound to the bundle.
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes | ||
| certification_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| path | Yes | |
| reused | Yes | |
| run_id | Yes | |
| status | Yes | |
| version | Yes | |
| manifest_hash | Yes | |
| excluded_metrics | Yes | |
| published_metrics | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true, and the title notes the certification requirement, so the bar is lower. The description still adds a genuinely new behavioral trait beyond the structured fields: fail-closed behavior on missing/invalid certification. It does not elaborate on what 'destructive' means here (e.g., what prior published state is overwritten), which caps it below 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, purpose first, precondition second, with zero filler. Every clause carries information an agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be described, and annotations cover safety/idempotency. The description covers purpose, precondition, and failure mode adequately for a two-parameter tool, though it leaves the destructive effect of publishing unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for two required parameters, so the description must compensate. It clarifies that certification_id must reference a valid certification bound to the bundle, which adds real semantics for that parameter, but run_id is never explained and no format/typing detail is given.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (publish certified artifacts) and adds a scope qualifier (certified only). It is discernible from the sibling certify_run by framing this as the downstream publish step, but it never names or contrasts that sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The precondition 'without a valid certification bound to the bundle' implies the tool cannot be used until certify_run has produced a certification, which is useful gating context. However, it never explicitly says when to use this versus certify_run, generate_dbt_artifacts, or the other publishing-adjacent siblings, leaving the routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resume_runA
Continue a paused or failed run. Gates re-check approvals; completed steps are reused, not recomputed.
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| gate | Yes | |
| error | No | |
| steps | Yes | |
| run_id | Yes | |
| status | Yes | |
| resources | Yes | |
| company_id | Yes | |
| next_action | Yes | |
| current_step | Yes | |
| connection_id | Yes | |
| pending_items | Yes | |
| pending_review_count | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (not read-only, not idempotent, non-destructive), and the description adds real behavior beyond them: gates re-check approvals and completed steps are reused rather than recomputed. It still omits auth/permission requirements and what happens to already-failed steps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the action and followed by the key behavioral guarantee. Every clause earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the description conveys the resume semantics well for a simple one-parameter tool. The only material gap is that the run_id parameter is left entirely undocumented.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is one parameter with 0% schema description coverage, and the description says nothing about run_id at all. Although the name is fairly self-explanatory, the low-coverage rule requires the description to compensate and it does not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (continue/resume) and resource (a run) plus the qualifying state (paused or failed). It implicitly separates itself from start_onboarding_run and get_run_status, but never names a sibling to make the distinction explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear trigger condition: use it for a run that is paused or failed, which contrasts with starting a new run. No explicit when-not guidance or named alternatives are provided, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_sandbox_testsA
Build the generated project with dbt in a disposable sandbox and reconcile metrics exactly.
On success the run pauses at the certification gate; on failure at the test-failures gate.
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| cached | Yes | |
| passed | Yes | |
| run_id | Yes | |
| status | Yes | |
| data_tests | Yes | |
| resource_uri | Yes | |
| dbt_exit_code | Yes | |
| waived_checks | Yes | |
| failing_checks | Yes | |
| reconciliation | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the safety profile (not read-only, not destructive, not idempotent, closed-world), so the bar is lower. The description adds real value beyond them: it runs in a disposable sandbox and pauses at a specific gate depending on outcome, which is meaningful state-transition context for a non-idempotent tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly worded sentences with zero filler. The core action is front-loaded and the outcome-gate behavior follows as supporting detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and annotations cover safety. The description conveys the sandbox behavior and gate outcomes, but omits prerequisites (e.g. whether dbt artifacts must be generated first), leaving a small gap for a stateful pipeline step.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description says nothing about run_id. However, it is a single, self-explanatory identifier, so the practical risk of misuse is low. The description adds no parameter meaning, which caps this below the baseline-4 case for zero-parameter tools.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource combination: 'Build the generated project with dbt in a disposable sandbox and reconcile metrics.' This clearly separates it from siblings like generate_dbt_artifacts and certify_run. It stops short of explicitly naming which sibling it is not, so a 5 isn't warranted.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the mention of the certification gate (success) and test-failures gate (failure), which places the tool in a pipeline, but it never states when to call it versus alternatives or what prerequisites must exist first. No explicit when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
start_onboarding_runA
Start read-only onboarding of a registered source (e.g. fixture:portco_a).
Runs connection validation, profiling, entity and join inference and canonical mapping,
then stops at the first human review gate. Returns the run status and pending review items.
| Name | Required | Description | Default |
|---|---|---|---|
| company_id | No | ||
| connection_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| gate | Yes | |
| error | No | |
| steps | Yes | |
| run_id | Yes | |
| status | Yes | |
| resources | Yes | |
| company_id | Yes | |
| next_action | Yes | |
| current_step | Yes | |
| connection_id | Yes | |
| pending_items | Yes | |
| pending_review_count | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the safety profile (not read-only, not destructive, not idempotent, closed world), so the description's added value is the workflow disclosure: which phases run, where execution halts, and what is returned. The phrase 'read-only onboarding' sits in tension with readOnlyHint=false, though it reads as describing source-side non-mutation (consistent with destructiveHint=false) rather than the tool's own side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short lines, front-loaded with the action and followed by execution scope and return behavior; no filler. Slightly marred by the ambiguous 'read-only' qualifier, which is the one phrase that could mislead.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a stateful pipeline-start tool in an eleven-tool suite, the description covers execution and terminal state well, and an output schema exists so return details needn't be repeated. However it omits prerequisites, permission requirements, and how it relates to resume_run / list_pending_reviews, which an agent needs to sequence calls correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for both parameters, so the description carries the full burden, yet only 'connection_id' is implied via the 'registered source (e.g. fixture:portco_a)' example. The optional 'company_id' parameter is never mentioned or explained, leaving its scoping role undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Start ... onboarding of a registered source') and enumerates the pipeline phases it executes (validation, profiling, entity/join inference, canonical mapping). It also distinguishes itself from the sibling 'resume_run' by framing this as the initial start that halts at the first human review gate.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The stopping condition ('stops at the first human review gate') implies the natural follow-up (list_pending_reviews / resume_run), but no explicit when-to-use or when-not-to-use guidance is given and no alternative is named. An agent must infer the relationship to the ten sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
submit_mapping_reviewA
Record a reviewer's decisions for an observed mapping or test-failure packet.
Decisions: approve | reject | approve_with_override (override keys: canonical_field, transform,
pii_handling). Supply the exact subject_hash and gate returned by list_pending_reviews.
Stale packets are rejected. Certification must use certify_run. Reviewer principals only.
| Name | Required | Description | Default |
|---|---|---|---|
| gate | Yes | ||
| run_id | Yes | ||
| comment | No | ||
| decisions | Yes | ||
| subject_hash | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| gate | Yes | |
| run_id | Yes | |
| reviewer | Yes | |
| decisions | Yes | |
| approval_id | Yes | |
| next_action | Yes | |
| subject_hash | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=false, non-idempotent, closed-world), the description adds real behavioral context: stale packets are rejected and only reviewer principals may call it. The override sub-keys for approve_with_override are also disclosed. It stops short of describing consequences of a rejected/partial submission or how decisions interact within one packet.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded, followed by the decision vocabulary, provenance requirement and constraints in a tight block. No filler sentences; every clause carries operational information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be described, and the description covers the mutation's auth, staleness and alternative-tool context. Minor gaps remain around run_id/comment semantics and what happens when only some decisions in a packet are acted on.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the load. It does document the decision enum values, the override keys (canonical_field, transform, pii_handling), and the provenance requirement for subject_hash and gate, but leaves run_id and the top-level comment unexplained and never states the gate enum values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: recording a reviewer's decisions against an observed mapping or test-failure packet, and names the two gates it applies to. It also distinguishes itself from certify_run, which handles certification, so the agent can route correctly without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says to supply the exact subject_hash and gate returned by list_pending_reviews (naming the prerequisite sibling), warns that stale packets are rejected, restricts callers to reviewer principals, and redirects certification to certify_run. When-to-use, prerequisites and the key alternative are all stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v0.1.1- Changed
submit_mapping_review3 fields changed- added
Input schema / properties / gateAdded value: +{ + "enum": [ + "mapping_review", + "test_failures" + ], + "title": "Gate", + "type": "string" +} - added
Input schema / properties / subject_hashAdded value: +{ + "title": "Subject Hash", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "run_id", - "decisions" -]New value: +[ + "run_id", + "subject_hash", + "gate", + "decisions" +]
12 tool updates
v0.1.0- First observed
certify_run - First observed
generate_dbt_artifacts - First observed
get_run_status - First observed
healthcheck - First observed
list_pending_reviews - First observed
profile_schema - First observed
propose_canonical_mapping - First observed
publish_run - First observed
resume_run - First observed
run_sandbox_tests - First observed
start_onboarding_run - First observed
submit_mapping_review
TDQS
Scored across 12 tools
Most tools have clearly distinct purposes along the pipeline (start, profile, propose, generate, test, publish). However, list_pending_reviews overlaps with get_run_status (both return pending review items), and submit_mapping_review vs certify_run both handle reviewer decisions with subject_hash, which could cause confusion without close reading.
Nearly all tools follow a consistent verb_noun snake_case pattern (list_pending_reviews, start_onboarding_run, generate_dbt_artifacts). The lone outlier is healthcheck, which is a noun with no verb, a minor deviation.
12 tools is well-scoped for a multi-stage data onboarding pipeline with human review gates, artifact generation, testing, and publishing. Each tool appears to own a distinct lifecycle step, with no redundant entries.
The core lifecycle is covered: start, status, resume, profile, propose, review, certify, generate, test, publish. Minor gaps exist, such as no cancel/abort run, no list-runs tool, and no way to retrieve generated artifacts or open findings directly for inspection.
Maintenance
Related MCP Connectors
Guarded MCP server for agent-readable business truth, provenance, readiness, and discovery.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
Hosted MCP server for AI-driven data ops. Create apps, manage schemas, and CRUD structured data.
Hosted MCP server for RudderStack, the agentic CDP that runs on your warehouse. Ask Claude, ChatGPT, Cursor or Codex why events failed, which warehouse loads broke, or where your tracking plan is violated. Build and test transformations and audiences. OAuth login, your permissions, PII masked.
Related MCP Servers
- AlicenseBqualityCmaintenanceA read-only MCP server that exposes dbt project artifacts and data quality result tables (BigQuery/Postgres) to LLM clients, enabling deep introspection, run-history analysis, source freshness, test coverage, and lineage walks.2795 npmMIT

RecoSearchofficial
AlicenseNot gradedqualityCmaintenanceA deterministic MCP server that governs read-only queries across multiple data sources, returning answers with full provenance (every row cited) or a typed refusal, ensuring LLM answers are traceable and contract-enforced.1Apache 2.0- AlicenseBqualityDmaintenanceA local, evidence-driven MCP runtime and control plane for open-source maintainers that provides workspace-bounded tools including controlled file operations, command execution, validation primitives, durable execution records, and human review workflows via stdio and Streamable HTTP transports.33MIT
- AlicenseBqualityBmaintenanceLocal-first MCP server for data quality that finds suspicious data, explains findings with evidence, tracks drift, and supports human-approved, reversible repair workflows. Deterministic by default, with AI optional.25170 PyPI2Apache 2.0