Metadata-Version: 2.4
Name: mcp-second-opinion
Version: 0.1.0
Summary: Let your MCP-aware agent consult rival LLMs (OpenAI, Gemini, Anthropic, Grok) mid-conversation.
Author-email: Akash <ahadagal@iu.edu>
License-Expression: MIT
License-File: LICENSE
Keywords: anthropic,gemini,grok,litellm,llm,mcp,openai,second-opinion
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: fastmcp>=0.2
Requires-Dist: litellm>=1.50
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Description-Content-Type: text/markdown

# mcp-second-opinion

Let your MCP-aware agent consult rival LLMs mid-conversation. One simple MCP server, four providers — OpenAI, Google Gemini, Anthropic, xAI/Grok — unified behind two tools.

## Install

```bash
pip install mcp-second-opinion
```

or with uv:

```bash
uv add mcp-second-opinion
```

## Configure

Set at least one of these environment variables:

| Variable | Provider |
|---|---|
| `OPENAI_API_KEY` | OpenAI |
| `GEMINI_API_KEY` | Google Gemini |
| `ANTHROPIC_API_KEY` | Anthropic |
| `XAI_API_KEY` | xAI/Grok |

Providers without a key set are gracefully disabled — they appear in panel responses with a friendly `error` field rather than crashing the server.

Optional:

| Variable | Default | Purpose |
|---|---|---|
| `MCP_SECOND_OPINION_PROFILE` | `flagship` | `flagship` \| `balanced` \| `cheap` — controls which model each provider uses in `ask_the_panel`. |
| `MCP_SECOND_OPINION_SELF_SKIP` | unset | Provider key to omit from panel (`openai`, `gemini`, `anthropic`, `grok`). Useful when the host is itself one of the panelists. |
| `MCP_SECOND_OPINION_TIMEOUT` | `30` | Per-provider timeout in seconds. |
| `MCP_SECOND_OPINION_MAX_TOKENS` | `2048` | Cap on rival output length. |

## Register with your MCP client

**Claude Desktop / Claude Code** (`mcp_settings.json` or equivalent):

```json
{
  "mcpServers": {
    "second-opinion": {
      "command": "mcp-second-opinion",
      "env": {
        "OPENAI_API_KEY": "sk-...",
        "GEMINI_API_KEY": "...",
        "ANTHROPIC_API_KEY": "...",
        "XAI_API_KEY": "..."
      }
    }
  }
}
```

## Tools

### `ask_other_model(question, model, context?, system_prompt?)`

Ask one specific rival.

```
question:      "is this regex correct? /^[a-z]+$/"
model:         "gpt-5" | "gemini-2.5-pro" | "claude-opus-4-7" | "grok-4" | ...
context:       optional — code snippets, prior reasoning, files
system_prompt: optional — persona/framing
```

Returns:
```json
{
  "answer": "...",
  "model": "gpt-5",
  "latency_ms": 842,
  "tokens": {"input": 47, "output": 92},
  "cost_usd": 0.0014
}
```

### `ask_the_panel(question, context?, system_prompt?)`

Fan out to every enabled provider in parallel.

```
question:      "what's wrong with this approach?"
context:       optional
system_prompt: optional — applied uniformly to all panelists
```

Returns:
```json
{
  "responses": {
    "openai":    {"answer": "...", "model": "gpt-5", "latency_ms": 800, "cost_usd": 0.001, "error": null},
    "gemini":    {"answer": "...", "model": "gemini-2.5-pro", "latency_ms": 750, "cost_usd": 0.0008, "error": null},
    "anthropic": {"answer": null, "model": "claude-opus-4-7", "error": "skipped (self)"},
    "grok":      {"answer": null, "model": "grok-4", "error": "XAI_API_KEY not set"}
  },
  "total_cost_usd": 0.0018,
  "total_latency_ms": 800
}
```

## How it works

The server is a thin layer over [LiteLLM](https://github.com/BerriAI/litellm), which provides a unified OpenAI-shaped interface to all four providers. Cost calculation comes from LiteLLM's pricing table.

## License

MIT
