Skip to main content
27 tools in four groups. Decision tools need no API key. Authoring tools require an Aethis API key and your own Anthropic API key for generation.

Decision tools

No API key required. Safe to call from any environment.

aethis_decide

Evaluate eligibility against either a single published ruleset (ruleset_id) or a composed rulebook (rulebook_id). Provide exactly one.
ParameterTypeRequiredDescription
ruleset_idstringconditionalSingle published ruleset — slug (aethis/uk-fsm/child-eligibility) or opaque ID. Mutually exclusive with rulebook_id. Anonymous decide works for public rulesets.
rulebook_idstringconditionalComposed rulebook — slug (aethis/uk-fsm) or opaque rb_<id>. Mutually exclusive with ruleset_id. Always requires an API key — anonymous callers get HTTP 401. (Available in aethis-mcp v0.7.0+.)
field_valuesobjectyesInput fields — see aethis_schema for expected names and types
include_tracebooleannoInclude evaluation trace showing how each criterion was evaluated
include_explanationbooleannoInclude human-readable rule descriptions with source references
aethis_decide({
  ruleset_id: "aethis/uk-fsm/child-eligibility",
  field_values: { "child.age": 10, "child.school_type": "state_funded" },
  include_trace: true,
  include_explanation: true
})
Composed rulebook variant — combines every live ruleset under the rulebook via its outcome_logic:
aethis_decide({
  rulebook_id: "aethis/uk-fsm",
  field_values: { "child.age": 10, "child.year_group": "year_6", "child.school_type": "state_funded",
                  "household.receives_universal_credit": true, "household.annual_net_earnings": 5000 }
})
{
  "decision": "eligible",
  "fields_provided": 2,
  "fields_evaluated": 2,
  "trace": {
    "status": "eligible",
    "group_statuses": {
      "school_type_check": "satisfied",
      "age_check": "satisfied"
    }
  },
  "explanation": [
    {
      "criterion_id": "relevant_school",
      "group": "school_type_check",
      "title": "Pupil attends a relevant school",
      "rule_text": "child.school_type equals \"state_funded\""
    },
    {
      "criterion_id": "age_range",
      "group": "age_check",
      "title": "Child is aged 4 to 15 inclusive",
      "rule_text": "( AND child.age is at least 4 AND child.age is at most 15)"
    }
  ]
}
When the decision is undetermined, the response also includes next_question, optimal_path, and missing_fields.

aethis_schema

Get the input fields required for an eligibility check.
ParameterTypeRequiredDescription
ruleset_idstringyesPublished rule ruleset ID
aethis_schema({ ruleset_id: "aethis/uk-fsm/child-eligibility" })
{
  "ruleset_id": "aethis/uk-fsm/child-eligibility",
  "fields": [
    {
      "key": "child.age",
      "sort": "Int",
      "description": "Age of the child in years at the start of the school year."
    },
    {
      "key": "child.school_type",
      "sort": "Enum",
      "enum_values": ["state_funded", "independent", "home_educated"],
      "description": "Type of school the child attends."
    }
  ]
}
Call before aethis_decide to discover what fields to provide.

aethis_next_question

Conversational eligibility — returns the optimal next question given answers so far. Call with empty field_values for the first question, then add each answer and call again until a decision is reached.
ParameterTypeRequiredDescription
ruleset_idstringyesPublished rule ruleset ID
field_valuesobjectyesAnswers collected so far — {} for first call
aethis_next_question({
  ruleset_id: "aethis/uk-fsm/child-eligibility",
  field_values: {}
})
Decision: undetermined (0/2 fields provided)

Next question to ask:
  Field: child.age
  Question: How old was the child at the start of the school year (on 1 September)?
  Priority weight: 2 (lower = more important)
  Notes:
    - [why] <api_response label="note_why">
The rules treat a child as 'under 16' based on their age at the start of the
school year. A child must be at least 4 (Reception age) and under 16 to be in scope.
</api_response>
    - [legal_background] <api_response label="note_legal_background">
Compulsory school age is assessed at 1 September of the relevant academic year
(Education Act 1996, s.8; FSM Regulations 2014, Regulation 3(1)-(2)).
</api_response>

Full remaining path (2 questions):
  1. How old was the child at the start of the school year? (child.age, weight=2)
  2. What type of school does the child attend? (child.school_type, weight=3)

