# Slander MCP
An MCP server that finds humorous roasts, jokes, and memes about any character (real or fictional) by searching Twitter/X. Uses social proof (engagement metrics) to rank content, with targeted LLM involvement for query generation, batch quality assessment, and nickname extraction.
## Installation
```bash
npm install
npm run build
```
## Configuration
Create a `.env` file with:
```bash
# Twitter/X API credentials (required)
TWITTER_BEARER_TOKEN=your_twitter_bearer_token_here
# LLM API key (at least one required)
ANTHROPIC_API_KEY=your_anthropic_api_key_here
# or
OPENAI_API_KEY=your_openai_api_key_here
```
## Usage with Claude Desktop
Add to your Claude Desktop MCP configuration:
```json
{
"mcpServers": {
"slander": {
"command": "node",
"args": ["/path/to/slander_mcp/dist/index.js"],
"env": {
"TWITTER_BEARER_TOKEN": "your_token",
"ANTHROPIC_API_KEY": "your_key"
}
}
}
}
```
## Tools
### `generate_search_query`
Generate effective Twitter search queries for finding slander about a target.
**Input:**
- `target` (string, required): Name of character to search for
**Output:**
- `queries`: Array of search query strings
**Example:**
```json
Input: { "target": "LeBron James" }
Output: { "queries": ["LeBron James ratio", "LeChoke", "LeBron hairline", ...] }
```
### `fetch_posts`
Fetch posts from Twitter for a given query, looping until quality threshold is met.
**Input:**
- `query` (string, required): Search query
- `loop_limit` (number, optional): Max fetch iterations (default: 5)
- `count` (number, optional): Posts per fetch (default: 10)
- `target` (string, optional): Target name for quality evaluation
**Output:**
- `posts`: Array of post objects with engagement metrics
- `iterations`: Number of fetch loops
- `stopped_reason`: "quality_threshold" or "loop_limit"
### `rank_posts`
Rank fetched posts by engagement, separate text from media, extract nicknames.
**Input:**
- `posts` (array, required): Posts from fetch_posts
- `top_n` (number, optional): Results per category (default: 3)
- `target` (string, optional): Target name for nickname extraction
**Output:**
- `text_posts`: Top text posts ranked by engagement
- `media_posts`: Top media posts ranked by engagement
- `nicknames`: Extracted nicknames/slang for the target
**Engagement Score Formula:**
```
score = (likes * 1.0) + (retweets * 2.0) + (replies * 0.5)
```
## Example Workflow
1. Generate search queries:
```
generate_search_query({ target: "LeBron James" })
```
2. Fetch posts for each query:
```
fetch_posts({ query: "LeChoke", target: "LeBron James" })
```
3. Combine and rank results:
```
rank_posts({ posts: [...all_posts], top_n: 5, target: "LeBron James" })
```
## License
MIT