Skip to main content
Glama
Mipiti
by Mipiti

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
MIPITI_API_KEYYesYour Mipiti API key
MIPITI_API_URLNoAPI base URLhttps://api.mipiti.io
SERVER_VERSIONYesIdentifier for the running server's MCP surface. For local runs, any sentinel string is fine (e.g., 'local').

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": true
}
logging
{}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
extensions
{
  "io.modelcontextprotocol/ui": {}
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
generate_threat_modelA

Generate a complete threat model from a feature description.

Analyzes the feature using the Security Properties (Confidentiality, Integrity, Availability, Usage) methodology with capability-defined attackers. Produces trust boundaries, asset inventory, attacker inventory, control objective matrix, and assumptions.

Runs a multi-step AI pipeline. Progress is reported automatically.

Similar-model short-circuit: if the backend finds an existing model in the workspace whose feature description substantially overlaps with the new one, it does NOT generate a duplicate. This tool returns {"similar_models": [{"id", "title", "reason"}, ...], "suggestion": "..."} with the candidate IDs instead. The agent should then either:

  • Call refine_threat_model on one of the candidates to extend the existing model (usually the right answer — avoids duplicate modeling of the same system and preserves control/assertion history).

  • Retry this tool with force=True to bypass the check and create a genuinely new model anyway (e.g., when the similarity is superficial and the operator confirmed the new model is distinct).

refine_threat_modelA

Refine an existing threat model based on an instruction.

Updates the model's assets, attackers, trust boundaries, and control objectives based on the instruction. Creates a new version. Progress is reported automatically.

Refine CANNOT silently replace an entity's identity under a stable ID or silently drop an entity. Behavior:

  • Preserved entities where the LLM proposed an identity- bearing rewrite (name / description / security_properties on assets; capability / archetype / position on attackers) run through a semantic-preservation guard. Rewrites classified as replace or ambiguous (or unavailable if the gate LLM is down) have their identity fields REVERTED to the pre-refine values. Each rejection shows up as an entry in the semantic_rejections array in this tool's return value — surface these to the operator.

  • Entities the LLM drops from the refined output are re- appended to the model unchanged. The only sanctioned removal path is remove_asset / remove_attacker (soft-delete).

  • CO IDs are stable across refinements; pairs (asset, attacker) that disappear come back as tombstones with removed=True (not renumbered). Controls that only mapped to tombstoned COs become orphaned at read time.

query_threat_modelA

Ask a question about an existing threat model.

Uses AI to answer questions about the model's assets, attackers, control objectives, assumptions, or security posture.

list_threat_modelsB

List all saved threat models.

Returns a summary of each model including ID, title, creation date, and version number. Use the model ID with other tools.

rename_threat_modelA

Rename a threat model. Metadata change only, does not create new version.

set_threat_model_parentA

Set (or clear) a model's parent on the recursive composition tree.

The composition substrate (Layer 0) builds an ancestor chain from each model's parent_id so child models inherit topology, control objectives, and other entities from their ancestors. Use this tool when wiring a child model under a platform / system / shared-services ancestor, or when re-rooting a model after a re-org.

Pass parent_id=None to clear the parent (the model becomes a tree root). The server rejects cycles (you cannot make a descendant your parent) and over-deep chains (depth bounded by MAX_TREE_DEPTH) with HTTP 400. Bumps the model version on success.

Returns the updated threat model.

declare_foundationB

Mark a model as a shared foundation that advertises providable controls.

A foundation is a shared service (auth, logging, a shared datastore) whose controls other models can delegate to. Each entry in provides advertises one of THIS model's controls as providable: {"control_id": "CTRL-07", "capability_label": "Validates session tokens", "description": "..."}. A capability always advertises a control (a proven mechanism), never an objective. visibility is "workspace" (default) or "explicit".

list_reliance

List a model's cross-model dependency edges (as consumer and as provider).

Returns {model_id, as_consumer: [...], as_provider: [...]}. Consumer edges are this model's declared delegations / reliances; provider edges are other models relying on this one (the blast radius if its controls change).

create_reliance

Declare a cross-model dependency: this model relies on a provider control.

Two modes (the target is ALWAYS a provider control — credit terminates at a proven mechanism):

  • delegated: this model does NOT implement an objective locally; it is handled entirely by the provider's control. Pass source_objective_id.

  • relied_upon: this model has its OWN control whose validity depends on the provider's control. Pass source_control_id.

The provider must be a model in the SAME workspace as the consumer (reliance is workspace-scoped and does not reach across workspace boundaries). The edge enters draft and runs LLM semantic validation; it carries no credit until confirmed via confirm_reliance (and only when validation returned valid). Returns the created edge.

confirm_relianceA

Promote a draft reliance edge to active (the credit-soundness gate).

Refuses unless LLM validation returned valid. A partial result or a mode mismatch is refused (never silently credited). Returns the updated edge.

delete_relianceC

Delete a cross-model reliance edge.

propose_attach_foundationA

Propose which of this model's objectives each foundation capability covers.

Read-only: returns candidate (objective ↔ provider control) pairs with a match score. Nothing is created or credited. Feed the chosen subset to attach_foundation.

attach_foundationA

Create draft delegation edges for selected (objective, control) pairs.

selections is a list of {"source_objective_id": ..., "provider_control_id": ...} (typically the operator-confirmed subset of propose_attach_foundation). Each becomes a delegated draft edge that runs LLM validation; none carries credit until separately confirmed. Returns {created, failed}.

list_tags

List the workspace's tags (the Affiliation primitive).

A tag is an overlapping, semantics-free grouping of models — for audit scopes, ad-hoc selections, or portfolios. Unlike a system, a model may carry many tags, and a tag never affects posture or credit. Returns {tags: [...]}.

create_tag

Create a tag, optionally seeding it with member models.

Tags group models for viewing/reporting without asserting any relationship between them and without moving credit. Tag names are unique per workspace.

delete_tag

Delete a tag (the grouping only; member models are not affected).

add_model_to_tag

Add a model to a tag. A model may belong to many tags (overlapping).

remove_model_from_tagA

Remove a model from a tag (the model itself is not deleted).

list_model_tagsB

List every tag a model belongs to (overlapping membership).

get_tag_risk_viewA

Aggregate per-CO risk rows across a tag's member models.

The tag-based aggregate posture view. Each row is delegation-aware (delegation_mitigated / delegating_controls), so a CO mitigated via a verified cross-model delegation reads as covered — consistent with the per-model assessment.

select_tag_compliance_frameworksA

Select compliance frameworks for a tag (scope-level).

Records the frameworks against the tag and propagates them to each member model — the tag becomes a compliance scope (e.g. an audit boundary) spanning several models, the same capability a system has.

get_tag_compliance_reportA

Cross-model compliance coverage report scoped to a tag's members.

Aggregates requirement coverage across every model the tag contains, the same as a system-level compliance report but over a freely-composed set.

export_tag_reportA

Export the signed auditor report for a tag (HTML).

Aggregates every member model's report plus the cross-model dependency graph and attestation status into one signed HTML document — the tag equivalent of the system auditor export. Returns {tag_id, format, content} where content is the HTML body.

delete_threat_modelA

Delete a threat model and all associated data. This cannot be undone.

get_threat_modelA

Get a specific threat model by ID.

Returns the full threat model including trust boundaries, assets, attackers, control objectives, and assumptions.

Important for agents reading model state:

  • Assets and attackers may carry deleted: true (soft-deleted). Exclude these when showing "what's in the model now"; include them only when discussing history or offering restore. Restore an entity via restore_asset / restore_attacker.

  • Control objectives may carry removed: true (tombstone — the (asset, attacker) pair was removed in a later version). Exclude these from coverage math and LLM prompts; they exist to keep CO IDs stable so controls referencing them can be detected as "orphaned" rather than silently rebinding.

export_threat_model

Export a threat model as CSV, PDF, or HTML.

The backend export endpoint runs as an async job (the synchronous render path was retired because cross-model assurance compute could pin the worker for minutes on large models). This tool kicks off the job, polls for completion via _await_backend_job (reporting progress), then fetches the rendered bytes.

export_threat_model_archive

Export the self-contained JSON audit archive for a threat model.

The archive carries every version, controls, assertions (with CI Tier 1/Tier 2 verdicts and attested flags), findings, risk acceptances, assumption overrides, attestations, and instance sufficiency signatures. Independently verifiable — CI OIDC JWTs verify against the issuer's public JWKS, workspace signatures against the workspace's published key, and sufficiency signatures against the origin instance's key (via the target's trusted_signers table).

