
Biomedical Search
Run semantic full-text biomedical searches across Valyu-backed sources from your agent or a Node CLI while you validate health or life-sciences product ideas.
Overview
Biomedical-search is an agent skill for the Idea phase that queries Valyu’s API for full-text and semantic biomedical search from a Node CLI wrapper.
Install
npx skills add https://github.com/yorkeccak/scientific-skills --skill biomedical-searchWhat is this skill?
- Node CLI wrapper (`search.mjs`) plus bash entry for agent and terminal invocation
- Full-text search across multiple biomedical data sources via Valyu API v1
- Semantic search capabilities on top of structured API queries
- API key resolution: `VALYU_API_KEY` env var or `~/.valyu/config.json`
- Discoverability helpers: `--path`, `--location`, `--where`, `--script-dir`
- Valyu API base `https://api.valyu.ai/v1`
- Config directory `~/.valyu/config.json`
Adoption & trust: 530 installs on skills.sh; 47 GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
You need fast, programmatic access to biomedical sources while scoping a product, but ad-hoc browser tab searching does not plug into your agent workflow.
Who is it for?
Solo builders researching biomed, digital health, or life-sciences ideas who already have or will obtain a Valyu API key.
Skip if: Teams that need guaranteed offline corpora, HIPAA-grade data handling, or production pipelines without reviewing Valyu terms and the Security Audits panel on this page.
When should I use this skill?
You need programmatic biomedical or life-sciences search while researching an opportunity or drafting evidence-backed specs.
What do I get? / Deliverables
You get structured search results from Valyu you can cite in notes or specs before moving into validation or build planning.
- Terminal search results from Valyu
- Reusable CLI path for agent tool invocation
Recommended Skills
Journey fit
Canonical shelf is Idea because the skill’s primary job is discovering and retrieving biomedical evidence before you commit to scope or build. Research is the natural fit for literature and dataset discovery via Valyu rather than implementation or shipping tasks.
How it compares
Use as a Valyu-backed research CLI skill, not as a general web MCP server or static PubMed bookmark list.
Common Questions / FAQ
Who is biomedical-search for?
Indie and solo builders shipping agent-assisted products in health, biotech, or research who want searchable biomedical corpora inside Claude Code, Cursor, or Codex.
When should I use biomedical-search?
During Idea research when validating mechanisms, competitors, or evidence—and anytime you need semantic literature search before locking validate-scope or build integrations.
Is biomedical-search safe to install?
It runs Node, may store an API key on disk under `~/.valyu/config.json`, and calls Valyu over the network; review the Security Audits panel on this page and rotate keys you do not trust in shared environments.
SKILL.md
READMESKILL.md - Biomedical Search
#!/bin/bash # Search CLI wrapper SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_PATH="${SCRIPT_DIR}/search" # Special commands for discoverability case "$1" in --path|--location|--where) echo "$SCRIPT_PATH" exit 0 ;; --script-dir) echo "$SCRIPT_DIR" exit 0 ;; esac node "${SCRIPT_DIR}/search.mjs" "$@" #!/usr/bin/env node /** * biomedical-search Search via Valyu API * Full-text search across multiple data sources with semantic search capabilities */ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs'; import { homedir } from 'os'; import { join } from 'path'; const VALYU_API_BASE = 'https://api.valyu.ai/v1'; const CONFIG_DIR = join(homedir(), '.valyu'); const CONFIG_FILE = join(CONFIG_DIR, 'config.json'); /** * Get API key from multiple sources (in order of priority): * 1. Environment variable (VALYU_API_KEY) * 2. Config file (~/.valyu/config.json) */ function getApiKey() { if (process.env.VALYU_API_KEY) { return process.env.VALYU_API_KEY; } if (existsSync(CONFIG_FILE)) { try { const config = JSON.parse(readFileSync(CONFIG_FILE, 'utf-8')); if (config.apiKey) { return config.apiKey; } } catch (e) { // Ignore parse errors } } return null; } /** * Save API key to config file */ function saveApiKey(apiKey) { if (!existsSync(CONFIG_DIR)) { mkdirSync(CONFIG_DIR, { recursive: true }); } let config = {}; if (existsSync(CONFIG_FILE)) { try { config = JSON.parse(readFileSync(CONFIG_FILE, 'utf-8')); } catch (e) { // Start fresh if parse fails } } config.apiKey = apiKey; writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2)); return true; } /** * Return setup required response */ function setupRequiredResponse() { return { success: false, setup_required: true, message: "Valyu API key not configured. Get your free API key ($10 credits) at https://platform.valyu.ai" }; } /** * Search multiple sources via Valyu API */ async function search(query, maxResults = 10) { const apiKey = getApiKey(); if (!apiKey) { return setupRequiredResponse(); } try { const response = await fetch(`${VALYU_API_BASE}/search`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey }, body: JSON.stringify({ query: query, search_type: 'proprietary', included_sources: ['valyu/valyu-pubmed', 'valyu/valyu-biorxiv', 'valyu/valyu-medrxiv', 'valyu/valyu-clinical-trials', 'valyu/valyu-drug-labels'], limit: maxResults }) }); const data = await response.json(); if (!response.ok) { return { success: false, error: data.detail || data.message || `HTTP ${response.status}`, status: response.status }; } return { success: true, type: 'biomedical_search', query: query, result_count: data.results?.length || 0, results: data.results || [], cost: data.cost || 0 }; } catch (error) { return { success: false, error: error.message }; } } /** * Setup command - save API key */ function setup(apiKey) { if (!apiKey) { return { success: false, error: "API key required. Usage: search setup <api-key>" }; } saveApiKey(apiKey); return { success: true, type: 'setup', message: "API key saved to ~/.valyu/config.json" }; } // Main CLI handler const [,, command, ...args] = process.argv; (async () => { let result; if (command === 'setup') { result = setup(args[0]); } else { // Treat first arg as query, second as maxResults const query = command || ''; const maxResults = args[0] ? parseInt(args[0], 10) : 10; if (!query) { result = { success: false, error: "Query required. Usage: search <query> [maxResults]" }; } el