All missing fields: child.age, child.school_type
notes (aethis-mcp v0.10.0+): when the ruleset’s author attached notes to a question, aethis_next_question renders them under a Notes block. Each line is - [<metadata.type>] <note>, where metadata.type labels the note (why, legal_background, and so on). Because a note is author-provided free text returned by the API, its body is wrapped in an <api_response label="note_..."> fence: untrusted-content hardening, so a note can never reach the model as an instruction. When the author attached no notes, the block is omitted entirely. The notes are grounded in the ruleset’s provenance, not the model’s general knowledge. The engine evaluates all paths simultaneously — the remaining path shows the 2 questions needed to reach the section-A decision. For richer multi-section flows that demonstrate ORed alternative routes, evaluate the composed rulebook (rulebook_id: "aethis/uk-fsm", API key required) — the engine surfaces a 9–11 question path across Sections B and C. After answering both child-eligibility fields:
aethis_next_question({
  ruleset_id: "aethis/uk-fsm/child-eligibility",
  field_values: {
    "child.age": 10,
    "child.school_type": "state_funded"
  }
})
Decision: eligible. No more questions needed.

aethis_explain

Human-readable descriptions of every rule compiled into a ruleset.
ParameterTypeRequiredDescription
ruleset_idstringyesPublished rule ruleset ID
aethis_explain({ ruleset_id: "aethis/uk-fsm/child-eligibility" })
{
  "ruleset_id": "aethis/uk-fsm/child-eligibility",
  "criteria": [
    {
      "criterion_id": "age_eligibility",
      "group": "age_eligibility",
      "title": "Child is aged 4 to 15 at the start of the school year",
      "rule_text": "( AND child.age is at least 4 AND child.age is at most 15)"
    },
    {
      "criterion_id": "school_type_eligibility",
      "group": "school_type_eligibility",
      "title": "Child attends a state-funded (relevant) school",
      "rule_text": "child.school_type equals \"state_funded\""
    }
  ]
}
Use for audit documentation, compliance review, or surfacing rule logic to end users.

aethis_explain_failure

Diagnose why a ruleset produced an unexpected outcome for specific test inputs.
ParameterTypeRequiredDescription
ruleset_idstringyesRuleset to diagnose
field_valuesobjectyesTest input values that produced the unexpected result
expected_outcomestringyes"eligible", "not_eligible", or "undetermined"
test_namestringnoName of the failing test case (included in diagnosis)
aethis_explain_failure({
  ruleset_id: "aethis/uk-fsm/child-eligibility",
  field_values: { "child.age": 10, "child.school_type": "independent" },
  expected_outcome: "not_eligible",
  test_name: "Age 10, independent school — not eligible"
})
Returns the actual vs. expected outcome, the specific criterion that failed, a diagnosis explaining why, and a suggested guidance hint to fix it:
{
  "actual_outcome": "eligible",
  "expected_outcome": "not_eligible",
  "is_failure": true,
  "diagnosis": "The compiled rule checks age only. The school_type constraint is missing.",
  "dsl_hint": "Add guidance: Regulation 3(2)(b) restricts eligibility to state-funded schools.",
  "criteria": [
    {
      "criterion_id": "age_range",
      "group": "age_check",
      "title": "Child is aged 4 to 15 inclusive",
      "rule_text": "( AND child.age >= 4 AND child.age <= 15)"
    }
  ],
  "group_statuses": { "age_check": "satisfied" }
}

Section and field discovery

Decompose legislation into sections and discover input fields. API key required. Anthropic key required for discovery (bring your own key).
Bring-your-own LLM key. Discovery and generation tools call an Anthropic model on your behalf and accept the key per request; it is used only for that request and never stored. Three forms, in order of preference:
  • anthropic_key_env (preferred) — the name of an environment variable (set in your MCP client config) that holds the key. The raw value never appears in the tool call, so it never lands in the host’s session transcript.
  • anthropic_key_keychain (preferred on macOS) — a keychain reference, either service:account or just account (service defaults to aethis-anthropic-key). The server reads it via the security command at call time.
  • anthropic_key (deprecated) — the raw key as a string. Passing it as a tool argument writes the key verbatim into the host’s session transcript, so prefer a reference form above.
Pass exactly one. Every tool that needs a model accepts all three; the tables below show anthropic_key for brevity, but it is optional, never required.