The backend renders the archive as an async job (the same cross-model assurance compute that motivated PDF/HTML to migrate away from synchronous rendering). This tool kicks off the job, polls for completion via _await_backend_job (reporting progress), then fetches and decodes the JSON envelope.

import_threat_model_archive

Import a JSON audit archive (from export_threat_model_archive) into the target workspace.

A fresh model_id is assigned every time, so the same envelope can be imported any number of times without collisions. Title collisions in the target workspace auto-suffix (imported YYYY-MM-DD). The caller must have write access to the target workspace.

get_controls

Get implementation controls for a threat model.

Returns controls that should be implemented to satisfy control objectives. If controls haven't been generated yet, auto-generates them.

By default excludes ORPHANED controls — controls whose every mapped CO is tombstoned (its asset/attacker pair was removed in a later version). Pass include_orphaned=True to see them. Each returned control carries a boolean orphaned field so callers can render the distinction.

get_control_generation_status

Poll the async control-generation status for a threat model.

When generate_threat_model / refine_threat_model return a controls_status other than complete, controls are being authored in the background — poll this until a terminal state, then read the controls.

Return shape: {status, mode, target_cos, ready_cos, error_message, elapsed_seconds} (or {status: "none"} when controls were built inline). status is queued | generating | deferred | complete | failed | skipped | none:

  • deferred — today's background-analysis budget is used up; generation resumes automatically at the daily reset (relay this to the user).

  • failederror_message says why (e.g. insufficient credits).

  • ready_cos / target_cos — coverage progress.

  • elapsed_seconds — time since queued; if it stays queued with a large elapsed, generation may not be progressing — surface that instead of polling forever.

regenerate_controlsA

Regenerate controls from control objectives.

Controls whose descriptions survive regeneration unchanged preserve their implementation status, evidence, notes, assertions, Jira mappings, and compliance mappings. Controls with changed or removed descriptions are soft-deleted (queryable via include_deleted=True).

When co_ids is specified, only the controls for those COs are regenerated — other controls are preserved as-is.

update_control_statusB

Update the implementation status of a security control.

Requires at least one assertion before marking as implemented. Check the control's assertion_count from get_controls before calling.

refine_controlA

Refine a control's description with AI-gated CO sufficiency check.

Two modes:

  • Provide description: proposes a new description directly.

  • Provide codebase_findings: the platform proposes a description based on existing code that may already satisfy the control.

  • Both can be provided: the platform evaluates the proposed description with the codebase findings as context.

