
Setup Tooluniverse
- 394 installs
- 1.6k repo stars
- Updated August 4, 2026
- mims-harvard/tooluniverse
setup-tooluniverse is an agent skill that installs ToolUniverse, configures credentials, registers default tools, and verifies agent calls work across MCP, CLI, and Python SDK modes in fresh dev or lab environments.
About
setup-tooluniverse in mims-harvard/ToolUniverse guides developers step-by-step through installing and configuring ToolUniverse for chat MCP mode, CLI (`tu`), or Python SDK access. The ecosystem connects to 2,000+ scientific databases and exposes 1,200+ tools, with compact MCP mode surfacing 5 core tools (list_tools, grep_tools, get_tool_info, execute_tool, find_tools) while keeping full catalogs reachable via execute_tool. Setup covers uv installation, MCP JSON for 12+ AI clients including Cursor, Claude Desktop, Claude Code, Windsurf, VS Code, Codex, and Gemini CLI, plus nine `tu` subcommands: status, list, find, grep, info, run, test, build, and serve. Developers reach for setup-tooluniverse when onboarding a lab machine, choosing MCP versus CLI versus SDK, troubleshooting uvx cold starts, or validating PubMed and related tool calls after API key configuration. The skill also copies bundled research skills into client skill directories and documents 23 agentic tools requiring LLM API keys for advanced scientific workflows.
- Installs ToolUniverse packages and dependencies
- Configures API keys and service endpoints
- Registers baseline scientific tools for agents
- Smoke-tests representative tool invocations
Setup Tooluniverse by the numbers
- 394 all-time installs (skills.sh)
- +10 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #2,010 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/mims-harvard/tooluniverse --skill setup-tooluniverseAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 394 |
|---|---|
| repo stars | ★ 1.6k |
| Last updated | August 4, 2026 |
| Repository | mims-harvard/tooluniverse ↗ |
How do you set up ToolUniverse MCP for agents?
Install ToolUniverse, configure credentials, register default tools, and verify agent calls work in a fresh dev or lab environment.
Who is it for?
Developers and researchers onboarding ToolUniverse in Cursor, Claude Code, Windsurf, or CLI environments who need MCP, tu CLI, or Python SDK access verified end-to-end.
Skip if: Teams with no scientific database or bioinformatics use cases, or environments where external MCP servers and uv package installs are blocked by policy.
When should I use this skill?
User asks to install ToolUniverse, configure MCP servers, choose MCP vs CLI vs SDK, run tu commands, troubleshoot uvx, or validate scientific tool calls.
What you get
Working MCP or CLI configuration, API key env blocks, validated tool calls, and copied ToolUniverse research skills in client directories.
- MCP or CLI configuration
- Validated tool call output
- Installed ToolUniverse skills
By the numbers
- 1200+ ToolUniverse tools across 2000+ scientific databases
- 9 tu CLI subcommands and 5 core MCP tools in compact mode
- MCP config documented for 12+ AI clients
Files
Setup ToolUniverse
Guide the user step-by-step through setting up ToolUniverse.
Agent Behavior
- Detect language from user's first message. Respond in their language; keep commands/URLs in English.
- Go one step at a time. Ask before proceeding.
- Use AskQuestion for structured choices.
- Explain briefly in plain language. Celebrate small wins.
- When something goes wrong, help troubleshoot before moving on.
Internal Notes (do not show)
ToolUniverse has 1200+ tools. The tooluniverse command enables compact mode automatically, exposing only 5 core MCP tools (list_tools, grep_tools, get_tool_info, execute_tool, find_tools) while keeping all tools accessible via execute_tool.
What is ToolUniverse?
Always explain first, in plain language:
ToolUniverse is free, open-source software connecting to 2,000+ scientific databases (PubMed, UniProt, ChEMBL, FAERS, ClinicalTrials.gov, etc.). Instead of visiting each website, you search from one place. Think of it like a universal remote for scientific databases.
Why AI assistants? The AI reads your question, figures out which databases to search, runs queries, and summarizes results. You just ask your question.
Step 1: Choose How to Use It
Present using AskQuestion:
| Mode | What it means | Who it's for |
|---|---|---|
| Chat mode | Ask questions to an AI assistant. No coding. | Most researchers. |
| Command line | Type short commands in Terminal. | Quick tests. Terminal-comfortable users. |
| Python code | Write scripts for automated pipelines. | Programmers. |
Options: "I want to ask questions" → Chat mode | "Quick try" → CLI | "I write Python" → SDK | "I don't know" → Recommend Chat mode
If Chat mode, ask which app (AskQuestion): Cursor, Claude Desktop, VS Code/Copilot, Windsurf, Claude Code, Gemini CLI, Codex, Cline/Trae/Antigravity/OpenCode. "I don't have any" → Recommend Claude Desktop.
Step 2: Install uv
Only prerequisite: uv (manages everything else automatically).
Terminal help (if needed): Mac: Cmd+Space → "Terminal" → Enter. Windows: Win key → "PowerShell" → Enter.
curl -LsSf https://astral.sh/uv/install.sh | sh(This is a safe, standard command that downloads and installs uv, a small package manager. It's widely used by Python developers. Close and reopen your terminal after it finishes.)
Verify: uv --version
CLI Setup
Make sure Step 2 is done, then try:
uvx --from tooluniverse tu status # How many tools?
uvx --from tooluniverse tu find 'drug safety' # Search by topic
uvx --from tooluniverse tu info FAERS_count_death_related_by_drug # See params
uvx --from tooluniverse tu run FAERS_count_death_related_by_drug '{"drug_name": "metformin"}'First run takes ~30s (downloads package), then instant. Shortcut: uv tool install tooluniverse → then just use tu directly.
All CLI subcommands
| Command | What it does | Example |
|---|---|---|
tu status | Show tool count and top categories | tu status |
tu list | List tools (modes: names, categories, basic, by_category, summary, custom) | tu list --mode basic --limit 20 |
tu find | Search by natural language (keyword scoring, no API key needed) | tu find 'protein structure analysis' |
tu grep | Text/regex pattern search | tu grep '^UniProt' --mode regex |
tu info | Show tool parameters and schema | tu info PubMed_search_articles |
tu run | Execute a tool | tu run PubMed_search_articles '{"query": "CRISPR"}' |
tu test | Test a tool with its example inputs | tu test UniProt_get_entry_by_accession |
tu build | Generate typed Python wrappers for Coding API | tu build --output ./my_tools |
tu serve | Start MCP stdio server (same as uvx tooluniverse) | tu serve |
Output flags (most commands except build/serve): --json (pretty) or --raw (compact, pipe-friendly).
Continue to Step 3 (API Keys).
SDK Setup
Make sure Step 2 is done. For detailed patterns, invoke the tooluniverse-sdk skill.
uv pip install tooluniverseCoding API — 3 calling patterns
Pattern 1: Direct import (typed, with autocomplete):
from tooluniverse.tools import UniProt_get_entry_by_accession
result = UniProt_get_entry_by_accession(accession="P12345")Pattern 2: Attribute access (no import needed per tool):
from tooluniverse import ToolUniverse
tu = ToolUniverse()
tu.load_tools()
result = tu.tools.UniProt_get_entry_by_accession(accession="P12345")Pattern 3: JSON-based (dynamic, for pipelines):
result = tu.run({"name": "UniProt_get_entry_by_accession", "arguments": {"accession": "P12345"}})Generate typed wrappers: tu build (creates importable Python modules with autocomplete).
Agentic Tools & Code Executor
ToolUniverse also includes 23 AI-powered agentic tools (ScientificTextSummarizer, HypothesisGenerator, ExperimentalDesignScorer, peer-review tools, etc.) and 2 code executor tools (python_code_executor, python_script_runner). These are called like any other tool — via tu.run() or execute_tool(). Agentic tools require an LLM API key (e.g., OPENAI_API_KEY).
Continue to Step 3 (API Keys).
MCP Setup (Chat Mode)
Make sure Step 2 is done (uv --version works).
Add ToolUniverse to your app's config
Config file help (if user seems unfamiliar): Config files are plain text that store settings — like a preference list for the app. You don't need to understand the format; just paste exactly what's shown below. Most apps have a Settings button that opens the file for you (see table). If the file is empty, paste the entire block. If it already has content, the agent should help merge it.
Default config (same for most clients):
{
"mcpServers": {
"tooluniverse": {
"command": "uvx",
"args": ["tooluniverse"],
"env": { "PYTHONIOENCODING": "utf-8" }
}
}
}Config file locations:
Claude Code users: skip manual MCP config — use the plugin instead. Invoke the tooluniverse-claude-code-plugin skill or run:```bash
claude plugin marketplace add mims-harvard/ToolUniverse
claude plugin install tooluniverse@tooluniverse
```
This installs MCP server + 115 skills + slash commands in one step.
| Client | File | How to Access |
|---|---|---|
| Cursor | ~/.cursor/mcp.json | Settings → MCP → Add new global MCP server |
| Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json | Settings → Developer → Edit Config |
| Claude Code | ~/.claude.json or .mcp.json | claude mcp add or edit directly (or use plugin — see above) |
| Windsurf | ~/.codeium/windsurf/mcp_config.json | MCP hammer icon → Configure |
| Cline | cline_mcp_settings.json | Cline panel → MCP Servers → Configure |
| Gemini CLI | ~/.gemini/settings.json | gemini mcp add or edit directly |
| Trae | .trae/mcp.json | Ctrl+U → AI Management → MCP → Configure |
Different formats: VS Code uses "servers" key with "type": "stdio". Codex uses TOML. OpenCode uses "mcp" key. See references/mcp-configs.md for these.
Continue to Step 3 (API Keys).
Step 3: API Keys
Many tools work without keys, but some unlock powerful features. Ask research interests first (AskQuestion):
- Literature / Drug discovery / Protein structure / Genomics / Rare diseases / Enzymology / Patent search / AI analysis / All / Skip
Map to recommended keys (2-4 to start). Walk through one at a time: explain what it unlocks, give registration link, wait for key, add to config.
Tier 1 (Core — recommend for most users):
| Key | Unlocks | Free? | Registration |
|---|---|---|---|
NCBI_API_KEY | PubMed (rate limit 3→10/s) | Yes | https://account.ncbi.nlm.nih.gov/settings/ |
NVIDIA_API_KEY | 16 tools: AlphaFold2, docking, genomics | Yes | https://build.nvidia.com |
BIOGRID_API_KEY | Protein interaction queries | Yes | https://webservice.thebiogrid.org/ |
FDA_API_KEY | FDA adverse events, drug labels (rate 240→1000/min) | Yes | https://open.fda.gov/apis/authentication/ |
Tier 2 (Specialized — based on interests):
| Key | Unlocks | Registration |
|---|---|---|
DISGENET_API_KEY | Gene-disease associations | https://disgenet.com/academic-apply |
OMIM_API_KEY | Mendelian/rare disease | https://omim.org/api |
ONCOKB_API_TOKEN | Precision oncology | https://www.oncokb.org/apiAccess |
UMLS_API_KEY | Medical terminology | https://uts.nlm.nih.gov/uts/ |
See API_KEYS_REFERENCE.md for the complete list with all tiers.
Adding keys:
Chat mode — add to env block in MCP config:
"env": {
"PYTHONIOENCODING": "utf-8",
"NCBI_API_KEY": "your_key_here"
}CLI — set environment variables:
export NCBI_API_KEY="your_key_here" # Current session
echo 'export NCBI_API_KEY="key"' >> ~/.zshrc # Persist across sessionsSDK — same as CLI (export or .env file).
Step 4: Test Together
Don't just tell — do it WITH the user.
Chat mode: Ask user to restart app. Then run a test call yourself: 1. list_tools or grep_tools with "PubMed" — confirm tools visible 2. execute_tool("PubMed_search_articles", {"query": "CRISPR", "max_results": 1}) — confirm it works 3. Celebrate: "It works! You have access to 1200+ scientific tools."
CLI: Run together:
tu status && tu find 'protein' && tu run PubMed_search_articles '{"query": "CRISPR", "max_results": 1}'SDK: Run the Python snippet from SDK Setup together.
If issues: Most common: app not restarted, uv not in PATH (reopen terminal), JSON syntax error in config.
Step 5: Install Skills (Recommended for Chat Mode)
Skills are pre-built research workflows that turn basic tool calls into expert investigations.
Chat mode users: The agent should run this for the user:
git clone --depth 1 https://github.com/mims-harvard/ToolUniverse.git /tmp/tu-skillsThen copy to client's skill directory:
| Client | Command |
|---|---|
| Cursor | mkdir -p .cursor/skills && cp -r /tmp/tu-skills/skills/* .cursor/skills/ |
| Claude Code | mkdir -p .claude/skills && cp -r /tmp/tu-skills/skills/* .claude/skills/ |
| Windsurf | mkdir -p .windsurf/skills && cp -r /tmp/tu-skills/skills/* .windsurf/skills/ |
| Codex | mkdir -p .agents/skills && cp -r /tmp/tu-skills/skills/* .agents/skills/ |
| Gemini CLI | mkdir -p .gemini/skills && cp -r /tmp/tu-skills/skills/* .gemini/skills/ |
Clean up: rm -rf /tmp/tu-skills
Skills activate automatically based on user's question. Try: "Research the drug metformin" or "What does the literature say about CRISPR in cancer?"
CLI users: Skills are designed for AI chat agents. Use tu find, tu info, tu run instead. For full multi-step workflows, use Chat mode or build SDK pipelines.
What's Next? (Guided First Use)
Don't list suggestions — run a live demo WITH the user.
Pick a demo query based on research interests (from Step 3):
| Interest | First query | Skill |
|---|---|---|
| Literature | "What does the literature say about CRISPR in cancer?" | literature-deep-research |
| Drug discovery | "Research the drug metformin" | drug-research |
| Protein structure | "Find protein structures for human EGFR" | protein-structure-retrieval |
| Genomics | "What genes are associated with type 2 diabetes?" | disease-research |
| Rare diseases | "Patient with progressive ataxia and oculomotor apraxia — differential diagnosis?" | rare-disease-diagnosis |
| Drug safety | "What are the adverse events for pembrolizumab?" | pharmacovigilance |
| General | "Research the drug aspirin" | drug-research |
Run the demo — invoke the skill and show real results.
Prompt cheat sheet (share after demo)
Chat mode users:
1. "Research the drug [name]" — full drug profile
2. "Research [disease]" — comprehensive disease analysis
3. "What are the known targets of [drug]?" — target intelligence
4. "What does the literature say about [topic]?" — deep literature review
5. "Find protein structures for [protein]" — 3D structures
6. "Is [variant] pathogenic?" — variant interpretation
7. "What drugs could be repurposed for [disease]?" — repurposing
8. "What are the adverse events for [drug]?" — safety analysis
9. "Find clinical trials for [disease/drug]" — trial matching
10. "What are the protein interactions for [gene]?" — interaction network
11. "What are the clinical guidelines for [condition]?" — practice guidelines
12. "Check drug interactions between [drug1] and [drug2]" — DDI analysis
>
Just ask naturally — I'll figure out which databases to search.
CLI users:
```bash
tu find 'drug safety' # Discover tools
tu info PubMed_search_articles # Check parameters
tu run PubMed_search_articles '{"query": "CRISPR cancer", "max_results": 3}'
tu run UniProt_get_entry_by_accession '{"accession": "P12345"}'
tu run FAERS_count_death_related_by_drug '{"drug_name": "metformin"}'
```
Write Agent Memory
After setup, write a reminder to the agent's memory file so future sessions know ToolUniverse is available.
| Client | File |
|---|---|
| Cursor | .cursor/rules/tooluniverse.md |
| Claude Code | CLAUDE.md or .claude/CLAUDE.md (append) |
| Windsurf | .windsurf/rules/tooluniverse.md |
| VS Code/Copilot | .github/copilot-instructions.md (append) |
| Codex / OpenCode | AGENTS.md (append) |
| Gemini CLI | GEMINI.md (append) |
| Cline | .clinerules/tooluniverse.md |
| Trae | .trae/rules/tooluniverse.md |
Content:
# ToolUniverse
For any scientific research question (drugs, genes, proteins, diseases, literature, clinical trials, etc.), invoke the `tooluniverse` skill — it routes to specialized research skills and 1,200+ database tools.Append (don't overwrite). Check for existing section first. Ask user permission.
Team / Project-Level Setup
If setting up ToolUniverse for a team or shared project:
Shared API keys: Create a .env file at the project root with all keys. Most clients and the CLI/SDK will pick up keys from .env automatically:
NCBI_API_KEY=your_shared_key
NVIDIA_API_KEY=your_shared_keyProject-level MCP config (so all team members get ToolUniverse automatically):
- Cursor:
.cursor/mcp.jsonin project root - Claude Code:
.mcp.jsonin project root - VS Code:
.vscode/mcp.jsonin project root - Windsurf: project-level via Windsurf UI
Project-level skills: Install skills into the project (e.g., .cursor/skills/) so all team members share them.
Team-wide upgrade: Each team member runs uv cache clean tooluniverse and restarts their app. To pin a specific version, use "args": ["tooluniverse==X.Y.Z"] in the MCP config.
Common Issues
| Issue | Fix |
|---|---|
requires-python >= 3.10 | uv python install 3.12 |
uvx: command not found | Run install script from Step 2, restart terminal |
| Context window overflow | Verify using uvx tooluniverse (compact mode is default) |
ModuleNotFoundError | uv pip install tooluniverse[all] |
| MCP server won't start | Test: uvx tooluniverse in terminal. Check JSON syntax. |
| API key 401/403 | Check key in env block, restart app, verify key name |
| Upgrade needed | uv cache clean tooluniverse then restart app |
Still stuck? GitHub issues or email Shanghua Gao.
Quick Reference
- Default:
uvx tooluniverse— auto-installs, compact mode - Upgrade:
uv cache clean tooluniverse+ restart - All scientific API keys are free
- Skills: https://github.com/mims-harvard/ToolUniverse/tree/main/skills
ToolUniverse API Keys Reference
Detailed guide for every API key used by ToolUniverse. Use this when walking users through key setup.
---
Tier 1: Core Scientific Keys
NCBI_API_KEY
- Service: NCBI (National Center for Biotechnology Information) / PubMed
- Required: No (optional, but strongly recommended)
- Tools that use it:
PubMed_search_articles,PubMed_get_article, and 3 more PubMed tools - What it does: Increases PubMed API rate limit from 3 requests/second to 10 requests/second. Without it, heavy literature searches may be throttled.
- How to get it:
1. Go to https://account.ncbi.nlm.nih.gov/ and sign in (via Google, ORCiD, eRA Commons, or Login.gov) 2. Go to Settings at https://account.ncbi.nlm.nih.gov/settings/ 3. Scroll to "API Key Management" at the bottom 4. Click "Create an API Key" 5. Copy the generated key
- Env variable:
NCBI_API_KEY
NVIDIA_API_KEY
- Service: NVIDIA NIM (NVIDIA Inference Microservices)
- Required: Yes (for NIM tools)
- Tools that use it: 16
NvidiaNIM_*tools including AlphaFold2 structure prediction, molecular docking (DiffDock), ESM protein embeddings, and genomics tools - What it does: Provides access to GPU-accelerated bioinformatics models hosted by NVIDIA. Covers protein structure prediction, molecular docking, and sequence analysis.
- How to get it:
1. Go to https://build.nvidia.com 2. Sign in or create a free NVIDIA account 3. Navigate to any NIM API (e.g., AlphaFold2) 4. Click "Get API Key" in the top right 5. Copy the key (starts with nvapi-)
- Env variable:
NVIDIA_API_KEY - Free tier: Yes, generous free credits for API calls
BIOGRID_API_KEY
- Service: BioGRID (Biological General Repository for Interaction Datasets)
- Required: Yes (tools will not work without it)
- Tools that use it:
BioGRID_get_interactions - What it does: Enables querying the BioGRID database for protein-protein interactions, genetic interactions, and chemical associations.
- How to get it:
1. Go to https://webservice.thebiogrid.org/ 2. Click "Register" to create a free account 3. After registration, your API access key will be provided 4. You can also find it under your account settings
- Env variable:
BIOGRID_API_KEY
DISGENET_API_KEY
- Service: DisGeNET (Disease-Gene Network)
- Required: Yes (tools will not work without it)
- Tools that use it: 5 DisGeNET tools for gene-disease associations, variant-disease associations, and disease enrichment analysis
- What it does: Provides access to one of the largest collections of gene-disease associations, integrating data from expert-curated repositories, GWAS catalogs, and animal models.
- How to get it:
1. Go to https://disgenet.com/academic-apply (for academic/non-profit use) 2. Fill out the application with your institutional email 3. Verify your email within 24 hours 4. Wait for approval (typically within 7 days) 5. Once approved, find your API key in your account settings
- Env variable:
DISGENET_API_KEY - Note: Free for academic use; commercial use requires a license
---
Tier 2: Specialized Scientific Keys
OMIM_API_KEY
- Service: OMIM (Online Mendelian Inheritance in Man)
- Required: Yes (tools will not work without it)
- Tools that use it: 4 OMIM tools for Mendelian disease data, gene-phenotype relationships, and clinical synopses
- What it does: Provides access to the authoritative database of human genes and genetic phenotypes, particularly for inherited diseases.
- How to get it:
1. Go to https://omim.org/api 2. Click "Request API Key" 3. Fill out the registration form (academic/institutional email recommended) 4. API key is typically emailed within 1-2 business days
- Env variable:
OMIM_API_KEY - Note: Approval may take time; academic users are prioritized
ONCOKB_API_TOKEN
- Service: OncoKB (Precision Oncology Knowledge Base)
- Required: Yes (tools will not work without it)
- Tools that use it: OncoKB tools for cancer gene annotations, actionable mutations, and therapeutic implications
- What it does: Provides access to MSK's precision oncology knowledge base with FDA-recognized biomarker-drug associations, levels of evidence for therapeutic implications.
- How to get it:
1. Go to https://www.oncokb.org/apiAccess 2. Click "Request API Access" 3. Register with your institutional email 4. For academic use, select the free academic license 5. Token is provided after approval
- Env variable:
ONCOKB_API_TOKEN - Note: Free for academic/research use
UMLS_API_KEY
- Service: UMLS (Unified Medical Language System) / NLM
- Required: Yes (tools will not work without it)
- Tools that use it: 5 UMLS tools for medical concept lookup, terminology mapping, cross-referencing between medical vocabularies (ICD, SNOMED, MeSH, etc.)
- What it does: Maps between medical terminologies, finds concept definitions, and navigates hierarchical relationships between medical concepts.
- How to get it:
1. Go to https://uts.nlm.nih.gov/uts/ 2. Click "Sign Up" to create a UMLS Terminology Services account 3. You'll need to accept the UMLS license agreement 4. After approval, go to "My Profile" to find your API key
- Env variable:
UMLS_API_KEY - Note: Requires license agreement acceptance; usually instant for US-based users
USPTO_API_KEY
- Service: USPTO (United States Patent and Trademark Office)
- Required: Yes (tools will not work without it)
- Tools that use it: 6 USPTO tools for patent search, patent data retrieval, and patent analysis
- What it does: Enables searching and retrieving US patent documents, patent claims, and patent family information.
- How to get it:
1. Create a USPTO account at https://my.uspto.gov/ (if you don't have one) 2. Go to the API manager at https://account.uspto.gov/api-manager/ 3. Log in with your USPTO credentials 4. Register for an API key -- it will be emailed to you
- Env variable:
USPTO_API_KEY
SEMANTIC_SCHOLAR_API_KEY
- Service: Semantic Scholar (Allen Institute for AI)
- Required: No (optional, but recommended for heavy literature use)
- Tools that use it:
SemanticScholar_search_papers - What it does: Increases rate limit from 1 request/second to 100 requests/second. Essential if doing bulk literature searches or citation analysis.
- How to get it:
1. Go to https://www.semanticscholar.org/product/api 2. Click "Request API Key" 3. Fill out the form with your use case 4. Key is typically emailed within a few days
- Env variable:
SEMANTIC_SCHOLAR_API_KEY
FDA_API_KEY
- Service: openFDA
- Required: No (optional, raises rate limits)
- Tools that use it: OpenFDA tools and FAERS adverse event analytics
- What it does: Increases openFDA rate limit from 240 requests/minute to 1000 requests/minute. Useful for drug safety signal analysis.
- How to get it:
1. Go to https://open.fda.gov/apis/authentication/ 2. Enter your email to request a key 3. Key is emailed instantly
- Env variable:
FDA_API_KEY
BRENDA_EMAIL + BRENDA_PASSWORD
- Service: BRENDA (Braunschweig Enzyme Database)
- Required: Yes (tools will not work without both)
- Tools that use it: 3 BRENDA tools for enzyme kinetics, substrate specificity, and enzyme functional data
- What it does: Provides access to the world's most comprehensive enzyme database with kinetic parameters (Km, Vmax, kcat), substrate/product data, and enzyme classifications.
- How to get it:
1. Go to https://brenda-enzymes.org/register.php 2. Fill in email, password, name, and scientific field 3. Complete the captcha and submit 4. Confirm your email 5. Use the email and password you registered with as the API credentials
- Env variables:
BRENDA_EMAILandBRENDA_PASSWORD - Note: This uses your login credentials, not a separate API key
MOUSER_API_KEY
- Service: Mouser Electronics
- Required: Yes (tools will not work without it)
- Tools that use it: 4 Mouser tools for electronic component search by keyword, part number, and manufacturer
- What it does: Provides access to Mouser's comprehensive catalog of electronic components, including ICs, resistors, capacitors, microcontrollers, and more. Includes pricing, availability, datasheets, and specifications.
- How to get it:
1. Go to https://www.mouser.com/api-search/ 2. Click "Sign Up For Search API" 3. Fill out the registration form (requires business/academic email) 4. API key is typically provided instantly after email verification
- Env variable:
MOUSER_API_KEY - Free tier: Yes, 1,000 requests/day, 30 requests/minute
DIGIKEY_CLIENT_ID + DIGIKEY_CLIENT_SECRET
- Service: Digi-Key Electronics
- Required: Yes (tools will not work without both)
- Tools that use it: 4 Digi-Key tools for product search, detailed product info, category browsing, and manufacturer listings
- What it does: Provides access to Digi-Key's extensive catalog of electronic components with detailed specifications, pricing, inventory, parametric search, and technical documentation.
- How to get it:
1. Go to https://developer.digikey.com/ 2. Click "Register" to create a free developer account 3. After login, go to "Organization" → "Production Apps" 4. Click "Create Production App" 5. Fill in app details (name, description, OAuth callback URL: https://localhost/callback) 6. After creation, copy the Client ID and Client Secret
- Env variables:
DIGIKEY_CLIENT_IDandDIGIKEY_CLIENT_SECRET - Free tier: Yes, 1,000 requests/day, 120 requests/minute
- Note: Uses OAuth2 authentication with automatic token refresh. The tool handles token management automatically.
---
Tier 3: LLM Provider Keys
These keys power ToolUniverse's agentic features -- tools that use LLMs to synthesize results, plan multi-step analyses, and generate reports. At least one LLM provider key is needed for these features.
The system checks providers in this order: Azure OpenAI -> OpenRouter -> Gemini. Configure whichever you prefer.
GEMINI_API_KEY
- Service: Google Gemini
- Required: No (one of the LLM providers needed for agentic features)
- What it does: Powers agentic tools using Google's Gemini models. Good default choice due to generous free tier.
- How to get it:
1. Go to https://aistudio.google.com/apikey 2. Sign in with your Google account 3. Click "Create API Key" (a default Google Cloud project is created automatically for new users) 4. Copy the key
- Env variable:
GEMINI_API_KEY - Free tier: Yes, generous free usage limits
OPENROUTER_API_KEY
- Service: OpenRouter
- Required: No (alternative LLM provider)
- What it does: Provides access to 100+ LLM models through a single API. Pay-per-use pricing, good flexibility.
- How to get it:
1. Go to https://openrouter.ai/ 2. Sign up or log in 3. Go to https://openrouter.ai/keys 4. Click "Create Key" 5. Add credits to your account for usage
- Env variable:
OPENROUTER_API_KEY
OPENAI_API_KEY
- Service: OpenAI
- Required: No (alternative LLM provider, also used for embeddings)
- What it does: Powers embedding-based tool finding and can serve as an LLM provider for agentic features.
- How to get it:
1. Go to https://platform.openai.com/ 2. Sign up or log in 3. Go to API Keys section 4. Click "Create new secret key" 5. Copy the key (starts with sk-)
- Env variable:
OPENAI_API_KEY
AZURE_OPENAI_API_KEY
- Service: Azure OpenAI Service
- Required: No (enterprise alternative to direct OpenAI)
- What it does: Same capabilities as OpenAI but through Azure infrastructure. Preferred for enterprise/institutional users.
- How to get it:
1. Go to Azure Portal (https://portal.azure.com) 2. Create or navigate to your Azure OpenAI resource 3. Go to "Keys and Endpoint" in the resource 4. Copy Key 1 or Key 2
- Env variables:
AZURE_OPENAI_API_KEYand optionallyAZURE_OPENAI_ENDPOINT - Note: Also set
AZURE_OPENAI_ENDPOINTif not using the default endpoint
ANTHROPIC_API_KEY
- Service: Anthropic (Claude)
- Required: No (alternative LLM provider)
- What it does: Enables Claude-based features.
- How to get it:
1. Go to https://console.anthropic.com/ 2. Sign up or log in 3. Go to API Keys section 4. Create a new key
- Env variable:
ANTHROPIC_API_KEY
HF_TOKEN
- Service: HuggingFace
- Required: No (optional, for model/dataset access)
- What it does: Enables access to gated HuggingFace models and datasets, and the HF Inference API for embeddings.
- How to get it:
1. Go to https://huggingface.co/settings/tokens 2. Sign up or log in 3. Click "New token" 4. Select "Read" access (sufficient for most uses) 5. Copy the token (starts with hf_)
- Env variable:
HF_TOKEN - Free tier: Yes
---
Quick Setup by Research Area
| Research Area | Recommended Keys |
|---|---|
| Literature/publications | NCBI_API_KEY, SEMANTIC_SCHOLAR_API_KEY |
| Drug discovery | NVIDIA_API_KEY, DISGENET_API_KEY, BIOGRID_API_KEY |
| Protein structure | NVIDIA_API_KEY |
| Rare diseases | OMIM_API_KEY, DISGENET_API_KEY, UMLS_API_KEY |
| Oncology | ONCOKB_API_TOKEN, DISGENET_API_KEY |
| Enzymology | BRENDA_EMAIL + BRENDA_PASSWORD |
| Drug safety | FDA_API_KEY, UMLS_API_KEY |
| Patents | USPTO_API_KEY |
| Electronic components/IC design | MOUSER_API_KEY, DIGIKEY_CLIENT_ID + DIGIKEY_CLIENT_SECRET |
| AI-powered analysis | Any one of: GEMINI_API_KEY, OPENROUTER_API_KEY, OPENAI_API_KEY |
| Full setup (all features) | All Tier 1 + relevant Tier 2 + one Tier 3 key |
Claude Desktop Setup
⚠️ The PATH Problem — Read This Before Writing Any Config
Claude Desktop is a GUI app. It launches in a clean environment and does not inherit your shell's PATH. This means if uvx lives in ~/.local/bin/uvx (the default for the uv curl installer), Claude Desktop cannot find it — and will show a silent failure like "Failed to spawn process" or "ENOENT" with no helpful error message.
You must resolve this before writing the config. There are three ways:
---
Fix A — Homebrew (macOS, recommended, permanent)
Homebrew installs uvx to /opt/homebrew/bin/uvx (Apple Silicon) or /usr/local/bin/uvx (Intel), which Claude Desktop can always find.
brew install uvIf you already installed uv via the curl installer, also run:
brew link uv --overwriteVerify the Homebrew binary exists (Claude Desktop will use this path directly):
/opt/homebrew/bin/uvx --version # Apple Silicon Mac
/usr/local/bin/uvx --version # Intel MacWith Homebrew uv installed, the standard config works:
{
"mcpServers": {
"tooluniverse": {
"command": "uvx",
"args": ["--refresh", "tooluniverse"],
"env": {
"PYTHONIOENCODING": "utf-8"
}
}
}
}---
Fix B — Use the absolute path (all Macs, no Homebrew needed)
Find where uvx actually lives:
which uvxCommon outputs:
- Homebrew Apple Silicon:
/opt/homebrew/bin/uvx - Homebrew Intel:
/usr/local/bin/uvx - curl installer:
/Users/yourname/.local/bin/uvx
Use that full path as "command" in the config:
{
"mcpServers": {
"tooluniverse": {
"command": "/Users/yourname/.local/bin/uvx",
"args": ["--refresh", "tooluniverse"],
"env": {
"PYTHONIOENCODING": "utf-8"
}
}
}
}Replace /Users/yourname/.local/bin/uvx with the actual output of which uvx.
---
Fix C — Symlink (Linux / advanced)
sudo ln -sf "$(which uvx)" /usr/local/bin/uvx---
Writing the Config
Config file location:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Use the one-liner to safely create or merge without overwriting existing servers:
python3 -c "
import json, os
p = os.path.expanduser('~/Library/Application Support/Claude/claude_desktop_config.json')
os.makedirs(os.path.dirname(p), exist_ok=True)
cfg = json.load(open(p)) if os.path.exists(p) else {}
cfg.setdefault('mcpServers', {})['tooluniverse'] = {
'command': 'uvx', 'args': ['--refresh', 'tooluniverse'],
'env': {'PYTHONIOENCODING': 'utf-8'}
}
json.dump(cfg, open(p, 'w'), indent=2)
print('Done:', p)
"If the user installed uv via curl (not Homebrew), replace 'command': 'uvx' with 'command': '/Users/yourname/.local/bin/uvx' using their actual path from which uvx.
Restarting Claude Desktop
Use ⌘Q (not just closing the window) to fully quit, then reopen.
⏱️ First launch takes 60–90 seconds while Claude Desktop downloads and installs ToolUniverse.
Verifying MCP Tools Are Loaded
Claude Desktop's UI for MCP tools has changed across versions — look for whichever of these appears in your chat input bar:
- Newer versions: A "Search and tools" button (or a + icon) at the bottom of the chat input. Click it → you should see
tooluniverselisted under connected tools/connectors. You can toggle it on/off from here. - Older versions: A 🔨 hammer icon in the bottom-right of the chat input. Click it to see the list of available tools from
tooluniverse.
If neither appears, check Settings → Developer → MCP Servers — it shows each server's connection status and any error messages.
Verifying in the Logs
While Claude Desktop is loading, monitor the MCP logs:
tail -f ~/Library/Logs/Claude/mcp*.log # macOS
tail -f ~/.config/Claude/logs/mcp*.log # LinuxLook for "tooluniverse" connected — that confirms it worked.
Common error messages and what they mean:
ENOENT/spawn uvx ENOENT→ uvx not found; use absolute path or Homebrew fixspawn /Users/you/.local/bin/uvx ENOENT→ wrong absolute path; runwhich uvxagainexit 1immediately → runuvx tooluniverse --helpin terminal to see the actual error
Installing Skills (Required)
Skills are required for ToolUniverse to work as an intelligent research assistant. Run in terminal:
Option A — npx (quickest):
npx skills add mims-harvard/ToolUniverse --allIf npx is not found, install Node.js from nodejs.org (LTS version includes npx), then retry.
Option B — git clone (if npx fails):
git clone --depth 1 --filter=blob:none --sparse https://github.com/mims-harvard/ToolUniverse.git /tmp/tu-skills
cd /tmp/tu-skills && git sparse-checkout set skills
# macOS — adjust path for Linux (~/.config/Claude/skills/) or Windows (%APPDATA%\Claude\skills\)
mkdir -p ~/Library/Application\ Support/Claude/skills && cp -r /tmp/tu-skills/skills/* ~/Library/Application\ Support/Claude/skills/
rm -rf /tmp/tu-skillsVerifying Skills Are Installed
After running npx skills add, check the terminal output — it prints the exact directory where skills were installed. Use that path to verify:
ls <path-from-npx-output> | grep tooluniverseIf the output didn't show the path, the default location for Claude Desktop varies by OS:
- macOS:
~/Library/Application Support/Claude/skills/ - Linux:
~/.config/Claude/skills/ - Windows:
%APPDATA%\Claude\skills\
# macOS example:
ls ~/Library/Application\ Support/Claude/skills | grep tooluniverse✅ Pass: You see folders like tooluniverse, tooluniverse-drug-research, etc. → skills are ready. ❌ Fail: Nothing listed → wrong directory or install didn't complete. Check SKILLS_CATALOG.md and retry.
Smoke test — in Claude Desktop, say:
"Use the tooluniverse skill to research the drug metformin"If the response is plain text with no tool calls, skills are not in the right directory.
Setup ToolUniverse - Usage Examples
Real-world examples of using the setup-tooluniverse skill.
Example 1: First-Time Setup for Cursor
User Request: "I want to use ToolUniverse in Cursor"
Agent Response:
1. Check Prerequisites
python scripts/check_prerequisites.pyOutput shows:
- ✓ Python 3.12 (compatible)
- ✓ pip available
- ✓ uv available
- ✓ Cursor config found
2. Install ToolUniverse
pip install tooluniverse3. Verify Installation
python scripts/verify_installation.pyOutput shows:
- ✓ Import successful (v1.0.17)
- ✓ Loaded 764 tools
- ✓ CLI commands available
4. Configure MCP
Create ~/Library/Application Support/Cursor/User/mcp.json:
{
"mcpServers": {
"tooluniverse": {
"command": "tooluniverse-smcp-stdio",
"args": ["--compact-mode"]
}
}
}5. Test Configuration
python scripts/test_mcp_connection.pyOutput shows:
- ✓ Config found and valid
- ✓ ToolUniverse configured
- ✓ Compact mode enabled
- ✓ Command available
6. Restart Cursor and verify MCP server appears
Example 2: Troubleshooting Installation
User Request: "ToolUniverse isn't working in Cursor"
Agent Response:
1. Run Diagnostics
python scripts/diagnose_setup.pyReport identifies issues:
- ❌ tooluniverse-smcp-stdio not found in PATH
- ⚠️ Multiple Python installations detected
2. Fix PATH Issue
# Find where pip installed scripts
python -m pip show tooluniverse | grep Location
# Add to PATH in ~/.zshrc or ~/.bashrc
export PATH="$HOME/.local/bin:$PATH"
# Reload shell
source ~/.zshrc3. Verify Fix
which tooluniverse-smcp-stdio
# Should show: /Users/username/.local/bin/tooluniverse-smcp-stdio4. Retest
python scripts/verify_installation.py
# Should now show all checks passingExample 3: Development Setup
User Request: "I'm developing ToolUniverse tools and need to test them"
Agent Response:
1. Clone Repository
git clone https://github.com/mims-harvard/ToolUniverse.git
cd ToolUniverse2. Install in Development Mode
pip install -e .3. Configure MCP for Development
In mcp.json:
{
"mcpServers": {
"tooluniverse-dev": {
"command": "python3",
"args": [
"-m",
"tooluniverse.smcp_server",
"--compact-mode",
"--verbose"
],
"cwd": "/path/to/ToolUniverse"
}
}
}4. Verify Development Setup
python scripts/verify_installation.pyShows development version is active
Example 4: Context Overflow Issue
User Request: "Cursor is super slow and keeps erroring when ToolUniverse loads"
Agent Response:
Diagnosis: Not using compact mode, causing context overflow.
1. Check Current Config
python scripts/test_mcp_connection.pyOutput shows:
- ⚠️ Compact mode NOT enabled
2. Fix Configuration
Update mcp.json to add --compact-mode:
{
"mcpServers": {
"tooluniverse": {
"command": "tooluniverse-smcp-stdio",
"args": ["--compact-mode"] // ← Add this
}
}
}3. Restart Cursor
4. Verify Fix
- MCP server should load quickly
- Only 5 tools shown in tool list
- Can still execute all 764+ tools via execute_tool
Example 5: Specific Tool Categories
User Request: "I only need protein and chemistry tools"
Agent Response:
1. List Available Categories
python scripts/list_tool_categories.pyShows categories like:
- UniProt (45 tools)
- ChEMBL (38 tools)
- PDB (25 tools)
- etc.
2. Configure Specific Categories
In mcp.json:
{
"mcpServers": {
"tooluniverse": {
"command": "tooluniverse-smcp-stdio",
"args": [
"--categories",
"UniProt",
"ChEMBL",
"PDB"
]
}
}
}3. Restart and Verify
Note: Even with specific categories, may cause context issues. Compact mode still recommended.
Example 6: UV Installation for Better Isolation
User Request: "I want to keep ToolUniverse isolated from my other Python projects"
Agent Response:
1. Install UV
curl -LsSf https://astral.sh/uv/install.sh | sh2. Create Dedicated Environment
mkdir -p ~/tooluniverse-env
cd ~/tooluniverse-env
uv pip install tooluniverse3. Configure MCP with UV
In mcp.json:
{
"mcpServers": {
"tooluniverse": {
"command": "uv",
"args": [
"--directory",
"/Users/username/tooluniverse-env",
"run",
"tooluniverse-smcp-stdio",
"--compact-mode"
]
}
}
}4. Test
python scripts/test_mcp_connection.pyExample 7: Python Version Incompatibility
User Request: "Getting error about Python version"
Agent Response:
1. Check Version
python3 --version
# Output: Python 3.9.7Problem: ToolUniverse requires 3.10-3.13
2. Install Compatible Python
macOS:
brew install python@3.12Ubuntu:
sudo apt install python3.12 python3.12-pip3. Install with Specific Version
python3.12 -m pip install tooluniverse4. Update MCP Config
If needed, specify Python version:
{
"mcpServers": {
"tooluniverse": {
"command": "python3.12",
"args": [
"-m",
"tooluniverse.smcp_server",
"--compact-mode"
]
}
}
}Example 8: Windows Setup
User Request: "Setting up on Windows 11"
Agent Response:
1. Check Prerequisites (PowerShell)
python --version
# Should show 3.10-3.13
pip --version2. Install ToolUniverse
pip install tooluniverse3. Find Config Location
%APPDATA%\Cursor\User\mcp.json4. Create Config
{
"mcpServers": {
"tooluniverse": {
"command": "tooluniverse-smcp-stdio",
"args": ["--compact-mode"]
}
}
}5. Test (PowerShell)
python scripts/verify_installation.pyExample 9: API Keys Configuration
User Request: "Some tools need API keys, how do I configure them?"
Agent Response:
1. Check Which Tools Need Keys
Most tools don't need API keys. Optional ones:
- OpenAI/Anthropic: For agentic tools
- UMLS: For medical terminology
2. Configure via Environment
Create .env file in project:
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
UMLS_API_KEY=your-key3. Or Configure in MCP
In mcp.json:
{
"mcpServers": {
"tooluniverse": {
"command": "tooluniverse-smcp-stdio",
"args": ["--compact-mode"],
"env": {
"OPENAI_API_KEY": "sk-...",
"UMLS_API_KEY": "your-key"
}
}
}
}Security Note: Don't commit API keys to git!
Example 10: Complete Fresh Setup
User Request: "Walk me through complete setup from scratch"
Agent Response:
# 1. Check prerequisites
cd ~/.cursor/skills/setup-tooluniverse
python scripts/check_prerequisites.py
# 2. Install ToolUniverse
pip install tooluniverse
# 3. Verify installation
python scripts/verify_installation.py
# 4. Create MCP config
cat > ~/Library/Application\ Support/Cursor/User/mcp.json << 'EOF'
{
"mcpServers": {
"tooluniverse": {
"command": "tooluniverse-smcp-stdio",
"args": ["--compact-mode"]
}
}
}
EOF
# 5. Test configuration
python scripts/test_mcp_connection.py
# 6. Restart Cursor (manual step)
# 7. Verify in Cursor
# - Check MCP servers list
# - Try: list_tools
# - Try: grep_tools with keyword "protein"Expected Timeline: 5-10 minutes total
Common Error Messages and Solutions
"Command not found: tooluniverse-smcp-stdio"
Solution: Scripts directory not in PATH
pip install --force-reinstall tooluniverse
# or add to PATH: export PATH="$HOME/.local/bin:$PATH""requires-python = '>=3.10'"
Solution: Python version too old
# Install compatible Python
brew install python@3.12 # macOS
# or download from python.org"ModuleNotFoundError: No module named 'tooluniverse'"
Solution: Not installed or wrong Python
# Verify installation
pip show tooluniverse
# If not installed
pip install tooluniverse"Context window overflow" or slow performance
Solution: Enable compact mode
"args": ["--compact-mode"] // Add to mcp.json"Directory not found" (uv configs)
Solution: Create directory
mkdir -p ~/tooluniverse-env
cd ~/tooluniverse-env
uv pip install tooluniverseReporting a ToolUniverse Issue
Use this when the user is stuck and the Common Issues table hasn't resolved the problem.
Agent: Compose the Issue Body
You have all the context from the conversation. Fill in the template below — do not ask the user to run any commands.
Title: [one-line summary, e.g. "Trae: tooluniverse MCP server not appearing after restart"]
**Client**: [Cursor / Trae / Claude Desktop / VS Code / Windsurf / etc.]
**OS**: [Windows 11 / macOS 14 / Ubuntu 22.04 — be specific]
**uv version**: [from Step 1 output earlier, or "unknown"]
**ToolUniverse version**: [from `uvx tooluniverse --version` output, or "unknown"]
**What I did**
1. [first step the user took]
2. [second step]
3. [etc.]
**Error message**[paste the exact error text here, or write "no error shown — server just doesn't appear"]
**What I expected**
[e.g. "tooluniverse to appear in the MCP servers list after restarting the app"]
**What was already tried**
- [fix 1 attempted and result]
- [fix 2 attempted and result]Once composed, output the filled issue body and then give the user the walkthrough below.
---
Walk the User Through GitHub
Say this to the user (adapt the language to match how they've been communicating):
"I've prepared the issue report below — you just need to copy and paste it. Here's how to submit it, step by step:
>
Step 1. Open this link in your browser:
https://github.com/mims-harvard/ToolUniverse/issues/new
>
Step 2. Sign in to GitHub. If you don't have an account, click "Sign up" — it's free and takes about a minute (no credit card needed). You can also sign up with Google.
>
Step 3. You'll see a form with two fields:
- Title — paste the one-line title from the report I prepared
- Leave a comment (the large text box) — paste the full report body
>
Step 4. Scroll down and click the green "Submit new issue" button.
>
That's it! The team usually replies within 1–2 days. You'll get an email notification when they respond — no need to check back manually."
---
Email Fallback
If the user is not comfortable with GitHub or can't create an account, they can send the same issue body by email:
shanghuagao@gmail.com
Subject line: ToolUniverse setup issue: [one-line summary]
ToolUniverse Installation Guide
Detailed installation options and troubleshooting.
Installation Methods
Method 1: PyPI (Recommended for Users)
Standard installation from Python Package Index:
pip install tooluniversePros: Simple, stable, latest release Cons: May not have cutting-edge features
Method 2: UV (Recommended for MCP)
Installation with uv package manager for better isolation:
# Install uv first
curl -LsSf https://astral.sh/uv/install.sh | sh
# Create dedicated environment
mkdir -p ~/tooluniverse-env
cd ~/tooluniverse-env
# Install ToolUniverse
uv pip install tooluniversePros: Better isolation, faster dependency resolution, works well with MCP Cons: Requires uv installation
Method 3: Development (For Contributors)
Install from source for development:
git clone https://github.com/mims-harvard/ToolUniverse.git
cd ToolUniverse
pip install -e .Pros: Latest features, can modify code Cons: May have bugs, requires git
Optional Dependencies
All Features
pip install tooluniverse[all]Specific Features
# Single-cell analysis
pip install tooluniverse[singlecell]
# Machine learning and embeddings
pip install tooluniverse[ml,embedding]
# Visualization tools
pip install tooluniverse[visualization]
# Graph analysis
pip install tooluniverse[graph]
# Bioinformatics tools
pip install tooluniverse[bioinformatics]
# Development tools
pip install tooluniverse[dev]Python Version Requirements
- Required: Python 3.10 - 3.13
- Not supported: Python <3.10 or >=3.14
Installing Specific Python Version
macOS (Homebrew)
brew install python@3.12
python3.12 -m pip install tooluniverseUbuntu/Debian
sudo apt update
sudo apt install python3.12 python3.12-pip
python3.12 -m pip install tooluniverseWindows
Download from python.org and select version 3.12.
Virtual Environment (Recommended)
Create isolated environment:
# Create virtual environment
python3 -m venv tooluniverse-venv
# Activate
source tooluniverse-venv/bin/activate # macOS/Linux
# or
tooluniverse-venv\Scripts\activate # Windows
# Install
pip install tooluniverseVerification
After installation, verify:
# Check installation
pip show tooluniverse
# Test import
python3 -c "from tooluniverse import ToolUniverse; print('✓ Import successful')"
# Check CLI commands
which tooluniverse-smcp-stdioCommon Installation Issues
Issue: pip not found
# macOS/Linux
python3 -m ensurepip --upgrade
# Windows
py -m ensurepip --upgradeIssue: Permission denied
# Use user installation
pip install --user tooluniverse
# Or use virtual environment (recommended)Issue: SSL certificate error
pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org tooluniverseIssue: Outdated pip
pip install --upgrade pip
pip install tooluniverseUninstallation
pip uninstall tooluniverseTo remove all data:
# Remove cache (if exists)
rm -rf ~/.cache/tooluniverseUpgrading
pip install --upgrade tooluniversePlatform-Specific Notes
macOS
- Use Homebrew Python recommended
- May need Xcode Command Line Tools:
xcode-select --install
Windows
- Use official Python installer
- Add Python to PATH during installation
- May need Microsoft C++ Build Tools for some dependencies
Linux
- Most distros work out of the box
- May need
python3-devpackage for compiling dependencies
MCP Configuration Guide
Advanced configuration options for ToolUniverse MCP integration.
Configuration File Locations
Cursor
- Global (all workspaces) — macOS/Linux:
~/.cursor/mcp.json· Windows:%USERPROFILE%\.cursor\mcp.json - Project-level (single workspace):
.cursor/mcp.jsonin the project root — can be committed to version control for team sharing
Claude Desktop
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
VS Code / Copilot
- Project-level (workspace root):
.vscode/mcp.json - Note: VS Code uses
"servers"key (not"mcpServers") and requires"type": "stdio"— see the VS Code template below.
Windsurf
- macOS/Linux:
~/.codeium/windsurf/mcp_config.json - Windows:
%USERPROFILE%\.codeium\windsurf\mcp_config.json
Claude Code
- Global:
~/.claude.json - Project-level:
.mcp.jsonin the project root
Gemini CLI
~/.gemini/settings.json
Antigravity
- macOS/Linux:
~/.gemini/antigravity/mcp_config.json - Windows:
%USERPROFILE%\.gemini\antigravity\mcp_config.json
Access via: Agent Panel → "..." → Manage MCP Servers → View raw config. Uses "mcpServers" key (same as Claude Desktop format).
Cline
Full path to cline_mcp_settings.json varies by OS:
- macOS:
~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json - Linux:
~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json - Windows:
%APPDATA%\Code\User\globalStorage\saoudrizwan.claude-dev\settings\cline_mcp_settings.json - Cline CLI (standalone):
~/.cline/data/settings/cline_mcp_settings.json
Access via Cline's "MCP Servers" icon → Configure tab → "Configure MCP Servers". Uses "mcpServers" key (same as Claude Desktop format).
Trae
- Windows:
%APPDATA%\Trae\User\mcp.json - macOS:
~/Library/Application Support/Trae/User/mcp.json - Linux:
~/.config/Trae/User/mcp.json
Verify the exact path in Trae: Settings → MCP → Open config file.
The AI agent can only access the global config. Project-level .trae/mcp.json is an experimental/beta feature and is not accessible to the agent — do not use it for MCP server registration.
For full Trae setup instructions (including manual write fallback and verification), see TRAE.md.
Configuration Templates
Basic Configuration (Recommended)
Zero-install setup using uvx (auto-downloads and runs ToolUniverse):
{
"mcpServers": {
"tooluniverse": {
"command": "uvx",
"args": ["--refresh", "tooluniverse"],
"env": {
"PYTHONIOENCODING": "utf-8"
}
}
}
}--refresh keeps ToolUniverse auto-updated on each startup (~1–2s overhead). Remove it to pin to the cached version and update manually with uv cache clean tooluniverse.
pip-Based Configuration (Alternative)
If you have ToolUniverse installed via pip install tooluniverse, you can use the installed command directly:
{
"mcpServers": {
"tooluniverse": {
"command": "tooluniverse-smcp-stdio",
"args": ["--compact-mode"],
"env": {
"PYTHONIOENCODING": "utf-8"
}
}
}
}Development Configuration
Using development installation:
{
"mcpServers": {
"tooluniverse": {
"command": "python3",
"args": [
"-m",
"tooluniverse.smcp_server",
"--compact-mode"
],
"cwd": "/path/to/ToolUniverse-main"
}
}
}VS Code / Copilot Configuration
VS Code uses a different schema. Create .vscode/mcp.json in the workspace root:
{
"servers": {
"tooluniverse": {
"command": "uvx",
"args": ["--refresh", "tooluniverse"],
"env": { "PYTHONIOENCODING": "utf-8" },
"type": "stdio"
}
}
}Key differences from standard config: uses "servers" (not "mcpServers") and requires "type": "stdio". After saving, fully restart VS Code and open Copilot Chat in that workspace.
Configuration Options
Compact Mode (Default with uvx)
When using uvx tooluniverse, compact mode is enabled by default — no flag needed. It exposes only 5 core tools to prevent context overflow, while keeping all 1000+ tools accessible via execute_tool.
If using the pip-based tooluniverse-smcp-stdio command, pass --compact-mode explicitly:
"args": ["--compact-mode"]Core tools exposed in compact mode:
list_tools- List all available toolsgrep_tools- Search tools by keywordget_tool_info- Get tool detailsexecute_tool- Execute any tool by namefind_tools- Find tools by description
Specific Categories
Load only specific tool categories:
"args": [
"--categories",
"uniprot",
"ChEMBL",
"opentarget",
"pdb"
]Available categories: Run uvx tooluniverse --list-categories to see all.
Warning: Multiple categories may still cause context issues.
Exclude Categories
Load all except specific categories:
"args": [
"--exclude-categories",
"mcp_auto_loader_boltz",
"mcp_auto_loader_expert_feedback"
]Specific Tools Only
Load only named tools:
"args": [
"--include-tools",
"UniProt_get_entry_by_accession",
"ChEMBL_get_molecule_by_chembl_id"
]Enable Hooks
Enable output processing hooks (disabled by default for stdio):
"args": [
"--refresh", "tooluniverse",
"--hooks",
"--hook-type",
"SummarizationHook"
]Hook types:
SummarizationHook- Summarize long outputsFileSaveHook- Save outputs to files
Verbose Logging
Enable detailed logging for debugging:
"args": [
"--refresh", "tooluniverse",
"--verbose"
]Environment Variables
Standard Variables
"env": {
"PYTHONIOENCODING": "utf-8",
"PYTHONPATH": "/custom/python/path",
"TOOLUNIVERSE_CACHE_DIR": "/custom/cache/dir"
}API Keys
For tools requiring authentication:
"env": {
"PYTHONIOENCODING": "utf-8",
"OPENAI_API_KEY": "your-key-here",
"ANTHROPIC_API_KEY": "your-key-here",
"UMLS_API_KEY": "your-key-here"
}Security Note: Avoid hardcoding keys. Use environment variables or .env files.
Better API Key Management
Use environment variables from shell:
"env": {
"PYTHONIOENCODING": "utf-8",
"OPENAI_API_KEY": "${OPENAI_API_KEY}"
}Then set in shell:
export OPENAI_API_KEY=your-key-hereMultiple MCP Servers
Configure multiple servers:
{
"mcpServers": {
"tooluniverse": {
"command": "uvx",
"args": ["--refresh", "tooluniverse"],
"env": { "PYTHONIOENCODING": "utf-8" }
},
"other-server": {
"command": "other-mcp-server",
"args": []
}
}
}Working Directory
Specify working directory:
{
"mcpServers": {
"tooluniverse": {
"command": "uvx",
"args": ["--refresh", "tooluniverse"],
"env": { "PYTHONIOENCODING": "utf-8" },
"cwd": "/path/to/working/directory"
}
}
}Testing Configuration
Validate JSON
Before saving, validate JSON syntax:
# macOS/Linux
cat mcp.json | python3 -m json.tool
# Or use online validatorTest Command Directly
Test the MCP command in terminal:
uvx tooluniverse --help
# Should print usage text without errorsTest with a ToolUniverse Skill
After skills are installed (see SKILL.md Step 6), verify end-to-end by invoking the tooluniverse router skill in your prompt:
"Use the tooluniverse skill to research the drug metformin"The tooluniverse skill is a router — it automatically picks the right sub-skill and calls multiple tools. Mentioning it explicitly ensures it activates on any client, since not all clients auto-detect skills from natural language alone.
If the response comes back as plain text without any tool calls, either skills are not installed, they are in the wrong directory, or the MCP server is not connected.
Other examples:
"Use the tooluniverse skill: what is known about Alzheimer's disease?""Use the tooluniverse skill: what does the literature say about CRISPR in cancer?"
Check Logs
After restarting application, check logs:
Cursor logs:
- macOS:
~/Library/Application Support/Cursor/logs/ - Look for files with "mcp" in the name
Claude Desktop logs:
- Access via app: Help → View Logs
Troubleshooting Configuration
Issue: Server Won't Start
1. Test command directly in terminal 2. Check JSON syntax (no trailing commas) 3. Verify paths are absolute, not relative 4. Check file permissions
Issue: Context Overflow
- Ensure
--compact-modeis in args - Reduce number of categories
- Use specific tools only
Issue: Command Not Found
- Verify uvx works:
uvx --version - Test ToolUniverse directly:
uvx tooluniverse --help - If uvx is missing, install uv:
curl -LsSf https://astral.sh/uv/install.sh | sh - For pip-based installs:
pip show tooluniverseandwhich tooluniverse-smcp-stdio
Issue: Environment Variables Not Working
- Use absolute paths
- Avoid ~ expansion (use full path)
- Check variable syntax in JSON
Performance Optimization
Fast Startup
Use minimal categories (compact mode is already the default):
"args": [
"--refresh", "tooluniverse",
"--categories",
"special_tools"
]Memory Optimization
Exclude heavy categories:
"args": [
"--refresh", "tooluniverse",
"--exclude-categories",
"mcp_auto_loader_boltz"
]Security Considerations
1. API Keys: Never commit config files with hardcoded keys 2. Paths: Use absolute paths to avoid ambiguity 3. Permissions: Restrict config file permissions (chmod 600) 4. Validation: Always validate JSON before saving
Example Configurations
Research Use Case
For scientific research with common tools:
{
"mcpServers": {
"tooluniverse": {
"command": "uvx",
"args": ["--refresh", "tooluniverse"],
"env": {
"PYTHONIOENCODING": "utf-8",
"NCBI_API_KEY": "your-key-here"
}
}
}
}Development Use Case
For tool development and testing:
{
"mcpServers": {
"tooluniverse-dev": {
"command": "python3",
"args": [
"-m",
"tooluniverse.smcp_server",
"--compact-mode",
"--verbose"
],
"cwd": "/path/to/ToolUniverse-main"
}
}
}Production Use Case
For production with specific tool categories:
{
"mcpServers": {
"tooluniverse-prod": {
"command": "uvx",
"args": [
"tooluniverse",
"--categories",
"uniprot",
"ChEMBL",
"opentarget"
],
"env": { "PYTHONIOENCODING": "utf-8" }
}
}
}Advanced Features
Space Configuration
Load preset tool configurations:
"args": [
"--compact-mode",
"--load",
"community/proteomics-toolkit"
]Custom Hook Configuration
Use custom hook configuration file:
"args": [
"--compact-mode",
"--hooks",
"--hook-config-file",
"/path/to/hook_config.json"
]MCP Configuration — Special Formats
Most clients use the standard mcpServers JSON format (see SKILL.md). These clients use different formats:
VS Code (Copilot)
Uses "servers" key (not "mcpServers") and requires "type" field. Add to .vscode/mcp.json:
{
"servers": {
"tooluniverse": {
"type": "stdio",
"command": "uvx",
"args": ["tooluniverse"],
"env": { "PYTHONIOENCODING": "utf-8" }
}
}
}Codex (TOML format)
Add to ~/.codex/config.toml:
[mcp_servers.tooluniverse]
command = "uvx"
args = ["tooluniverse"]
env = { "PYTHONIOENCODING" = "utf-8" }OpenCode
Uses mcp key with type and command as array in opencode.json:
{
"mcp": {
"tooluniverse": {
"type": "local",
"command": ["uvx", "tooluniverse"],
"enabled": true,
"environment": { "PYTHONIOENCODING": "utf-8" }
}
}
}Antigravity
Standard mcpServers format. Access via: "..." dropdown → Manage MCP Servers → View raw config.
{
"mcpServers": {
"tooluniverse": {
"command": "uvx",
"args": ["tooluniverse"],
"env": { "PYTHONIOENCODING": "utf-8" }
}
}
}#!/usr/bin/env python3
"""
Check prerequisites for ToolUniverse installation.
This script verifies:
- Python version (3.10-3.13 required)
- pip availability
- uv availability (optional)
- System platform
- Available disk space
"""
import sys
import subprocess
import platform
import shutil
from pathlib import Path
def check_python_version():
"""Check if Python version is compatible (3.10-3.13)."""
version = sys.version_info
print(f"\n🐍 Python Version: {version.major}.{version.minor}.{version.micro}")
if version.major != 3:
print(" ❌ FAIL: Python 3 required")
return False
if version.minor < 10:
print(f" ❌ FAIL: Python 3.10+ required (current: 3.{version.minor})")
return False
if version.minor >= 14:
print(f" ❌ FAIL: Python <3.14 required (current: 3.{version.minor})")
return False
print(" ✓ PASS: Python version compatible")
return True
def check_pip():
"""Check if pip is available."""
print("\n📦 Checking pip...")
try:
result = subprocess.run(
[sys.executable, "-m", "pip", "--version"],
capture_output=True,
text=True,
check=True
)
print(f" ✓ PASS: {result.stdout.strip()}")
return True
except subprocess.CalledProcessError:
print(" ❌ FAIL: pip not available")
print(" Install with: python3 -m ensurepip --upgrade")
return False
def check_uv():
"""Check if uv is available (optional but recommended)."""
print("\n⚡ Checking uv (optional)...")
uv_path = shutil.which("uv")
if uv_path:
try:
result = subprocess.run(
["uv", "--version"],
capture_output=True,
text=True,
check=True
)
print(f" ✓ PASS: uv found at {uv_path}")
print(f" Version: {result.stdout.strip()}")
return True
except subprocess.CalledProcessError:
print(f" ⚠️ WARNING: uv found but not working properly")
return False
else:
print(" ⚠️ NOT FOUND: uv not installed (recommended for MCP)")
print(" Install with: curl -LsSf https://astral.sh/uv/install.sh | sh")
return False
def check_system():
"""Check system information."""
print("\n💻 System Information:")
print(f" Platform: {platform.system()} {platform.release()}")
print(f" Machine: {platform.machine()}")
print(f" Python implementation: {platform.python_implementation()}")
return True
def check_disk_space():
"""Check available disk space."""
print("\n💾 Disk Space:")
try:
home = Path.home()
stat = shutil.disk_usage(home)
free_gb = stat.free / (1024**3)
print(f" Available: {free_gb:.2f} GB")
if free_gb < 1:
print(" ⚠️ WARNING: Less than 1 GB free space")
return False
else:
print(" ✓ PASS: Sufficient disk space")
return True
except Exception as e:
print(f" ⚠️ WARNING: Could not check disk space: {e}")
return True
def check_cursor_config_location():
"""Check if Cursor config directory exists."""
print("\n📁 Cursor Configuration:")
system = platform.system()
if system == "Darwin": # macOS
cursor_dir = Path.home() / "Library" / "Application Support" / "Cursor"
elif system == "Windows":
cursor_dir = Path.home() / "AppData" / "Roaming" / "Cursor"
else: # Linux
cursor_dir = Path.home() / ".config" / "Cursor"
if cursor_dir.exists():
print(f" ✓ FOUND: {cursor_dir}")
mcp_config = cursor_dir / "User" / "mcp.json"
if mcp_config.exists():
print(f" ✓ mcp.json exists at {mcp_config}")
else:
print(f" ℹ️ mcp.json not found (will need to create)")
print(f" Location: {mcp_config}")
return True
else:
print(f" ⚠️ Cursor directory not found: {cursor_dir}")
print(" This is normal if using Claude Desktop instead")
return False
def main():
"""Run all prerequisite checks."""
print("=" * 60)
print("ToolUniverse Installation Prerequisites Check")
print("=" * 60)
results = {
"Python version": check_python_version(),
"pip": check_pip(),
"uv": check_uv(),
"System": check_system(),
"Disk space": check_disk_space(),
"Cursor config": check_cursor_config_location(),
}
print("\n" + "=" * 60)
print("Summary:")
print("=" * 60)
critical_checks = ["Python version", "pip"]
all_critical_passed = all(results[check] for check in critical_checks)
for check, passed in results.items():
status = "✓" if passed else ("⚠️" if check not in critical_checks else "❌")
print(f"{status} {check}")
print("=" * 60)
if all_critical_passed:
print("\n✅ Ready to install ToolUniverse!")
print("\nNext steps:")
print(" 1. Run: pip install tooluniverse")
print(" 2. Run: python scripts/verify_installation.py")
return 0
else:
print("\n❌ Please fix critical issues before installing.")
return 1
if __name__ == "__main__":
sys.exit(main())
#!/usr/bin/env python3
"""
Comprehensive diagnostic tool for ToolUniverse setup issues.
Generates a detailed report covering:
- System information
- Python environment
- Installation status
- Configuration validation
- Common issue detection
"""
import sys
import subprocess
import platform
import json
import shutil
from pathlib import Path
from datetime import datetime
class DiagnosticReport:
"""Generate comprehensive diagnostic report."""
def __init__(self):
self.report = []
self.issues = []
self.warnings = []
def add_section(self, title):
"""Add a section header."""
self.report.append(f"\n{'=' * 60}")
self.report.append(f"{title}")
self.report.append(f"{'=' * 60}")
def add_line(self, line):
"""Add a line to report."""
self.report.append(line)
def add_issue(self, issue):
"""Add an issue."""
self.issues.append(issue)
self.report.append(f"❌ ISSUE: {issue}")
def add_warning(self, warning):
"""Add a warning."""
self.warnings.append(warning)
self.report.append(f"⚠️ WARNING: {warning}")
def add_success(self, message):
"""Add a success message."""
self.report.append(f"✓ {message}")
def get_report(self):
"""Get full report as string."""
return "\n".join(self.report)
def save_report(self, filename):
"""Save report to file."""
with open(filename, 'w') as f:
f.write(self.get_report())
def check_system_info(report):
"""Gather system information."""
report.add_section("System Information")
report.add_line(f"Platform: {platform.system()} {platform.release()}")
report.add_line(f"Machine: {platform.machine()}")
report.add_line(f"Processor: {platform.processor()}")
report.add_line(f"Python version: {sys.version}")
report.add_line(f"Python executable: {sys.executable}")
def check_python_environment(report):
"""Check Python environment details."""
report.add_section("Python Environment")
# Check Python version compatibility
version = sys.version_info
if version.major == 3 and 10 <= version.minor < 14:
report.add_success(f"Python {version.major}.{version.minor}.{version.micro} (compatible)")
else:
report.add_issue(f"Python {version.major}.{version.minor} not compatible (need 3.10-3.13)")
# Check pip
try:
result = subprocess.run(
[sys.executable, "-m", "pip", "--version"],
capture_output=True,
text=True,
check=True
)
report.add_success(f"pip: {result.stdout.strip()}")
except subprocess.CalledProcessError:
report.add_issue("pip not available")
# Check site-packages
try:
import site
report.add_line(f"Site packages: {site.getsitepackages()}")
except Exception:
report.add_warning("Could not determine site-packages location")
def check_tooluniverse_installation(report):
"""Check ToolUniverse installation status."""
report.add_section("ToolUniverse Installation")
# Try to import
try:
import tooluniverse
report.add_success(f"ToolUniverse imported: version {tooluniverse.__version__}")
# Get installation location
tu_path = Path(tooluniverse.__file__).parent
report.add_line(f"Installation path: {tu_path}")
# Try to load tools
try:
from tooluniverse import ToolUniverse
tu = ToolUniverse()
report.add_line("Attempting to load tools...")
tu.load_tools()
tool_count = len(tu.tools)
report.add_success(f"Loaded {tool_count} tools")
if tool_count < 700:
report.add_warning(f"Expected ~764 tools, only loaded {tool_count}")
except Exception as e:
report.add_issue(f"Could not load tools: {e}")
except ImportError as e:
report.add_issue(f"ToolUniverse not installed: {e}")
report.add_line("Install with: pip install tooluniverse")
def check_cli_commands(report):
"""Check CLI command availability."""
report.add_section("CLI Commands")
commands = [
"tooluniverse-smcp-stdio",
"tooluniverse-smcp-server",
"tooluniverse-smcp",
"tooluniverse-http-api",
]
for cmd in commands:
cmd_path = shutil.which(cmd)
if cmd_path:
report.add_success(f"{cmd}: {cmd_path}")
else:
report.add_issue(f"{cmd} not found in PATH")
def check_mcp_configuration(report):
"""Check MCP configuration files."""
report.add_section("MCP Configuration")
system = platform.system()
# Determine config locations
if system == "Darwin": # macOS
cursor_config = Path.home() / "Library" / "Application Support" / "Cursor" / "User" / "mcp.json"
claude_config = Path.home() / "Library" / "Application Support" / "Claude" / "claude_desktop_config.json"
elif system == "Windows":
cursor_config = Path.home() / "AppData" / "Roaming" / "Cursor" / "User" / "mcp.json"
claude_config = Path.home() / "AppData" / "Roaming" / "Claude" / "claude_desktop_config.json"
else: # Linux
cursor_config = Path.home() / ".config" / "Cursor" / "User" / "mcp.json"
claude_config = Path.home() / ".config" / "Claude" / "claude_desktop_config.json"
configs = [
("Cursor", cursor_config),
("Claude Desktop", claude_config),
]
found_any = False
for app_name, config_path in configs:
if config_path.exists():
found_any = True
report.add_success(f"{app_name} config found: {config_path}")
# Parse and validate
try:
with open(config_path, 'r') as f:
config = json.load(f)
# Check for ToolUniverse
if "mcpServers" in config and "tooluniverse" in config["mcpServers"]:
tu_config = config["mcpServers"]["tooluniverse"]
report.add_success("ToolUniverse server configured")
report.add_line(f" Command: {tu_config.get('command')}")
report.add_line(f" Args: {tu_config.get('args', [])}")
# Check for compact mode
if "--compact-mode" in tu_config.get("args", []):
report.add_success("Compact mode enabled")
else:
report.add_warning("Compact mode not enabled (may cause context overflow)")
else:
report.add_warning(f"ToolUniverse not configured in {app_name}")
except json.JSONDecodeError as e:
report.add_issue(f"Invalid JSON in {config_path}: {e}")
except Exception as e:
report.add_warning(f"Could not parse {config_path}: {e}")
else:
report.add_line(f"{app_name} config not found: {config_path}")
if not found_any:
report.add_warning("No MCP configuration files found")
def check_optional_dependencies(report):
"""Check optional dependencies."""
report.add_section("Optional Dependencies")
deps = {
"sentence_transformers": "ML/embedding tools",
"cellxgene_census": "Single-cell tools",
"biopython": "Bioinformatics tools",
"rdkit": "Chemistry tools",
"py3Dmol": "3D visualization",
}
for package, purpose in deps.items():
try:
__import__(package)
report.add_success(f"{package} installed ({purpose})")
except ImportError:
report.add_line(f"{package} not installed ({purpose})")
def check_common_issues(report):
"""Check for common setup issues."""
report.add_section("Common Issues Check")
# Issue 1: PATH not including scripts
scripts_in_path = any(
"scripts" in p.lower() or "bin" in p.lower()
for p in sys.path
)
if scripts_in_path:
report.add_success("Scripts directory appears to be in PATH")
else:
report.add_warning("Scripts directory may not be in PATH")
# Issue 2: Multiple Python installations
try:
result = subprocess.run(
["which", "-a", "python3"],
capture_output=True,
text=True,
check=True
)
python_installs = result.stdout.strip().split('\n')
if len(python_installs) > 1:
report.add_warning(f"Multiple Python installations found: {python_installs}")
report.add_line("Ensure you're using the correct one")
else:
report.add_success(f"Single Python installation: {python_installs[0]}")
except Exception:
pass # Windows or other systems
# Issue 3: Disk space
try:
stat = shutil.disk_usage(Path.home())
free_gb = stat.free / (1024**3)
if free_gb < 1:
report.add_warning(f"Low disk space: {free_gb:.2f} GB free")
else:
report.add_success(f"Disk space: {free_gb:.2f} GB free")
except Exception:
pass
def generate_recommendations(report):
"""Generate recommendations based on findings."""
report.add_section("Recommendations")
if report.issues:
report.add_line("\n🔴 Critical Issues to Fix:")
for i, issue in enumerate(report.issues, 1):
report.add_line(f" {i}. {issue}")
if report.warnings:
report.add_line("\n🟡 Warnings to Review:")
for i, warning in enumerate(report.warnings, 1):
report.add_line(f" {i}. {warning}")
if not report.issues and not report.warnings:
report.add_line("\n✅ No issues detected! Setup looks good.")
report.add_line("\n📚 Next Steps:")
if report.issues:
report.add_line(" 1. Fix critical issues listed above")
report.add_line(" 2. Rerun: python scripts/diagnose_setup.py")
else:
report.add_line(" 1. Restart Cursor or Claude Desktop")
report.add_line(" 2. Verify MCP server appears")
report.add_line(" 3. Test with: list_tools or grep_tools")
def main():
"""Run comprehensive diagnostics."""
report = DiagnosticReport()
report.add_section("ToolUniverse Setup Diagnostic Report")
report.add_line(f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
# Run all checks
check_system_info(report)
check_python_environment(report)
check_tooluniverse_installation(report)
check_cli_commands(report)
check_mcp_configuration(report)
check_optional_dependencies(report)
check_common_issues(report)
generate_recommendations(report)
# Print report
print(report.get_report())
# Save to file
output_file = Path("tooluniverse_diagnostic_report.txt")
report.save_report(output_file)
print(f"\n\n📄 Report saved to: {output_file.absolute()}")
# Return status
if report.issues:
print("\n❌ Issues detected - see report above")
return 1
else:
print("\n✅ Diagnostic complete - no critical issues")
return 0
if __name__ == "__main__":
sys.exit(main())
#!/usr/bin/env python3
"""
List all available ToolUniverse tool categories.
Shows categories with tool counts to help users choose which to load.
"""
import sys
def list_categories():
"""List all tool categories with counts."""
print("=" * 60)
print("ToolUniverse Tool Categories")
print("=" * 60)
try:
from tooluniverse import ToolUniverse
print("\nLoading ToolUniverse...")
tu = ToolUniverse()
tu.load_tools()
# Group tools by category
categories = {}
for tool_name, tool_info in tu.tools.items():
# Extract category from tool name (usually prefix before first underscore)
parts = tool_name.split('_')
if len(parts) > 1:
category = parts[0]
else:
category = "uncategorized"
if category not in categories:
categories[category] = []
categories[category].append(tool_name)
# Sort by tool count (descending)
sorted_categories = sorted(
categories.items(),
key=lambda x: len(x[1]),
reverse=True
)
print(f"\nTotal categories: {len(categories)}")
print(f"Total tools: {len(tu.tools)}")
print("\n" + "-" * 60)
print(f"{'Category':<30} {'Tool Count':>10}")
print("-" * 60)
for category, tools in sorted_categories:
print(f"{category:<30} {len(tools):>10}")
print("-" * 60)
# Show usage examples
print("\n📋 Usage Examples:")
print("-" * 60)
# Get top 5 categories
top_categories = [cat for cat, _ in sorted_categories[:5]]
print("\n1. Load specific categories:")
print(f' --categories {" ".join(top_categories[:3])}')
print("\n2. Load all except specific:")
print(f' --exclude-categories {" ".join(top_categories[:2])}')
print("\n3. Use compact mode (recommended):")
print(' --compact-mode')
print("\n💡 Recommendation:")
print(" Use --compact-mode to avoid context window overflow.")
print(" This exposes 5 core tools while keeping all 764+ tools")
print(" accessible via execute_tool.")
return 0
except ImportError:
print("\n❌ ToolUniverse not installed")
print("Install with: pip install tooluniverse")
return 1
except Exception as e:
print(f"\n❌ Error: {e}")
return 1
def main():
"""Main entry point."""
return list_categories()
if __name__ == "__main__":
sys.exit(main())
#!/usr/bin/env python3
"""
Test MCP connection and configuration.
This script verifies:
- MCP configuration file exists
- Configuration is valid JSON
- ToolUniverse server is configured
- Compact mode is enabled (recommended)
- Can execute basic MCP operations
"""
import sys
import json
import platform
from pathlib import Path
def find_mcp_config():
"""Find MCP configuration file for Cursor or Claude Desktop."""
print("\n📁 Looking for MCP configuration...")
system = platform.system()
# Cursor locations
if system == "Darwin": # macOS
cursor_config = Path.home() / "Library" / "Application Support" / "Cursor" / "User" / "mcp.json"
claude_config = Path.home() / "Library" / "Application Support" / "Claude" / "claude_desktop_config.json"
elif system == "Windows":
cursor_config = Path.home() / "AppData" / "Roaming" / "Cursor" / "User" / "mcp.json"
claude_config = Path.home() / "AppData" / "Roaming" / "Claude" / "claude_desktop_config.json"
else: # Linux
cursor_config = Path.home() / ".config" / "Cursor" / "User" / "mcp.json"
claude_config = Path.home() / ".config" / "Claude" / "claude_desktop_config.json"
# Check which config exists
configs = []
if cursor_config.exists():
configs.append(("Cursor", cursor_config))
if claude_config.exists():
configs.append(("Claude Desktop", claude_config))
if not configs:
print(f" ❌ No MCP config found")
print(f" Expected locations:")
print(f" Cursor: {cursor_config}")
print(f" Claude: {claude_config}")
return None
# Return all found configs
for app, path in configs:
print(f" ✓ Found {app} config: {path}")
return configs
def parse_config(config_path):
"""Parse and validate MCP configuration."""
print(f"\n📝 Parsing configuration: {config_path.name}")
try:
with open(config_path, 'r') as f:
config = json.load(f)
print(" ✓ Valid JSON format")
return config
except json.JSONDecodeError as e:
print(f" ❌ Invalid JSON: {e}")
return None
except Exception as e:
print(f" ❌ Error reading file: {e}")
return None
def check_tooluniverse_config(config):
"""Check if ToolUniverse is configured."""
print("\n🔍 Checking ToolUniverse configuration...")
if "mcpServers" not in config:
print(" ❌ No 'mcpServers' section found")
return False
servers = config["mcpServers"]
if "tooluniverse" not in servers:
print(" ❌ ToolUniverse not configured")
print(f" Found servers: {', '.join(servers.keys())}")
return False
tu_config = servers["tooluniverse"]
print(" ✓ ToolUniverse server found")
# Check command
if "command" not in tu_config:
print(" ❌ No 'command' specified")
return False
command = tu_config["command"]
print(f" Command: {command}")
# Check args
args = tu_config.get("args", [])
print(f" Arguments: {args}")
# Check for compact mode
has_compact_mode = "--compact-mode" in args
if has_compact_mode:
print(" ✓ Compact mode ENABLED (recommended)")
else:
print(" ⚠️ Compact mode NOT enabled")
print(" WARNING: May cause context window overflow!")
print(' Add "--compact-mode" to args array')
# Check environment variables
env = tu_config.get("env", {})
if env:
print(f" Environment variables: {list(env.keys())}")
return True
def test_command_availability(config):
"""Test if the configured command is available."""
print("\n🖥️ Testing command availability...")
if "mcpServers" not in config or "tooluniverse" not in config["mcpServers"]:
return False
import shutil
tu_config = config["mcpServers"]["tooluniverse"]
command = tu_config.get("command")
if not command:
return False
cmd_path = shutil.which(command)
if cmd_path:
print(f" ✓ Command found: {cmd_path}")
return True
else:
print(f" ❌ Command not found: {command}")
print(" Solution: Ensure ToolUniverse is installed")
return False
def check_working_directory(config):
"""Check if working directory exists (for uv configurations)."""
print("\n📂 Checking working directory...")
if "mcpServers" not in config or "tooluniverse" not in config["mcpServers"]:
return True
tu_config = config["mcpServers"]["tooluniverse"]
args = tu_config.get("args", [])
# Look for --directory flag
try:
dir_index = args.index("--directory")
if dir_index + 1 < len(args):
work_dir = Path(args[dir_index + 1])
if work_dir.exists():
print(f" ✓ Directory exists: {work_dir}")
return True
else:
print(f" ❌ Directory not found: {work_dir}")
print(f" Create with: mkdir -p {work_dir}")
return False
except ValueError:
# No --directory flag, that's fine
print(" ℹ️ No working directory specified (using system)")
return True
def test_basic_import():
"""Test if ToolUniverse can be imported in MCP context."""
print("\n🐍 Testing ToolUniverse import...")
try:
from tooluniverse import ToolUniverse
_tu = ToolUniverse()
print(" ✓ Import successful")
return True
except ImportError as e:
print(f" ❌ Import failed: {e}")
return False
def generate_sample_config():
"""Generate a sample MCP configuration."""
print("\n📋 Sample MCP Configuration:")
print("-" * 60)
sample = {
"mcpServers": {
"tooluniverse": {
"command": "tooluniverse-smcp-stdio",
"args": ["--compact-mode"],
"env": {
"PYTHONIOENCODING": "utf-8"
}
}
}
}
print(json.dumps(sample, indent=2))
print("-" * 60)
def main():
"""Run all MCP connection tests."""
print("=" * 60)
print("ToolUniverse MCP Connection Test")
print("=" * 60)
# Find config
configs = find_mcp_config()
if not configs:
print("\n❌ No MCP configuration found")
generate_sample_config()
print("\nCreate mcp.json with the configuration above and restart your application.")
return 1
# Test each config found
all_passed = True
for app_name, config_path in configs:
print(f"\n{'=' * 60}")
print(f"Testing {app_name} Configuration")
print(f"{'=' * 60}")
config = parse_config(config_path)
if not config:
all_passed = False
continue
results = {
"ToolUniverse config": check_tooluniverse_config(config),
"Command available": test_command_availability(config),
"Working directory": check_working_directory(config),
"Import test": test_basic_import(),
}
print(f"\n{'-' * 60}")
print(f"{app_name} Summary:")
print(f"{'-' * 60}")
for check, passed in results.items():
status = "✓" if passed else "❌"
print(f"{status} {check}")
if not all(results.values()):
all_passed = False
print("\n" + "=" * 60)
if all_passed:
print("\n✅ MCP configuration verified!")
print("\nNext steps:")
print(" 1. Restart Cursor or Claude Desktop")
print(" 2. Look for 'tooluniverse' in MCP servers list")
print(" 3. Try a test query:")
print(" - list_tools")
print(" - grep_tools with keyword 'protein'")
print(" - execute_tool with any tool name")
return 0
else:
print("\n❌ MCP configuration has issues")
print("\nFix the errors above, then:")
print(" 1. Save your mcp.json changes")
print(" 2. Restart Cursor or Claude Desktop")
print(" 3. Run this script again")
return 1
if __name__ == "__main__":
sys.exit(main())
#!/usr/bin/env python3
"""
Verify ToolUniverse installation.
This script checks:
- ToolUniverse import
- Version information
- Tool loading
- Basic functionality
- CLI commands availability
"""
import sys
import subprocess
import shutil
from pathlib import Path
def check_import():
"""Check if ToolUniverse can be imported."""
print("\n📦 Checking ToolUniverse import...")
try:
import tooluniverse
print(f" ✓ PASS: ToolUniverse imported successfully")
print(f" Version: {tooluniverse.__version__}")
return True, tooluniverse
except ImportError as e:
print(f" ❌ FAIL: Cannot import tooluniverse")
print(f" Error: {e}")
print("\n Solution: Install with 'pip install tooluniverse'")
return False, None
def check_tool_loading(tooluniverse):
"""Check if tools can be loaded."""
print("\n🔧 Checking tool loading...")
try:
from tooluniverse import ToolUniverse
tu = ToolUniverse()
# Load tools (may take 10-30 seconds on first run)
print(" Loading tools (this may take a moment)...")
tu.load_tools()
tool_count = len(tu.tools)
print(f" ✓ PASS: Loaded {tool_count} tools")
if tool_count < 700:
print(f" ⚠️ WARNING: Expected ~764 tools, got {tool_count}")
print(" Some tool categories may not be loaded")
return True
except Exception as e:
print(f" ❌ FAIL: Could not load tools")
print(f" Error: {e}")
return False
def check_basic_execution(tooluniverse):
"""Test basic tool execution."""
print("\n⚙️ Testing basic tool execution...")
try:
from tooluniverse import ToolUniverse
tu = ToolUniverse()
tu.load_tools()
# Try to find a tool
result = tu.run({
"name": "Tool_Finder_Keyword",
"arguments": {"description": "protein", "limit": 3}
})
if result and "error" not in result:
print(" ✓ PASS: Tool execution successful")
return True
else:
print(" ⚠️ WARNING: Tool execution returned unexpected result")
print(f" Result: {result}")
return False
except Exception as e:
print(f" ❌ FAIL: Tool execution failed")
print(f" Error: {e}")
return False
def check_cli_commands():
"""Check if CLI commands are available."""
print("\n🖥️ Checking CLI commands...")
commands = [
"tooluniverse-smcp-stdio",
"tooluniverse-smcp-server",
"tooluniverse-http-api",
]
available = []
missing = []
for cmd in commands:
cmd_path = shutil.which(cmd)
if cmd_path:
print(f" ✓ {cmd}: {cmd_path}")
available.append(cmd)
else:
print(f" ❌ {cmd}: not found")
missing.append(cmd)
if missing:
print(f"\n ⚠️ Missing commands: {', '.join(missing)}")
print(" This may indicate scripts directory is not in PATH")
print(" Solution: pip install --force-reinstall tooluniverse")
return False
return True
def check_stdio_command():
"""Test if stdio command runs without errors."""
print("\n🔌 Testing MCP stdio command...")
cmd_path = shutil.which("tooluniverse-smcp-stdio")
if not cmd_path:
print(" ❌ FAIL: tooluniverse-smcp-stdio not found")
return False
try:
# Start the command and immediately terminate it
process = subprocess.Popen(
["tooluniverse-smcp-stdio", "--compact-mode"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
# Give it a moment to start
import time
time.sleep(2)
# Terminate
process.terminate()
process.wait(timeout=5)
# Check if it started without immediate errors
if process.returncode in [0, -15, 143]: # 0 = clean exit, -15/143 = SIGTERM
print(" ✓ PASS: MCP stdio command starts successfully")
return True
else:
print(f" ⚠️ WARNING: Command exited with code {process.returncode}")
stderr = process.stderr.read()
if stderr:
print(f" Error output: {stderr[:200]}")
return False
except subprocess.TimeoutExpired:
process.kill()
print(" ⚠️ WARNING: Command timed out (may be running)")
return True
except Exception as e:
print(f" ❌ FAIL: Could not test command")
print(f" Error: {e}")
return False
def check_optional_dependencies():
"""Check for optional dependencies."""
print("\n📚 Checking optional dependencies...")
optional_deps = {
"sentence_transformers": "embedding/ml features",
"cellxgene_census": "single-cell tools",
"biopython": "bioinformatics tools",
"rdkit": "chemistry visualization",
}
installed = []
missing = []
for package, purpose in optional_deps.items():
try:
__import__(package)
print(f" ✓ {package}: installed ({purpose})")
installed.append(package)
except ImportError:
print(f" ℹ️ {package}: not installed ({purpose})")
missing.append(package)
if missing:
print(f"\n ℹ️ Optional dependencies not installed: {', '.join(missing)}")
print(" Install with: pip install tooluniverse[all]")
return True # Optional deps don't fail the check
def main():
"""Run all installation verification checks."""
print("=" * 60)
print("ToolUniverse Installation Verification")
print("=" * 60)
# Check import first
import_ok, tooluniverse = check_import()
if not import_ok:
print("\n❌ Installation verification FAILED")
print("ToolUniverse is not installed or cannot be imported.")
return 1
# Run other checks
results = {
"Import": True, # Already checked above
"Tool loading": check_tool_loading(tooluniverse),
"Basic execution": check_basic_execution(tooluniverse),
"CLI commands": check_cli_commands(),
"MCP stdio": check_stdio_command(),
"Optional deps": check_optional_dependencies(),
}
print("\n" + "=" * 60)
print("Summary:")
print("=" * 60)
critical_checks = ["Import", "Tool loading", "CLI commands", "MCP stdio"]
all_critical_passed = all(results.get(check, False) for check in critical_checks)
for check, passed in results.items():
status = "✓" if passed else ("❌" if check in critical_checks else "ℹ️")
print(f"{status} {check}")
print("=" * 60)
if all_critical_passed:
print("\n✅ Installation verified successfully!")
print("\nNext steps:")
print(" 1. Configure MCP in Cursor/Claude Desktop")
print(" 2. Add this to mcp.json:")
print(' {"mcpServers": {"tooluniverse": {')
print(' "command": "tooluniverse-smcp-stdio",')
print(' "args": ["--compact-mode"]')
print(' }}}')
print(" 3. Restart Cursor/Claude Desktop")
print(" 4. Run: python scripts/test_mcp_connection.py")
return 0
else:
print("\n❌ Installation has issues. Please fix the errors above.")
return 1
if __name__ == "__main__":
sys.exit(main())
ToolUniverse Skills Catalog
65+ pre-built research workflows. Skills activate automatically when the AI detects a relevant request, or trigger them explicitly (e.g., "Use the tooluniverse skill to research the drug aspirin").
Research Skills
| Skill | What It Does |
|---|---|
tooluniverse | General strategies for using 1000+ tools effectively |
tooluniverse-drug-research | Comprehensive drug profiling (identity, pharmacology, safety, ADMET) |
tooluniverse-target-research | Drug target intelligence (structure, interactions, druggability) |
tooluniverse-disease-research | Systematic disease analysis across 10 research dimensions |
tooluniverse-literature-deep-research | Thorough literature reviews with evidence grading |
tooluniverse-drug-repurposing | Find new therapeutic uses for existing drugs |
tooluniverse-precision-oncology | Mutation-based treatment recommendations for cancer |
tooluniverse-rare-disease-diagnosis | Phenotype-to-diagnosis for suspected rare diseases |
tooluniverse-pharmacovigilance | Drug safety signal analysis from FDA adverse event data |
tooluniverse-infectious-disease | Rapid pathogen characterization & drug repurposing |
Data Retrieval Skills
| Skill | What It Does |
|---|---|
tooluniverse-protein-structure-retrieval | Protein 3D structure retrieval & quality assessment |
tooluniverse-sequence-retrieval | DNA/RNA/protein sequence retrieval from NCBI/ENA |
tooluniverse-chemical-compound-retrieval | Chemical compound data from PubChem/ChEMBL |
tooluniverse-expression-data-retrieval | Gene expression & omics datasets |
Clinical Skills
| Skill | What It Does |
|---|---|
tooluniverse-variant-interpretation | Genetic variant clinical interpretation |
tooluniverse-cancer-variant-interpretation | Cancer somatic variant clinical interpretation |
tooluniverse-clinical-guidelines | Clinical guideline retrieval and synthesis |
tooluniverse-clinical-trial-design | Clinical trial design and protocol analysis |
tooluniverse-clinical-trial-matching | Patient-to-trial matching based on eligibility |
tooluniverse-precision-medicine-stratification | Patient stratification for precision medicine |
tooluniverse-drug-drug-interaction | Drug-drug interaction analysis |
tooluniverse-adverse-event-detection | Drug adverse event signal detection |
tooluniverse-immunotherapy-response-prediction | Immunotherapy response biomarker analysis |
Drug Discovery Skills
| Skill | What It Does |
|---|---|
tooluniverse-drug-target-validation | Target validation for drug discovery |
tooluniverse-binder-discovery | Small molecule binder discovery via virtual screening |
tooluniverse-antibody-engineering | Antibody design and optimization |
tooluniverse-protein-therapeutic-design | AI-guided protein therapeutic design |
tooluniverse-chemical-safety | Chemical safety and toxicity assessment |
tooluniverse-network-pharmacology | Network-based drug-target-disease analysis |
Genomics & Omics Skills
| Skill | What It Does |
|---|---|
tooluniverse-variant-analysis | Genomic variant analysis workflows |
tooluniverse-gwas-drug-discovery | GWAS-driven drug target discovery |
tooluniverse-gwas-finemapping | GWAS fine-mapping to causal variants |
tooluniverse-gwas-snp-interpretation | GWAS SNP functional interpretation |
tooluniverse-gwas-study-explorer | GWAS study discovery and comparison |
tooluniverse-gwas-trait-to-gene | Trait-to-gene mapping from GWAS |
tooluniverse-polygenic-risk-score | Polygenic risk score calculation and interpretation |
tooluniverse-structural-variant-analysis | Structural variant detection and annotation |
tooluniverse-crispr-screen-analysis | CRISPR screen hit identification and analysis |
tooluniverse-epigenomics | Epigenomic data analysis (ChIP-seq, ATAC-seq) |
tooluniverse-gene-enrichment | Gene set enrichment and pathway analysis |
Transcriptomics & Proteomics Skills
| Skill | What It Does |
|---|---|
tooluniverse-rnaseq-deseq2 | RNA-seq differential expression with DESeq2 |
tooluniverse-single-cell | Single-cell RNA-seq analysis workflows |
tooluniverse-spatial-transcriptomics | Spatial transcriptomics analysis |
tooluniverse-spatial-omics-analysis | Spatial omics data analysis |
tooluniverse-proteomics-analysis | Proteomics data analysis and interpretation |
tooluniverse-metabolomics | Metabolomics data analysis and annotation |
tooluniverse-metabolomics-analysis | Advanced metabolomics pathway analysis |
tooluniverse-multi-omics-integration | Multi-omics data integration workflows |
tooluniverse-multiomic-disease-characterization | Disease characterization across omics layers |
Systems Biology & Other Skills
| Skill | What It Does |
|---|---|
tooluniverse-protein-interactions | Protein-protein interaction network analysis |
tooluniverse-systems-biology | Systems biology network modeling |
tooluniverse-phylogenetics | Phylogenetic analysis and tree building |
tooluniverse-statistical-modeling | Statistical modeling for biological data |
tooluniverse-image-analysis | Biomedical image analysis workflows |
tooluniverse-immune-repertoire-analysis | Immune repertoire (BCR/TCR) analysis |
tooluniverse-sdk | Build research pipelines with the Python SDK |
setup-tooluniverse | This setup guide |
How to Install
npx skills add mims-harvard/ToolUniverse --allOr manually clone and copy to your client's skills directory:
| Client | Skills Directory |
|---|---|
| Cursor | .cursor/skills/ |
| Windsurf | .windsurf/skills/ |
| Claude Code | .claude/skills/ |
| Gemini CLI | .gemini/skills/ |
| Qwen Code | .qwen/skills/ |
| Codex (OpenAI) | .agents/skills/ |
| OpenCode | .opencode/skills/ |
| Trae | .trae/skills/ |
| Cline / VS Code | .skills/ |
Trae IDE Setup
Use your system terminal — not Trae's built-in terminal.
Trae may run in a sandboxed environment. All installation commands (uv,npx,git) must be run in your OS terminal (Windows: PowerShell or Command Prompt; macOS/Linux: Terminal app). Commands run inside Trae's terminal panel may appear to succeed but Trae won't find the tools after restart.
---
Step 1: Install uvx
Open your system terminal (not Trae's terminal) and check if uv is already installed:
uvx --versionIf the command is not found, install uv:
macOS / Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
source ~/.zshrc 2>/dev/null || source ~/.bashrc 2>/dev/nullWindows (PowerShell):
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"Then close and reopen PowerShell so the new uvx command is available.
Verify ToolUniverse loads:
uvx tooluniverse --helpThis should print help text. If it fails, see TROUBLESHOOTING.md.
⏸️ Ask: "Does uvx tooluniverse --help print help text in your system terminal?" Wait before continuing.---
Step 2: Set Up Global Config
Trae's global MCP config is the only config the AI agent can access.
Find the config path: Open Trae → Settings → MCP (or "..." menu → Open MCP config).
Expected locations by OS:
- Windows:
%APPDATA%\Trae\User\mcp.json(e.g.C:\Users\yourname\AppData\Roaming\Trae\User\mcp.json) - macOS:
~/Library/Application Support/Trae/User/mcp.json - Linux:
~/.config/Trae/User/mcp.json
⏸️ Ask: "Can you open Trae Settings → MCP and confirm the config file path it shows?" Confirm before continuing.
Config JSON
{
"mcpServers": {
"tooluniverse": {
"command": "uvx",
"args": ["--refresh", "tooluniverse"],
"env": {
"PYTHONIOENCODING": "utf-8"
}
}
}
}Option A — Python one-liner (try first, run in system terminal)
Replace CONFIG_PATH with the confirmed path:
python3 -c "
import json, os
p = r'CONFIG_PATH'
os.makedirs(os.path.dirname(p), exist_ok=True)
cfg = json.load(open(p)) if os.path.exists(p) else {}
cfg.setdefault('mcpServers', {})['tooluniverse'] = {
'command': 'uvx', 'args': ['--refresh', 'tooluniverse'],
'env': {'PYTHONIOENCODING': 'utf-8'}
}
json.dump(cfg, open(p, 'w'), indent=2)
print('Done:', p)
"Option B — Trae Settings UI (recommended if Option A fails)
Trae has a built-in MCP configuration panel that bypasses file permission issues:
1. Press Ctrl U (or click the Agents icon) to open the Agents panel 2. Click the AI Management gear icon → MCP → Configure Manually 3. Paste the full JSON block above into the text field 4. Click Confirm 5. Restart Trae fully
⏸️ Ask: "Did tooluniverse appear in the MCP panel after restarting?" Wait before continuing.
Option C — Direct file paste (last resort)
If both Options A and B fail:
1. Open the global config file in a text editor (Notepad, VS Code, etc.) at the path confirmed above 2. If the file is empty or missing, paste the full JSON block above 3. If the file already has content, add the "tooluniverse" block inside the existing "mcpServers" object 4. Save the file 5. Restart Trae fully
⏸️ Ask: "Did the config get written? Do you see tooluniverse in Settings → MCP?" Wait before continuing.
⚠️ Do Not Use Project-Level Config
.trae/mcp.json is an experimental/beta feature. The agent cannot access project-level MCP servers. If Trae shows an "Enable Project MCP" option — ignore it. Always use the global config path.
---
Step 3: Install Skills
Skills are required for ToolUniverse to work as an intelligent research assistant. Run these in your system terminal.
Option A — npx (quickest)
npx skills add mims-harvard/ToolUniverse --allIf npx is not found, install Node.js from nodejs.org (the LTS version includes npm and npx), then retry.
Option B — git clone (if npx fails: corporate network, cert issues, or proxy problems)
If git is not found, install it from git-scm.com, then retry.
macOS / Linux:
git clone --depth 1 --filter=blob:none --sparse https://github.com/mims-harvard/ToolUniverse.git /tmp/tu-skills
cd /tmp/tu-skills && git sparse-checkout set skills
mkdir -p ~/.trae/skills && cp -r /tmp/tu-skills/skills/* ~/.trae/skills/
rm -rf /tmp/tu-skillsWindows (PowerShell — run each line separately):
# Run each line separately — PowerShell does not support && like bash
git clone --depth 1 --filter=blob:none --sparse https://github.com/mims-harvard/ToolUniverse.git "$env:TEMP\tu-skills"
Set-Location "$env:TEMP\tu-skills"
git sparse-checkout set skills
New-Item -ItemType Directory -Force "$env:APPDATA\Trae\skills" | Out-Null
robocopy "$env:TEMP\tu-skills\skills" "$env:APPDATA\Trae\skills" /E
Remove-Item -Recurse -Force "$env:TEMP\tu-skills"Note: The exact skills directory for Trae may vary. Check SKILLS_CATALOG.md if skills don't activate after installation.
Verify skills were installed — run in your system terminal:
macOS / Linux:
ls ~/.trae/skills | grep tooluniverseWindows (PowerShell):
Get-ChildItem "$env:APPDATA\Trae\skills" | Where-Object { $_.Name -like "*tooluniverse*" }✅ Pass: You see folders like tooluniverse, tooluniverse-drug-research, etc. → proceed to Step 4. ❌ Fail: Nothing listed → the install didn't complete or went to the wrong directory. Re-run the install command or try the git clone option.
⏸️ Ask: "Do you see tooluniverse skill folders listed?" Wait before continuing.
---
Step 4: Restart and Test
1. Fully quit Trae (not just close the window), then reopen it 2. First launch takes 60–90 seconds while Trae downloads ToolUniverse in the background
Check MCP connection: Open Trae Settings → MCP. tooluniverse should appear with a green/connected status.
Live tool test (verifies MCP is working):
list_toolsor
execute_tool("PubMed_search_articles", {"query": "CRISPR", "max_results": 1})Skills smoke test (verifies skills are installed):
Say: "Use the tooluniverse skill to research the drug metformin"The tooluniverse skill is a router — it picks the right sub-skill automatically. If the response is plain text with no tool calls, skills are not installed or not in the correct directory.
If something is still broken, check: 1. The config file is at the correct global path (not .trae/mcp.json) 2. uvx tooluniverse --help works in your system terminal (not Trae's terminal) 3. Trae was fully restarted 4. Fetch TROUBLESHOOTING.md for more diagnostics, or GITHUB_ISSUE.md to report the issue.
Troubleshooting ToolUniverse Setup
When something fails, always provide the exact copy-paste fix command — don't just say "check the logs."
Issue 1: Python Version Incompatibility
Symptom: Error containing requires-python = ">=3.10" or Python 3.9 is not supported
Fix:
brew install python@3.12 # macOS
# or: sudo apt install python3.12 # Ubuntu/Debian
python3.12 -m pip install tooluniverseIssue 2: uvx or uv Not Found
Symptom: uvx: command not found or uv: command not found
Fix:
curl -LsSf https://astral.sh/uv/install.sh | sh
source ~/.zshrc 2>/dev/null || source ~/.bashrc 2>/dev/null
uvx --version # verify it workedIssue 3: Context Window Overflow
Symptom: MCP server loads but the client becomes very slow, or gives "context too large" errors
Note: Compact mode is already the default — the tooluniverse entry point enables it automatically. If still hitting context limits:
"args": ["--refresh", "tooluniverse", "--tool-categories", "uniprot,chembl,pubmed"]Restart the app after editing.
Issue 4: Import Errors for Specific Tools
Symptom: Tool fails with ModuleNotFoundError: No module named 'rdkit' (or similar)
Fix:
pip install tooluniverse[all]
# Or the specific extra needed:
# pip install tooluniverse[visualization] # rdkit, py3Dmol
# pip install tooluniverse[singlecell] # cellxgene
# pip install tooluniverse[ml,embedding] # sentence-transformers, admet-aiIssue 5: MCP Server Won't Start
Symptom: No tooluniverse server in client's server list, "Failed to spawn process", "ENOENT", "command not found"
#1 most common cause — GUI apps (Claude Desktop, Windsurf) don't inherit shell PATH.
Option A — Homebrew (macOS, recommended, permanent):
brew install uv
# Then restart the app — can now use "uvx" everywhere, no absolute path neededOption B — Symlink (macOS/Linux, permanent):
sudo ln -sf "$(which uvx)" /usr/local/bin/uvx # Intel Mac / Linux
# OR for Apple Silicon Mac:
sudo ln -sf "$(which uvx)" /opt/homebrew/bin/uvxOption C — Absolute path (all platforms, quick fix):
which uvx # macOS/Linux → e.g. /opt/homebrew/bin/uvx or /Users/you/.local/bin/uvx
where uvx # WindowsUse that full path as "command" in your config instead of "uvx".
Full diagnostic chain — run these in order:
# 1. Can uvx find and run it?
uvx tooluniverse --help
# 2. Does it start without errors? (Ctrl+C to stop)
uvx tooluniverse
# 3. Is the config file valid JSON?
python3 -m json.tool ~/.cursor/mcp.json # replace path for your client
# 4. View the client's MCP logs
tail -50 ~/Library/Logs/Claude/mcp*.log 2>/dev/null # Claude Desktop (macOS)
tail -50 ~/Library/Application\ Support/Cursor/logs/*.log # Cursor (macOS)Fix based on where the chain breaks. Other common causes: trailing commas in JSON, wrong config file path.
Issue 6: API Key Errors (401/403)
Symptom: Tool returns "unauthorized", "forbidden", or "invalid API key"
Diagnostic:
echo $NCBI_API_KEY # replace with the failing key nameCommon fixes:
- Keys must be in the
"env"block in your MCP config file (not a.envfile the app doesn't load):
"env": { "PYTHONIOENCODING": "utf-8", "NCBI_API_KEY": "your_key_here" }- Wrong key name: variable must match exactly (e.g.,
ONCOKB_API_TOKENnotONCOKB_API_KEY) - Restart required after editing the config file
- Free tier pending: DisGeNET and OMIM may take 24–48h for account approval
Issue 7: Upgrading ToolUniverse
Symptom: User wants a newer version, or tools are missing / behavior is outdated
The recommended config uses "--refresh" which auto-updates on every launch. If the user's config doesn't have it:
"args": ["--refresh", "tooluniverse"]To upgrade immediately:
uv cache clean tooluniverse # clears uvx cache, then restart the MCP clientTo pin a specific version:
"args": ["tooluniverse==1.0.19"]For pip users:
pip install --upgrade tooluniverseIssue 8: Python Version Too New
Symptom: Errors like requires-python >=3.10,<3.14, SyntaxError in ToolUniverse code, or ModuleNotFoundError for a built-in module after upgrading Python.
ToolUniverse supports Python 3.10–3.13. Python 3.14+ (pre-release) may break things.
Check your Python version:
python3 --version
uvx tooluniverse --help # see what Python uvx picks upFix — pin to a compatible Python for uvx:
uvx --python 3.12 tooluniverse --helpIf that works, update your MCP config to use the pinned version:
{
"mcpServers": {
"tooluniverse": {
"command": "uvx",
"args": ["--python", "3.12", "--refresh", "tooluniverse"],
"env": { "PYTHONIOENCODING": "utf-8" }
}
}
}Issue 9: Stale or Broken Package Version
Symptom: A tool that used to work now errors, or a new tool listed in docs isn't available, or you see AttributeError / ImportError referencing ToolUniverse internals.
Step 1 — force a fresh install:
uv cache clean tooluniverse
uvx tooluniverse --version # should pull the latestStep 2 — check what version is running:
uvx tooluniverse --versionStep 3 — pin to latest stable if auto-update pulls a broken release:
# In your MCP config args:
"args": ["tooluniverse==<last-known-good-version>"]
# Check releases: https://github.com/mims-harvard/ToolUniverse/releasesStill Stuck? File a GitHub Issue
If none of the above fixes it, open a GitHub issue. Run this script first — it collects system info with no personal data (paths and usernames are stripped):
python3 - << 'EOF'
import sys, platform, subprocess, os, re, urllib.parse
home = os.path.expanduser("~")
def run(cmd):
try:
out = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, text=True).strip()
except Exception as e:
out = f"error: {e}"
return re.sub(re.escape(home), "~", out)
lines = [
"**Environment**",
f"- OS: {platform.system()} {platform.release()} {platform.machine()}",
f"- Python: {sys.version.split()[0]}",
f"- uv: {run('uv --version')}",
f"- uvx: {run('uvx --version')}",
f"- ToolUniverse: {run('uvx tooluniverse --version 2>/dev/null || echo unknown')}",
"",
"**Steps to reproduce**",
"1. <describe what you did>",
"",
"**Error message**",
"```",
"<paste full error here>",
"```",
"",
"**Expected behavior**",
"<what you expected to happen>",
]
body = "\n".join(lines)
title = "Bug: <brief description>"
url = ("https://github.com/mims-harvard/ToolUniverse/issues/new"
"?title=" + urllib.parse.quote(title)
+ "&body=" + urllib.parse.quote(body))
print("=" * 60)
print("ISSUE BODY (copy-paste if opening manually):")
print("=" * 60)
print(body)
print()
print("=" * 60)
print("PRE-FILLED ISSUE URL (open in browser):")
print("=" * 60)
print(url)
EOFThe script prints two things: 1. Issue body — copy-paste it into https://github.com/mims-harvard/ToolUniverse/issues/new 2. Pre-filled URL — open it in a browser to get a GitHub issue form with the info already filled in
If GitHub CLI (`gh`) is installed, you can create the issue directly — paste the body from above, then run:
gh issue create --repo mims-harvard/ToolUniverse \
--title "Bug: <brief description>" \
--body "<paste issue body here>"You can also email Shanghua Gao with the issue body.
Related skills
How it compares
Pick setup-tooluniverse for scientific database MCP onboarding; pick generic MCP setup skills when the integration is not ToolUniverse-specific.
FAQ
How many tools does setup-tooluniverse expose?
setup-tooluniverse configures access to 1,200+ ToolUniverse tools spanning 2,000+ scientific databases such as PubMed, UniProt, and ChEMBL. Compact MCP mode surfaces 5 core tools while execute_tool reaches the full catalog after uvx installation and client restart.
Which access modes does setup-tooluniverse support?
setup-tooluniverse supports chat MCP mode via uvx tooluniverse, CLI mode with nine tu subcommands including find, run, and status, and Python SDK mode with three Coding API calling patterns. The skill walks through uv install, client-specific MCP JSON, API keys, and live validati
Which AI clients can setup-tooluniverse configure?
setup-tooluniverse documents MCP setup for 12+ clients including Cursor, Claude Desktop, Claude Code, Windsurf, VS Code, Codex, Gemini CLI, Cline, and Trae. Claude Code users can alternatively install the ToolUniverse plugin for MCP plus 115 bundled research skills in one step.