aethis_discover_sections

Propose how to split source legislation into independently testable sections.
ParameterTypeRequiredDescription
domainstringyesDomain identifier (e.g. "uk_fsm")
sourcesarrayyesSource documents: [{ name: "...", content: "..." }] (1–10)
anthropic_keystringnoOptional, deprecated. Prefer anthropic_key_env / anthropic_key_keychain (see the note above); a raw key here lands in the session transcript. Used for this request only, never stored.
aethis_discover_sections({
  domain: "uk_fsm",
  sources: [
    { name: "Education Act 1996", content: "Section 512 — Provision of meals..." },
    { name: "FSM Regulations 2014", content: "Regulation 3 — Persons who..." }
  ],
  anthropic_key: "sk-ant-..."
})
Returns proposed sections with names, descriptions, keywords, and a confidence score.

aethis_validate_sections

Compare discovered sections against an expected list.
ParameterTypeRequiredDescription
domainstringyesDomain identifier
expected_sectionsarrayyesSection names the SME expects (snake_case)
discovered_sectionsarrayyesSection names returned by aethis_discover_sections
aethis_validate_sections({
  domain: "uk_fsm",
  expected_sections: ["child_eligibility", "household_qualifying_criteria", "universal_infant_fsm"],
  discovered_sections: ["child_eligibility", "household_benefits", "universal_infant_fsm"]
})
Returns match count, missing sections (expected but not found), and extra sections (found but not expected).

aethis_refine_sections

Add guidance to improve section discovery, then re-discover.
ParameterTypeRequiredDescription
domainstringyesDomain identifier
feedbackstringyesWhat was wrong and how to fix it — reference specific legislation
sourcesarrayyesSame source documents used in the initial discovery
anthropic_keystringnoOptional, deprecated. Prefer anthropic_key_env / anthropic_key_keychain (see the note above); a raw key here lands in the session transcript.
aethis_refine_sections({
  domain: "uk_fsm",
  feedback: "Rename 'household_benefits' to 'household_qualifying_criteria' — it covers Regulation 4 qualifying criteria, not just benefits.",
  sources: [...],
  anthropic_key: "sk-ant-..."
})

aethis_set_field_spec

Store expected fields for a project. Once set, every aethis_discover_fields call auto-validates against this spec.
ParameterTypeRequiredDescription
project_idstringyesProject ID
expected_fieldsarrayyes[{ key, sort, enum_values? }]
aethis_set_field_spec({
  project_id: "proj_8CzLVwyx53rTGEJv",
  expected_fields: [
    { key: "child.age", sort: "Int" },
    { key: "child.school_type", sort: "Enum", enum_values: ["state_funded", "independent", "home_educated"] }
  ]
})
Field types: Bool, Int, Enum, Date, Duration, String.

aethis_discover_fields

Discover input fields from the project’s source text. Run before writing test cases.
ParameterTypeRequiredDescription
project_idstringyesProject ID
anthropic_keystringnoOptional, deprecated. Prefer anthropic_key_env / anthropic_key_keychain (see the note above); a raw key here lands in the session transcript. Used for this request only, never stored.
Returns fields with name, type, description, enum values, a completeness score (0–1), and any missing pathways. If a field spec was set, also returns validation results.

aethis_validate_fields

Explicit validation of discovered fields against an expected spec.
ParameterTypeRequiredDescription
project_idstringyesProject ID
expected_fieldsarrayyes[{ key, sort, enum_values? }] — same format as aethis_set_field_spec
Returns PASS/FAIL with lists of: missing fields, type mismatches, enum value mismatches, and extra discovered fields.

aethis_refine_fields

Add guidance to improve field discovery, then re-discover.
ParameterTypeRequiredDescription
project_idstringyesProject ID
feedbackstringyesWhat was wrong — reference specific source text
anthropic_keystringnoOptional, deprecated. Prefer anthropic_key_env / anthropic_key_keychain (see the note above); a raw key here lands in the session transcript.
aethis_refine_fields({
  project_id: "proj_8CzLVwyx53rTGEJv",
  feedback: "Section 512ZA defines 'relevant school' as maintained schools and Academies only. Add child.school_type as an Enum with values: state_funded, independent, home_educated.",
  anthropic_key: "sk-ant-..."
})

Rule generation

Create, iterate, and publish rule rulesets. API key required. Anthropic key required for generation — see the bring-your-own LLM key note above for the preferred anthropic_key_env / anthropic_key_keychain forms.

aethis_create_ruleset

Create a new project with source text and test cases.
ParameterTypeRequiredDescription
namestringyesHuman-readable name
section_idstringyesUnique section identifier (e.g. "child_eligibility")
source_textstringyesSource legislation, policy, or specification text
test_casesarrayyes[{ name, field_values, expected_outcome }] — at least 1
domainstringnoDomain hint (e.g. "uk_fsm")
aethis_create_ruleset({
  name: "Child eligibility gate",
  section_id: "child_eligibility",
  domain: "uk_fsm",
  source_text: "Section 512 — Provision of meals...",
  test_cases: [
    { name: "Age 4, state school — eligible", field_values: { "child.age": 4, "child.school_type": "state_funded" }, expected_outcome: "eligible" },
    { name: "Age 3, state school — too young", field_values: { "child.age": 3, "child.school_type": "state_funded" }, expected_outcome: "not_eligible" }
  ]
})
Returns project_id. Use this ID for all subsequent calls.

aethis_generate_and_test

Generate rules from source text and run all test cases. Takes 60–120 seconds.
ParameterTypeRequiredDescription
project_idstringyesProject ID from aethis_create_ruleset
anthropic_keystringnoOptional, deprecated. Prefer anthropic_key_env / anthropic_key_keychain (see the note above); a raw key here lands in the session transcript. Used for this request only, never stored.
aethis_generate_and_test({
  project_id: "proj_8CzLVwyx53rTGEJv",
  anthropic_key: "sk-ant-..."
})
Returns pass/fail count, individual test results, and for failures: the criterion that failed and a hint for fixing it.

aethis_refine

Add optional guidance, then make the minimal edit to fix failing tests — seeded from the section’s active ruleset, keeping passing tests green — and re-run the full suite. This is incremental re-authoring: it does not rebuild the section from scratch (use aethis_generate_and_test for that). Available in aethis-mcp v0.9.0+.
ParameterTypeRequiredDescription
project_idstringyesProject ID
feedbackstringnoGuidance text — must reference specific source clauses
anthropic_keystringnoOptional, deprecated. Prefer anthropic_key_env / anthropic_key_keychain (see the note above); a raw key here lands in the session transcript. Used for this request only, never stored.
aethis_refine({
  project_id: "proj_8CzLVwyx53rTGEJv",
  feedback: "Regulation 3(2)(b) restricts eligibility to state-funded schools. Independent schools and home-educated children are excluded.",
  anthropic_key: "sk-ant-..."
})
Returns the same output as aethis_generate_and_test — pass/fail count with test results.

aethis_add_guidance

Add a guidance hint without regenerating. Use to accumulate multiple hints before triggering a run.
ParameterTypeRequiredDescription
project_idstringyesProject ID
guidance_textstringyesDomain knowledge or correction — reference specific source text
process_typestringno"rule_generation" (default) or "field_extraction"
adherencestringno"exact", "guided" (default), or "loose"
process_type controls which authoring phase the hint targets:
  • "rule_generation" — influences how rules are compiled from source text
  • "field_extraction" — influences how input fields are discovered
adherence controls how strictly the LLM must follow the hint:
  • "exact" — must follow precisely
  • "guided" — strong preference (default)
  • "loose" — suggestion only

aethis_add_domain_guidance

Add guidance that applies to all projects in a domain — use for cross-section principles.
ParameterTypeRequiredDescription
domainstringyesDomain identifier
guidance_textstringyesCross-section guidance
process_typestringno"rule_generation", "field_extraction", or "section_discovery"
adherencestringno"exact", "guided" (default), or "loose"
notesstringnoSME commentary or provenance — never sent to LLM
aethis_add_domain_guidance({
  domain: "uk_fsm",
  guidance_text: "Use child.* prefix for child fields, household.* for household fields.",
  process_type: "field_extraction",
  adherence: "exact"
})

aethis_list_guidance / aethis_list_domain_guidance

List all guidance hints for a project or domain.
ParameterTypeRequiredDescription
project_idstringyes (list_guidance)Project ID
domainstringyes (list_domain_guidance)Domain identifier

aethis_publish