The AI evaluates whether the mitigation group still collectively satisfies all mapped control objectives. If rejected, returns {accepted: false, reason, per_co} with per-CO reasoning.

Side effect on accepted refinements: every assertion attached to this control is superseded — their claims were authored against the prior description and are not guaranteed to align with the new one. The response includes superseded_assertions: <count> so the caller knows how many. Re-submit any assertion that still applies under the new description; superseded rows remain in history with superseded_by="control_refined:...".

remap_controlA

Mechanical, non-AI-gated remap of a control's CO mappings.

Distinct from refine_control (AI-gated description edit) and set_mitigation_groups (AI-gated CO-centric group authoring). Use remap_control when the operator already knows the correct co_ids and just needs to persist the mapping change — e.g., restoring mappings after an asset/attacker edit left the control with stale or orphaned CO references. No LLM evaluation runs.

Rejects target co_ids that do not exist on the model or are tombstoned (the pair was removed in a later version) — map to live COs only.

assign_control_to_componentsA

Replace a control's component scope.

Components are the canonical code-binding for controls. A control scoped to one or more components is visible to coding agents working in those repos (matched via Component.repo_url + Component.path); an unscoped control is visible everywhere.

Use this tool when:

  • Wiring a previously unscoped control to the component(s) that implement it (so coding agents see the control on their repo).

  • Adding a second component to a cross-cutting control (e.g., "all microservices enforce JWT validation").

  • Correcting a wrong component assignment.

assign_asset_to_componentsA

Replace an asset's component scope.

Mirror of assign_control_to_components for assets. Components are the canonical bridge between security architecture (trust boundaries) and code organization (repos). Linking assets to components flows boundary context into reachability derivation without giving Asset its own trust_boundary_ids.

An asset's component scope can be:

  • Unscoped (empty string): no explicit code-ownership binding. Reach decisions fall back to LLM judgment of the asset's description / security properties.

  • Single-component: standard case for assets handled by one deployable unit.

  • Multi-component: a multi-instance asset that flows through several components (e.g., a session token on client + cache

    • DB — each component handles a distinct instance).

Mechanical, non-AI-gated. Validates only that every referenced component exists on the model.

model_coherence_reportA

Static-analysis report on coherence between the model's component declarations, the code-binding strings on its controls and assertions, and the structural reachability of every CO.

Pass co_id to scope the report to findings carrying that CO id (the co_* reachability findings + the attestation cross-link findings). Component- and assertion-level findings without a CO binding are excluded in single-CO mode. 404 if the CO doesn't exist on the model.

The report carries up to twelve finding types, grouped below by concern. Each finding includes the entity IDs it concerns (co_id, asset_id, attacker_id, component_id, etc.) so the agent can dispatch the resolution tool directly without re-fetching the model.

Component / assertion bindings:

  • control_component_unknown — control references a component ID that no longer exists. Resolve: assign_control_to_components.

  • asset_component_unknown — asset references a missing component. Resolve: edit_asset (with corrected component_ids).

  • assertion_repo_mismatch — an assertion's repo does not match the repo_url of any component scoping its control. Resolve: rebind the assertion or rescope the control.

  • assertion_repo_orphan — an assertion has a repo but its control is unscoped. Resolve: assign_control_to_components to scope the control, or correct the assertion's repo.

  • control_unscoped_with_scoped_assertions — control is unscoped, but its assertions all carry a single component's repo. Resolve: assign_control_to_components to that component.

  • component_unbound — a component has no repo_url (speculative; LLM-proposed during generation, or operator- added without a binding yet). Resolve: edit_component with the real repo URL once the codebase exists. Speculative is a valid lifecycle state, not an error — surfaced so the gap is visible to auditors.

Reachability findings (deterministic composer; indeterminate verdicts surface as findings, never auto-decided by an LLM):

  • co_attacker_unpositioned — the CO's attacker has no positioned trust boundaries. Resolve: edit_attacker (set trust_boundary_ids), or add_assumption with a structured exclusion predicate.

  • co_asset_unbounded — the CO's asset has no component-derived trust boundaries. Resolve: assign_asset_to_components, edit_asset (with component_ids), or add_assumption with a structured exclusion.

  • co_no_shared_boundary — attacker and asset boundaries do not intersect. Resolve: re-position the attacker via edit_attacker, scope the asset to a shared component via assign_asset_to_components, or add_assumption with a structured exclusion.

  • co_missing_entity — the CO references a missing asset/attacker; model state inconsistent. Resolve: restore the entity (restore_asset / restore_attacker) or remove the orphaned CO via refine_threat_model.

Use this before relying on component-scoped control discovery, when assertion verification fails for path/repo reasons, or to enumerate structural-completeness gaps the operator should address before treating the model as audit-ready. get_reachability_verdicts exposes the underlying composer verdicts directly when the finding-shape summary isn't enough.

get_reachability_verdictsA

Composer verdicts for every live CO on the model. Pass co_id to retrieve a single verdict (skips the cross-CO loop).

Pure derivation over the model's structural primitives — components, asset.component_ids, trust_boundary.passes, attacker.trust_boundary_ids + attack_vector, and Assumption.exclusion predicates. NOT persisted on the CO. Re- running this call against the model JSON produces the same result every time — that's the verification an auditor performs.

get_composition_overviewA

Composition index for a model — counts, tree metadata, warnings.

Cheapest call in the composition surface (~1-2KB). Use this first to learn whether composition is enabled, where the model sits on the recursive tree (parent + ancestor chain + child ids), how many own vs inherited entities and COs there are per kind, and whether any structural warnings (cycle, parent missing, max depth exceeded) need surfacing before drilling into sub-resources.

