second-opinion-mcp 0.3.1__py3-none-any.whl → 0.3.3__py3-none-any.whl
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.
- second_opinion_mcp/__init__.py +1 -1
- second_opinion_mcp/server.py +43 -0
- {second_opinion_mcp-0.3.1.dist-info → second_opinion_mcp-0.3.3.dist-info}/METADATA +86 -3
- second_opinion_mcp-0.3.3.dist-info/RECORD +9 -0
- second_opinion_mcp-0.3.1.dist-info/RECORD +0 -9
- {second_opinion_mcp-0.3.1.dist-info → second_opinion_mcp-0.3.3.dist-info}/WHEEL +0 -0
- {second_opinion_mcp-0.3.1.dist-info → second_opinion_mcp-0.3.3.dist-info}/entry_points.txt +0 -0
- {second_opinion_mcp-0.3.1.dist-info → second_opinion_mcp-0.3.3.dist-info}/licenses/LICENSE +0 -0
second_opinion_mcp/__init__.py
CHANGED
second_opinion_mcp/server.py
CHANGED
|
@@ -1575,6 +1575,42 @@ def _validate_startup_requirements() -> tuple[bool, str]:
|
|
|
1575
1575
|
return True, ""
|
|
1576
1576
|
|
|
1577
1577
|
|
|
1578
|
+
def _check_for_updates() -> tuple[str | None, str | None]:
|
|
1579
|
+
"""Check PyPI for newer version of second-opinion-mcp.
|
|
1580
|
+
|
|
1581
|
+
Returns:
|
|
1582
|
+
(latest_version, current_version) if update available, (None, None) otherwise.
|
|
1583
|
+
"""
|
|
1584
|
+
import urllib.request
|
|
1585
|
+
import json
|
|
1586
|
+
|
|
1587
|
+
try:
|
|
1588
|
+
from second_opinion_mcp import __version__ as current_version
|
|
1589
|
+
except ImportError:
|
|
1590
|
+
current_version = "0.0.0"
|
|
1591
|
+
|
|
1592
|
+
try:
|
|
1593
|
+
# Quick timeout to not delay startup
|
|
1594
|
+
url = "https://pypi.org/pypi/second-opinion-mcp/json"
|
|
1595
|
+
req = urllib.request.Request(url, headers={"User-Agent": "second-opinion-mcp"})
|
|
1596
|
+
with urllib.request.urlopen(req, timeout=3) as response:
|
|
1597
|
+
data = json.loads(response.read().decode())
|
|
1598
|
+
latest_version = data.get("info", {}).get("version", "0.0.0")
|
|
1599
|
+
|
|
1600
|
+
# Simple version comparison (works for semver)
|
|
1601
|
+
def parse_version(v: str) -> tuple[int, ...]:
|
|
1602
|
+
return tuple(int(x) for x in v.split(".")[:3] if x.isdigit())
|
|
1603
|
+
|
|
1604
|
+
if parse_version(latest_version) > parse_version(current_version):
|
|
1605
|
+
return latest_version, current_version
|
|
1606
|
+
|
|
1607
|
+
except Exception:
|
|
1608
|
+
# Don't fail startup on update check errors
|
|
1609
|
+
pass
|
|
1610
|
+
|
|
1611
|
+
return None, None
|
|
1612
|
+
|
|
1613
|
+
|
|
1578
1614
|
def main():
|
|
1579
1615
|
"""Run the MCP server with stdio transport."""
|
|
1580
1616
|
import sys
|
|
@@ -1585,6 +1621,13 @@ def main():
|
|
|
1585
1621
|
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
1586
1622
|
)
|
|
1587
1623
|
|
|
1624
|
+
# Check for updates (non-blocking, quick timeout)
|
|
1625
|
+
latest, current = _check_for_updates()
|
|
1626
|
+
if latest:
|
|
1627
|
+
print(f"Update available: {current} -> {latest}", file=sys.stderr)
|
|
1628
|
+
print("Run: pipx upgrade second-opinion-mcp", file=sys.stderr)
|
|
1629
|
+
print(file=sys.stderr)
|
|
1630
|
+
|
|
1588
1631
|
# Validate minimum requirements
|
|
1589
1632
|
ok, error = _validate_startup_requirements()
|
|
1590
1633
|
if not ok:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: second-opinion-mcp
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: Multi-model AI analysis for Claude - get second opinions from DeepSeek, Kimi, and OpenRouter
|
|
5
5
|
Project-URL: Homepage, https://github.com/MarvinFS/second-opinion-mcp
|
|
6
6
|
Project-URL: Repository, https://github.com/MarvinFS/second-opinion-mcp
|
|
@@ -143,6 +143,56 @@ Full workflow: parallel reviews from both models, debate, then synthesis instruc
|
|
|
143
143
|
Perform a comprehensive code review of ./myproject using review_synthesis
|
|
144
144
|
```
|
|
145
145
|
|
|
146
|
+
## Usage Examples
|
|
147
|
+
|
|
148
|
+
### Thorough Code Review Workflow
|
|
149
|
+
|
|
150
|
+
For comprehensive code reviews, use this prompt pattern with Claude Code:
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
MyProject: perform a comprehensive deep parallel code review with deepseek and kimi
|
|
154
|
+
using mcp server second-opinion - save resulting md files to the project folder
|
|
155
|
+
to the docs subfolder in md format.
|
|
156
|
+
|
|
157
|
+
After that perform Consensus debate + arbiter synthesis using same mcp server tools
|
|
158
|
+
with opus 4.5 compiling a final document for the final review.
|
|
159
|
+
|
|
160
|
+
First 2 tasks can be run in parallel.
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
This triggers parallel code_review calls to DeepSeek and Moonshot, then a consensus debate on findings, and finally Claude synthesizes the final review document.
|
|
164
|
+
|
|
165
|
+
### Quick Second Opinion
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
Use second_opinion to review this database schema:
|
|
169
|
+
CREATE TABLE users (
|
|
170
|
+
id SERIAL PRIMARY KEY,
|
|
171
|
+
email VARCHAR(255),
|
|
172
|
+
password VARCHAR(255)
|
|
173
|
+
);
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Critical Challenge
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
Use challenge to critique this proposal: "We should use a global singleton for
|
|
180
|
+
database connections because it's simpler"
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Consensus Debate
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
Use consensus to debate: "GraphQL vs REST for our internal microservices API"
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Code Review with Focus Areas
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
Use code_review on directory="./src" with focus_areas=["security", "error-handling"]
|
|
193
|
+
and save_to="./docs/reviews"
|
|
194
|
+
```
|
|
195
|
+
|
|
146
196
|
## Configuration
|
|
147
197
|
|
|
148
198
|
### Changing Providers
|
|
@@ -179,10 +229,23 @@ To update keys:
|
|
|
179
229
|
second-opinion-mcp setup
|
|
180
230
|
```
|
|
181
231
|
|
|
182
|
-
Or manually:
|
|
232
|
+
Or manually set each provider's key:
|
|
183
233
|
|
|
184
234
|
```bash
|
|
185
|
-
|
|
235
|
+
# DeepSeek (key starts with sk-)
|
|
236
|
+
python -c "import keyring; keyring.set_password('second-opinion', 'deepseek', 'sk-YOUR_DEEPSEEK_KEY')"
|
|
237
|
+
|
|
238
|
+
# Moonshot/Kimi
|
|
239
|
+
python -c "import keyring; keyring.set_password('second-opinion', 'moonshot', 'YOUR_MOONSHOT_KEY')"
|
|
240
|
+
|
|
241
|
+
# OpenRouter (key starts with sk-or-)
|
|
242
|
+
python -c "import keyring; keyring.set_password('second-opinion', 'openrouter', 'sk-or-YOUR_OPENROUTER_KEY')"
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Verify keys are configured:
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
python -c "import keyring; print('deepseek:', bool(keyring.get_password('second-opinion', 'deepseek'))); print('moonshot:', bool(keyring.get_password('second-opinion', 'moonshot'))); print('openrouter:', bool(keyring.get_password('second-opinion', 'openrouter')))"
|
|
186
249
|
```
|
|
187
250
|
|
|
188
251
|
### Claude Desktop Configuration
|
|
@@ -279,6 +342,25 @@ Use code_review with focus_areas=["security", "error-handling", "performance"]
|
|
|
279
342
|
Use code_review on directory="./src" with save_to="./docs/reviews"
|
|
280
343
|
```
|
|
281
344
|
|
|
345
|
+
## Updating
|
|
346
|
+
|
|
347
|
+
The server checks for updates on startup and notifies you if a new version is available.
|
|
348
|
+
|
|
349
|
+
To update manually:
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
pipx upgrade second-opinion-mcp
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Or reinstall:
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
pipx uninstall second-opinion-mcp
|
|
359
|
+
pipx install second-opinion-mcp
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
Your API keys are preserved in the system keyring across updates.
|
|
363
|
+
|
|
282
364
|
## Uninstalling
|
|
283
365
|
|
|
284
366
|
```bash
|
|
@@ -291,6 +373,7 @@ pipx uninstall second-opinion-mcp
|
|
|
291
373
|
# Optional: remove stored API keys
|
|
292
374
|
python -c "import keyring; keyring.delete_password('second-opinion', 'deepseek')"
|
|
293
375
|
python -c "import keyring; keyring.delete_password('second-opinion', 'moonshot')"
|
|
376
|
+
python -c "import keyring; keyring.delete_password('second-opinion', 'openrouter')"
|
|
294
377
|
```
|
|
295
378
|
|
|
296
379
|
## Security
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
second_opinion_mcp/__init__.py,sha256=6U4p4K4W9gGMT_T_lyVbgmKDFAR0fSl93hO8ALABO2Y,373
|
|
2
|
+
second_opinion_mcp/__main__.py,sha256=WDv19O6nvIH69GR_DUfXqDt-wm8bgsHNqvPm1LEIKzs,509
|
|
3
|
+
second_opinion_mcp/cli.py,sha256=A88Y0TZQ_B38YliHKzohAOLTZuGdMZzH4bEjyC1Tv_A,15279
|
|
4
|
+
second_opinion_mcp/server.py,sha256=46cHbK0GgL0VBCGI3gmTA1-vQ1jRDdQ6MsCCqWw3LVk,62237
|
|
5
|
+
second_opinion_mcp-0.3.3.dist-info/METADATA,sha256=yapnby2rQe1S9uJeNIjPeyDNLNMo5saW04hqEK4GAws,10815
|
|
6
|
+
second_opinion_mcp-0.3.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
7
|
+
second_opinion_mcp-0.3.3.dist-info/entry_points.txt,sha256=-E8BA2gFyU4qW-kJL8SV9Pg1Cc7glOCmraJoZH0PZP8,72
|
|
8
|
+
second_opinion_mcp-0.3.3.dist-info/licenses/LICENSE,sha256=dPx2Jy-Ejearvfh6IlF2PN4Srt-nZW8M4bW5EW7RPAg,1065
|
|
9
|
+
second_opinion_mcp-0.3.3.dist-info/RECORD,,
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
second_opinion_mcp/__init__.py,sha256=THy3IptvV_KjNfRHMlhqUKNucORFcyKadnH8QfzFOXI,373
|
|
2
|
-
second_opinion_mcp/__main__.py,sha256=WDv19O6nvIH69GR_DUfXqDt-wm8bgsHNqvPm1LEIKzs,509
|
|
3
|
-
second_opinion_mcp/cli.py,sha256=A88Y0TZQ_B38YliHKzohAOLTZuGdMZzH4bEjyC1Tv_A,15279
|
|
4
|
-
second_opinion_mcp/server.py,sha256=Q6ra1wffKPoT2sfU6RIbTA-V93XgwA3faW3qLIVIoDw,60696
|
|
5
|
-
second_opinion_mcp-0.3.1.dist-info/METADATA,sha256=GKMM_Oh9_UgDLQrqzP1IXX-FlUP-8PNDRqA2yANeMCA,8476
|
|
6
|
-
second_opinion_mcp-0.3.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
7
|
-
second_opinion_mcp-0.3.1.dist-info/entry_points.txt,sha256=-E8BA2gFyU4qW-kJL8SV9Pg1Cc7glOCmraJoZH0PZP8,72
|
|
8
|
-
second_opinion_mcp-0.3.1.dist-info/licenses/LICENSE,sha256=dPx2Jy-Ejearvfh6IlF2PN4Srt-nZW8M4bW5EW7RPAg,1065
|
|
9
|
-
second_opinion_mcp-0.3.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|