Publish the current rule ruleset. Runs tests first — refuses if any fail unless force: true.
ParameterTypeRequiredDescription
project_idstringyesProject ID
forcebooleannoPublish even if tests are failing
labelstringnoHuman-readable version label
namestringnoOverride the human-readable section name. When omitted, the ruleset keeps the name set at generation time (a titlecase of section_id, e.g. english_languageEnglish Language). Section names are surfaced in rulebook responses.
aethis_publish({
  project_id: "proj_8CzLVwyx53rTGEJv",
  label: "v1 — child eligibility gate (age 4–15, state-funded schools)"
})
Returns ruleset_id, version, and test pass count. Auto-deprecates the previous active ruleset.

Discovery and management

aethis_discover_rulesets

Browse the public showcase catalogue across all tenants. No API key required — the no-auth entry point for first-time discovery and demos. Returns slug, ruleset_id, name (the human-readable section title), description, field_count, and rule_count for each; pass a slug or ruleset_id to aethis_decide / aethis_schema / aethis_explain. Distinct from aethis_list_rulesets, which is tenant-scoped.
ParameterTypeRequiredDescription
limitnumbernoMaximum rulesets to return (default 20, max 50)
offsetnumbernoPagination offset (default 0)

aethis_list_rulebooks

List rulebooks — composed wholes that bridge multiple rulesets — in the current tenant. No parameters. Returns rulebook_id, slug (e.g. aethis/uk-fsm), name, domain, status (draft / active / archived), version, outcome_logic (the composition Expr AST), ruleset_refs, and timestamps. Tenant-scoped — requires an API key. Pass a returned rulebook_id or slug to aethis_decide (as rulebook_id) or aethis_rulebook_schema.

aethis_rulebook_schema

Get the composition and aggregated input fields for a rulebook. Returns the outcome_logic Expr AST (how the bridged rulesets compose, e.g. A AND (B OR C)), the list of bridged rulesets (ruleset_name, ruleset_id, slug, status), and the union of all required input fields. Call this before aethis_decide on a rulebook_id to know what field_values to supply.
ParameterTypeRequiredDescription
rulebook_idstringyesRulebook slug (e.g. aethis/uk-fsm) or opaque rb_<id>

aethis_list_projects

List all projects. No parameters. Returns project IDs, names, domains, and latest ruleset info.

aethis_list_rulesets

List all rulesets for a project.
ParameterTypeRequiredDescription
project_idstringyesProject ID

aethis_archive_project / aethis_archive_ruleset

Permanently archive a project or ruleset. Archived items are preserved but excluded from listings and /decide resolution.
ParameterTypeRequiredDescription
project_idstringyes (archive_project)Project to archive
ruleset_idstringyes (archive_ruleset)Ruleset to archive

Common workflows

Evaluate eligibility (2 calls)

aethis_schema({ ruleset_id })          → field names, types, enum values
aethis_decide({ ruleset_id, fields })  → eligible / not_eligible / undetermined

Conversational evaluation (loop)

aethis_next_question({ ruleset_id, field_values: {} })        → first question
aethis_next_question({ ruleset_id, field_values: { ... } })   → next question or decision
// Repeat until decision is reached

Single-section authoring

aethis_create_ruleset(name, section_id, source_text, test_cases)  → project_id
aethis_discover_fields(project_id)                                → confirm field names
                                                                  → write test cases
aethis_generate_and_test(project_id)                              → run tests
aethis_refine(project_id, feedback) × N                           → iterate on failures
aethis_publish(project_id)                                        → ruleset_id

Multi-section authoring (three phases)

Phase 1 — sections (once per domain):
aethis_discover_sections(domain, sources)
aethis_validate_sections(domain, expected, discovered)
aethis_refine_sections(domain, feedback, sources)     // if wrong
Phase 2 — fields (per section):
aethis_set_field_spec(project_id, expected_fields)    // optional, recommended
aethis_discover_fields(project_id)
aethis_validate_fields(project_id, expected_fields)   // explicit gate
aethis_refine_fields(project_id, feedback)            // if wrong
Phase 3 — rules (per section):
aethis_create_ruleset(...)
aethis_generate_and_test(project_id)
aethis_refine(project_id, feedback)     // repeat until all pass
aethis_publish(project_id)             → ruleset_id
See Section discovery, Field vocabulary, and Rule generation for detailed guidance.