Return shape::

{
  model_id, model_version, flag_enabled,
  tree: {parent_id, ancestor_chain, depth, child_ids},
  counts: {
    entities: {kind: {own, inherited}, ...},
    control_objectives: {total, live, covered, uncovered,
      indeterminate, by_origin: {own, cross, inherited}},
    reconciliation_candidates: {certain, heuristic},
  },
  warnings: [str, ...],
}

When TREE_COMPOSITION_ENABLED is off on the backend, returns the same shape with all counts zeroed and flag_enabled: false.

list_effective_entitiesA

Effective entity set (own ⊕ inherited) keyed by kind.

Returns the entity set this model sees after composition with ancestors: trust boundaries, components, assets, attackers, and (when applicable) attack paths. Each entry carries its provenance — whether it originates on this model or is inherited from an ancestor — plus a fully-qualified id so cross-model references are unambiguous.

Pair with list_effective_control_objectives and get_effective_coverage to see how inherited topology contributes to coverage credit.

Return shape::

{
  model_id, flag_enabled,
  kinds: {
    trust_boundaries: [{kind, qualified_id, owner_model_id,
      owner_title, origin, entity}, ...],
    components: [...], assets: [...], attackers: [...], ...
  },
  total, page, page_size,
}

When composition is disabled on the backend, kinds is returned with every kind mapped to an empty list and flag_enabled: false.

Omitting page / page_size defaults to page=1, page_size=100 — the response is paginated and no longer returns every entity in a single call.

list_effective_control_objectives

Effective control objectives with origin classification.

Returns every CO visible on the effective model, each tagged with its origin: own (authored on this model), cross (an inherited CO whose asset or attacker is local to this model), or inherited (purely inherited from an ancestor). Use this to see what control objectives the model is on the hook for — including those it inherits — before reading coverage or reach.

Return shape::

{
  model_id, flag_enabled,
  control_objectives: [
    {co_qid, asset_qid, attacker_qid,
     security_properties: ["C"|"I"|"A"|"U", ...],
     origin: "own"|"cross"|"inherited"},
    ...
  ],
}

When composition is disabled on the backend, returns an empty list and flag_enabled: false.

get_effective_coverage

Effective coverage rollup with credited inheritance.

Per effective CO: whether it is covered, how much credit comes from controls owned by this model vs inherited from ancestors, and the list of contributing controls (with the owning model id, origin tag, verification status, and mitigation group). This is the surface that drives the composition view's coverage / compliance numbers — it reflects TREE_COMPOSITION_ENABLED math, not the per-model coverage shown by get_verification_report.

Return shape::

{
  model_id, flag_enabled,
  coverage: [
    {co_qid, is_covered, own_credit, inherited_credit,
     contributing_controls: [{control_id, owner_model_id,
       origin, is_verified, mitigation_group}, ...]},
    ...
  ],
  total, page, page_size,
}

When composition is disabled on the backend, coverage is empty and flag_enabled: false.

Omitting page / page_size defaults to page=1, page_size=100 — the response is paginated and no longer returns every coverage row in a single call.

get_reach_verdicts

Per-CO reachability verdicts over the composed effective topology.

Same shape as get_reachability_verdicts, but evaluated against the merged tree: own components and trust boundaries combined with everything inherited, and qualified ids used for cross-model references. Use this when the model is a child on the composition tree and you need reach state that reflects the ancestor topology, not just the local model document.

Return shape::

{
  model_id, flag_enabled,
  verdicts: [
    {co_qid, asset_qid, attacker_qid,
     kind: "reachable"|"unreachable"|"indeterminate",
     reason: <structural label>},
    ...
  ],
  total, page, page_size,
}

When composition is disabled on the backend, verdicts is empty and flag_enabled: false — fall back to get_reachability_verdicts for the per-model derivation.

Omitting page / page_size defaults to page=1, page_size=100 — the response is paginated and no longer returns every verdict in a single call.

list_effective_attack_paths

Effective AttackPath set + lifted missing/dangling suggestions.

AttackPaths inherit from ancestors with the same own / inherited provenance as other entities. The suggestions block is the missing-path / dangling-path delta computed against the composed effective topology — a child sees the inherited baseline claims, the composed reach surface, and the delta against both.

Return shape::

{
  model_id, flag_enabled,
  effective_paths: [{kind, qualified_id, owner_model_id,
    owner_title, origin, entity}, ...],
  lattice_positions: int,
  authored_paths: int,
  suggestions: {missing_path: [...], dangling_path: [...]},
}

When composition is disabled on the backend, effective_paths is empty, the counts are zero, suggestions is empty, and flag_enabled: false.

list_reconciliation_candidates

Reconciliation candidates between this model and its ancestors.

When a model inherits entities (assets, attackers, components, trust boundaries) from an ancestor and the operator has authored a locally-named entity that looks like the same real-world thing, the reconciliation engine surfaces the pair as a candidate so the operator can decide whether to alias it onto the inherited qualified id. Tier certain is a deterministic match (same qid or structurally identical) and is safe to auto-apply; tier heuristic is a fuzzy name/description match that needs review.

Paginated. Use this on child models in a recursive tree to find duplicates that should be collapsed before they distort coverage.

Return shape::

{
  model_id, flag_enabled, total,
  tiers: {certain: int, heuristic: int},
  page, page_size,
  candidates: [
    {kind, own_qid, inherited_qid,
     tier: "certain"|"heuristic", reasons: [str, ...]},
    ...
  ],
}

