├── .gitignore ├── LICENSE ├── README.md ├── package-lock.json ├── package.json ├── src ├── index.ts └── validation.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules/ 3 | npm-debug.log* 4 | yarn-debug.log* 5 | yarn-error.log* 6 | 7 | # Build output 8 | build/ 9 | dist/ 10 | *.tsbuildinfo 11 | 12 | # IDE and editor files 13 | .idea/ 14 | .vscode/ 15 | *.swp 16 | *.swo 17 | .DS_Store 18 | 19 | # Environment variables 20 | .env 21 | .env.local 22 | .env.*.local 23 | 24 | # Logs 25 | logs/ 26 | *.log 27 | 28 | # Test coverage 29 | coverage/ 30 | 31 | # Temporary files 32 | *.tmp 33 | *.temp 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Teglon Labs 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. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Anti-Bullshit MCP Server 2 | 3 | A Model Context Protocol server for analyzing claims, validating sources, and detecting manipulation using multiple epistemological frameworks. 4 | 5 | ## Features 6 | 7 | The server provides three main tools for detecting and analyzing bullshit: 8 | 9 | ### 1. analyze_claim 10 | Analyzes claims using multiple epistemological frameworks: 11 | 12 | - **Empirical Framework** 13 | - Focuses on verifiable evidence 14 | - Evaluates reproducible results 15 | - Cross-references academic and scientific sources 16 | - Assesses methodological rigor 17 | 18 | - **Responsible Framework** 19 | - Evaluates ethical implications 20 | - Assesses community impact 21 | - Considers traditional knowledge 22 | - Validates source credibility 23 | 24 | - **Harmonic Framework** 25 | - Assesses coherence with established knowledge 26 | - Integrates multiple perspectives 27 | - Considers contextual appropriateness 28 | - Evaluates systemic implications 29 | 30 | - **Pluralistic Framework** 31 | - Combines all other frameworks 32 | - Considers multiple ways of knowing 33 | - Evaluates contextual appropriateness 34 | - Assesses practical outcomes 35 | - Checks alignment with community values 36 | 37 | ### 2. validate_sources 38 | - Extracts and analyzes cited sources 39 | - Validates credibility and authority 40 | - Cross-references across multiple platforms 41 | - Evaluates methodological soundness 42 | - Checks for conflicts of interest 43 | 44 | ### 3. check_manipulation 45 | Detects manipulation tactics including: 46 | - Emotional manipulation 47 | - Social pressure 48 | - False authority 49 | - Artificial scarcity 50 | - Urgency creation 51 | 52 | ## Installation 53 | 54 | ### Prerequisites 55 | - Node.js >= 18.0.0 56 | - npm or yarn 57 | 58 | ### Setup 59 | 60 | 1. Install dependencies: 61 | ```bash 62 | npm install 63 | ``` 64 | 65 | 2. Build the server: 66 | ```bash 67 | npm run build 68 | ``` 69 | 70 | 3. Add to Claude Desktop (MacOS): 71 | ```json 72 | { 73 | "mcpServers": { 74 | "anti-bullshit": { 75 | "command": "node", 76 | "args": ["/path/to/anti-bullshit-mcp-server/build/index.js"] 77 | } 78 | } 79 | } 80 | ``` 81 | 82 | Path: `~/Library/Application Support/Claude/claude_desktop_config.json` 83 | 84 | Or for VSCode extension: 85 | Path: `~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json` 86 | 87 | ## Usage Examples 88 | 89 | ```typescript 90 | // Analyze a claim 91 | const result = await analyze_claim({ 92 | text: "Studies show that 87% of experts agree with this controversial claim", 93 | framework: "empirical" 94 | }); 95 | 96 | // Validate sources 97 | const validation = await validate_sources({ 98 | text: "According to Dr. Smith's groundbreaking research...", 99 | framework: "responsible" 100 | }); 101 | 102 | // Check for manipulation 103 | const check = await check_manipulation({ 104 | text: "Act now! This exclusive offer expires in the next 10 minutes!" 105 | }); 106 | ``` 107 | 108 | ## Development 109 | 110 | For development with auto-rebuild: 111 | ```bash 112 | npm run watch 113 | ``` 114 | 115 | Debug with MCP Inspector: 116 | ```bash 117 | npm run inspector 118 | ``` 119 | 120 | ## Testing Timeline 121 | 122 | The server uses 2025-01-01 as the reference date for temporal analysis of claims (particularly relevant for Goodman's "grue" paradox and similar philosophical puzzles). 123 | 124 | ## License 125 | 126 | MIT 127 | 128 | ## Author 129 | 130 | Teglon Labs (teglon@vibes.lol) 131 | 132 | ## Contributing 133 | 134 | 1. Fork the repository 135 | 2. Create your feature branch (`git checkout -b feature/amazing-feature`) 136 | 3. Commit your changes (`git commit -am 'Add some amazing feature'`) 137 | 4. Push to the branch (`git push origin feature/amazing-feature`) 138 | 5. Open a Pull Request 139 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anti-bullshit-mcp-server", 3 | "version": "0.1.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "anti-bullshit-mcp-server", 9 | "version": "0.1.0", 10 | "dependencies": { 11 | "@modelcontextprotocol/sdk": "0.6.0", 12 | "axios": "^1.7.9" 13 | }, 14 | "bin": { 15 | "anti-bullshit-mcp-server": "build/index.js" 16 | }, 17 | "devDependencies": { 18 | "@types/node": "^20.11.24", 19 | "typescript": "^5.3.3" 20 | } 21 | }, 22 | "node_modules/@modelcontextprotocol/sdk": { 23 | "version": "0.6.0", 24 | "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-0.6.0.tgz", 25 | "integrity": "sha512-9rsDudGhDtMbvxohPoMMyAUOmEzQsOK+XFchh6gZGqo8sx9sBuZQs+CUttXqa8RZXKDaJRCN2tUtgGof7jRkkw==", 26 | "license": "MIT", 27 | "dependencies": { 28 | "content-type": "^1.0.5", 29 | "raw-body": "^3.0.0", 30 | "zod": "^3.23.8" 31 | } 32 | }, 33 | "node_modules/@types/node": { 34 | "version": "20.17.12", 35 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.12.tgz", 36 | "integrity": "sha512-vo/wmBgMIiEA23A/knMfn/cf37VnuF52nZh5ZoW0GWt4e4sxNquibrMRJ7UQsA06+MBx9r/H1jsI9grYjQCQlw==", 37 | "dev": true, 38 | "license": "MIT", 39 | "dependencies": { 40 | "undici-types": "~6.19.2" 41 | } 42 | }, 43 | "node_modules/asynckit": { 44 | "version": "0.4.0", 45 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 46 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", 47 | "license": "MIT" 48 | }, 49 | "node_modules/axios": { 50 | "version": "1.7.9", 51 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", 52 | "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", 53 | "license": "MIT", 54 | "dependencies": { 55 | "follow-redirects": "^1.15.6", 56 | "form-data": "^4.0.0", 57 | "proxy-from-env": "^1.1.0" 58 | } 59 | }, 60 | "node_modules/bytes": { 61 | "version": "3.1.2", 62 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 63 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 64 | "license": "MIT", 65 | "engines": { 66 | "node": ">= 0.8" 67 | } 68 | }, 69 | "node_modules/combined-stream": { 70 | "version": "1.0.8", 71 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 72 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 73 | "license": "MIT", 74 | "dependencies": { 75 | "delayed-stream": "~1.0.0" 76 | }, 77 | "engines": { 78 | "node": ">= 0.8" 79 | } 80 | }, 81 | "node_modules/content-type": { 82 | "version": "1.0.5", 83 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 84 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 85 | "license": "MIT", 86 | "engines": { 87 | "node": ">= 0.6" 88 | } 89 | }, 90 | "node_modules/delayed-stream": { 91 | "version": "1.0.0", 92 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 93 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", 94 | "license": "MIT", 95 | "engines": { 96 | "node": ">=0.4.0" 97 | } 98 | }, 99 | "node_modules/depd": { 100 | "version": "2.0.0", 101 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 102 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 103 | "license": "MIT", 104 | "engines": { 105 | "node": ">= 0.8" 106 | } 107 | }, 108 | "node_modules/follow-redirects": { 109 | "version": "1.15.9", 110 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", 111 | "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", 112 | "funding": [ 113 | { 114 | "type": "individual", 115 | "url": "https://github.com/sponsors/RubenVerborgh" 116 | } 117 | ], 118 | "license": "MIT", 119 | "engines": { 120 | "node": ">=4.0" 121 | }, 122 | "peerDependenciesMeta": { 123 | "debug": { 124 | "optional": true 125 | } 126 | } 127 | }, 128 | "node_modules/form-data": { 129 | "version": "4.0.1", 130 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", 131 | "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", 132 | "license": "MIT", 133 | "dependencies": { 134 | "asynckit": "^0.4.0", 135 | "combined-stream": "^1.0.8", 136 | "mime-types": "^2.1.12" 137 | }, 138 | "engines": { 139 | "node": ">= 6" 140 | } 141 | }, 142 | "node_modules/http-errors": { 143 | "version": "2.0.0", 144 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 145 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 146 | "license": "MIT", 147 | "dependencies": { 148 | "depd": "2.0.0", 149 | "inherits": "2.0.4", 150 | "setprototypeof": "1.2.0", 151 | "statuses": "2.0.1", 152 | "toidentifier": "1.0.1" 153 | }, 154 | "engines": { 155 | "node": ">= 0.8" 156 | } 157 | }, 158 | "node_modules/iconv-lite": { 159 | "version": "0.6.3", 160 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", 161 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", 162 | "license": "MIT", 163 | "dependencies": { 164 | "safer-buffer": ">= 2.1.2 < 3.0.0" 165 | }, 166 | "engines": { 167 | "node": ">=0.10.0" 168 | } 169 | }, 170 | "node_modules/inherits": { 171 | "version": "2.0.4", 172 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 173 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 174 | "license": "ISC" 175 | }, 176 | "node_modules/mime-db": { 177 | "version": "1.52.0", 178 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 179 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 180 | "license": "MIT", 181 | "engines": { 182 | "node": ">= 0.6" 183 | } 184 | }, 185 | "node_modules/mime-types": { 186 | "version": "2.1.35", 187 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 188 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 189 | "license": "MIT", 190 | "dependencies": { 191 | "mime-db": "1.52.0" 192 | }, 193 | "engines": { 194 | "node": ">= 0.6" 195 | } 196 | }, 197 | "node_modules/proxy-from-env": { 198 | "version": "1.1.0", 199 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", 200 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", 201 | "license": "MIT" 202 | }, 203 | "node_modules/raw-body": { 204 | "version": "3.0.0", 205 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", 206 | "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", 207 | "license": "MIT", 208 | "dependencies": { 209 | "bytes": "3.1.2", 210 | "http-errors": "2.0.0", 211 | "iconv-lite": "0.6.3", 212 | "unpipe": "1.0.0" 213 | }, 214 | "engines": { 215 | "node": ">= 0.8" 216 | } 217 | }, 218 | "node_modules/safer-buffer": { 219 | "version": "2.1.2", 220 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 221 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 222 | "license": "MIT" 223 | }, 224 | "node_modules/setprototypeof": { 225 | "version": "1.2.0", 226 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 227 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", 228 | "license": "ISC" 229 | }, 230 | "node_modules/statuses": { 231 | "version": "2.0.1", 232 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 233 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 234 | "license": "MIT", 235 | "engines": { 236 | "node": ">= 0.8" 237 | } 238 | }, 239 | "node_modules/toidentifier": { 240 | "version": "1.0.1", 241 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 242 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 243 | "license": "MIT", 244 | "engines": { 245 | "node": ">=0.6" 246 | } 247 | }, 248 | "node_modules/typescript": { 249 | "version": "5.7.3", 250 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", 251 | "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", 252 | "dev": true, 253 | "license": "Apache-2.0", 254 | "bin": { 255 | "tsc": "bin/tsc", 256 | "tsserver": "bin/tsserver" 257 | }, 258 | "engines": { 259 | "node": ">=14.17" 260 | } 261 | }, 262 | "node_modules/undici-types": { 263 | "version": "6.19.8", 264 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", 265 | "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", 266 | "dev": true, 267 | "license": "MIT" 268 | }, 269 | "node_modules/unpipe": { 270 | "version": "1.0.0", 271 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 272 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 273 | "license": "MIT", 274 | "engines": { 275 | "node": ">= 0.8" 276 | } 277 | }, 278 | "node_modules/zod": { 279 | "version": "3.24.1", 280 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", 281 | "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", 282 | "license": "MIT", 283 | "funding": { 284 | "url": "https://github.com/sponsors/colinhacks" 285 | } 286 | } 287 | } 288 | } 289 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anti-bullshit-mcp-server", 3 | "version": "0.1.0", 4 | "description": "MCP server for analyzing claims, validating sources, and detecting manipulation using multiple epistemological frameworks (empirical, responsible, harmonic, and pluralistic)", 5 | "private": true, 6 | "type": "module", 7 | "author": { 8 | "name": "Teglon Labs", 9 | "email": "teglon@vibes.lol" 10 | }, 11 | "license": "MIT", 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/teglon/anti-bullshit-mcp-server.git" 15 | }, 16 | "bin": { 17 | "anti-bullshit-mcp-server": "./build/index.js" 18 | }, 19 | "files": [ 20 | "build" 21 | ], 22 | "scripts": { 23 | "build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"", 24 | "prepare": "npm run build", 25 | "watch": "tsc --watch", 26 | "inspector": "npx @modelcontextprotocol/inspector build/index.js" 27 | }, 28 | "dependencies": { 29 | "@modelcontextprotocol/sdk": "0.6.0", 30 | "axios": "^1.7.9" 31 | }, 32 | "devDependencies": { 33 | "@types/node": "^20.11.24", 34 | "typescript": "^5.3.3" 35 | }, 36 | "keywords": [ 37 | "mcp", 38 | "model-context-protocol", 39 | "epistemology", 40 | "claim-analysis", 41 | "source-validation", 42 | "manipulation-detection", 43 | "fact-checking", 44 | "critical-thinking", 45 | "bullshit-detection" 46 | ], 47 | "engines": { 48 | "node": ">=18.0.0" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { Server } from "@modelcontextprotocol/sdk/server/index.js"; 3 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; 4 | import { 5 | CallToolRequestSchema, 6 | ErrorCode, 7 | ListToolsRequestSchema, 8 | McpError, 9 | } from "@modelcontextprotocol/sdk/types.js"; 10 | import { VALIDATION_FRAMEWORKS, validateWithFramework, getValidationSuggestions } from "./validation.js"; 11 | 12 | const server = new Server( 13 | { 14 | name: "anti-bullshit-mcp-server", 15 | version: "0.1.0", 16 | }, 17 | { 18 | capabilities: { 19 | tools: { 20 | analyze_claim: true, 21 | validate_sources: true, 22 | check_manipulation: true 23 | }, 24 | }, 25 | } 26 | ); 27 | 28 | // Load validation framework configuration from environment 29 | const VALIDATION_FRAMEWORK = (process.env.VALIDATION_FRAMEWORK || "pluralistic") as keyof typeof VALIDATION_FRAMEWORKS; 30 | 31 | // List available tools 32 | server.setRequestHandler(ListToolsRequestSchema, async () => { 33 | return { 34 | tools: [ 35 | { 36 | name: "analyze_claim", 37 | description: "Analyze a claim using multiple epistemological frameworks and suggest validation steps", 38 | inputSchema: { 39 | type: "object", 40 | properties: { 41 | text: { 42 | type: "string", 43 | description: "Claim to analyze", 44 | }, 45 | framework: { 46 | type: "string", 47 | description: "Validation framework to use (empirical, responsible, harmonic, or pluralistic)", 48 | enum: ["empirical", "responsible", "harmonic", "pluralistic"], 49 | } 50 | }, 51 | required: ["text"], 52 | }, 53 | }, 54 | { 55 | name: "validate_sources", 56 | description: "Validate sources and evidence using configured framework", 57 | inputSchema: { 58 | type: "object", 59 | properties: { 60 | text: { 61 | type: "string", 62 | description: "Text containing claims and sources to validate", 63 | }, 64 | framework: { 65 | type: "string", 66 | description: "Validation framework to use", 67 | enum: ["empirical", "responsible", "harmonic", "pluralistic"], 68 | } 69 | }, 70 | required: ["text"], 71 | }, 72 | }, 73 | { 74 | name: "check_manipulation", 75 | description: "Check for manipulation tactics across different cultural contexts", 76 | inputSchema: { 77 | type: "object", 78 | properties: { 79 | text: { 80 | type: "string", 81 | description: "Text to analyze for manipulation", 82 | } 83 | }, 84 | required: ["text"], 85 | }, 86 | } 87 | ], 88 | }; 89 | }); 90 | 91 | // Handle tool execution 92 | interface ToolArguments { 93 | text: string; 94 | framework?: string; 95 | } 96 | 97 | server.setRequestHandler(CallToolRequestSchema, async (request) => { 98 | const { name, arguments: rawArgs } = request.params; 99 | const args = rawArgs as unknown as ToolArguments; 100 | 101 | if (!args || typeof args.text !== 'string') { 102 | throw new McpError(ErrorCode.InvalidParams, "Text parameter is required and must be a string"); 103 | } 104 | 105 | try { 106 | if (name === "analyze_claim") { 107 | const framework: keyof typeof VALIDATION_FRAMEWORKS = 108 | (typeof args.framework === 'string' && args.framework in VALIDATION_FRAMEWORKS) 109 | ? args.framework as keyof typeof VALIDATION_FRAMEWORKS 110 | : VALIDATION_FRAMEWORK; 111 | const validation = validateWithFramework(args.text, framework, { 112 | hasEmpirical: /evidence|study|research|data/i.test(args.text), 113 | servesWellbeing: /benefit|improve|help|support/i.test(args.text), 114 | maintainsHarmony: /balance|harmony|integrate/i.test(args.text) 115 | }); 116 | 117 | const suggestions = getValidationSuggestions(args.text, framework); 118 | 119 | // Generate cross-referencing prompts 120 | const crossRefPrompts = [ 121 | `- Use Exa MCP server to search for general information: "${args.text}"`, 122 | `- Use Brave Search for independent web sources: "${args.text}"`, 123 | `- Search ArXiv for preprints and technical papers: "${args.text}"`, 124 | `- Use Google Scholar MCP server to find peer-reviewed research: "${args.text}"`, 125 | `- Cross-reference findings between academic and general sources to identify consensus or conflicts` 126 | ]; 127 | 128 | // Framework-specific cross-references 129 | if (framework === "empirical" || framework === "pluralistic") { 130 | crossRefPrompts.push( 131 | `- Compare methodologies between ArXiv papers and peer-reviewed research`, 132 | `- Analyze replication status across different studies`, 133 | `- Cross-validate findings between academic databases` 134 | ); 135 | } 136 | 137 | if (framework === "responsible" || framework === "pluralistic") { 138 | crossRefPrompts.push( 139 | `- Use Exa MCP server to search for community impact studies: "${args.text}"`, 140 | `- Cross-reference academic findings with community experiences`, 141 | `- Compare traditional knowledge with modern research findings` 142 | ); 143 | } 144 | 145 | if (framework === "harmonic" || framework === "pluralistic") { 146 | crossRefPrompts.push( 147 | `- Use Exa MCP server to search for alternative perspectives: "${args.text}"`, 148 | `- Compare Eastern and Western research approaches`, 149 | `- Synthesize findings across different knowledge systems` 150 | ); 151 | } 152 | 153 | return { 154 | content: [ 155 | { 156 | type: "text", 157 | text: `Analysis using ${framework} framework:\n\n` + 158 | `Requirements:\n${suggestions.join("\n")}\n\n` + 159 | `Confidence level: ${validation.confidence}\n\n` + 160 | `Suggested cross-references:\n${crossRefPrompts.join("\n")}` 161 | }, 162 | { 163 | type: "text", 164 | text: JSON.stringify({ 165 | framework, 166 | validation, 167 | suggestions, 168 | crossRefPrompts 169 | }) 170 | } 171 | ], 172 | }; 173 | } 174 | 175 | if (name === "validate_sources") { 176 | const framework: keyof typeof VALIDATION_FRAMEWORKS = 177 | (typeof args.framework === 'string' && args.framework in VALIDATION_FRAMEWORKS) 178 | ? args.framework as keyof typeof VALIDATION_FRAMEWORKS 179 | : VALIDATION_FRAMEWORK; 180 | 181 | // Extract sources 182 | const sourcePattern = /according to|cited by|reported by|study by|research by|experts|scientists/gi; 183 | const sources = []; 184 | let match: RegExpExecArray | null; 185 | while ((match = sourcePattern.exec(args.text)) !== null) { 186 | const context = args.text.substring( 187 | Math.max(0, match.index - 30), 188 | Math.min(args.text.length, match.index + 70) 189 | ); 190 | sources.push({ 191 | type: "citation", 192 | context: context.trim() 193 | }); 194 | } 195 | 196 | // Generate validation prompts for each source 197 | const validationPrompts = sources.flatMap((source: { type: string; context: string }) => { 198 | const basePrompts = [ 199 | `- Use Exa MCP server to verify credibility of: "${source.context}"`, 200 | `- Use Brave Search to find independent verification: "${source.context}"`, 201 | `- Search ArXiv for related technical papers: "${source.context}"`, 202 | `- Use Google Scholar MCP server to check academic citations: "${source.context}"`, 203 | `- Cross-reference findings between different platforms to establish credibility` 204 | ]; 205 | 206 | if (framework === "empirical" || framework === "pluralistic") { 207 | basePrompts.push( 208 | `- Compare methodologies and results across different studies`, 209 | `- Verify replication status and reproducibility`, 210 | `- Cross-validate findings between different research groups` 211 | ); 212 | } 213 | 214 | if (framework === "responsible" || framework === "pluralistic") { 215 | basePrompts.push( 216 | `- Use Exa MCP server to search for community perspectives: "${source.context}"`, 217 | `- Compare academic findings with real-world impacts`, 218 | `- Cross-reference with local knowledge and experiences` 219 | ); 220 | } 221 | 222 | if (framework === "harmonic" || framework === "pluralistic") { 223 | basePrompts.push( 224 | `- Compare perspectives across different cultural contexts`, 225 | `- Synthesize findings from multiple knowledge systems`, 226 | `- Identify areas of consensus and divergence` 227 | ); 228 | } 229 | 230 | return basePrompts; 231 | }); 232 | 233 | return { 234 | content: [ 235 | { 236 | type: "text", 237 | text: `Source validation using ${framework} framework:\n\n` + 238 | `Found ${sources.length} sources to validate.\n\n` + 239 | `Validation steps:\n${validationPrompts.join("\n")}` 240 | }, 241 | { 242 | type: "text", 243 | text: JSON.stringify({ 244 | framework, 245 | sources, 246 | validationPrompts 247 | }, null, 2) 248 | } 249 | ], 250 | }; 251 | } 252 | 253 | if (name === "check_manipulation") { 254 | const patterns = { 255 | emotional: /fear|urgent|must act|limited time|don't wait|before it's too late/i, 256 | social: /everyone knows|nobody wants|you don't want to be|don't miss out/i, 257 | authority: /experts say|scientists claim|studies show|research proves/i, 258 | scarcity: /limited time|exclusive|rare opportunity|don't miss out/i 259 | }; 260 | 261 | const detectedPatterns = Object.entries(patterns) 262 | .filter(([_, pattern]) => pattern.test(args.text)) 263 | .map(([type]) => type); 264 | 265 | // Generate validation prompts 266 | const validationPrompts = [ 267 | `- Use Exa MCP server to search for factual information: "${args.text}"`, 268 | `- Use Brave Search for independent fact-checking: "${args.text}"`, 269 | `- Search ArXiv for technical analysis: "${args.text}"`, 270 | `- Use Google Scholar MCP server to find peer-reviewed research: "${args.text}"`, 271 | `- Cross-reference findings across different platforms to establish truth` 272 | ]; 273 | 274 | if (detectedPatterns.includes("authority")) { 275 | validationPrompts.push( 276 | `- Use Google Scholar MCP server to verify credibility of cited authorities`, 277 | `- Cross-reference authority claims with independent research`, 278 | `- Compare expert opinions across different fields` 279 | ); 280 | } 281 | 282 | if (detectedPatterns.includes("emotional")) { 283 | validationPrompts.push( 284 | `- Use Exa MCP server to find balanced, non-emotional discussions`, 285 | `- Compare emotional appeals with empirical evidence`, 286 | `- Cross-validate claims across multiple neutral sources` 287 | ); 288 | } 289 | 290 | if (detectedPatterns.includes("social") || detectedPatterns.includes("scarcity")) { 291 | validationPrompts.push( 292 | `- Verify claims using multiple independent sources`, 293 | `- Cross-reference marketing claims with factual data`, 294 | `- Compare urgency claims with historical patterns` 295 | ); 296 | } 297 | 298 | return { 299 | content: [ 300 | { 301 | type: "text", 302 | text: `Manipulation check results:\n\n` + 303 | `Detected patterns: ${detectedPatterns.join(", ") || "None"}\n\n` + 304 | `Suggested validation:\n${validationPrompts.join("\n")}` 305 | }, 306 | { 307 | type: "text", 308 | text: JSON.stringify({ 309 | detectedPatterns, 310 | validationPrompts 311 | }, null, 2) 312 | } 313 | ], 314 | }; 315 | } 316 | 317 | throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`); 318 | } catch (error: unknown) { 319 | if (error instanceof McpError) { 320 | throw error; 321 | } 322 | throw new McpError( 323 | ErrorCode.InternalError, 324 | `Error analyzing text: ${(error instanceof Error ? error.message : String(error)) as string}` 325 | ); 326 | } 327 | }); 328 | 329 | // Start the server 330 | const transport = new StdioServerTransport(); 331 | await server.connect(transport); 332 | console.error("Anti-bullshit MCP server running on stdio"); 333 | -------------------------------------------------------------------------------- /src/validation.ts: -------------------------------------------------------------------------------- 1 | // Validation frameworks based on different epistemological traditions 2 | export const VALIDATION_FRAMEWORKS = { 3 | // Western empirical framework focused on evidence and logic 4 | empirical: { 5 | validateClaim: (claim: string) => ({ 6 | claim, 7 | type: "empirical", 8 | requirements: [ 9 | "Verifiable evidence from multiple sources", 10 | "Logical consistency across different contexts", 11 | "Reproducible results with documented methodology", 12 | "Cross-referenced academic and scientific sources", 13 | "Peer-reviewed validation where applicable" 14 | ] 15 | }), 16 | confidenceLevel: (evidence: any) => 17 | evidence.hasEmpirical ? "high" : "low" 18 | }, 19 | 20 | // Indigenous framework focused on responsible truth and community impact 21 | responsible: { 22 | validateClaim: (claim: string) => ({ 23 | claim, 24 | type: "responsible", 25 | requirements: [ 26 | "Benefits community wellbeing with documented impact", 27 | "Aligns with traditional knowledge and modern research", 28 | "Respects natural balance and sustainable practices", 29 | "Verified by diverse community perspectives", 30 | "Supported by both qualitative and quantitative evidence" 31 | ] 32 | }), 33 | confidenceLevel: (evidence: any) => 34 | evidence.servesWellbeing ? "high" : "low" 35 | }, 36 | 37 | // Eastern framework focused on harmony and contextual truth 38 | harmonic: { 39 | validateClaim: (claim: string) => ({ 40 | claim, 41 | type: "harmonic", 42 | requirements: [ 43 | "Maintains balance across different domains", 44 | "Considers context from multiple viewpoints", 45 | "Integrates perspectives from various disciplines", 46 | "Synthesizes traditional and modern knowledge", 47 | "Demonstrates coherence across different frameworks" 48 | ] 49 | }), 50 | confidenceLevel: (evidence: any) => 51 | evidence.maintainsHarmony ? "high" : "low" 52 | }, 53 | 54 | // Pluralistic framework that combines multiple validation approaches 55 | pluralistic: { 56 | validateClaim: (claim: string) => ({ 57 | claim, 58 | type: "pluralistic", 59 | requirements: [ 60 | "Consider multiple ways of knowing and validate across frameworks", 61 | "Evaluate contextual appropriateness in different settings", 62 | "Assess practical outcomes with measurable metrics", 63 | "Check alignment with community values and scientific consensus", 64 | "Cross-reference academic, practical, and community sources", 65 | "Integrate insights from diverse knowledge systems" 66 | ] 67 | }), 68 | confidenceLevel: (evidence: any) => { 69 | const scores = [ 70 | evidence.hasEmpirical ? 1 : 0, 71 | evidence.servesWellbeing ? 1 : 0, 72 | evidence.maintainsHarmony ? 1 : 0 73 | ]; 74 | const avg = scores.reduce((a,b) => a + b) / scores.length; 75 | return avg > 0.7 ? "high" : avg > 0.3 ? "medium" : "low"; 76 | } 77 | } 78 | }; 79 | 80 | // Helper functions for validation 81 | export function validateWithFramework( 82 | claim: string, 83 | framework: keyof typeof VALIDATION_FRAMEWORKS, 84 | evidence: any 85 | ) { 86 | const validator = VALIDATION_FRAMEWORKS[framework]; 87 | return { 88 | requirements: validator.validateClaim(claim), 89 | confidence: validator.confidenceLevel(evidence) 90 | }; 91 | } 92 | 93 | export function getValidationSuggestions( 94 | claim: string, 95 | framework: keyof typeof VALIDATION_FRAMEWORKS 96 | ): string[] { 97 | const requirements = VALIDATION_FRAMEWORKS[framework].validateClaim(claim).requirements; 98 | return requirements.map(req => `- Verify if claim "${claim}" meets requirement: ${req}`); 99 | } 100 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "module": "NodeNext", 5 | "moduleResolution": "NodeNext", 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "strict": true, 9 | "skipLibCheck": true, 10 | "outDir": "build", 11 | "rootDir": "src", 12 | "declaration": true, 13 | "sourceMap": true, 14 | "resolveJsonModule": true, 15 | "noImplicitAny": true, 16 | "noUnusedLocals": true, 17 | "noUnusedParameters": true, 18 | "noImplicitReturns": true, 19 | "noFallthroughCasesInSwitch": true 20 | }, 21 | "include": ["src/**/*"], 22 | "exclude": ["node_modules", "build"] 23 | } 24 | --------------------------------------------------------------------------------