Argumentation model: 7 components, 4 phases. Bad logic crashes. Good logic flows.
Project description
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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file toulmini-1.0.0.tar.gz.
File metadata
- Download URL: toulmini-1.0.0.tar.gz
- Upload date:
- Size: 151.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d5d6c0ee223dd8667166b0393115ba57bad008011656d93ab236bf33ca422252
|
|
| MD5 |
48a46aace8331f04b769f9357c32115c
|
|
| BLAKE2b-256 |
8bd576091f1666001067d7f03aac8095b307474d37c5d1ccb9c48eaa4769db0d
|
Provenance
The following attestation bundles were made for toulmini-1.0.0.tar.gz:
Publisher:
publish.yml on Hmbown/Toulmini
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
toulmini-1.0.0.tar.gz -
Subject digest:
d5d6c0ee223dd8667166b0393115ba57bad008011656d93ab236bf33ca422252 - Sigstore transparency entry: 731067207
- Sigstore integration time:
-
Permalink:
Hmbown/Toulmini@d17d4f45c2fb56ebd7d3cbc5b9053e05ff4714ab -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/Hmbown
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d17d4f45c2fb56ebd7d3cbc5b9053e05ff4714ab -
Trigger Event:
release
-
Statement type:
File details
Details for the file toulmini-1.0.0-py3-none-any.whl.
File metadata
- Download URL: toulmini-1.0.0-py3-none-any.whl
- Upload date:
- Size: 15.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
85d1700ce51dac129894dd0c83b233cef8ce243f6169ace34f709db7ec3460e1
|
|
| MD5 |
000c1736354c14b8fe0f3ab8d29754c3
|
|
| BLAKE2b-256 |
7267563ea5d096849613c90f0d4fd8c41900e09c59d08b59e5daaa99223011a8
|
Provenance
The following attestation bundles were made for toulmini-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on Hmbown/Toulmini
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
toulmini-1.0.0-py3-none-any.whl -
Subject digest:
85d1700ce51dac129894dd0c83b233cef8ce243f6169ace34f709db7ec3460e1 - Sigstore transparency entry: 731067210
- Sigstore integration time:
-
Permalink:
Hmbown/Toulmini@d17d4f45c2fb56ebd7d3cbc5b9053e05ff4714ab -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/Hmbown
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d17d4f45c2fb56ebd7d3cbc5b9053e05ff4714ab -
Trigger Event:
release
-
Statement type: