
Devtu Auto Discover Apis
- 339 installs
- 1.6k repo stars
- Updated August 4, 2026
- mims-harvard/tooluniverse
Scan biomedical services and OpenAPI specs to register new ToolUniverse connectors with minimal hand-written boilerplate.
About
devtu-auto-discover-apis helps ToolUniverse maintainers automatically find and draft integrations for biomedical APIs, turning specs and documentation into registrable tools so agents can call more scientific services faster.
- Automates discovery of candidate API endpoints
- Drafts tool metadata from specs and docs
- Speeds onboarding of new scientific data sources
- Cuts manual connector scaffolding for maintainers
Devtu Auto Discover Apis by the numbers
- 339 all-time installs (skills.sh)
- +5 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #1,232 of 4,347 Backend & APIs 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 devtu-auto-discover-apisAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 339 |
|---|---|
| repo stars | ★ 1.6k |
| Last updated | August 4, 2026 |
| Repository | mims-harvard/tooluniverse ↗ |
What it does
Scan biomedical services and OpenAPI specs to register new ToolUniverse connectors with minimal hand-written boilerplate.
Files
Automated Life Science API Discovery & Tool Creation
Discover, create, validate, and integrate life science APIs into ToolUniverse.
Four-Phase Workflow
Gap Analysis → API Discovery → Tool Creation → Validation → Integration
↓ ↓ ↓ ↓ ↓
Coverage Web Search devtu-create devtu-fix Git PRHuman approval gates after: discovery, creation, validation, and before PR.
---
Phase 1: Discovery & Gap Analysis
1.1 Analyze Current Coverage
Load ToolUniverse, categorize tools by domain (genomics, proteomics, drug discovery, clinical, omics, imaging, literature, pathways, systems biology). Count per category.
1.2 Identify Gap Domains
- Critical Gap: <5 tools in category
- Moderate Gap: 5-15 tools, missing key subcategories
- Emerging Gap: New technologies not represented
Common gaps: single-cell genomics, metabolomics, patient registries, microbial genomics, multi-omics integration, synthetic biology, toxicology.
1.3 Web Search for APIs
For each gap domain, run multiple queries: 1. "[domain] API REST JSON" — direct API search 2. "[domain] public database" — database discovery 3. "[domain] API 2025 OR 2026" — recent releases 4. "[domain] database" site:nar.oxfordjournals.org — NAR Database Issue
Extract: base URL, endpoints, auth method, parameter schemas, rate limits.
1.4 Score and Prioritize
| Criterion | Max Points |
|---|---|
| Documentation Quality | 20 |
| API Stability | 15 |
| Authentication Simplicity | 15 |
| Coverage | 15 |
| Maintenance | 10 |
| Community | 10 |
| License | 10 |
| Rate Limits | 5 |
High priority (>=70), Medium (50-69), Low (<50).
1.5 Generate Discovery Report
Coverage analysis, prioritized candidates with scores, implementation roadmap.
---
Phase 2: Tool Creation
For each API, use Skill(skill="devtu-create-tool") or follow these patterns.
Architecture Decision
- Multiple endpoints → multi-operation tool (single class, multiple JSON wrappers)
- Single endpoint → single-operation acceptable
Key Steps
1. Design tool class following template — see references/tool-templates.md 2. Create JSON config with oneOf return_schema 3. Find real test examples (use List endpoint → extract IDs → verify) 4. Register in default_config.py
Critical Requirements
- return_schema MUST have
oneOf(success + error schemas) - test_examples MUST use real IDs (NO placeholders)
- Tool name <= 55 characters
- NEVER raise exceptions in
run()— return error dict - Set timeout on all HTTP requests (30s)
---
Phase 3: Validation
Full guide: references/validation-guide.md
Quick Validation Checklist
1. Schema: oneOf structure, data wrapper, error field 2. Placeholders: No TEST/DUMMY/PLACEHOLDER in test_examples 3. Loading: 3-step check (class registered, config registered, wrappers generated) 4. Integration tests: python scripts/test_new_tools.py [api_name] -v → 100% pass
Fix failures with Skill(skill="devtu-fix-tool").
---
Phase 4: Integration
Use Skill(skill="devtu-github") or: 1. Create branch: feature/add-[api-name]-tools 2. Stage tool files + default_config.py 3. Commit with descriptive message 4. Push and create PR with validation results
---
Processing Patterns
| Pattern | When to Use |
|---|---|
| Batch (multiple APIs → single PR) | Same domain, similar structure |
| Iterative (one API at a time) | Complex auth, novel patterns |
| Discovery-only (report, no tools) | Planning roadmap |
| Validation-only (audit existing) | PR review, quality check |
---
References
- Tool templates (Python class + JSON config): references/tool-templates.md
- Validation & integration guide: references/validation-guide.md
Tool Creation Templates
Python Tool Class Template
from typing import Dict, Any
from tooluniverse.tool import BaseTool
from tooluniverse.tool_utils import register_tool
import requests
import os
@register_tool("[APIName]Tool")
class [APIName]Tool(BaseTool):
"""Tool for [API Name] - [brief description]."""
BASE_URL = "[API base URL]"
def __init__(self, tool_config):
super().__init__(tool_config)
self.parameter = tool_config.get("parameter", {})
self.required = self.parameter.get("required", [])
self.api_key = os.environ.get("[API_KEY_NAME]", "")
def run(self, arguments: Dict[str, Any]) -> Dict[str, Any]:
operation = arguments.get("operation")
if not operation:
return {"status": "error", "error": "Missing required parameter: operation"}
if operation == "operation1":
return self._operation1(arguments)
else:
return {"status": "error", "error": f"Unknown operation: {operation}"}
def _operation1(self, arguments: Dict[str, Any]) -> Dict[str, Any]:
param1 = arguments.get("param1")
if not param1:
return {"status": "error", "error": "Missing required parameter: param1"}
try:
headers = {}
if self.api_key:
headers["Authorization"] = f"Bearer {self.api_key}"
response = requests.get(
f"{self.BASE_URL}/endpoint",
params={"param1": param1},
headers=headers,
timeout=30
)
response.raise_for_status()
data = response.json()
return {
"status": "success",
"data": data.get("results", []),
"metadata": {"total": data.get("total", 0), "source": "[API Name]"}
}
except requests.exceptions.Timeout:
return {"status": "error", "error": "API timeout after 30 seconds"}
except requests.exceptions.HTTPError as e:
return {"status": "error", "error": f"HTTP {e.response.status_code}: {e.response.text[:200]}"}
except Exception as e:
return {"status": "error", "error": f"Unexpected error: {str(e)}"}JSON Configuration Template
[
{
"name": "[APIName]_operation1",
"class": "[APIName]Tool",
"description": "[What it does]. Returns [format]. [Input]. Example: [usage]. [Notes].",
"parameter": {
"type": "object",
"required": ["operation", "param1"],
"properties": {
"operation": {"const": "operation1", "description": "Operation identifier (fixed)"},
"param1": {"type": "string", "description": "Description with format/constraints"}
}
},
"return_schema": {
"oneOf": [
{
"type": "object",
"properties": {
"data": {"type": "array", "items": {"type": "object", "properties": {"id": {"type": "string"}, "name": {"type": "string"}}}},
"metadata": {"type": "object", "properties": {"total": {"type": "integer"}, "source": {"type": "string"}}}
}
},
{"type": "object", "properties": {"error": {"type": "string"}}, "required": ["error"]}
]
},
"test_examples": [{"operation": "operation1", "param1": "real_value_from_api_docs"}]
}
]Authentication Patterns
Public: No special handling.
API Key (Optional):
self.api_key = os.environ.get("API_KEY_NAME", "")
# JSON: "optional_api_keys": ["API_KEY_NAME"]API Key (Required):
self.api_key = os.environ.get("API_KEY_NAME")
if not self.api_key:
raise ValueError("API_KEY_NAME environment variable required")
# JSON: "required_api_keys": ["API_KEY_NAME"]Advanced Patterns
Async Polling (job-based APIs)
Submit → poll → retrieve. Max 60 attempts, 2s interval = 2min timeout.
SOAP APIs
Require operation parameter (e.g., "operation": "search_genes").
Pagination
Fetch pages until empty or partial page. Track total_pages and total_items.
File Naming
- Python:
src/tooluniverse/[api_name]_tool.py - JSON:
src/tooluniverse/data/[api_name]_tools.json - Register in:
src/tooluniverse/default_config.py
Critical Requirements
- return_schema MUST have oneOf (success + error)
- test_examples MUST use real IDs (NO placeholders)
- Tool name <= 55 characters
- Description 150-250 chars
- NEVER raise exceptions in run() — return error dict
- Set timeout on all HTTP requests (30s)
Validation & Integration Guide
Phase 3: Validation
Schema Validation
Check return_schema structure for each tool:
- Must have
oneOfwith 2 schemas (success + error) - Success schema must have
datafield - No placeholder values in test_examples
Tool Loading Verification (3-Step)
# Step 1: Class registered
from tooluniverse.tool_registry import get_tool_registry
registry = get_tool_registry()
assert "APINameTool" in registry
# Step 2: Config registered
from tooluniverse.default_config import TOOLS_CONFIGS
assert "api_category" in TOOLS_CONFIGS
# Step 3: Wrappers generated
from tooluniverse import ToolUniverse
tu = ToolUniverse()
tu.load_tools()
assert hasattr(tu.tools, 'APIName_operation1')Integration Tests
python scripts/test_new_tools.py [api_name] -v
# Expect: 100% pass rateHandle failures:
- 404: Invalid test example ID → find real ID
- Schema mismatch: fix return_schema to match actual response
- Timeout: increase timeout or add retry
- Parameter error: verify with API docs
Phase 4: Integration
Git Workflow
git checkout -b feature/add-[api-name]-tools
git add src/tooluniverse/[api_name]_tool.py
git add src/tooluniverse/data/[api_name]_tools.json
git add src/tooluniverse/default_config.py
git commit -m "Add [API Name] tools for [domain]"
git push -u origin feature/add-[api-name]-tools
gh pr create --title "Add [API Name] tools" --body-file pr_description.mdQuality Gates
| Gate | Review | Approve if |
|---|---|---|
| Post-Discovery | discovery_report.md | Prioritization looks good |
| Post-Creation | .py and .json files | Implementation looks good |
| Post-Validation | validation_report.md | All tests passing |
| Pre-PR | PR description | Ready for merge |
Troubleshooting
| Issue | Solution |
|---|---|
| API docs not found | Check /api/docs, /openapi.json, GitHub SDKs |
| Auth too complex | Document OAuth setup, use env vars for tokens |
| No real test examples | Use List endpoint, check API docs/GitHub |
| Tools won't load | Check default_config.py, JSON syntax, @register_tool |
| Schema mismatch | Call API directly, inspect raw response, fix schema |
| Rate limits | Add time.sleep(1), use API key, exponential backoff |
Success Criteria
- All tools load into ToolUniverse
- 100% test pass rate
- No schema validation errors
- No placeholder values
- PR created with full documentation