Toulmini
"The purpose of an argument is not to establish the truth of a conclusion, but to justify the right to hold it." — Stephen Toulmin, The Uses of Argument (1958)
A Logic Harness for arguments. Forces LLMs into structured, sequential reasoning through Toulmin's argumentation model—7 components, 4 phases. Bad logic crashes. Good logic flows.
When to Use Toulmini
Holiday dinner getting heated? Uncle says something that doesn't quite add up. Instead of arguing, try: "I wonder what my Logic Harness would say about that."
Toulmini turns debates into structured inquiry. Instead of getting defensive, invite others on the journey of figuring out what actually makes logical sense—together.
Perfect for:
- Family gatherings — When loved ones hold views that seem illogical, explore why instead of fighting
- Philosophical questions — "Would immortality be a curse?" "Is free will an illusion?"
- Contested claims — Force any argument through rigorous logical scrutiny
- Self-reflection — Test your own beliefs before defending them
What is Toulmin's Model?
Stephen Toulmin's argumentation model breaks reasoning into six interconnected components (plus a final verdict):
graph TD
DATA["DATA (Grounds)"] --> CLAIM
BACKING --> WARRANT
WARRANT --> CLAIM
REBUTTAL --> WARRANT
QUALIFIER --> CLAIM
CLAIM --> VERDICT
| Component | Purpose | Example ("Would immortality be a curse?") |
|---|---|---|
| DATA | Raw facts/evidence (must be cited) | "Terror Management Theory shows meaning derives from mortality awareness" |
| CLAIM | Assertion based only on the data | "Immortality constitutes a psychological curse" |
| WARRANT | Logical principle connecting data to claim | "If well-being depends on mortality awareness, removing mortality eliminates flourishing" |
| BACKING | Authority supporting the warrant | "Heidegger, Becker, empirical TMT research" |
| REBUTTAL | Conditions where the warrant fails | "Unless meaning can arise from sources unrelated to death awareness" |
| QUALIFIER | Degree of certainty | "Possibly" (45% confidence) |
| VERDICT | Final synthesis | "REMANDED" — insufficient empirical grounding |
The 4 Tools
Phase 1: initiate_toulmin_sequence
Starts the analysis. Extracts DATA and constructs CLAIM.
- Input:
query(str) - "Is this copyright infringement?" - Output: Structured prompt → JSON with data + claim
Phase 2: inject_logic_bridge
Builds the logical bridge: WARRANT and BACKING.
- Input:
query,data_json,claim_json - Output: Structured prompt → JSON with warrant + backing
⚠️ HARD REJECTION: If strength == "weak" or "irrelevant", chain terminates.
Phase 3: stress_test_argument
Adversarial attack: REBUTTAL and QUALIFIER.
- Input:
query,data_json,claim_json,warrant_json,backing_json - Output: Structured prompt → JSON with rebuttal + qualifier
Must find "black swan" scenarios where the warrant fails.
Phase 4: render_verdict
Final judgment on the complete 6-part chain.
- Input: All 6 component JSONs +
query - Output: Structured prompt → JSON with verdict
Verdicts: SUSTAINED | OVERRULED | REMANDED
Execution Flow (The "Toulmin Loop")
Each phase consists of two distinct steps:
- Tool Call: The MCP server returns a strict system directive (Prompt).
- LLM Generation: The LLM follows that directive to generate structured JSON.
Query: "Would immortality be a curse?"
Phase 1: Grounding
- Tool Call:
initiate_toulmin_sequence(query) - LLM Generates:
- DATA: Terror Management Theory, hedonic adaptation research
- CLAIM: "Immortality constitutes a psychological curse..."
Phase 2: Logic Bridge
- Tool Call:
inject_logic_bridge(query, data, claim) - LLM Generates:
- WARRANT: "If well-being depends on mortality awareness..."
- BACKING: Heidegger, Becker, empirical TMT research
- Strength Check: "strong" ✓
Phase 3: Stress Test
- Tool Call:
stress_test_argument(...) - LLM Generates:
- REBUTTAL: Category error (mortal→immortal psychology)
- QUALIFIER: "possibly" (45% confidence)
Phase 4: Judgment
- Tool Call:
render_verdict(...) - LLM Generates:
- VERDICT: "REMANDED" - insufficient empirical grounding
See examples/ for complete JSON traces.
Why This Exists
LLMs tend to hedge, compromise, or give "balanced" answers without confronting genuine contradictions. Toulmini forces separation:
- No hedging in claims — qualifiers come later
- No skipping steps — can't render verdict without rebuttal
- Hard rejection of weak backing — stops the chain if support is speculative
- Adversarial stress testing — must find "black swan" edge cases
Architectural Constraints
| Constraint | Enforcement |
|---|---|
| No external API calls | Local-only, your LLM only |
| Strict schemas | Pydantic validation on all components |
| Sequential dependencies | Phase N requires Phases 1..N-1 |
| JSON-only output | Prompts forbid conversational responses |
| Stderr logging | STDIO-safe (no stdout pollution) |
Project Structure
toulmini/
├── pyproject.toml
├── README.md
├── verify_toulmini.py # Verification script
├── examples/ # Full reasoning traces
└── src/toulmini/
├── __init__.py
├── server.py # MCP entry point (FastMCP)
├── prompts.py # 4 JSON-forcing prompt templates
└── models/
├── __init__.py
├── base.py # Citation, Literal types
├── components.py # 7 Toulmin components
└── chain.py # ToulminChain aggregate
Failure Modes
| Condition | Result |
|---|---|
warrant.strength == "weak" |
Chain terminates |
backing.strength == "weak" |
Chain terminates |
rebuttal.strength == "absolute" |
Verdict must be "overruled" |
qualifier.confidence_pct < 30 |
Verdict should be "overruled" or "remanded" |
| Missing prior phase output | Tool returns error JSON |
Installation & Configuration
Prerequisites
- Python 3.10+
- pip or uv
Install Toulmini
pip install toulmini
Or for development:
git clone https://github.com/Hmbown/Toulmini.git
cd Toulmini
pip install -e .
Configure Your MCP Client
Claude Code (CLI)
The fastest way to add Toulmini:
claude mcp add toulmini --scope user -- python -m toulmini.server
Verify it's connected:
claude mcp list
Then in any Claude Code session, type /mcp to see Toulmini's status.
Alternative scopes:
--scope user— Available in all your projects--scope project— Shared with your team via.mcp.json- No flag — Local to current project only
Claude Desktop (macOS/Windows/Linux)
1. Find your config file:
| Platform | Location |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
| Linux | ~/.config/Claude/claude_desktop_config.json |
2. Add Toulmini to the config:
{
"mcpServers": {
"toulmini": {
"command": "python",
"args": ["-m", "toulmini.server"]
}
}
}
3. Restart Claude Desktop completely (not just refresh).
4. Verify: Ask Claude to use one of the Toulmini tools, or check the Developer Console.
Cursor
1. Open Cursor Settings → Features → MCP Servers
2. Add a new server with this configuration:
{
"toulmini": {
"command": "python",
"args": ["-m", "toulmini.server"]
}
}
3. Save and restart Cursor.
Windsurf
1. Open Windsurf Settings → MCP Configuration
2. Add Toulmini:
{
"mcpServers": {
"toulmini": {
"command": "python",
"args": ["-m", "toulmini.server"]
}
}
}
3. Restart Windsurf.
Verify Installation
Run the verification script:
python verify_toulmini.py
Or test manually by asking your AI assistant:
"Use the initiate_toulmin_sequence tool to analyze: Would immortality be a curse?"
Troubleshooting
| Issue | Solution |
|---|---|
| Server not found | Ensure toulmini is installed: pip show toulmini |
| Connection failed | Check Python is in your PATH |
| JSON parse error | Validate your config file syntax |
| Tools not appearing | Restart your client completely |
Inspired By
- Hegelion — Dialectical reasoning (thesis/antithesis/synthesis)
- Stephen Toulmin, The Uses of Argument (1958)
License
MIT
Development
Running Tests
To run the tests, install pytest and mcp[cli], then run:
PYTHONPATH=src pytest
Metadata
Release files for toulmini 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| toulmini-1.0.0.tar.gz | 151.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| toulmini-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 166.6 kB
Release files / toulmini-1.0.0.tar.gz
| Download URL | toulmini-1.0.0.tar.gz |
|---|---|
| Size | 151.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d5d6c0ee223dd8667166b0393115ba57bad008011656d93ab236bf33ca422252
|
|
BLAKE2b-256 checksum How to use checksums |
8bd576091f1666001067d7f03aac8095b307474d37c5d1ccb9c48eaa4769db0d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 28, 2025.
Transparency logRelease files / toulmini-1.0.0-py3-none-any.whl
| Download URL | toulmini-1.0.0-py3-none-any.whl |
|---|---|
| Size | 15.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
85d1700ce51dac129894dd0c83b233cef8ce243f6169ace34f709db7ec3460e1
|
|
BLAKE2b-256 checksum How to use checksums |
7267563ea5d096849613c90f0d4fd8c41900e09c59d08b59e5daaa99223011a8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 28, 2025.
Transparency log