mental-models-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. mental_models_mcp-0.1.0/LICENSE +21 -0
  2. mental_models_mcp-0.1.0/MANIFEST.in +3 -0
  3. mental_models_mcp-0.1.0/PKG-INFO +133 -0
  4. mental_models_mcp-0.1.0/README.md +105 -0
  5. mental_models_mcp-0.1.0/pyproject.toml +70 -0
  6. mental_models_mcp-0.1.0/setup.cfg +4 -0
  7. mental_models_mcp-0.1.0/src/mental_models_mcp/__init__.py +5 -0
  8. mental_models_mcp-0.1.0/src/mental_models_mcp/__main__.py +6 -0
  9. mental_models_mcp-0.1.0/src/mental_models_mcp/catalog.py +211 -0
  10. mental_models_mcp-0.1.0/src/mental_models_mcp/data/index.json +287 -0
  11. mental_models_mcp-0.1.0/src/mental_models_mcp/py.typed +0 -0
  12. mental_models_mcp-0.1.0/src/mental_models_mcp/router.py +177 -0
  13. mental_models_mcp-0.1.0/src/mental_models_mcp/server.py +310 -0
  14. mental_models_mcp-0.1.0/src/mental_models_mcp/telemetry.py +247 -0
  15. mental_models_mcp-0.1.0/src/mental_models_mcp/updates.py +153 -0
  16. mental_models_mcp-0.1.0/src/mental_models_mcp.egg-info/PKG-INFO +133 -0
  17. mental_models_mcp-0.1.0/src/mental_models_mcp.egg-info/SOURCES.txt +22 -0
  18. mental_models_mcp-0.1.0/src/mental_models_mcp.egg-info/dependency_links.txt +1 -0
  19. mental_models_mcp-0.1.0/src/mental_models_mcp.egg-info/entry_points.txt +3 -0
  20. mental_models_mcp-0.1.0/src/mental_models_mcp.egg-info/requires.txt +6 -0
  21. mental_models_mcp-0.1.0/src/mental_models_mcp.egg-info/top_level.txt +1 -0
  22. mental_models_mcp-0.1.0/tests/test_catalog_and_router.py +113 -0
  23. mental_models_mcp-0.1.0/tests/test_e2e_stdio.py +97 -0
  24. mental_models_mcp-0.1.0/tests/test_telemetry_redaction.py +62 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Surendran B
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,3 @@
1
+ include README.md
2
+ include LICENSE
3
+ recursive-include src/mental_models_mcp/data *.json
@@ -0,0 +1,133 @@
1
+ Metadata-Version: 2.4
2
+ Name: mental-models-mcp
3
+ Version: 0.1.0
4
+ Summary: Multi-disciplinary mental models, cognitive orientation coaching, and dialectical reasoning engine for AI agents and humans. Zero API keys.
5
+ Author-email: Surendran B <reachsuren@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://mental-models.builditwithai.xyz
8
+ Project-URL: Repository, https://github.com/surendranb/mental-models-mcp
9
+ Project-URL: Issues, https://github.com/surendranb/mental-models-mcp/issues
10
+ Keywords: mental-models,munger-latticework,decision-making,cognitive-coaching,systems-thinking,first-principles,inversion,mcp,mcp-server,model-context-protocol,ai-agent,claude,claude-code,cursor
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: mcp<3,>=2.0.0
23
+ Requires-Dist: requests>=2.31.0
24
+ Provides-Extra: dev
25
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
26
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
27
+ Dynamic: license-file
28
+
29
+ # Mental Models MCP
30
+
31
+ > Multi-disciplinary mental models, cognitive orientation coaching, and dialectical reasoning engine for AI agents and humans. Zero API keys required.
32
+
33
+ `mental-models-mcp` equips AI assistants and human decision-makers with Charlie Munger's latticework of mental models across systems thinking, decision analysis, strategic risk, cognitive biases, and first-principles engineering.
34
+
35
+ Built for anyone navigating high-stakes decisions under uncertainty—software engineers evaluating architectural forks, founders choosing product trade-offs, analysts diagnosing systemic incidents, researchers stress-testing hypotheses, and autonomous AI agents seeking to avoid agreeable sycophancy.
36
+
37
+ ---
38
+
39
+ ## Quickstart
40
+
41
+ ### Option A — Any MCP Harness (incl. Claude Desktop, Cursor, Antigravity, Windsurf)
42
+
43
+ Add to your client configuration:
44
+
45
+ ```json
46
+ {
47
+ "mcpServers": {
48
+ "mental-models": {
49
+ "command": "uvx",
50
+ "args": ["mental-models-mcp"]
51
+ }
52
+ }
53
+ }
54
+ ```
55
+
56
+ Or via NPX:
57
+
58
+ ```json
59
+ {
60
+ "mcpServers": {
61
+ "mental-models": {
62
+ "command": "npx",
63
+ "args": ["-y", "mental-models-mcp"]
64
+ }
65
+ }
66
+ }
67
+ ```
68
+
69
+ ### Option B — Claude Code CLI Plugin
70
+
71
+ ```bash
72
+ claude plugin marketplace add surendranb/mental-models-mcp
73
+ claude plugin install mental-models-mcp
74
+ ```
75
+
76
+ ### Option C — Standalone CLI Execution
77
+
78
+ ```bash
79
+ uvx mental-models-mcp
80
+ ```
81
+
82
+ ---
83
+
84
+ ## Core Tools
85
+
86
+ 1. **`route_mental_model(problem, domain, problem_type)`**:
87
+ Lightweight L0 index scoring candidate frameworks against your situation. Defaults to `status: "NONE"` on routine syntax or trivial formatting tasks to conserve context tokens.
88
+ 2. **`get_mental_model(model_id, mode)`**:
89
+ Fetches the operational playbook for a mental model with 4 execution modes:
90
+ - `checklist` *(Default)*: Step-by-step thinking protocol, failure boundaries, and diagnostic probing questions.
91
+ - `explain`: Core principle, historical origin, and worked engineering example.
92
+ - `challenge_assumptions`: Dialectical anti-sycophancy sparring to uncover confirmation bias and unstated assumptions.
93
+ - `full`: Complete unabridged markdown playbook.
94
+ 3. **`list_mental_models(category, discipline)`**:
95
+ Categorical and topical exploration across the 150-model master taxonomy.
96
+ 4. **`skills_list()` / `skill_read(name)`**:
97
+ Dynamic runtime onboarding and reference guides fetched live from GitHub with local fallback.
98
+ 5. **`check_for_updates()`**:
99
+ PyPI version verification and automated upgrade hints.
100
+
101
+ ---
102
+
103
+ ## Catalog & Taxonomy
104
+
105
+ The latticework indexes **150 mental models** across 12 disciplines:
106
+ - Systems Thinking (Feedback Loops, Theory of Constraints, Tragedy of the Commons)
107
+ - Decision Analysis (First Principles, Inversion, Opportunity Cost, Two-Way Doors)
108
+ - Strategic Risk (Antifragility, Chesterton's Fence, Cynefin Framework, Lindy Effect, Via Negativa)
109
+ - Cognitive Biases (Confirmation Bias, Hanlon's Razor, Incentive-Caused Bias, Sunk Cost Fallacy)
110
+ - First-Principles Engineering (Conway's Law, Gall's Law, Goodhart's Law, Occam's Razor)
111
+ - Computer Systems (Little's Law, CAP Theorem, Backpressure, Amdahl's Law)
112
+ - Microeconomics & Game Theory (Pareto Efficiency, Nash Equilibrium, Comparative Advantage)
113
+ - Evolutionary Biology (Red Queen Effect, Aposematism, Evolutionary Mismatch)
114
+ - Physics & Thermodynamics (Entropy, Critical Mass, Activation Energy)
115
+ - Military Strategy (OODA Loop, Sun Tzu's Asymmetry, Defense in Depth)
116
+ - Cryptography & Trust (Zero-Knowledge Proofs, Byzantine Fault Tolerance)
117
+ - Capital Allocation & Finance (Compounding, Ergodicity, Kelly Criterion)
118
+
119
+ ---
120
+
121
+ ## Telemetry & Privacy
122
+
123
+ `mental-models-mcp` collects anonymous usage telemetry to monitor server reliability, tool latency, and query patterns across client harnesses.
124
+ - Operational metrics: tool execution duration, status codes, and result counts.
125
+ - Intent analysis: query intent truncated up to 300 characters.
126
+ - Secret hygiene: credentials, API keys, and authorization tokens are automatically scrubbed (`[REDACTED]`).
127
+ - Opt out any time by setting `DO_NOT_TRACK=1` or `MCP_TELEMETRY_OPT_OUT=1`.
128
+
129
+ ---
130
+
131
+ ## License
132
+
133
+ MIT © [Surendran B](https://github.com/surendranb)
@@ -0,0 +1,105 @@
1
+ # Mental Models MCP
2
+
3
+ > Multi-disciplinary mental models, cognitive orientation coaching, and dialectical reasoning engine for AI agents and humans. Zero API keys required.
4
+
5
+ `mental-models-mcp` equips AI assistants and human decision-makers with Charlie Munger's latticework of mental models across systems thinking, decision analysis, strategic risk, cognitive biases, and first-principles engineering.
6
+
7
+ Built for anyone navigating high-stakes decisions under uncertainty—software engineers evaluating architectural forks, founders choosing product trade-offs, analysts diagnosing systemic incidents, researchers stress-testing hypotheses, and autonomous AI agents seeking to avoid agreeable sycophancy.
8
+
9
+ ---
10
+
11
+ ## Quickstart
12
+
13
+ ### Option A — Any MCP Harness (incl. Claude Desktop, Cursor, Antigravity, Windsurf)
14
+
15
+ Add to your client configuration:
16
+
17
+ ```json
18
+ {
19
+ "mcpServers": {
20
+ "mental-models": {
21
+ "command": "uvx",
22
+ "args": ["mental-models-mcp"]
23
+ }
24
+ }
25
+ }
26
+ ```
27
+
28
+ Or via NPX:
29
+
30
+ ```json
31
+ {
32
+ "mcpServers": {
33
+ "mental-models": {
34
+ "command": "npx",
35
+ "args": ["-y", "mental-models-mcp"]
36
+ }
37
+ }
38
+ }
39
+ ```
40
+
41
+ ### Option B — Claude Code CLI Plugin
42
+
43
+ ```bash
44
+ claude plugin marketplace add surendranb/mental-models-mcp
45
+ claude plugin install mental-models-mcp
46
+ ```
47
+
48
+ ### Option C — Standalone CLI Execution
49
+
50
+ ```bash
51
+ uvx mental-models-mcp
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Core Tools
57
+
58
+ 1. **`route_mental_model(problem, domain, problem_type)`**:
59
+ Lightweight L0 index scoring candidate frameworks against your situation. Defaults to `status: "NONE"` on routine syntax or trivial formatting tasks to conserve context tokens.
60
+ 2. **`get_mental_model(model_id, mode)`**:
61
+ Fetches the operational playbook for a mental model with 4 execution modes:
62
+ - `checklist` *(Default)*: Step-by-step thinking protocol, failure boundaries, and diagnostic probing questions.
63
+ - `explain`: Core principle, historical origin, and worked engineering example.
64
+ - `challenge_assumptions`: Dialectical anti-sycophancy sparring to uncover confirmation bias and unstated assumptions.
65
+ - `full`: Complete unabridged markdown playbook.
66
+ 3. **`list_mental_models(category, discipline)`**:
67
+ Categorical and topical exploration across the 150-model master taxonomy.
68
+ 4. **`skills_list()` / `skill_read(name)`**:
69
+ Dynamic runtime onboarding and reference guides fetched live from GitHub with local fallback.
70
+ 5. **`check_for_updates()`**:
71
+ PyPI version verification and automated upgrade hints.
72
+
73
+ ---
74
+
75
+ ## Catalog & Taxonomy
76
+
77
+ The latticework indexes **150 mental models** across 12 disciplines:
78
+ - Systems Thinking (Feedback Loops, Theory of Constraints, Tragedy of the Commons)
79
+ - Decision Analysis (First Principles, Inversion, Opportunity Cost, Two-Way Doors)
80
+ - Strategic Risk (Antifragility, Chesterton's Fence, Cynefin Framework, Lindy Effect, Via Negativa)
81
+ - Cognitive Biases (Confirmation Bias, Hanlon's Razor, Incentive-Caused Bias, Sunk Cost Fallacy)
82
+ - First-Principles Engineering (Conway's Law, Gall's Law, Goodhart's Law, Occam's Razor)
83
+ - Computer Systems (Little's Law, CAP Theorem, Backpressure, Amdahl's Law)
84
+ - Microeconomics & Game Theory (Pareto Efficiency, Nash Equilibrium, Comparative Advantage)
85
+ - Evolutionary Biology (Red Queen Effect, Aposematism, Evolutionary Mismatch)
86
+ - Physics & Thermodynamics (Entropy, Critical Mass, Activation Energy)
87
+ - Military Strategy (OODA Loop, Sun Tzu's Asymmetry, Defense in Depth)
88
+ - Cryptography & Trust (Zero-Knowledge Proofs, Byzantine Fault Tolerance)
89
+ - Capital Allocation & Finance (Compounding, Ergodicity, Kelly Criterion)
90
+
91
+ ---
92
+
93
+ ## Telemetry & Privacy
94
+
95
+ `mental-models-mcp` collects anonymous usage telemetry to monitor server reliability, tool latency, and query patterns across client harnesses.
96
+ - Operational metrics: tool execution duration, status codes, and result counts.
97
+ - Intent analysis: query intent truncated up to 300 characters.
98
+ - Secret hygiene: credentials, API keys, and authorization tokens are automatically scrubbed (`[REDACTED]`).
99
+ - Opt out any time by setting `DO_NOT_TRACK=1` or `MCP_TELEMETRY_OPT_OUT=1`.
100
+
101
+ ---
102
+
103
+ ## License
104
+
105
+ MIT © [Surendran B](https://github.com/surendranb)
@@ -0,0 +1,70 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "mental-models-mcp"
7
+ version = "0.1.0"
8
+ description = "Multi-disciplinary mental models, cognitive orientation coaching, and dialectical reasoning engine for AI agents and humans. Zero API keys."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ authors = [
12
+ {name = "Surendran B", email = "reachsuren@gmail.com"}
13
+ ]
14
+ requires-python = ">=3.10"
15
+ dependencies = [
16
+ "mcp>=2.0.0,<3",
17
+ "requests>=2.31.0",
18
+ ]
19
+ keywords = [
20
+ "mental-models",
21
+ "munger-latticework",
22
+ "decision-making",
23
+ "cognitive-coaching",
24
+ "systems-thinking",
25
+ "first-principles",
26
+ "inversion",
27
+ "mcp",
28
+ "mcp-server",
29
+ "model-context-protocol",
30
+ "ai-agent",
31
+ "claude",
32
+ "claude-code",
33
+ "cursor"
34
+ ]
35
+ classifiers = [
36
+ "Development Status :: 4 - Beta",
37
+ "Intended Audience :: Developers",
38
+ "Programming Language :: Python :: 3",
39
+ "Programming Language :: Python :: 3.10",
40
+ "Programming Language :: Python :: 3.11",
41
+ "Programming Language :: Python :: 3.12",
42
+ "Programming Language :: Python :: 3.13",
43
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
44
+ ]
45
+
46
+ [project.urls]
47
+ Homepage = "https://mental-models.builditwithai.xyz"
48
+ Repository = "https://github.com/surendranb/mental-models-mcp"
49
+ Issues = "https://github.com/surendranb/mental-models-mcp/issues"
50
+
51
+ [project.scripts]
52
+ mental-models-mcp = "mental_models_mcp.server:main"
53
+ mental-models = "mental_models_mcp.server:main"
54
+
55
+ [project.optional-dependencies]
56
+ dev = [
57
+ "pytest>=8.0.0",
58
+ "pytest-asyncio>=0.23.0",
59
+ ]
60
+
61
+ [tool.setuptools.packages.find]
62
+ where = ["src"]
63
+
64
+ [tool.setuptools.package-data]
65
+ mental_models_mcp = ["py.typed", "data/*.json"]
66
+
67
+ [tool.pytest.ini_options]
68
+ asyncio_mode = "auto"
69
+ asyncio_default_fixture_loop_scope = "function"
70
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,5 @@
1
+ # SPDX-License-Identifier: MIT
2
+ """Multi-disciplinary mental models and cognitive orientation engine for AI agents and humans."""
3
+
4
+ __version__ = "0.1.0"
5
+ __all__ = ["__version__"]
@@ -0,0 +1,6 @@
1
+ # SPDX-License-Identifier: MIT
2
+ """Entry point for python -m mental_models_mcp."""
3
+ from mental_models_mcp.server import main
4
+
5
+ if __name__ == "__main__":
6
+ main()
@@ -0,0 +1,211 @@
1
+ # SPDX-License-Identifier: MIT
2
+ """Catalog indexing, dynamic GitHub fetching, and local cache management for mental models."""
3
+ from __future__ import annotations
4
+ import json
5
+ import os
6
+ import re
7
+ import urllib.request
8
+ from pathlib import Path
9
+ from typing import Any, Dict, List, Optional, Tuple
10
+
11
+ GITHUB_RAW_BASE = "https://raw.githubusercontent.com/surendranb/mental-models-mcp/main"
12
+ LOCAL_CACHE_DIR = Path.home() / ".cache" / "mental-models"
13
+
14
+ _CACHED_INDEX: Optional[Dict[str, Any]] = None
15
+
16
+
17
+ def get_repo_root() -> Path:
18
+ """Best effort to locate local repo root if running from source checkout."""
19
+ return Path(__file__).resolve().parents[2]
20
+
21
+
22
+ def load_index(force_reload: bool = False) -> Dict[str, Any]:
23
+ """Loads models index from local package data, source checkout, or GitHub raw."""
24
+ global _CACHED_INDEX
25
+ if _CACHED_INDEX is not None and not force_reload:
26
+ return _CACHED_INDEX
27
+
28
+ # 1. Check bundled package data
29
+ package_data = Path(__file__).parent / "data" / "index.json"
30
+ if package_data.exists():
31
+ try:
32
+ _CACHED_INDEX = json.loads(package_data.read_text(encoding="utf-8"))
33
+ return _CACHED_INDEX
34
+ except Exception:
35
+ pass
36
+
37
+ # 2. Check local repo root
38
+ repo_models_index = get_repo_root() / "models" / "index.json"
39
+ if repo_models_index.exists():
40
+ try:
41
+ _CACHED_INDEX = json.loads(repo_models_index.read_text(encoding="utf-8"))
42
+ return _CACHED_INDEX
43
+ except Exception:
44
+ pass
45
+
46
+ # 3. Check disk cache
47
+ cache_index = LOCAL_CACHE_DIR / "index.json"
48
+ if cache_index.exists():
49
+ try:
50
+ _CACHED_INDEX = json.loads(cache_index.read_text(encoding="utf-8"))
51
+ return _CACHED_INDEX
52
+ except Exception:
53
+ pass
54
+
55
+ # 4. Fetch from GitHub raw
56
+ try:
57
+ url = f"{GITHUB_RAW_BASE}/models/index.json"
58
+ req = urllib.request.Request(url, headers={"User-Agent": "mental-models-mcp"})
59
+ with urllib.request.urlopen(req, timeout=4.0) as resp:
60
+ data = json.loads(resp.read().decode("utf-8"))
61
+ _CACHED_INDEX = data
62
+ LOCAL_CACHE_DIR.mkdir(parents=True, exist_ok=True)
63
+ cache_index.write_text(json.dumps(data, indent=2), encoding="utf-8")
64
+ return _CACHED_INDEX
65
+ except Exception:
66
+ pass
67
+
68
+ return {"version": "0.0.0", "categories": [], "models": []}
69
+
70
+
71
+ def get_model_metadata(model_id: str) -> Optional[Dict[str, Any]]:
72
+ """Lookup model definition from index by ID (normalized)."""
73
+ norm = (model_id or "").strip().lower().replace("-", "_")
74
+ index = load_index()
75
+ for m in index.get("models", []):
76
+ if m.get("id", "").lower().replace("-", "_") == norm:
77
+ return m
78
+ return None
79
+
80
+
81
+ def fetch_model_markdown(model_path: str) -> Tuple[Optional[str], str]:
82
+ """Fetches model markdown from local repo, disk cache, or GitHub raw."""
83
+ # 1. Local disk cache
84
+ cached_path = LOCAL_CACHE_DIR / model_path
85
+ if cached_path.exists():
86
+ try:
87
+ return cached_path.read_text(encoding="utf-8"), "cache"
88
+ except Exception:
89
+ pass
90
+
91
+ # 2. Local repository workspace (if developing locally)
92
+ repo_path = get_repo_root() / model_path
93
+ if repo_path.exists():
94
+ try:
95
+ return repo_path.read_text(encoding="utf-8"), "local"
96
+ except Exception:
97
+ pass
98
+
99
+ # 3. GitHub raw fetch
100
+ url = f"{GITHUB_RAW_BASE}/{model_path}"
101
+ try:
102
+ req = urllib.request.Request(url, headers={"User-Agent": "mental-models-mcp"})
103
+ with urllib.request.urlopen(req, timeout=5.0) as resp:
104
+ content = resp.read().decode("utf-8", "replace")
105
+ # Cache locally for offline reliability
106
+ try:
107
+ cached_path.parent.mkdir(parents=True, exist_ok=True)
108
+ cached_path.write_text(content, encoding="utf-8")
109
+ except Exception:
110
+ pass
111
+ return content, "github"
112
+ except Exception:
113
+ pass
114
+
115
+ return None, "missing"
116
+
117
+
118
+ def parse_markdown_sections(text: str) -> Dict[str, str]:
119
+ """Splits markdown into titled sections."""
120
+ sections: Dict[str, str] = {}
121
+ current_title = "header"
122
+ current_lines: List[str] = []
123
+
124
+ for line in text.splitlines():
125
+ if line.startswith("## "):
126
+ if current_lines:
127
+ sections[current_title] = "\n".join(current_lines).strip()
128
+ current_title = line[3:].strip()
129
+ current_lines = [line]
130
+ else:
131
+ current_lines.append(line)
132
+
133
+ if current_lines:
134
+ sections[current_title] = "\n".join(current_lines).strip()
135
+
136
+ return sections
137
+
138
+
139
+ def slice_playbook(markdown_text: str, mode: str, metadata: Dict[str, Any]) -> str:
140
+ """Slices markdown playbook by mode to prevent context bloat."""
141
+ mode_clean = (mode or "checklist").strip().lower()
142
+ if mode_clean == "full":
143
+ return markdown_text
144
+
145
+ sections = parse_markdown_sections(markdown_text)
146
+ header = sections.get("header", f"# {metadata.get('title', 'Mental Model')}")
147
+
148
+ # Section matchers
149
+ core_principle = next((v for k, v in sections.items() if "core principle" in k.lower()), "")
150
+ failure_boundaries = next((v for k, v in sections.items() if "not to use" in k.lower() or "failure" in k.lower()), "")
151
+ thinking_steps = next((v for k, v in sections.items() if "operational" in k.lower() or "steps" in k.lower()), "")
152
+ probing_questions = next((v for k, v in sections.items() if "probing" in k.lower() or "questions" in k.lower()), "")
153
+ worked_example = next((v for k, v in sections.items() if "example" in k.lower()), "")
154
+
155
+ parts = [header]
156
+
157
+ if mode_clean == "checklist":
158
+ # Actionable focus: failure boundaries + operational steps + diagnostic probing
159
+ if failure_boundaries:
160
+ parts.append(failure_boundaries)
161
+ if thinking_steps:
162
+ parts.append(thinking_steps)
163
+ if probing_questions:
164
+ parts.append(probing_questions)
165
+ elif mode_clean == "explain":
166
+ # Conceptual understanding: core principle + failure boundaries + worked example
167
+ if core_principle:
168
+ parts.append(core_principle)
169
+ if failure_boundaries:
170
+ parts.append(failure_boundaries)
171
+ if worked_example:
172
+ parts.append(worked_example)
173
+ elif mode_clean == "challenge_assumptions":
174
+ # Cognitive coaching / anti-sycophancy: probing questions + failure boundaries
175
+ if probing_questions:
176
+ parts.append(probing_questions)
177
+ if failure_boundaries:
178
+ parts.append(failure_boundaries)
179
+ else:
180
+ # Unknown mode fallback to full
181
+ return markdown_text
182
+
183
+ # If parsing found matching sections, join them; otherwise fallback to full text
184
+ if len(parts) > 1:
185
+ return "\n\n".join(p for p in parts if p.strip())
186
+ return markdown_text
187
+
188
+
189
+ def list_models_catalog(category: str = "", discipline: str = "") -> List[Dict[str, Any]]:
190
+ """List all models in index, optionally filtered."""
191
+ index = load_index()
192
+ models = index.get("models", [])
193
+ cat_norm = (category or "").strip().lower()
194
+ disc_norm = (discipline or "").strip().lower()
195
+
196
+ filtered = []
197
+ for m in models:
198
+ if cat_norm and cat_norm != m.get("category", "").lower():
199
+ continue
200
+ if disc_norm and disc_norm not in m.get("discipline", "").lower():
201
+ continue
202
+ filtered.append({
203
+ "id": m.get("id"),
204
+ "title": m.get("title"),
205
+ "category": m.get("category"),
206
+ "discipline": m.get("discipline"),
207
+ "description": m.get("description"),
208
+ "domains": m.get("domains", []),
209
+ "problem_types": m.get("problem_types", []),
210
+ })
211
+ return filtered