OCL CLI
Command-line interface for the Open Concept Lab API. Search, browse, and manage concepts, mappings, sources, and collections from your terminal. Multi-server ready.
Designed for both humans and AI agents.
Installation
Recommended: pipx (isolated global install)
pipx install openconceptlab
This installs ocl as a global command with no dependency conflicts. Get pipx if you don't have it.
Alternative: pip
pip install openconceptlab
Alternative: uv
uv tool install openconceptlab
One-off (no install)
Run without installing using pipx or uvx:
pipx run openconceptlab --help
uvx openconceptlab --help
For development
git clone https://github.com/OpenConceptLab/ocl-cli.git
cd ocl-cli
pip install -e ".[dev]"
Verify installation
ocl --version
ocl --help
Use as a Python library
The openconceptlab package also installs the API client the ocl command uses:
from openconceptlab import OCLAPIClient
with OCLAPIClient(token="<your OCL API token>", client_name="my-tool/1.0") as ocl:
hits = ocl.search_concepts(query="malaria", owner="CIEL", repo="CIEL", limit=5)
for concept in hits["results"]:
print(concept["id"], concept["display_name"])
Pass auth_scheme="Bearer" to use an OIDC access token instead of an API token.
HTTP errors raise openconceptlab.APIError, with status_code, detail and the parsed response body. Network failures raise the httpx exception (httpx.TimeoutException or httpx.TransportError) once retries run out. A client holds one token, so create one per user.
Quick Start
1. Authenticate
You need an API token from app.openconceptlab.org:
# Store your token (prompts securely)
ocl login
# Verify authentication
ocl whoami
Or pass a token directly:
ocl --token YOUR_TOKEN whoami
Or set an environment variable:
export OCL_API_TOKEN=your_token_here
ocl whoami
2. Explore the API
# Search for organizations
ocl org list WHO
# Search for sources
ocl repo list --owner CIEL --type source
# Search for concepts
ocl concept search malaria --owner CIEL --repo CIEL
# Get a specific concept with its cross-terminology mappings
ocl concept get CIEL CIEL 116128 --include-mappings
# Search for mappings (--owner/--repo scope the mapping's source)
ocl mapping search --owner CIEL --repo CIEL --to-concept 116128
3. JSON output for scripting and agents
Use the -j flag (before the subcommand) for machine-readable JSON output:
ocl -j concept search malaria --owner CIEL --repo CIEL
ocl -j concept get CIEL CIEL 116128
4. Verbose vs summary output
Search/list commands return a summary by default (compact, fast). Use --verbose to get full details (names, descriptions, extras, timestamps):
# Summary (default)
ocl concept search malaria --owner CIEL --repo CIEL
# Verbose — more columns, more data from API
ocl concept search malaria --owner CIEL --repo CIEL --verbose
# Debug — show HTTP requests on stderr
ocl -d concept search malaria --owner CIEL --repo CIEL
The --verbose flag controls the OCL API's ?verbose=true parameter. With -j, it returns more fields in the JSON response.
Commands
Organizations
ocl org list [QUERY] [--verbose] [--limit N] [--page N]
ocl org get ORG
ocl org members ORG [--limit N]
ocl org repos ORG [--type source|collection|all] [--verbose] [--limit N] [--page N]
# Organization management
ocl org create ORG_ID NAME [--company ...] [--website ...] [--location ...] [--public-access View|Edit|None]
ocl org delete ORG_ID [--yes]
ocl org add-member ORG USERNAME
ocl org remove-member ORG USERNAME [--yes]
Users
ocl user list [QUERY] [--verbose] [--limit N] [--page N]
ocl user get USERNAME
ocl user repos USERNAME [--type source|collection|all] [--verbose] [--limit N] [--page N]
ocl user orgs USERNAME [--limit N]
Repositories (sources & collections)
Sources and collections are unified under ocl repo with a --type flag.
# Browse
ocl repo list [QUERY] [--owner OWNER] [--type source|collection|all] [--custom-validation-schema SCHEMA] [--updated-since YYYY-MM-DD] [--all-versions] [--verbose]
ocl repo get OWNER REPO [--type source|collection] [--repo-version VERSION]
ocl repo versions OWNER REPO [--type source|collection] [--updated-since YYYY-MM-DD]
# Create & update
ocl repo create OWNER REPO_ID NAME --type source|collection [options]
ocl repo update OWNER REPO [--name NAME] [--description DESC]
ocl repo version-create OWNER REPO VERSION_ID [--released/--no-released] [--match-algorithms es,llm]
ocl repo version-update OWNER REPO VERSION_ID [--released/--no-released] [--match-algorithms es,llm]
# Without --match-algorithms, a new source version is vectorized (semantic matching)
# when its HEAD is. Opt in or out when you create it:
ocl repo version-create Regenstrief LOINC 2.82 --match-algorithms es,llm # opt in: vectorized
ocl repo version-create Regenstrief LOINC 2.82 --match-algorithms es # opt out: not vectorized
--match-algorithms applies to sources only. Set it when you create a version rather than with version-update afterwards. Changing an existing version's match algorithms makes the server reindex its concepts: adding llm embeds them, which can take hours for a large repository, and removing it can drop their vectors. version-update --match-algorithms prints a warning to that effect.
# Custom attributes
ocl repo extras OWNER REPO
ocl repo extra-set OWNER REPO KEY VALUE
ocl repo extra-del OWNER REPO KEY
Exports
Manage cached ZIP exports of repository versions (sources and collections). Exports contain the full JSON representation of a version — metadata, concepts, mappings, and references.
# Check if an export is available
ocl repo export status OWNER REPO VERSION --type source|collection
# Trigger export creation (if not already cached)
ocl repo export create OWNER REPO VERSION --type source|collection
# Download, saved under the API's name; never replaces an existing file
# (-o FILE saves it as FILE, overwriting; -o DIR saves it in that existing directory)
ocl repo export download OWNER REPO VERSION --type source|collection [-o FILE|DIR]
# Delete a cached export
ocl repo export delete OWNER REPO VERSION --type source|collection
Example — download the latest CIEL release export:
ocl repo export status CIEL CIEL v2026-03-23 --type source
ocl repo export download CIEL CIEL v2026-03-23 --type source
# Saved to orgs_CIEL_sources_CIEL_v2026-03-23_<lastUpdated>.zip
The API names exports [owner-type]_[owner]_[repo-type]_[repo]_[version]_[expansion]_[lastUpdated].zip, with the expansion when the export has one. An older export the API can't name keeps its storage name; if no usable name comes back at all, the command asks for -o FILE.
Concepts
# Search & browse
ocl concept search [QUERY] [--owner OWNER] [--repo REPO] [--concept-class CLASS]
ocl concept list [--owner OWNER] [--repo REPO] [--repo-type source|collection]
ocl concept get OWNER SOURCE CONCEPT_ID [--repo-version VERSION] [--include-mappings] [--include-inverse-mappings]
ocl concept versions OWNER SOURCE CONCEPT_ID
ocl concept names OWNER SOURCE CONCEPT_ID [--verbose]
ocl concept descriptions OWNER SOURCE CONCEPT_ID [--verbose]
ocl concept extras OWNER SOURCE CONCEPT_ID
# Create & update
ocl concept create OWNER SOURCE CONCEPT_ID --concept-class CLASS --name NAME [--datatype TYPE]
ocl concept update OWNER SOURCE CONCEPT_ID [--concept-class CLASS] [--datatype TYPE]
ocl concept retire OWNER SOURCE CONCEPT_ID
ocl concept delete OWNER SOURCE CONCEPT_ID [--yes] # hard delete; staff only
ocl concept name-add OWNER SOURCE CONCEPT_ID NAME --locale LOCALE
ocl concept description-add OWNER SOURCE CONCEPT_ID TEXT --locale LOCALE
ocl concept extra-set OWNER SOURCE CONCEPT_ID KEY VALUE
ocl concept extra-del OWNER SOURCE CONCEPT_ID KEY
# Intelligent matching
ocl concept match TERM... --target-source SOURCE [--target-owner OWNER] [--verbose] [--limit N]
ocl concept match "glucose" --target-source CIEL --concept-class Diagnosis --limit 5
ocl concept match "malaria" "diabetes" --target-source CIEL --include-mappings --limit 1
Mappings
# Search & browse (--owner/--repo scope the mapping's source, not the concept sources)
ocl mapping search [QUERY] [--owner OWNER] [--repo REPO] [--map-type TYPE]
ocl mapping search --owner CIEL --repo CIEL --from-concept 138041 --verbose
ocl mapping search --owner CIEL --repo CIEL --to-concept 116128
ocl mapping get OWNER SOURCE MAPPING_ID [--repo-version VERSION]
ocl mapping versions OWNER SOURCE MAPPING_ID
# Create & update
ocl mapping create OWNER SOURCE --map-type TYPE --from-concept-url URL --to-concept-url URL
ocl mapping update OWNER SOURCE MAPPING_ID [--map-type TYPE]
ocl mapping retire OWNER SOURCE MAPPING_ID
ocl mapping delete OWNER SOURCE MAPPING_ID [--yes] # hard delete; staff only
Cascade
Navigate concept hierarchies and related mappings:
ocl cascade OWNER REPO CONCEPT_ID [--repo-version VERSION] [--levels N] [--reverse]
Collection References
ocl ref list OWNER COLLECTION [--collection-version VERSION]
ocl ref add OWNER COLLECTION EXPRESSION... [--cascade sourcemappings|sourcetoconcepts]
ocl ref remove OWNER COLLECTION EXPRESSION...
Expansions
ocl expansion list OWNER COLLECTION VERSION
ocl expansion get OWNER COLLECTION [--collection-version VERSION] [--expansion-id ID]
ocl expansion create OWNER COLLECTION VERSION
Bulk Import
Submit files for bulk import. Supports JSON Lines (.json, .jsonl), CSV (.csv), and OCL export ZIP (.zip):
ocl import file data.jsonl # submit JSON Lines file
ocl import file export.zip --queue myqueue # submit to named queue
ocl import file data.csv --no-update --parallel 3 # CSV, skip existing, 3 threads
ocl import file data.jsonl --wait # submit and poll until complete
ocl import status TASK_ID # check import status
ocl import status TASK_ID --wait # poll until complete
ocl import list # list active/recent imports
ocl import list --queue myqueue # list imports in specific queue
Task Management
Monitor async operations on the server:
ocl task list [--state SUCCESS|FAILURE|PENDING|STARTED] [--verbose]
ocl task get TASK_ID
Server Management
OCL CLI supports multiple OCL server environments:
# List configured servers
ocl server list
# Add a custom server
ocl server add my-server https://api.my-ocl.org --name "My OCL Server"
# Switch default server
ocl server use ocl-dev
# Use a specific server for one command
ocl -s ocl-qa concept search malaria
Pre-configured servers: ocl-prod (default), ocl-dev, ocl-qa, ocl-staging
Versioning
OCL resources are versioned. Use --repo-version (for sources/repos) or --collection-version (for collections) to access specific versions:
# Get latest released version of a source
ocl repo get CIEL CIEL --repo-version latest
# Get a named version
ocl repo get CIEL CIEL --repo-version v2026-01-26
# Get a concept as it existed in a specific source version
ocl concept get CIEL CIEL 116128 --repo-version v2026-01-26
# Omit --repo-version to get HEAD (working draft)
ocl concept get CIEL CIEL 116128
Configuration
Config is stored at ~/.ocl/config.json. It's created automatically on first use.
Token resolution order
--tokenCLI flagOCL_API_TOKENenvironment variable- Server-specific env var (e.g.
OCL_API_TOKEN_PROD) - Token stored via
ocl login
Server resolution order
--server/-sCLI flagOCL_SERVERenvironment variabledefault_serverin config file
Agent Integration
The CLI is designed for use by AI agents via subprocess calls. Key features:
ocl reference --jsondumps the full command tree in one call — all commands, args, options-jflag outputs structured JSON on stdout- Exit codes: 0 = success, 1 = client error, 2 = server error, 3 = auth error
- Errors go to stderr, data goes to stdout
- Non-interactive: all parameters via flags/args (except
ocl login)
Example agent usage:
# Search and parse results
ocl -j concept search "diabetes" --owner CIEL --repo CIEL --limit 10
# Get a specific concept
ocl -j concept get CIEL CIEL 116128
# Create a mapping (with token via env var)
OCL_API_TOKEN=xxx ocl -j mapping create MYORG MYSOURCE \
--map-type SAME-AS \
--from-concept-url /orgs/CIEL/sources/CIEL/concepts/116128/ \
--to-concept-url /orgs/WHO/sources/ICD-10-WHO/concepts/B54/
Advanced: Real-World Queries with jq
The CLI's --json output pairs naturally with jq for ad-hoc analytics that would otherwise require direct database access.
Example: OpenMRS repo activity report
Count source versions, collection versions, distinct orgs, and distinct users with OpenMRS Validation Schema repos updated in the last 6 months (ocl_issues#2032):
ocl -j repo list --custom-validation-schema OpenMRS --updated-since 2025-09-27 \
--all-versions --limit 500 \
| jq '{
source_versions: [.results[] | select(.repo_type == "Source")] | length,
collection_versions: [.results[] | select(.repo_type == "Collection")] | length,
organizations: [.results[] | select(.owner_type == "Organization") | .owner] | unique | length,
users: [.results[] | select(.owner_type == "User") | .owner] | unique | length
}'
Key flags used:
--custom-validation-schema OpenMRS— server-side filter via Elasticsearch--updated-since 2025-09-27— only repos updated in the last 6 months--all-versions— return one row per repo version (not just HEAD), so version counts are direct-j(before subcommand) — structured JSON output for piping tojq
Requirements
- Python 3.10+
- Dependencies: click, httpx, tenacity, python-dotenv
Metadata
Release files for openconceptlab 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| openconceptlab-0.2.0.tar.gz | 62.8 kB | Without provenance | Details for openconceptlab-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| openconceptlab-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for openconceptlab-0.2.0-py3-none-any.whl |
Total release size: 123.7 kB
Release files / openconceptlab-0.2.0.tar.gz
| Download URL | openconceptlab-0.2.0.tar.gz |
|---|---|
| Size | 62.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
66a6ca6b9921ad31e3644edd4dc8901ec2ff4d07a57dedda529198172af0e1f8
|
|
BLAKE2b-256 checksum How to use checksums |
cb6a7305259799f349fa58dc8e330f318b5aaeac58ece14584768715006db8ed
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.10
|
Release files / openconceptlab-0.2.0-py3-none-any.whl
| Download URL | openconceptlab-0.2.0-py3-none-any.whl |
|---|---|
| Size | 60.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c6ffb42dd1db61b859a51a4ac4176d93e89050ae49a0066adbe6aa743eca8ca3
|
|
BLAKE2b-256 checksum How to use checksums |
bc2deba68ad2729106570e43721f45355efaa3cd4b064ee136c62474197c6d41
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.10
|
Security for openconceptlab 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.