When composition is disabled on the backend, total is 0, candidates is empty, and flag_enabled: false.

apply_certain_reconciliation_match

Apply a certain-tier reconciliation candidate. Mutates state.

Soft-deletes the descendant's own duplicate entity; the inherited entity becomes the canonical surface for the effective-model resolver. Use after surveying candidates via list_reconciliation_candidates. Certain-tier candidates apply directly; heuristic-tier candidates need operator review of the structural divergence and are refused server-side unless confirm_heuristic=True is passed to acknowledge the divergence.

The server re-validates the candidate against current live state before applying; if the model has moved since the candidate was detected, returns 400 and the operator should refresh the candidate list and retry. Bumps model version and emits an activity event on success.

reject_reconciliation_candidate

Reject a reconciliation candidate. Mutates state.

Records the operator's "these are NOT duplicates" decision at org scope so the candidate detector filters this pair out of the active queue on subsequent reads. Idempotent on the natural key (model_id, kind, own_qid, inherited_qid) — re-rejecting an existing pair returns the same row. Use when list_reconciliation_candidates surfaces a pair that looks like a duplicate but the operator has confirmed it is not.

Persistence is at org scope, not model state — the rejection is durable across sessions and teammates but does NOT bump model version.

unreject_reconciliation_candidate

Remove a persisted reconciliation rejection. Mutates state.

The pair becomes eligible to surface in the active candidate queue again on the next read of list_reconciliation_candidates. Use when the operator changes their mind about a prior rejection — the surrogate rejection_id comes from rejections[*].id on list_reconciliation_rejections (or the return value of reject_reconciliation_candidate).

Does NOT bump model version (rejection is org state, not model state).

list_reconciliation_rejections

List persisted reconciliation rejections for a model.

Returns the operator's "these are NOT duplicates" decisions on this model in rejected_at ascending order — the same set the candidate detector consults to filter the active queue. Use this to render the rejected section of a triage view, or to find the surrogate id needed by unreject_reconciliation_candidate.

When TREE_COMPOSITION_ENABLED is off, returns {model_id, flag_enabled: false, rejections: []} so the caller can render the disabled state without a separate code path. The same empty shape is returned with flag_enabled: true when the rejection store is not configured on the instance.

lift_composition_entityA

Promote a shared-anchor entity from two sibling descendants to their lowest common ancestor. Mutates state across three models.

The operator has confirmed (via the composition lift-candidate view) that the entity local_id_a on descendant_a_id and the entity local_id_b on descendant_b_id are the same logical thing and should be modeled once on the LCA. The route's model_id is the operator's current context model — typically the LCA, but the server accepts any ancestor of both descendants.

Conflict resolution. The server re-detects field-level and attached-state conflicts against current live state before applying. If new conflicts have surfaced since the operator's last candidate fetch, the call returns 400 with the missing conflict keys; refresh composition_lift_candidates and resubmit with resolutions covering every key. Each entry in field_resolutions / attached_state_resolutions is "keep_a" | "keep_b" | "keep_both" (union for list/set fields; falls back to B for scalars).

Over-application gate. The lift extends visibility to every descendant of the LCA, not just the two source descendants. The server runs an over-application gate that refuses lifts touching descendants outside an acknowledged set; pass acknowledged_third_party_subtrees to acknowledge specific subtrees, or skip_overapplication_gate=True to override entirely after explicit operator confirmation.

Each affected model (LCA + both descendants) bumps version and emits a model_refined activity event; a structured lift_applied event with the full lift_event payload lands on the LCA. The audit pack surfaces this under lift_history.

split_composition_entityA

Push an ancestor-owned entity down to one or more descendants and soft-delete the ancestor's copy. Mutates state across the ancestor + every target descendant.

Inverse of lift_composition_entity. Use when an entity that currently lives on an ancestor is in fact descendant-specific and should be modeled separately per descendant — the operator chooses which descendants take a copy. A new local id is minted on each target; attached state on the ancestor's entity (assertions, jira mappings, risk acceptances, etc.) is duplicated to every target.

The route's model_id IS the ancestor (the entity being split lives on it). Each affected model (ancestor + every target descendant) bumps version and emits a model_refined activity event; a structured split_applied event with the full split_event payload lands on the ancestor. The audit pack surfaces this under split_history.

preview_undo_lift_composition

Preview the inverse plan (or divergence refusal) for a prior lift_applied event WITHOUT mutating any state.

Read-only counterpart to undo_lift_composition_event. Used by the confirmation flow so the operator sees what an undo would do before committing — either the inverse state operations the apply step will commit (tombstone the lifted LCA entity, restore the source descendants' copies, rewrite CO references), or the enumerated reasons the divergence detector refuses the undo.

undo_lift_composition_event

Apply the inverse of a previous lift_applied event.

Re-runs the divergence detector immediately before applying and refuses with 409 + the structured refusal block when state has materially evolved since the forward lift (assertions submitted on the lifted entity, downstream COs added that reference it, the entity edited, etc.). On success, persists the inverse state operations across the LCA + every affected source descendant and emits a structured lift_undone activity event citing original_event_id so the audit pack can chain undo to its forward.

preview_undo_split_composition

Preview the inverse plan (or divergence refusal) for a prior split_applied event WITHOUT mutating any state.

Counterpart to preview_undo_lift_composition for splits. Same {plan, refusal} shape; the plan block carries the split-specific inverse operations (restore at the ancestor, tombstone the duplicated copies on every target descendant) instead of the lift mirrors.

undo_split_composition_event

Apply the inverse of a previous split_applied event.

Mirror of undo_lift_composition_event for splits. Re-runs the divergence detector before applying and refuses with 409 + a structured refusal block when state has materially evolved since the forward split. On success, restores the ancestor's entity, tombstones the duplicated copies on every target descendant, persists across all affected models, and emits a structured split_undone activity event citing original_event_id.

get_control_objective

Get a single control objective with its composer verdict.

Returns the CO's typed fields, the IDs of any controls that map to it, and the deterministic reachability verdict — the structural derivation that backs any reach claim on the CO.

Tombstoned COs (removed: true) are returned with the flag set; the verdict is omitted because reach state is frozen at the removal version.

set_co_cal

Set the per-CO ISO/SAE 21434 Cybersecurity Assurance Level (CAL).

CAL is a 1-4 grade on each individual control objective that expresses how much assurance the control program owes for that specific objective. It lives on the control_objectives identity side-table — writes do NOT create a new threat-model version, and the value survives soft-delete + revival of the CO.

Pass cal=None (or omit it) to clear the value.

get_asset

Get a single asset. Soft-deleted assets carry deleted: true; the caller decides whether to surface them.

get_attacker

Get a single attacker. Soft-deleted attackers carry deleted: true.

get_component

Get a single component. Speculative components (repo_url="") are returned as-is — the empty repo IS the lifecycle state, not an error.

get_trust_boundary

Get a single trust boundary, including its passes set (closed-vocabulary subset of {Network, Adjacent, Local, Physical}).

get_assumption

Get a single assumption with its override applied.

Mirrors list_assumptions' merge logic for one entity. Returns the assumption's typed fields, structured exclusion predicate (when present), and the override layer (status / justification / linked CO IDs / target model). Soft-deleted assumptions carry deleted: true.

get_control

Get a single control with verified-status enrichment and an orphaned flag derived from the live CO set.

Returns the control directly (not wrapped in an array). 404 if the control doesn't exist on the requested version.

get_mitigation_groups

Get the current mitigation group structure for a control objective.

Returns the grouped view of controls for this CO with details (id, description, status) for each control:

  • groups: numbered groups (within=AND, across=OR)

  • defense_in_depth: tracked but not required for mitigation

  • unmapped: model controls not mapped to this CO (available for assignment)

Use cases:

  • Before set_mitigation_groups to see the current structure

  • When reviewing a CO's assessment to understand why it is at_risk or mitigated

  • When deciding which unmapped controls to assign to a CO

set_mitigation_groups

Declaratively set the mitigation group structure for a CO.

Replaces all mitigation group assignments for this CO. AI-gated: the platform evaluates whether the new structure satisfies the CO.

Mitigation groups define alternative paths to satisfy a CO:

  • Within a group: AND — all controls must be implemented

  • Across groups: OR — any complete group mitigates the CO

  • Defense-in-depth: tracked but not required for mitigation

add_evidence

Attach auxiliary metadata to a control (docs, links, artifacts).

Evidence is contextual metadata — it does NOT count toward implementation status. Only assertions prove controls.

remove_evidence

Remove an evidence item from a control by index.

import_controls

Import existing security controls into a threat model.

Accepts structured JSON or free-text. Controls are auto-mapped to COs and deduplicated against existing ones. The parse/map/dedup runs as a background job (polled for progress), then — because this mutates the model — you are asked to confirm before the controls are saved.

delete_control

Soft-delete a security control with justification.

Blocks with HTTP 409 if this is the only control covering any control objective. Add a replacement control or refine the threat model first.

check_control_gaps

Check for missing controls.

Analyzes existing controls against control objectives and suggests COs with insufficient coverage.

get_control_objectives

Get control objective matrix for a threat model.

Returns COs with references to which controls cover each one. By default returns compact summary (total count only). Pass offset/limit to retrieve specific COs.

assess_model

Run assurance assessment on a threat model.

Evaluates each control objective based on control implementation status. Returns summary (mitigated/at_risk/unassessed) and progressive metrics (defined/implemented/verified). No LLM calls — deterministic.

Use summary_only=True to get just the counts without per-CO assessments.

get_review_queue

Returns controls not reviewed in 90+ days.

Lists implemented/verified controls whose assertions have not been checked recently. For each stale control, verify assertions against codebase.

add_asset

Add a new asset to a threat model. Creates a new version.

The caller supplies identity-bearing fields (name, description, security_properties, notes) plus optional component scoping; the backend LLM-reasons the factor decomposition (and composes the impact rating from it). The same prompt the generation pipeline uses for LLM-produced assets is reused here, so factors are calibrated consistently regardless of who introduced the asset. Override any factor post-create via edit_asset with a change_reason for the audit trail.

component_ids (optional) links the asset to one or more deployable units. Components are the canonical bridge between security architecture (trust boundaries) and code organization (repos); linking assets here flows boundary context into the reachability graph. Multi-component is the right shape for multi-instance assets (e.g., a session token on client + cache).

LLM-gated against a re-add of a previously soft-deleted asset on the same model. Three possible outcomes:

  • Normal create — fresh asset with a new ID. Returns the envelope {"model": ThreatModel, "controls_carried": N, ...}.

  • Auto-restore — proposal matched a soft-deleted asset; that asset is un-deleted (CO tombstones revive). Response carries auto_restored: True, restored_asset_id, and discarded_fields.

  • Similar-verdict rejection{"accepted": False, "classification": "similar", "candidate_restore_id": "A-N", ...}; nothing saved.

Fails with a tool error on:

  • 503 — restore-candidate evaluator OR factor-reasoning evaluator unavailable. Retry with backoff.

  • 502 — restore-candidate evaluator returned malformed response. Retry same prompt.

edit_asset

Edit an existing asset. Only provided fields changed.

The composed impact is server-derived from the factor fields; there is no way to set it directly. To change the rating, set factor values (the platform composes the new rating) and supply change_reason documenting the operator override of the LLM-generated factors. The reason is captured in the rating-revision audit trail.

LLM-gated on identity-bearing fields (name, description, security_properties). Factor and notes edits skip the gate.

Outcomes when identity fields change:

  • Accepted edit (LLM classifies as preserve) — normal envelope response.

  • Rejected edit (LLM classifies as replace / ambiguous) — {"accepted": False, ...}; nothing saved. Soft-delete + add-new instead.

Editing a soft-deleted asset is rejected — restore_asset first. 503 on evaluator outage, 502 on malformed response, 400 when factor fields are sent without change_reason.

remove_asset

Soft-delete an asset. Creates a new version.

The asset's ID is preserved forever — never reused. Its linked (asset × attacker) CO pairs are tombstoned, which orphans any controls mapped to them. Use restore_asset to un-delete and revive the tombstones (orphaned controls become active again).

restore_asset

Un-soft-delete an asset. Revives its tombstoned COs with their original IDs, un-orphaning any linked controls.

add_attacker

Add a new attacker to a threat model. Creates a new version.

The caller supplies identity-bearing fields (capability, position, archetype, trust_boundary_ids); the backend LLM-reasons the factor decomposition. Override any factor post-create via edit_attacker with a change_reason. Mirror of add_asset semantics.

Three outcomes (normal create / auto-restore / similar-rejection) mirror add_asset. 503 on factor-reasoning or restore-candidate evaluator outage, 502 on malformed restore-candidate response.

edit_attacker

Edit an existing attacker. Only provided fields changed.

The composed likelihood is server-derived from the factor fields; to change the rating, set factor values and supply change_reason for the audit trail.

LLM-gated on identity-bearing fields (capability, archetype, position). Factor and trust_boundary edits skip the gate.

503 on evaluator outage, 502 on malformed response, 400 when factor fields are sent without change_reason.

remove_attackerA

Soft-delete an attacker. Creates a new version.

Same lifecycle as remove_asset: ID preserved, linked COs tombstoned, orphaned controls derived at read time. Use restore_attacker to un-delete.

restore_attacker

Un-soft-delete an attacker. Revives tombstoned COs; un-orphans any linked controls.

reevaluate_threat_model_factors

Re-run the LLM factor judgment on every asset and attacker in a threat model. Useful for re-baselining factors after a bug fix or feature-description change, without regenerating the whole model (which would destroy controls, assertions, components).

Each entity's factors and rationale are replaced with a fresh LLM-judged decomposition; the composed impact / likelihood is re-derived deterministically from the new factors. Each re-rating is recorded as a rating revision in the audit trail with change_reason (default: "LLM factor re-evaluation") so the starting-point regeneration is distinguishable from operator- supplied factor overrides via edit_asset / edit_attacker.

The platform's LLM factor judgment is a starting point. For deployment-specific factor adjustments (e.g., elevated regulatory_scope because your tenant is HIPAA-covered, or Commodity prevalence because your endpoint is public-internet exposed), use edit_asset / edit_attacker afterward with a change_reason documenting the operator override.

Per-entity soft-fail: an LLM failure on one entity is recorded in the response's failed_entities list (with id, kind, and reason); the remaining entities are still re-evaluated and their rating revisions persisted as they complete. The endpoint returns 503 only when every live entity failed — in which case nothing was persisted; retry when the evaluator is reachable.

Soft-deleted assets and attackers are skipped.

recompute_verdicts

Re-run coverage and group-sufficiency verdict evaluation for a model.

Enqueues a fresh evaluation of every control's coverage verdict and every live control objective's group-sufficiency verdict, bypassing the normal quiet-period batching. Evaluation runs in the background; re-read the model's divergence report (or coverage surfaces) shortly after to see updated verdicts.

Cost visibility: the response carries estimated_credits — an informational estimate of the evaluation cost (see also get_recompute_quote for the pre-flight version). Nothing is charged from the estimate; actual usage is metered as the evaluation runs, per the account's plan.

Returns a 503-mapped error when verdict observability is unavailable on the deployment.

get_recompute_quote

Get the informational pre-flight cost estimate for recompute_verdicts on a model.

Nothing is charged from the estimate — actual usage is metered as the evaluation runs. The estimate carries computed_at and the pricing rate_version in force so a stale quote is detectable.

Returns a 503-mapped error when verdict observability is unavailable on the deployment.

revalidate_threat_model_entities

Re-run quality validation on a threat model's existing assets and attackers, as if they were freshly generated. A fast first-pass check judges every entity; only the ones it flags get a deeper review that confirms them, sharpens their wording, or flags them for you.

Use this to apply validation improvements to an already-generated model, or to clear stale quality warnings — without regenerating the whole model (which would destroy controls, assertions, and components). It is non-destructive: an entity that should be removed is left in place with a quality warning rather than deleted, so no control objective loses its asset or attacker anchor. The result is saved as a new model version; controls and control objectives carry forward.

May consume credits for the entities that need the deeper review; a model already in good shape costs nothing. Returns the updated model envelope: {"accepted": true, "model": {...}}.

list_compliance_frameworks

List available compliance frameworks.

Returns built-in frameworks (e.g., OWASP ASVS) and custom frameworks.

import_compliance_framework

Import a custom compliance framework. Requires PRO tier.

Use this when your customer's program (regulatory, contractual, or internal) is not covered by Mipiti's 11 built-in frameworks. After import, the framework is selectable on threat models exactly like a built-in.

Schema (top-level fields): - name (required): framework display name - version (optional): e.g. "1.0" - description (optional): one-paragraph description - level_definitions (optional, level-aware frameworks only): map keyed by stringified integer level ("1", "2", …) because the key IS the cumulative-filter ordinal (level <= target_level) and the level: int field on every requirement. Non-integer keys are rejected with HTTP 400. Human labels are decoupled — "Baseline" / "Hardened" / "SL3" / "CAL Critical" live in the name field, not the key. Each value is {"name", "description", "source"}. Ships the per-level legend to the LLM prompt and the framework-target UI. source is "authoritative" when paraphrased from the published standard, "mipiti_convention" when you defined the tiers yourself. - requirements (required, non-empty list): each entry takes id (required), description (required), level (optional integer, default 1), chapter_id / chapter_name / section_id / section_name / title (optional grouping), scope (optional, "component" default or "system" for requirements covered if ANY model satisfies them), level_specific_text (optional map of per-tier text; same stringified-integer-key rule as level_definitions).

Example minimal body::

{
  "name": "ACME Internal Baseline",
  "version": "2026.1",
  "requirements": [
    {"id": "ACME-1", "description": "All endpoints authenticate", "level": 1},
    {"id": "ACME-2", "description": "TLS 1.3 in transit", "level": 1}
  ]
}

Example with per-level legend + per-requirement parameters::

{
  "name": "ACME Tiered",
  "level_definitions": {
    "1": {"name": "Baseline", "description": "Minimum.",
          "source": "authoritative"},
    "2": {"name": "Hardened", "description": "Sensitive data.",
          "source": "mipiti_convention"}
  },
  "requirements": [
    {"id": "ACME-PWD",
     "description": "Passwords meet policy",
     "level": 1,
     "level_specific_text": {
       "1": "Min 8 characters.",
       "2": "Min 14 + MFA required."
     }}
  ]
}
select_compliance_frameworks

Select compliance frameworks for a threat model. Requires PRO tier.

Selecting a framework automatically triggers auto-remediation in the background: auto-maps existing controls, excludes non-applicable requirements by taxonomy, and suggests/applies new entities for remaining gaps. The response includes auto_remediate_jobs — these run in the background and complete automatically.

get_compliance_report

Get compliance gap analysis report.

Evaluates each framework requirement against mapped controls. By default returns summary; pass status/offset/limit for details.

map_control_to_requirementC

Map a security control to a compliance framework requirement.

auto_map_controls

Use LLM to map controls to framework requirements. Takes 20-45 seconds.

Requires PRO tier.

auto_remediate

Automatically close compliance gaps for a framework. Requires PRO tier.

Three-phase loop: (1) auto-map existing controls to unmapped requirements, (2) exclude requirements for non-applicable taxonomy primitives, (3) suggest and apply new assets/attackers for remaining gaps.

Phase (3) routes every proposal whose name matches a soft-deleted asset/attacker through the same restore-candidate LLM gate add_asset uses, so reanimating a previously removed entity reinstates its stable ID and every CO tombstone + control tied to it (rather than spawning a duplicate fresh ID). The response distinguishes assets_added / attackers_added (genuinely new) from assets_restored / attackers_restored (revived soft- deletes) and lists restored_asset_ids / restored_attacker_ids. Proposals the gate classified as similar (or that fail-closed on an unavailable / malformed gate response) appear under skipped with a per-entry reason — the operator decides whether to restore manually or rephrase.

Converges automatically: stops when fully covered or when no further progress can be made.

This runs automatically when a framework is selected, but can be re-triggered manually if the model changes.

list_workspaces

List workspaces the current user belongs to.

update_organization

Set per-organization level grades for IEC 62443-4-1 and NIST CSF.

Admin-only: the backend requires the caller to be an admin in the organization (or a superadmin). Non-admins will get a 403; do not invoke this tool unless you've verified admin role for the target org.

target_ml is the IEC 62443-4-1 Maturity Level the organization targets for its secure-development program (1-5). csf_tier is the NIST CSF Tier the organization targets for its cybersecurity risk-management posture (1-4).

Because None on the wire is indistinguishable from "field omitted", pass clear_target_ml=True or clear_csf_tier=True to explicitly reset a value to NULL. Omitting both the value and its clear_* flag leaves the existing server-side value untouched.

list_systems

List all saved systems in current workspace.

get_systemB

Get a system container by ID with member model summaries.

create_system

Create a new system container.

add_model_to_system

Add a threat model to a system container.

add_component

Add a component to a threat model.

Components bridge security architecture to code organization. They map trust boundaries to repos so controls can be scoped to the codebase that implements them. They also drive the deterministic reachability composer's asset-boundary derivation: an asset's trust-boundary footprint is the union of its components' trust_boundary_ids.

A component with empty repo_url is speculative — a topology waypoint that hasn't been bound to code yet. The coherence report surfaces these as component_unbound findings. Speculative components are valid in the lifecycle (LLM-proposed during generation, or operator-added during planning); ground them via edit_component once the code exists.

edit_component

Edit a component's properties.

Per-component level grades are orthogonal axes — set whichever apply to the program the component is in scope for. Leave a field unset (None) to keep the current server-side value; backend treats absent fields as "unchanged".

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Mipiti/mipiti-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server