Agent skill

Normalizing Rxnorm

by maziyarpanahi in maziyarpanahi/openmed

Normalizes drug mentions extracted by OpenMed to RxNorm RxCUIs using the free public RxNav/RxNorm REST API.

Apache-2.0Auto-check passedBackend & APIs

Install Normalizing Rxnorm

skills CLI
$ npx skills add maziyarpanahi/openmed --skill normalizing-rxnorm -a claude-code

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

GitHub CLI
$ gh skill install maziyarpanahi/openmed normalizing-rxnorm --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/normalizing-rxnorm .claude/skills/normalizing-rxnorm && 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
normalizing-rxnorm
GitHub stars
5.5k
Token cost
~2k tokens
SKILL.md length
620 words
Files
1
Skills in repo
74
Repo updated
First seen
Licence
Apache-2.0

At a glance

Normalizes drug mentions extracted by OpenMed to RxNorm RxCUIs using the free public RxNav/RxNorm REST API.

  • Works in 6 steps: Extract drug spans with OpenMed… → Parse each span into name + strength +… → Exact match the cleaned name with… → …
  • The user wants to code
  • SKILL.md covers When to use, Quick start (real RxNav API…, Workflow and Hand-off from OpenMed, plus 2 more sections
  • Reaches rxnav.nlm.nih.gov and nlm.nih.gov

What it does

Normalizing Rxnorm is an agent skill from maziyarpanahi/openmed. Normalizes drug mentions extracted by OpenMed to RxNorm RxCUIs using the free public RxNav/RxNorm REST API. Use when the user wants to code, standardize, or de-duplicate medication names, resolve a brand/generic/ingredient to a stable RxCUI, link strength+dose-form to an SCD/SBD, attach NDCs, or build a US Core Medication resource. Trigger keywords: RxNorm, RxCUI, RxNav, drug normalization, medication coding, NDC, ingredient, SCD, SBD, brand vs generic, getApproximateMatch. Pairs after OpenMed NER: consume…

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 Backend & APIs, covering Database schema design and REST APIs. The repository describes itself as: Local-first healthcare AI: clinical NER & HIPAA PII de-identification that runs 100% on-device. 2,200+ medical models, 21 languages, Apple MLX + Python, no cloud, no patient data…. The licence is Apache-2.0.

When your agent uses it

  • The user wants to code
  • De-duplicate medication names
  • Resolve a brand/generic/ingredient to a stable RxCUI
  • Link strength+dose-form to an SCD/SBD

Example prompts

  • “Use the normalizing-rxnorm skill to normaliz drug mentions extracted by OpenMed to RxNorm RxCUIs using the free public RxNav/RxNorm REST API”
  • “/normalizing-rxnorm”

Requirements

  • Python 3

Workflow steps

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

  1. Extract drug spans with OpenMed (pharma_detection_superclinical).
  2. Parse each span into name + strength + dose form when present
  3. Exact match the cleaned name with /rxcui.json?name=. If empty, fall back
  4. Pick the right term type (TTY) for your use case
  5. Validate by reading /rxcui/{rxcui}/properties.json and confirming the
  6. Emit {system: "http://www.nlm.nih.gov/research/umls/rxnorm", code, display}.

What it can do on your machine

Read from SKILL.md and the folder at commit ea920f3. 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:

    • rxnav.nlm.nih.gov
    • nlm.nih.gov

    Also links to:

    • hl7.org

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

  • Credentials

    Names no API keys, tokens, secrets or passwords.

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

Context cost

Normalizing Rxnorm loads about 2k tokens when it runs. Until then it costs about 187 tokens; SKILL.md has 620 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~187
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 ea920f3, republished under its Apache-2.0 licence (© maziyarpanahi). 620 words, ~2,022 tokens.

Download SKILL.mdSave it as .claude/skills/normalizing-rxnorm/SKILL.md (or your agent's skills folder).
name
normalizing-rxnorm
description
Normalizes drug mentions extracted by OpenMed to RxNorm RxCUIs using the free public RxNav/RxNorm REST API. Use when the user wants to code, standardize, or de-duplicate medication names, resolve a brand/generic/ingredient to a stable RxCUI, link strength+dose-form to an SCD/SBD, attach NDCs, or build a US Core Medication resource. Trigger keywords: RxNorm, RxCUI, RxNav, drug normalization, medication coding, NDC, ingredient, SCD, SBD, brand vs generic, getApproximateMatch. Pairs after OpenMed NER: consume Pharmaceutical/Chemical entities from openmed.analyze_text and map each drug span to an RxCUI. RxNorm and RxNav are fully public and free — no API key, no license barrier, the lowest-friction terminology in this set.
license
Apache-2.0
metadata.project
OpenMed
metadata.category
terminology-coding
metadata.pairs
after
metadata.version
1.0

Normalizing drug mentions to RxNorm

Map free-text medication mentions that OpenMed extracts to RxNorm — the U.S. National Library of Medicine's normalized drug nomenclature. The unit of meaning is the RxCUI (RxNorm Concept Unique Identifier): a stable integer that ties together brand, generic, ingredient, strength, and dose form.

RxNorm and the RxNav REST API are fully public and free: no API key, no license agreement, no rate-limit registration for normal use. Of every skill in this terminology batch, this one has the highest value-to-friction ratio — start here when grounding medications.

When to use

  • A clinical note names drugs ("metformin 500 mg", "Lipitor", "amox/clav") and you need one stable code per drug for storage, analytics, or interoperability.
  • You must distinguish ingredient ("metformin", IN) from a prescribable product — SCD (Semantic Clinical Drug, generic) or SBD (Semantic Brand Drug) — e.g. "metformin 500 MG Oral Tablet".
  • You need to de-duplicate brand/generic synonyms onto one concept.
  • You need NDC codes (package-level) for a product, or a US Core Medication/MedicationRequest coded with RxNorm.

If the source text is non-English or you need ATC/SNOMED links instead, see mapping-to-snomed; RxNorm itself is U.S.-centric.

Quick start (real RxNav API calls)

Base URL: https://rxnav.nlm.nih.gov/REST. No auth. JSON via ?...&... paths ending in nothing or .json depending on endpoint; the REST root returns XML by default, so request JSON explicitly.

python
import requests

BASE = "https://rxnav.nlm.nih.gov/REST"

def rxcui_for(name: str) -> str | None:
    """Exact-match RxCUI lookup for a normalized drug name."""
    r = requests.get(f"{BASE}/rxcui.json", params={"name": name}, timeout=10)
    r.raise_for_status()
    ids = r.json().get("idGroup", {}).get("rxnormId", [])
    return ids[0] if ids else None

def approximate(name: str, max_entries: int = 3) -> list[dict]:
    """Fuzzy match for misspelled or abbreviated drug text."""
    r = requests.get(
        f"{BASE}/approximateTerm.json",
        params={"term": name, "maxEntries": max_entries},
        timeout=10,
    )
    r.raise_for_status()
    return r.json().get("approximateGroup", {}).get("candidate", [])

print(rxcui_for("metformin"))                       # -> '6809' (ingredient)
print(approximate("metformin 500"))                 # fuzzy -> candidate RxCUIs

Resolve a full prescribable product (ingredient + strength + form) to an SCD:

python
# getApproximateMatch / getRxConceptProperties give term type (TTY)
def properties(rxcui: str) -> dict:
    r = requests.get(f"{BASE}/rxcui/{rxcui}/properties.json", timeout=10)
    r.raise_for_status()
    return r.json().get("properties", {})

# Find the SCD ("metformin 500 MG Oral Tablet") from the ingredient:
def related_by_tty(rxcui: str, tty: str) -> list[dict]:
    r = requests.get(
        f"{BASE}/rxcui/{rxcui}/related.json", params={"tty": tty}, timeout=10
    )
    r.raise_for_status()
    groups = r.json().get("relatedGroup", {}).get("conceptGroup", [])
    out = []
    for g in groups:
        out.extend(g.get("conceptProperties", []) or [])
    return out

Attach NDCs and check interactions (both public):

python
ndcs = requests.get(f"{BASE}/rxcui/{rxcui}/ndcs.json").json()   # package codes

Workflow

  1. Extract drug spans with OpenMed (pharma_detection_superclinical).
  2. Parse each span into name + strength + dose form when present ("metformin 500 mg tablet" → ingredient metformin, strength 500 MG, form Oral Tablet).
  3. Exact match the cleaned name with /rxcui.json?name=. If empty, fall back to /approximateTerm.json.
  4. Pick the right term type (TTY) for your use case:
    • IN ingredient — analytics, allergy lists, class rollups.
    • SCD generic product / SBD brand product — orders, US Core Medication.
    • BN brand name, PIN precise ingredient — display/lineage.
  5. Validate by reading /rxcui/{rxcui}/properties.json and confirming the tty and name match expectations; record the score from approximate matches as a confidence signal.
  6. Emit {system: "http://www.nlm.nih.gov/research/umls/rxnorm", code, display}.

Hand-off from OpenMed

OpenMed's analyze_text returns a dict whose entities list contains, per span, the keys text, label, confidence, start, end. Consume the Pharmaceutical/Chemical entities directly:

python
import openmed, requests

note = "Patient on metformin 500 mg BID and atorvastatin 20 mg nightly."
result = openmed.analyze_text(
    note,
    model_name="pharma_detection_superclinical",   # Pharmaceutical category
    output_format="dict",
)

DRUG_LABELS = {"DRUG", "MEDICATION", "CHEM"}        # OpenMed Pharmaceutical labels
for ent in result["entities"]:
    if ent["label"] in DRUG_LABELS:
        span = ent["text"]                          # e.g. "metformin"
        rxcui = rxcui_for(span) or (
            (approximate(span) or [{}])[0].get("rxcui")
        )
        print(span, "->", rxcui, f"(conf {ent['confidence']:.2f})")

Keep OpenMed's character offsets (start/end) alongside the RxCUI so every code is traceable back to the exact source span — never store the raw note text in your mapping table.

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

Edge cases & gotchas

  • Strength/form live in separate spans. OpenMed labels the drug name; the "500 mg" and "tablet" may be adjacent tokens. Reassemble using offsets before querying for an SCD, or you will only get the ingredient.
  • Combination products ("amoxicillin/clavulanate") normalize to a single multi-ingredient SCD; do not split them into two RxCUIs.
  • Brand vs generic. Lipitor (SBD/BN) and atorvastatin (IN/SCD) are different RxCUIs of the same drug. Decide up front which TTY your pipeline stores and map the other via /related.json.
  • Approximate-match noise. approximateTerm will happily return a candidate for garbage input. Gate on the returned score and re-validate with /properties.json before trusting it.
  • Obsolete RxCUIs. Use /rxcui/{rxcui}/historystatus.json to detect retired/remapped concepts; follow the remap rather than storing a dead code.
  • Licensing: none for RxNorm/RxNav. RxNorm is public domain. But RxNorm includes source vocabularies (e.g. some proprietary drug data) whose own terms-of-use apply if you redistribute the full dataset — calling the live API for normalization is unrestricted. Do not bundle UMLS to get RxNorm; RxNav is the clean path.
  • Local-first stays intact. Run OpenMed NER on-device; only the de-identified drug string leaves the process to hit RxNav. Never send a raw note containing PHI to the API.

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/normalizing-rxnorm of maziyarpanahi/openmed.

Open the folder on GitHubat commit ea920f3

Compare with similar skills

Normalizing Rxnorm 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.

Normalizing Rxnorm compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Normalizing Rxnorm this skillmaziyarpanahi/openmed5.5k—~2kAutomated safety check: PassApache-2.0
Data Client Schemareactive/data-client2k—~2.3kAutomated safety check: PassApache-2.0
API Architectcuriositech/some_claude_skills2431 repos~1.4kAutomated safety check: PassMIT
Openapi Spec Writercuriositech/some_claude_skills2431 repos~4.2kAutomated safety check: PassMIT
Wp REST API Developmentjorgerosal/wordpress-skills101—~299Automated safety check: PassMIT
Project GeneratorLeoYeAI/openclaw-master-skills2.2k—~4.5kAutomated safety check: PassMIT

Similar skills

  • Data Client Schema

    reactive/data-client

    Model data with @data-client schemas (Entity, EntityMixin, Collection, Union, Query, Values, All, Invalidate, Lazy, Scalar) for atomic, consistent, referentially-equal async data via normalization…

    2k GitHub stars~2.3k tokensUpdated today
    Backend & APIsAuto-check passed
  • API Architect

    curiositech/some_claude_skills

    Expert API designer for REST, GraphQL, gRPC architectures. An agent skill from curiositech/some_claude_skills.

    243 GitHub starsUsed in 1 repo~1.4k tokens
    Backend & APIsAuto-check passed
  • Openapi Spec Writer

    curiositech/some_claude_skills

    Expert in writing OpenAPI 3.0/3.1 specifications for REST APIs.

    243 GitHub starsUsed in 1 repo~4.2k tokens
    Backend & APIsAuto-check passed
  • Wp REST API Development

    jorgerosal/wordpress-skills

    WordPress REST API review for Codex. An agent skill from jorgerosal/wordpress-skills.

    101 GitHub stars~299 tokensUpdated 4 mo ago
    Backend & APIsAuto-check passed
  • Project Generator

    LeoYeAI/openclaw-master-skills

    Automatically transform requirement documents or natural language descriptions into complete full-stack projects (Java backend + Vue frontend) with MANDATORY interactive tech stack selection.

    2.2k GitHub stars~4.5k tokensUpdated 2 mo ago
    DevelopmentAuto-check passed
  • Project Docs

    jezweb/claude-skills

    Generate project documentation from codebase analysis — ARCHITECTURE.md, APIENDPOINTS.md, DATABASESCHEMA.md.

    1.1k GitHub stars~1.6k tokensUpdated 2 days ago
    DatabasesAuto-check: notes

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 Normalizing Rxnorm

What does Normalizing Rxnorm do?

Normalizes drug mentions extracted by OpenMed to RxNorm RxCUIs using the free public RxNav/RxNorm REST API. Normalizing Rxnorm is an agent skill from maziyarpanahi/openmed. Normalizes drug mentions extracted by OpenMed to RxNorm RxCUIs using the free public RxNav/RxNorm REST API.

When should I use Normalizing Rxnorm?

Normalizing Rxnorm fits situations like: the user wants to code; de-duplicate medication names; resolve a brand/generic/ingredient to a stable RxCUI; link strength+dose-form to an SCD/SBD.

How do I install Normalizing Rxnorm in Claude Code?

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

How do I install Normalizing Rxnorm in Codex?

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

Can I use Normalizing Rxnorm 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 normalizing-rxnorm -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/normalizing-rxnorm, .gemini/skills/normalizing-rxnorm, .github/skills/normalizing-rxnorm and .opencode/skills/normalizing-rxnorm in your project.

What does Normalizing Rxnorm need to run?

SKILL.md names no scripts, command-line tools or credentials: Normalizing Rxnorm is instructions for the agent only. Our summary lists: Python 3.

Does Normalizing Rxnorm access the network?

SKILL.md names 3 domains. In commands or code: rxnav.nlm.nih.gov and nlm.nih.gov; the agent is likely to contact these when it follows the instructions. As links in the text: hl7.org. This is read from the text; nothing was executed.

Is Normalizing Rxnorm 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 Normalizing Rxnorm use?

Normalizing Rxnorm 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 Normalizing Rxnorm use?

About 2k tokens (SKILL.md is roughly 8.1k 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 Normalizing Rxnorm?

Skills that share tags, products or a category with Normalizing Rxnorm: Data Client Schema (reactive/data-client, 2k stars), API Architect (curiositech/some_claude_skills, 243 stars), Openapi Spec Writer (curiositech/some_claude_skills, 243 stars) and Wp REST API Development (jorgerosal/wordpress-skills, 101 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Normalizing Rxnorm?

maziyarpanahi (a GitHub user) maintains it in maziyarpanahi/openmed, which has 5,457 GitHub stars. The repository holds 74 skills in this directory. The repository was last updated on October 7, 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.