medsci-agent
Health Gecti
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Community trust — 18 GitHub stars
Code Uyari
- process.env — Environment variable access in packages/core/src/__tests__/config.test.ts
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
Biomedical research agent with 28 MCP tools powered by MedGemma, TxGemma and OpenCode
The open source biomedical research agent.
MedSci Agent gives any LLM access to 28 biomedical and execution tools — drug ADMET prediction, protein structure search, single-cell RNA-seq analysis, medical image interpretation, literature search, policy-controlled document acquisition, and isolated sandbox execution — powered by MedGemma, TxGemma, and OpenCode. The core model calls use local Ollama by default; PaperQA follows the explicit backend configured in opencode.json.
Built for the MedGemma Impact Challenge.
Quick Start
Once setup is complete and the configured model backends are available, open the project in OpenCode and try:
Drug discovery:
Analyze the drug-likeness of ibuprofen (CC(C)Cc1ccc(cc1)C(C)C(=O)O) and predict its ADMET properties.

Single-cell omics:
Read my H5AD file, preprocess it, cluster with Leiden at resolution 0.5, and run differential expression.

Literature search:
Search PubMed for recent papers on CRISPR-Cas9 gene therapy for sickle cell disease.

The Agent automatically selects the right tools, calls MedGemma for interpretation, and returns a synthesized answer.
Architecture
You bring your own LLM. Configure any model in OpenCode (via /model) and it becomes the orchestrator — it reads your query, selects the right tools, calls them through MCP, and synthesizes the results. The MCP servers handle the domain logic underneath.
Cloud LLM (user's choice via OpenCode)
|
| tool calls via MCP
v
+--- MCP Servers (Bun / TypeScript) ---+
| |
| server-drug 5 tools |
| server-protein 5 tools |
| server-literature 4 tools |
| server-acquisition 2 tools |
| server-imaging 1 tool |
| server-omics 5 tools |
| server-paperqa 1 tool |
| server-sandbox 5 tools |
| |
+-------+-------------------+-----------+
| |
v v
Ollama (local) Python Sidecar
- MedGemma 4B - RDKit
- TxGemma 2B - BioPython
- Scanpy
MedGemma interprets tool outputs — it reads raw data from APIs and computational tools, then provides clinically relevant summaries. Every tool that calls MedGemma returns a model_used flag and degrades gracefully if the model is unavailable.
TxGemma predicts ADMET properties (absorption, distribution, metabolism, excretion, toxicity). It runs exact prompt templates from the Therapeutics Data Commons and outputs binary classifications for six safety endpoints.
The Python sidecar is a long-running process that pre-imports scientific libraries and handles requests over stdin/stdout via JSON-RPC. This avoids the 2–5 second startup cost of importing RDKit or Scanpy on every call.
synthesize parameter: Every drug, protein, and omics tool accepts an optional "synthesize": false input field. When false, the tool skips the MedGemma interpretation step and returns raw data immediately. This is useful when you want fast data-only results, or when Ollama is unavailable. Default is true (synthesis enabled).
Tools
Drug Discovery (server-drug)
| Tool | Description | Backend |
|---|---|---|
analyze_molecule |
Physicochemical properties from SMILES (MW, LogP, TPSA, HBD/HBA, rings, formula) | RDKit + MedGemma |
lipinski_filter |
Lipinski Rule of Five drug-likeness check | RDKit |
molecular_similarity |
Tanimoto similarity between two molecules using Morgan fingerprints | RDKit |
predict_admet |
BBB penetration, intestinal absorption, hERG blocking, CYP3A4 inhibition, Ames mutagenicity, DILI risk | TxGemma + RDKit + MedGemma |
search_chembl |
Search ChEMBL for bioactive molecules and targets | ChEMBL API + MedGemma |
Protein Analysis (server-protein)
| Tool | Description | Backend |
|---|---|---|
parse_fasta |
Parse FASTA files, return sequence metadata | BioPython |
analyze_sequence |
Sequence length, composition, molecular weight | BioPython + MedGemma |
search_uniprot |
Search UniProt by gene, protein name, or accession | UniProt API + MedGemma |
search_pdb |
Search PDB for 3D structures by protein or PDB ID | RCSB PDB API + MedGemma |
predict_structure |
Retrieve AlphaFold predicted structure and confidence scores | AlphaFold DB API + MedGemma |
Literature, Acquisition & Synthesis (server-literature, server-acquisition & server-paperqa)
| Tool | Description | Backend |
|---|---|---|
search_pubmed |
Search PubMed with Boolean and MeSH queries | NCBI E-utilities + MedGemma |
fetch_abstract |
Fetch full abstract and metadata by PMID | NCBI E-utilities + MedGemma |
search_openalex |
Search OpenAlex for scholarly works, citations, open access status | OpenAlex API + MedGemma |
search_clinical_trials |
Search ClinicalTrials.gov by condition, drug, or intervention | ClinicalTrials.gov API + MedGemma |
resolve_identifier_to_sources |
Resolve DOI/PMID/PMCID into candidate source URLs with provenance and confidence | NCBI ID Converter + deterministic transforms |
acquire_documents |
Policy-controlled document retrieval from DOI/PMID/PMCID/URL with content-level labeling and explicit extraction backend metadata (pmid/pmcid: BioC-first with Scrapling fallback, doi/url: Scrapling-primary) |
NCBI BioC + Scrapling sidecar + safety policy engine |
search_and_analyze |
Deep semantic synthesis of up to 10 identifiers/documents (internal NCBI acquisition or pre-acquired documents) using contextual LLM re-ranking | PaperQA2 + Tantivy |
Medical Imaging (server-imaging)
| Tool | Description | Backend |
|---|---|---|
analyze_medical_image |
Analyze X-ray, CT, pathology, or dermatology images (PNG/JPEG, max 50 MB) | MedGemma (multimodal) |
Omics (server-omics)
| Tool | Description | Backend |
|---|---|---|
read_h5ad |
Load H5AD file, return observation and variable metadata | Scanpy |
preprocess_omics |
Filter, normalize, log-transform, find highly variable genes | Scanpy |
cluster_cells |
Leiden or Louvain clustering with UMAP coordinates | Scanpy |
differential_expression |
Differential expression between groups (Wilcoxon, t-test, logreg) | Scanpy + MedGemma |
gene_set_enrichment |
Pathway enrichment against MSigDB, GO, KEGG via Enrichr | Enrichr API + MedGemma |
Sandbox Execution (server-sandbox)
| Tool | Description | Backend |
|---|---|---|
sandbox_prepare |
Create/reuse a Docker sandbox with default network_policy=deny |
Docker Sandbox CLI |
sandbox_run_job |
Execute command in sandbox with deterministic timeout + logs | Docker Sandbox CLI |
sandbox_status |
Check sandbox state (running/stopped/unknown) with retry/backoff |
Docker Sandbox CLI |
sandbox_fetch_artifact |
Read artifact/log content with size/path safety constraints | Host file access + safety checks |
sandbox_teardown |
Stop or remove sandbox | Docker Sandbox CLI |
Setup
For development setup and checks that do not require running models, see CONTRIBUTING.md.
Fresh install — complete sequence
# 1. Install Bun and uv (if not already installed)
curl -fsSL https://bun.sh/install | bash
curl -LsSf https://astral.sh/uv/install.sh | sh
# 2. Clone and install JS/TS dependencies
git clone https://github.com/omar-A-hassan/medsci-agent.git
cd medsci-agent
bun install
# 3. Create Python environments
bun run setup:py:core # RDKit + BioPython + Scanpy → .venv/
bun run setup:py:paperqa # PaperQA + Scrapling + ACE → packages/server-paperqa/.venv-paperqa/
# 4. Pull Ollama models (Ollama must be installed first: https://ollama.com)
ollama pull medgemma:latest
ollama pull mxbai-embed-large
ollama pull hf.co/matrixportalx/txgemma-2b-predict-GGUF:Q4_K_M
# 5. (Optional) Load environment overrides before starting OpenCode
cp -n .env.example .env
# Add a real provider key to .env only when using ACE or cloud PaperQA.
set -a; source .env; set +a
# 6. Verify setup
bun run typecheck
bun test
# 7. Open in OpenCode
opencode # MCP servers start automatically via opencode.json
The opencode.json is pre-configured with local Ollama and Python paths for the core servers. Its medsci-paperqa block explicitly sets PQA_LLM_BACKEND=openrouter, so PaperQA requires OPENROUTER_API_KEY unless you change that per-server value to ollama. See Configure OpenCode and Configuration.
Prerequisites
- Bun >= 1.1
- uv (Python package and environment manager)
- Ollama
- OpenCode
- Docker Desktop 4.40+ with the Docker AI Sandbox feature enabled (required for sandbox tools only)
- The
sandbox_*tools usedocker sandboxsubcommands — a first-party feature in Docker Desktop 4.40+. Enable it under Settings → Features in Development → Docker AI Sandbox. - All other tools work without Docker.
- The
Sandbox not available? If you don't have Docker Desktop 4.40+ you can still use all 23 non-sandbox tools. Leave the
medsci-sandboxMCP server enabled — calls to sandbox tools will return clear errors rather than crashing.
1. Clone and install
git clone https://github.com/omar-A-hassan/medsci-agent.git
cd medsci-agent
bun install
2. Python environments
The system uses two strictly decoupled Python virtual environments, both managed with uv.
Core Environment (Required):
bun run setup:py:core
PaperQA + Acquisition Environment (Required for strict full-text retrieval and deep synthesis):
bun run setup:py:paperqa
Or run both in one command:
bun run setup:py:all
Important: Set
MEDSCI_PYTHONto.venv/bin/python3for core tools. Bothmedsci-paperqaandmedsci-acquisitionshould run withpackages/server-paperqa/.venv-paperqa/bin/python3to keep Scrapling and PaperQA dependencies in one environment.Dependency ownership:
.venv(uv groups:scientific,test): core science sidecars (RDKit/BioPython/Scanpy and related tool stacks).packages/server-paperqa/.venv-paperqa(uv groups:paperqa,ace,test): PaperQA + acquisition parsing + ACE stack.
3. Pull Ollama models
ollama pull medgemma:latest # Biomedical interpretation
ollama pull mxbai-embed-large # Document embeddings for PaperQA
ollama pull hf.co/matrixportalx/txgemma-2b-predict-GGUF:Q4_K_M # ADMET prediction
If medgemma:latest is not available directly, pull the GGUF from HuggingFace and alias it:
ollama pull hf.co/unsloth/medgemma-4b-it-GGUF:Q4_K_M
cp ~/.ollama/models/manifests/hf.co/unsloth/medgemma-4b-it-GGUF/Q4_K_M \
~/.ollama/models/manifests/registry.ollama.ai/library/medgemma/latest
Note: The
cpcommand creates an alias so the code can reference the model asmedgemma:latestregardless of how it was downloaded.
4. Configure OpenCode
The included opencode.json is pre-configured. Set the model field to your preferred cloud LLM:
{
"model": "openai/gpt-4o"
}
The core servers (medsci-drug, medsci-protein, medsci-omics, medsci-imaging, and medsci-literature) use .venv/bin/python3. medsci-acquisition and medsci-paperqa use packages/server-paperqa/.venv-paperqa/bin/python3. Update those MEDSCI_PYTHON values in their individual opencode.json environment blocks if your virtual environments are elsewhere. Per-server values override the shell environment loaded from .env.
For key-free local PaperQA, change only the medsci-paperqa block in opencode.json from "PQA_LLM_BACKEND": "openrouter" to "PQA_LLM_BACKEND": "ollama"; its PQA_OLLAMA_URL and local embedding model are already configured there.
4.1 Optional: Enable ACE MCP (self-improvement layer)
MedSci now supports optional ACE MCP integration for adaptive strategy learning.
Install ACE MCP in the PaperQA/acquisition virtual environment (recommended):
bun run setup:py:paperqa
Configured MCP server name: ace-mcp (in opencode.json)
ACE model default: openrouter/arcee-ai/trinity-large-preview:free (set via ACE_MCP_DEFAULT_MODEL in opencode.json). This is a free OpenRouter model that requires OPENROUTER_API_KEY. To change:
export ACE_MCP_DEFAULT_MODEL="your/provider-model"
Credential model for ACE:
- ACE runs as a separate MCP process and needs provider credentials available in that process environment.
- If you use OpenAI for ACE, export
OPENAI_API_KEYbefore starting OpenCode. - If you use Anthropic/Gemini/Mistral/etc for ACE, set the corresponding provider key env var.
- ACE can use the same cloud provider/model family you use in OpenCode, but it does not automatically inherit the currently selected chat model unless you configure
ACE_MCP_DEFAULT_MODELaccordingly. - ACE in this setup is intentionally decoupled from local MedSci models (
medgemma,txgemma, PaperQA embedding model) and should not use them unless you explicitly reconfigure it.
Default behavior in MedSci:
- in-run reflection is read-only (
ace.ask/ace.skillbook.get) - automatic post-run learning is triggered by plugin guardrails (gated by evidence quality)
- manual fallback remains available via
/ace-learn
Skillbooks are persisted under .opencode/ace/skillbooks/.
Why ACE is installed in packages/server-paperqa/.venv-paperqa (not the core .venv):
- ACE learning is orchestration/synthesis logic, closest to the PaperQA + acquisition stack.
- Keeping ACE out of the core scientific sidecar avoids dependency drift for RDKit/Scanpy/BioPython workflows.
- This preserves strict environment separation and reduces breakage risk in domain toolchains.
Example override:
export ACE_MCP_DEFAULT_MODEL="anthropic/claude-3-5-sonnet-latest"
export ANTHROPIC_API_KEY="..."
Key export timing: API keys must be exported in the shell before starting OpenCode. MCP server processes are spawned at startup and inherit env from that moment — changing env vars afterwards has no effect until OpenCode is restarted.
5. Run tests
bun run test:all
This runs:
- all Bun tests across MCP servers (including sidecar-in-loop tests when
packages/server-paperqa/.venv-paperqaexists), - and PaperQA Python tests using the PaperQA venv interpreter.
6. Start
Make sure Ollama is running, then open the project directory in OpenCode. The MCP servers start automatically.
OpenCode Agent Usage
Agent roles
medsciis the primary orchestrator for cross-domain workflows.drug,protein,omics, andimagingare focused subagents for domain-deep tasks.- All agents follow a planning-first contract (brief plan before first tool call, then strict sequential execution).
Built-in project commands
This repo ships OpenCode slash commands under .opencode/commands:
/triage— classify request and propose minimal sequential MCP plan/lit-deep— literature discovery + PaperQA deep synthesis workflow/sandbox-job— sandbox lifecycle run (prepare → run_job → status(advisory) → fetch → teardown)/qc-check— maker-checker quality gate on scientific outputs/handoff-report— compact handoff for next agent/human/ace-learn— manual ACE learning fallback/override for a completed task/ace-strategies— inspect ACE strategy state for a domain/session
Sandbox command default
For inline script execution, prefer:
python3 -c "print('sandbox smoke ok')"
instead of python -c ... to avoid environment-path variability across sandbox templates.
Determinism and status policy
- Treat
sandbox_run_jobsuccess/failure as source-of-truth for execution outcome. - Treat
sandbox_statusas advisory state signal. - Backend applies status retry/backoff before returning
unknown.
Configuration
The complete reference, with safe defaults and optional credentials commented out, is .env.example. Bun auto-loads .env for direct bun run commands from the project root. For OpenCode, Python sidecars, and ACE, export the values in your shell before starting OpenCode so they are inherited by those processes. Explicit per-server values in opencode.json take precedence over inherited values. The main runtime variables are:
| Variable | Default | Description |
|---|---|---|
MEDSCI_PROFILE |
standard |
Hardware profile: lite, standard, or full |
MEDSCI_PYTHON |
python3 |
Fallback Python binary; core OpenCode servers override it with .venv/bin/python3 |
MEDSCI_OLLAMA_URL |
http://127.0.0.1:11434 |
Ollama API endpoint |
MEDSCI_OLLAMA_MODEL |
medgemma:latest |
Default Ollama model for interpretation |
MEDSCI_OLLAMA_TIMEOUT |
120000 |
Ollama request timeout in milliseconds |
MEDSCI_PYTHON_TIMEOUT |
60000 |
Python sidecar request timeout in milliseconds |
PQA_LLM_MODEL |
ollama/medgemma:latest |
LLM model PaperQA uses for summarization/answering (litellm format) |
PQA_EMBEDDING_MODEL |
ollama/mxbai-embed-large |
Embedding model PaperQA uses for document indexing |
PQA_OLLAMA_URL |
http://localhost:11434 |
Ollama endpoint for PaperQA (separate from core) |
PQA_EMAIL |
medsci-agent@localhost |
Email for NCBI API access (required by NCBI usage policy) |
PQA_USE_DOC_DETAILS |
false |
If true, enables PaperQA metadata inference during indexing (less reliable with local models) |
PQA_CHUNK_CHARS |
1200 |
Default chunk size (characters) for PaperQA document reader before embedding |
PQA_CHUNK_OVERLAP |
100 |
Overlap (characters) between adjacent chunks |
PQA_CHUNK_MIN_CHARS |
400 |
Lower bound for automatic chunk-size backoff retries on embedding context errors |
PQA_CHUNK_BACKOFF_RETRIES |
3 |
Number of times to retry indexing with smaller chunks on embed context-limit errors |
PQA_ACQUIRE_CONCURRENCY |
3 |
Max concurrent NCBI acquisition requests in PaperQA |
PQA_MAX_TEXT_CHARS |
1500000 |
Hard cap on acquired paper text size (chars) to avoid indexing blowups |
PQA_NEGATIVE_CACHE_TTL_HOURS |
24 |
TTL for acquisition negative-cache entries (failed sources) |
PQA_LLM_TIMEOUT_SECONDS |
180 |
Timeout (seconds) for LLM and summary LLM requests via LiteLLM; OpenCode sets 480 for medsci-paperqa |
PQA_ANSWER_MAX_SOURCES |
5 |
Maximum number of sources PaperQA includes in a synthesized answer |
PQA_EVIDENCE_K |
10 |
Number of evidence chunks PaperQA gathers before answering; OpenCode sets 5 for medsci-paperqa |
PQA_DOCSET_CACHE_MAX_ENTRIES |
8 |
Max number of in-memory docset cache entries per workspace |
PQA_DOCSET_CACHE_MAX_BYTES |
209715200 |
Max total bytes for in-memory docset cache (default 200 MB) |
PQA_PREFLIGHT_CACHE_TTL_SECONDS |
300 |
TTL for cached Ollama preflight checks to avoid repeated startup latency |
PQA_SKIP_PREFLIGHT |
false |
If true, skip Ollama model reachability/model-presence preflight checks |
PQA_ENABLE_DOCUMENT_INPUT |
true |
If false, rejects documents payloads and only allows identifier-based acquisition |
PQA_LLM_BACKEND |
ollama |
LLM backend for PaperQA: ollama (local), openrouter, or anthropic (cloud); opencode.json currently overrides medsci-paperqa to openrouter |
PQA_CLOUD_MODEL |
openrouter/anthropic/claude-sonnet-4-5 |
Cloud model name in LiteLLM format; set an explicit compatible value when PQA_LLM_BACKEND=anthropic |
PQA_QUERY_TIMEOUT_MS |
(auto-calculated) | Direct override for PaperQA total query timeout in milliseconds (caps at 540,000 ms). Overrides the automatic per-paper calculation. |
Acquisition-related environment variables (optional, server-acquisition):
| Variable | Default | Description |
|---|---|---|
ACQ_REQUIRE_SCRAPLING |
false |
If true, acquisition sidecar health check and HTML extraction hard-fail when Scrapling is unavailable. Default false enables graceful fallback to BeautifulSoup/regex. |
ACQ_PYTHON |
unset | Optional explicit acquisition Python; otherwise MEDSCI_PYTHON or the configured PaperQA venv path is used |
ACQ_CACHE_DIR |
.opencode/acquired_docs |
Cache location for acquired document payloads |
ACQ_MAX_BYTES_HARD_CAP |
10000000 |
Hard upper bound on response body bytes regardless of per-call options |
Sandbox-related environment variables (optional, server-sandbox):
| Variable | Default | Description |
|---|---|---|
MEDSCI_SANDBOX_DEFAULT_TEMPLATE |
unset | Optional default Docker sandbox template |
MEDSCI_SANDBOX_PULL_TEMPLATE |
missing |
Template pull policy: missing, always, never |
MEDSCI_SANDBOX_ARTIFACT_ROOT |
sandbox-artifacts |
Artifact root directory for run logs/metadata |
MEDSCI_SANDBOX_DEFAULT_TIMEOUT_SEC |
600 |
Default run timeout (seconds) |
MEDSCI_SANDBOX_MAX_TIMEOUT_SEC |
3600 |
Max allowed run timeout (seconds) |
MEDSCI_SANDBOX_STATUS_RETRY_ATTEMPTS |
2 |
Number of status retries before returning unknown |
MEDSCI_SANDBOX_STATUS_RETRY_BACKOFF_MS |
1000 |
Milliseconds between status retries |
ACE_MCP_* values are also set directly in the ace-mcp environment block in opencode.json; shell values do not override them. OPENROUTER_API_KEY, ANTHROPIC_API_KEY, and provider credentials used by ACE are optional and should be exported before starting OpenCode only for the selected cloud backend or provider.
OpenCode policy hardening (included)
opencode.json includes baseline hardening:
edit,task,skill,webfetch,external_directory,doom_loopdefault toaskbashallowlist for safe read-only/dev commandsbashdenylist for destructive actions (rm *,git push*)- agent-specific task/skill permission scoping for
medsci
Plugin guardrails (included)
Project plugin: .opencode/plugins/medsci-guardrails.ts
- Blocks reading sensitive
.envfiles via thereadtool (allows.env.example) - Logs tool telemetry (
tool,session_id,duration_ms,failed) viaclient.app.log - Adds ACE telemetry tags (
ace_tool,ace_learning_write) for auditability - Triggers automatic post-run
/ace-learncommand execution when high-signal tool evidence is present
The MEDSCI_PROFILE setting controls which Python libraries are pre-imported when the sidecar starts. All tools work regardless of profile — the sidecar imports libraries lazily on first use — but pre-importing avoids a cold-start delay on the first call.
| Profile | Pre-imported | Use case |
|---|---|---|
lite |
RDKit | Drug discovery tools only, lower memory usage |
standard |
RDKit, Scanpy, BioPython, leidenalg, igraph, pynndescent | Most workflows |
full |
All available | Fastest first-call latency across all tools |
PaperQA Data Nuances
When querying papers via server-paperqa, the tool performs a multi-step pipeline:
- Text Acquisition — Full-text articles are acquired via the NCBI BioC PMC API (DOIs, PMIDs, or PMCIDs). Papers not in PMC Open Access fall back to abstract-only via the BioC PubMed API. Acquired text is cached as
.txtfiles in.opencode/pqa_papers/.search_and_analyzealso accepts pre-acquireddocumentspayloads. When provided, PaperQA skips internal acquisition and indexes those documents directly.
- Indexing — PaperQA2 indexes the text files and builds a search index in
.opencode/pqa_index/. - RAG Synthesis — The query runs against indexed chunks using Ollama for both summarization and final answer generation.
- Models (local): When
medsci-paperqais changed toPQA_LLM_BACKEND=ollama, PaperQA usesPQA_LLM_MODEL(default:ollama/medgemma:latest) for summarization and answering, andPQA_EMBEDDING_MODEL(default:ollama/mxbai-embed-large) for document embeddings. Both run locally via Ollama. - Models (cloud): Set
PQA_LLM_BACKEND=openrouterorPQA_LLM_BACKEND=anthropicto route the LLM calls to a cloud provider instead of Ollama. The embedding model always stays local. Export the corresponding API key before starting OpenCode:
Cloud backends skip the Ollama LLM preflight check and tend to be significantly faster for synthesis. The acquisition and embedding steps still run locally.# OpenRouter (supports many models) export PQA_LLM_BACKEND=openrouter export PQA_CLOUD_MODEL="openrouter/anthropic/claude-3-5-sonnet" export OPENROUTER_API_KEY="sk-or-..." # Anthropic direct export PQA_LLM_BACKEND=anthropic export PQA_CLOUD_MODEL="anthropic/claude-opus-4-5" export ANTHROPIC_API_KEY="sk-ant-..." - Preflight: The sidecar verifies Ollama reachability and required model presence before indexing/query. Failures return structured codes (
OLLAMA_UNREACHABLE,MODEL_NOT_FOUND). - Agent Type: Uses
"fake"agent mode (deterministic search → gather evidence → answer path) rather than an LLM-driven agent, which reduces token usage. - Paper Limits: The
search_and_analyzeschema strictly bounds processing to 10 inputs per call (papers or documents) to avoid Out-of-Memory crashes. - Document Provenance Contract: Pre-acquired documents can include
extraction_backend(scrapling,beautifulsoup,regex,pdf_text,plain_text) andfallback_usedso downstream synthesis can reason about evidence quality explicitly. - PMC Open Access Coverage: Full-text retrieval requires papers to be in the PMC Open Access subset (~3.5M articles). Papers outside this subset get abstract-only indexing — the response includes an
acquisition_summaryshowing which papers were full-text vs abstract-only. - Stage-Gated Responses:
search_and_analyzenow returnsstage_status(acquire,index,query) and fail-soft terminal codes (ACQUIRE_NONE_SUCCESS,INDEX_ZERO_SUCCESS,API_AUTH_FAILED) instead of opaque failures.API_AUTH_FAILEDmeans the cloud LLM API key was missing or rejected — checkOPENROUTER_API_KEY/ANTHROPIC_API_KEY. - Embedding Context Guardrail: Indexing now uses conservative chunk defaults and automatic chunk-size backoff retries when Ollama embedding rejects large inputs (
/api/embedcontext-limit errors). - Caching: Paper acquisition uses canonicalized identifier hashing + manifests. Index/query path includes in-memory docset cache and persisted manifests under
.opencode/pqa_index/manifest.json. - Stateful Indexes: Do not manually delete
.opencode/pqa_index/or.opencode/pqa_papers/while a PaperQA query is in progress.
Troubleshooting
OLLAMA_UNREACHABLE — PaperQA or MedGemma fails to connect
Ollama must be running before OpenCode starts. MCP server processes inherit the environment at startup — run ollama serve first, then open OpenCode. Verify with:
curl http://localhost:11434/api/tags
MODEL_NOT_FOUND — Model missing
Pull the required model:
ollama pull medgemma:latest
ollama pull mxbai-embed-large
ollama pull hf.co/matrixportalx/txgemma-2b-predict-GGUF:Q4_K_M
If medgemma:latest resolves but the sidecar still says MODEL_NOT_FOUND, the PQA_LLM_MODEL env var may reference a different name than what Ollama has. Check with ollama list.
API_AUTH_FAILED — Cloud PaperQA authentication error
The API key for PQA_LLM_BACKEND was not found or is invalid. Export it in the shell before starting OpenCode:
export OPENROUTER_API_KEY="sk-or-..." # for PQA_LLM_BACKEND=openrouter
export ANTHROPIC_API_KEY="sk-ant-..." # for PQA_LLM_BACKEND=anthropic
ACQUIRE_NONE_SUCCESS — PaperQA couldn't fetch any papers
The papers may not be in PMC Open Access. PaperQA falls back to abstract-only indexing for papers outside PMC OA (~3.5M articles). If you have access to the full text, use acquire_documents first to get pre-acquired documents, then pass them directly to search_and_analyze.
Python sidecar tools fail (drug/protein/omics)
The core Python environment may not be set up:
bun run setup:py:core # installs RDKit, BioPython, Scanpy into .venv/
Then verify MEDSCI_PYTHON in opencode.json points to .venv/bin/python3.
Scrapling warning in acquisition
If you see SCRAPLING_REQUIRED in logs, the acquisition sidecar is running without Scrapling. This is normal — ACQ_REQUIRE_SCRAPLING=false (the default) lets it fall back to BeautifulSoup/regex HTML extraction. To enable Scrapling:
bun run setup:py:paperqa # Scrapling is installed in the PaperQA venv
And set MEDSCI_PYTHON for medsci-acquisition in opencode.json to packages/server-paperqa/.venv-paperqa/bin/python3 (it already is by default).
Sandbox tools fail with docker: command not found or connection errors
The sandbox tools require Docker Desktop 4.40+ with the AI Sandbox feature enabled. If Docker Desktop isn't installed or the daemon isn't running, sandbox calls return errors — all other tools continue to work normally.
ACE MCP fails to start
Verify the PaperQA venv is set up (bun run setup:py:paperqa) and that OPENROUTER_API_KEY is exported before starting OpenCode (ACE uses OpenRouter by default).
Project Structure
medsci-agent/
packages/
core/ Shared library (Ollama client, Python sidecar, config, types)
python/
sidecar.py Long-running Python process with scientific library handlers
server-drug/ Drug discovery MCP server
server-protein/ Protein analysis MCP server
server-literature/ Literature search MCP server
server-acquisition/ Policy-controlled retrieval MCP server
server-imaging/ Medical imaging MCP server
server-omics/ Single-cell and omics MCP server
server-paperqa/ Deep literature synthesis MCP server (identifier or document ingestion)
server-sandbox/ Isolated sandbox execution MCP server
.opencode/
agents/ Agent definitions (orchestrator + 4 domain specialists + PaperQA routing)
commands/ Reusable slash commands for MedSci workflows
plugins/ OpenCode plugin guardrails and telemetry hooks
skills/ Skill definitions for OpenCode
opencode.json OpenCode configuration (model, MCP servers)
Runtime Artifacts
Sandbox runs generate runtime artifacts (for debugging and reproducibility), typically under sandbox-artifacts/ or a configured artifact root:
job-*/stdout.logjob-*/stderr.logjob-*/metadata.json
These are not source files and are safe to delete. Sandbox teardown removes containers; host-side artifacts remain unless explicitly pruned.
Acknowledgments
This project builds on the following work:
- Prompt Repetition (Leviathan, Kalman & Matias, 2025) — Our
interpretWithMedGemmafunction repeats the instruction after the data context to improve non-reasoning model accuracy. - TxGemma (Wang, Schmidgall, Jaeger et al., 2025) — ADMET prediction uses verbatim prompt templates from Google's TxGemma, trained on Therapeutics Data Commons benchmarks.
- PaperQA2 (Future-House/paper-qa) — Deep literature synthesis and RAG is powered by FutureHouse's PaperQA2 library, with text acquired via NCBI's BioC API.
- Agentic Context Engine (ACE) (kayba-ai/agentic-context-engine) — ACE MCP integration powers MedSci's strategy-learning and post-run self-improvement loop.
- K-Dense Scientific Skills (K-Dense-AI/claude-scientific-skills) — The OpenCode skills in this project are adapted from K-Dense AI's open-source collection of 147+ scientific skills for AI agents.
License
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi
