Agent skill

Linking Umls Concepts

by maziyarpanahi in maziyarpanahi/openmed

Links entities extracted by OpenMed to UMLS Metathesaurus CUIs using the USER'S OWN UTS API key, with nothing from the Metathesaurus bundled or cached.

Apache-2.0Auto-check passedDevelopment

Install Linking Umls Concepts

skills CLI
$ npx skills add maziyarpanahi/openmed --skill linking-umls-concepts -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install maziyarpanahi/openmed linking-umls-concepts --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/maziyarpanahi/openmed.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/linking-umls-concepts .claude/skills/linking-umls-concepts && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
linking-umls-concepts
GitHub stars
5.5k
Token cost
~2k tokens
SKILL.md length
619 words
Files
1
Skills in repo
74
Repo updated
First seen
Licence
Apache-2.0

At a glance

Links entities extracted by OpenMed to UMLS Metathesaurus CUIs using the USER'S OWN UTS API key, with nothing from the Metathesaurus bundled or cached.

  • Works in 6 steps: Extract spans with OpenMed (Disease,… → Search each span via /search/{version}… → Filter by semantic type (TUI) so a drug… → …
  • The user wants to normalize concepts across vocabularies to a single CUI
  • SKILL.md covers When to use, Quick start (user-supplied UTS…, Workflow and Hand-off from OpenMed, plus 2 more sections
  • Reaches uts-ws.nlm.nih.gov; needs API_KEY and UTS_API_KEY

What it does

Linking Umls Concepts is an agent skill from maziyarpanahi/openmed. Links entities extracted by OpenMed to UMLS Metathesaurus CUIs using the USER'S OWN UTS API key, with nothing from the Metathesaurus bundled or cached. Use when the user wants to normalize concepts across vocabularies to a single CUI, resolve synonyms via the UMLS, filter by semantic type, or cross-walk between SNOMED CT, ICD-10, RxNorm and MeSH through their shared CUI. Trigger keywords: UMLS, CUI, Metathesaurus, UTS API key, semantic type, TUI, MetaMap, QuickUMLS, concept normalization, cross-vocabulary. Pairs…

Its SKILL.md is about 2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Development, covering Diagrams and Database schema design. The repository describes itself as: Local-first healthcare AI: clinical NER and HIPAA PII de-identification on hardware you control. 2,200+ medical models, 35 model-backed PII languages, and Python, MLX, Android… The licence is Apache-2.0.

When your agent uses it

  • The user wants to normalize concepts across vocabularies to a single CUI
  • Resolve synonyms via the UMLS
  • Filter by semantic type
  • Cross-walk between SNOMED CT

Example prompts

  • “Use the linking-umls-concepts skill to link entities extracted by OpenMed to UMLS Metathesaurus CUIs using the USER'S OWN UTS API key, with nothing…”
  • “/linking-umls-concepts”

Requirements

  • Python 3
  • A credential in API_KEY
  • A credential in UTS_API_KEY

Workflow steps

6 steps, taken from the first numbered list in SKILL.md.

  1. Extract spans with OpenMed (Disease, Pharmaceutical, Chemical, Anatomy).
  2. Search each span via /search/{version} for candidate CUIs.
  3. Filter by semantic type (TUI) so a drug span resolves to a substance
  4. Rank candidates (exact preferred-name match > synonym match) and combine
  5. Cross-walk the chosen CUI to whatever target you actually store —
  6. Emit the CUI plus the target code(s) and OpenMed source offsets.

What it can do on your machine

Read from SKILL.md and the folder at commit 34d7b8c. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are python).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • uts-ws.nlm.nih.gov

    Also links to:

    • nlm.nih.gov
    • uts.nlm.nih.gov
    • documentation.uts.nlm.nih.gov
    • lhncbc.nlm.nih.gov
    • github.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • API_KEY
    • UTS_API_KEY

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Linking Umls Concepts loads about 2k tokens when it runs. Until then it costs about 198 tokens; SKILL.md has 619 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~198
When it runs · the whole SKILL.md, loaded when a task matches
~2k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from maziyarpanahi/openmed at commit 34d7b8c, republished under its Apache-2.0 licence (© maziyarpanahi). 619 words, ~2,039 tokens.

Download SKILL.mdSave it as .claude/skills/linking-umls-concepts/SKILL.md (or your agent's skills folder).
name
linking-umls-concepts
description
Links entities extracted by OpenMed to UMLS Metathesaurus CUIs using the USER'S OWN UTS API key, with nothing from the Metathesaurus bundled or cached. Use when the user wants to normalize concepts across vocabularies to a single CUI, resolve synonyms via the UMLS, filter by semantic type, or cross-walk between SNOMED CT, ICD-10, RxNorm and MeSH through their shared CUI. Trigger keywords: UMLS, CUI, Metathesaurus, UTS API key, semantic type, TUI, MetaMap, QuickUMLS, concept normalization, cross-vocabulary. Pairs after OpenMed NER: consume Disease/Pharmaceutical/Chemical/Anatomy entities from openmed.analyze_text and resolve each span to a CUI out-of-process. UMLS is license-restricted — the Metathesaurus is NEVER bundled; every call uses the user's UTS account.
license
Apache-2.0
metadata.project
OpenMed
metadata.category
terminology-coding
metadata.pairs
after
metadata.version
1.0

Linking OpenMed entities to UMLS CUIs

Resolve concept spans that OpenMed extracts to UMLS Metathesaurus concepts. The atom is the CUI (Concept Unique Identifier, e.g. C0011860): one CUI unifies synonyms from many source vocabularies (SNOMED CT, ICD-10-CM, RxNorm, MeSH, LOINC), making the CUI the natural hub for cross-vocabulary normalization. Every concept also carries one or more semantic types (TUIs, e.g. Disease or Syndrome T047) for type-based filtering.

Hard licensing boundary — read first. The UMLS Metathesaurus is license-restricted. OpenMed and this skill never bundle, ship, or cache Metathesaurus content. Concept linking runs out-of-process against the NLM UTS (UMLS Terminology Services) REST API using the user's own UTS API key. A free UTS account + API key is required (request at uts.nlm.nih.gov and accept the UMLS license). The Metathesaurus stays user-supplied: your code holds only the key (from the environment) and stores only returned CUIs/strings.

When to use

  • You need one canonical id across vocabularies — e.g. to unify a SNOMED CT disorder, an ICD-10 code, and a free-text mention onto a single CUI.
  • You want synonym normalization ("MI", "myocardial infarction", "heart attack" → C0027051).
  • You need semantic-type filtering to keep only, say, Pharmacologic Substance or Disease or Syndrome entities.
  • You are cross-walking codes and need the CUI as the join key before pivoting to RxNorm (normalizing-rxnorm) or SNOMED (mapping-to-snomed).

Quick start (user-supplied UTS API key)

The UTS REST API base is https://uts-ws.nlm.nih.gov/rest. Authentication uses your API key as the apiKey query parameter (the modern, simplest method).

python
import os, requests

UTS = "https://uts-ws.nlm.nih.gov/rest"
API_KEY = os.environ["UTS_API_KEY"]          # USER's own key — never hardcoded
VERSION = "current"                           # or a fixed release like 2024AB

def search(term: str, sabs: str | None = None, count: int = 10) -> list[dict]:
    """Search the Metathesaurus for a term; optionally restrict source vocabs."""
    params = {"string": term, "apiKey": API_KEY, "pageSize": count}
    if sabs:                                   # e.g. "SNOMEDCT_US,RXNORM,ICD10CM"
        params["sabs"] = sabs
    r = requests.get(f"{UTS}/search/{VERSION}", params=params, timeout=15)
    r.raise_for_status()
    return r.json().get("result", {}).get("results", [])

def concept(cui: str) -> dict:
    """Pull a concept's preferred name and semantic types."""
    r = requests.get(f"{UTS}/content/{VERSION}/CUI/{cui}",
                     params={"apiKey": API_KEY}, timeout=15)
    r.raise_for_status()
    return r.json().get("result", {})

def crosswalk(cui: str, target_sab: str) -> list[dict]:
    """Atoms of a CUI in a target vocabulary (the cross-walk)."""
    r = requests.get(f"{UTS}/content/{VERSION}/CUI/{cui}/atoms",
                     params={"apiKey": API_KEY, "sabs": target_sab,
                             "pageSize": 50}, timeout=20)
    r.raise_for_status()
    return r.json().get("result", [])

hits = search("type 2 diabetes")              # -> [{ui: 'C0011860', name: ...}, ...]
sct = crosswalk("C0011860", "SNOMEDCT_US")    # CUI -> SNOMED CT codes

Workflow

  1. Extract spans with OpenMed (Disease, Pharmaceutical, Chemical, Anatomy).
  2. Search each span via /search/{version} for candidate CUIs.
  3. Filter by semantic type (TUI) so a drug span resolves to a substance concept, not a same-named disease. Pull semantic types from /content/.../CUI/{cui} and keep only the expected group.
  4. Rank candidates (exact preferred-name match > synonym match) and combine with OpenMed's confidence to choose one CUI.
  5. Cross-walk the chosen CUI to whatever target you actually store — SNOMEDCT_US, ICD10CM, RXNORM, MSH — via /CUI/{cui}/atoms?sabs=.
  6. Emit the CUI plus the target code(s) and OpenMed source offsets.

Hand-off from OpenMed

openmed.analyze_text(..., output_format="dict") returns entities, each a dict with text, label, confidence, start, end. Use the label to pick the semantic-type group you keep:

python
import openmed

note = "History of myocardial infarction; started on lisinopril."
result = openmed.analyze_text(
    note,
    model_name="disease_detection_superclinical",   # Disease category
    output_format="dict",
)

# OpenMed label -> acceptable UMLS semantic-type groups (TUI prefixes)
KEEP_STY = {
    "DISEASE":  {"Disease or Syndrome", "Sign or Symptom", "Neoplastic Process"},
    "DRUG":     {"Pharmacologic Substance", "Clinical Drug"},
    "CHEM":     {"Pharmacologic Substance", "Organic Chemical"},
}

for ent in result["entities"]:
    for hit in search(ent["text"], count=5):
        cui = hit["ui"]
        stys = {s["name"] for s in concept(cui).get("semanticTypes", [])}
        if not KEEP_STY.get(ent["label"]) or stys & KEEP_STY[ent["label"]]:
            print(ent["text"], ent["start"], ent["end"], "->", cui, hit["name"])
            break

Keep OpenMed's start/end offsets beside each CUI for traceability. Store only CUIs and codes — never the raw note, never a local copy of the Metathesaurus.

Show full SKILL.md (231 more words)Show less

Edge cases & gotchas

  • Never bundle or cache the Metathesaurus. No vendored MRCONSO, no local concept dump baked into the package. If you precompute, do it inside the user's licensed environment, not in distributed OpenMed assets.
  • The UTS key is the user's. Read it from the environment/secret store; never embed it, log it, or commit it. One key, the user's license, their rate limits.
  • Semantic-type filtering is essential. Many strings are polysemous across types ("cold" = symptom vs temperature). Without TUI filtering you will link to the wrong concept family.
  • Version pin for reproducibility. current drifts at each UMLS release. Pin a release (e.g. 2024AB) for stable, auditable mappings; record it.
  • Source-vocab restriction. Restrict sabs to the vocabularies you are licensed for and actually need; this both narrows results and respects per-source license terms inside UMLS.
  • CUI as hub, not endpoint. Downstream systems usually want a target code (SNOMED/ICD/RxNorm), so resolve to CUI then cross-walk — don't store only the CUI if your consumers expect billable/clinical codes.
  • Offline alternatives are still user-licensed. Tools like MetaMap or QuickUMLS run locally but require a UMLS download under the user's license; OpenMed neither ships nor requires those datasets.
  • Local-first. OpenMed NER runs on-device; only de-identified concept strings reach UTS. No PHI over the wire.

Standards & references

© maziyarpanahi, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/linking-umls-concepts of maziyarpanahi/openmed.

Open the folder on GitHubat commit 34d7b8c

Compare with similar skills

Linking Umls Concepts next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Linking Umls Concepts compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Linking Umls Concepts this skillmaziyarpanahi/openmed5.5k—~2kAutomated safety check: PassApache-2.0
Walkthroughalexanderop/walkthrough141—~3.4kAutomated safety check: NotesNone
Managedcode Orleans Graphmanagedcode/dotnet-skills486—~1.6kAutomated safety check: PassMIT
Datamodellmnimbalyst/nimbalyst1.9k—~713Automated safety check: PassMIT
Drizzle Erdhiroppy/mf-dashboard418—~627Automated safety check: PassMIT
Entity ModelAI-Unified-Process/marketplace142—~1.9kAutomated safety check: PassApache-2.0

Similar skills

  • Walkthrough

    alexanderop/walkthrough

    Generates a self-contained HTML file with an interactive, clickable Mermaid diagram (flowchart or ER diagram) that explains how a codebase feature, flow, architecture, or database schema works.

    141 GitHub stars~3.4k tokensUpdated 6 mo ago
    DevelopmentAuto-check: notes
  • Managedcode Orleans Graph

    managedcode/dotnet-skills

    Integrate ManagedCode.Orleans.Graph into an Orleans-based .NET application for grain-call policy enforcement, deadlock detection, live-call telemetry, and Mermaid graph diagnostics.

    486 GitHub stars~1.6k tokensUpdated yesterday
    DatabasesAuto-check passed
  • Datamodellm

    nimbalyst/nimbalyst

    Create visual data models for database schemas using Nimbalyst's DataModelLM editor.

    1.9k GitHub stars~713 tokensUpdated today
    DatabasesAuto-check passed
  • Drizzle Erd

    hiroppy/mf-dashboard

    A skill your agent uses when needing to visualize database schema, generate ERD diagrams from Drizzle ORM schemas, or understand table relationships

    418 GitHub stars~627 tokensUpdated today
    DatabasesAuto-check passed
  • Entity Model

    AI-Unified-Process/marketplace

    Creates entity model documents with Mermaid.js ER diagrams and attribute tables defining entities, relationships, data types, and validation rules.

    142 GitHub stars~1.9k tokensUpdated 6 days ago
    DatabasesAuto-check passed
  • Data Model Creation

    TencentCloudBase/CloudBase-AI-Toolkit

    [Deprecated] Optional advanced tool for complex data modeling.

    1.1k GitHub starsUsed in 1 repo~1.8k tokens
    DatabasesAuto-check passed

More from maziyarpanahi/openmed

All 74 skills in this repo
  • Checks OpenMed de-identified clinical text against the 18 HIPAA Safe Harbor identifier categories and reports gaps and residual re-identification risk.

    5.5k GitHub stars~1.7k tokensUpdated today
    Auto-check passed
  • OpenMed Model Card Writer

    maziyarpanahi/openmed

    Fills in a model card for an OpenMed clinical NER or de-identification model from its evaluation reports: intended use, metrics, subgroups and limitations.

    5.5k GitHub stars~1.8k tokensUpdated today
    Auto-check passed
  • Walks a data pipeline against the HIPAA Privacy and Security Rule checklist and produces a gap report before it processes patient data.

    5.5k GitHub stars~2k tokensUpdated today
    Auto-check passed
  • ICD-10 Coding Assistant

    maziyarpanahi/openmed

    Suggests candidate ICD-10-CM diagnosis and ICD-10-PCS procedure codes for clinical text extracted by OpenMed, with rationale for a certified coder to review.

    5.5k GitHub stars~2k tokensUpdated today
    Auto-check passed
  • OpenMed ETL to OMOP CDM

    maziyarpanahi/openmed

    Maps OpenMed-extracted, terminology-coded conditions, drugs and measurements into OMOP CDM v5.4 tables for OHDSI and ATLAS analytics.

    5.5k GitHub stars~1.9k tokensUpdated today
    Auto-check passed
  • Extracting SDOH and Z-Codes

    maziyarpanahi/openmed

    Finds social risks such as housing instability or food insecurity in clinical notes and proposes matching ICD-10-CM Z-codes for a coder to confirm.

    5.5k GitHub stars~1.9k tokensUpdated today
    Auto-check passed

Categories

Questions about Linking Umls Concepts

What does Linking Umls Concepts do?

Links entities extracted by OpenMed to UMLS Metathesaurus CUIs using the USER'S OWN UTS API key, with nothing from the Metathesaurus bundled or cached. Linking Umls Concepts is an agent skill from maziyarpanahi/openmed. Links entities extracted by OpenMed to UMLS Metathesaurus CUIs using the USER'S OWN UTS API key, with nothing from the Metathesaurus bundled or cached.

When should I use Linking Umls Concepts?

Linking Umls Concepts fits situations like: the user wants to normalize concepts across vocabularies to a single CUI; resolve synonyms via the UMLS; filter by semantic type; cross-walk between SNOMED CT.

How do I install Linking Umls Concepts in Claude Code?

Run `npx skills add maziyarpanahi/openmed --skill linking-umls-concepts -a claude-code`. Or copy the skill folder (skills/linking-umls-concepts in maziyarpanahi/openmed) into .claude/skills/linking-umls-concepts in your project. Claude Code loads it when a task matches its description.

How do I install Linking Umls Concepts in Codex?

Run `npx skills add maziyarpanahi/openmed --skill linking-umls-concepts -a codex`. Or copy the skill folder (skills/linking-umls-concepts in maziyarpanahi/openmed) into .agents/skills/linking-umls-concepts in your project. Codex loads it when a task matches its description.

Can I use Linking Umls Concepts in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add maziyarpanahi/openmed --skill linking-umls-concepts -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/linking-umls-concepts, .gemini/skills/linking-umls-concepts, .github/skills/linking-umls-concepts and .opencode/skills/linking-umls-concepts in your project.

What does Linking Umls Concepts need to run?

Going by SKILL.md and its folder, Linking Umls Concepts needs credentials named API_KEY and UTS_API_KEY. Our summary lists: Python 3; A credential in API_KEY; A credential in UTS_API_KEY.

Does Linking Umls Concepts access the network?

SKILL.md names 6 domains. In commands or code: uts-ws.nlm.nih.gov; the agent is likely to contact it when it follows the instructions. As links in the text: nlm.nih.gov, uts.nlm.nih.gov, documentation.uts.nlm.nih.gov, lhncbc.nlm.nih.gov and github.com. This is read from the text; nothing was executed.

Is Linking Umls Concepts safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Linking Umls Concepts use?

Linking Umls Concepts is published under the Apache-2.0 licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Linking Umls Concepts use?

About 2k tokens (SKILL.md is roughly 8.2k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Linking Umls Concepts?

Skills that share tags, products or a category with Linking Umls Concepts: Walkthrough (alexanderop/walkthrough, 141 stars), Managedcode Orleans Graph (managedcode/dotnet-skills, 486 stars), Datamodellm (nimbalyst/nimbalyst, 1.9k stars) and Drizzle Erd (hiroppy/mf-dashboard, 418 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Linking Umls Concepts?

maziyarpanahi (a GitHub user) maintains it in maziyarpanahi/openmed, which has 5,506 GitHub stars. The repository holds 74 skills in this directory. The repository was last updated on October 11, 2026.

Source: maziyarpanahi/openmed on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.