Config-based providers let you connect any REST API to lean-ctx without writing a single line of Rust. Drop a TOML or JSON file into your providers directory, and lean-ctx automatically discovers and registers it.
Your AI agent can then query live data from GitHub issues, Jira tickets, database records, or any API — all through the same ctx_provider tool.
Quick Start
Create the providers directory
Drop a TOML config file
Restart lean-ctx — your provider is live
Configuration Reference
| Section | Field | Type | Description |
|---|---|---|---|
[provider] | id | string | Unique identifier (used in ctx_provider query) |
name | string | Human-readable display name | |
base_url | string | API base URL (no trailing slash) | |
description | string? | Optional description shown in ctx_provider list | |
[auth] | type | enum | bearer, api_key_header, api_key_query, basic, header, none |
token_env | string? | Environment variable name for bearer token | |
key_env | string? | Environment variable name for API key | |
header_name | string? | Custom header name (for api_key_header / header) | |
username_env | string? | Environment variable for Basic auth username | |
password_env | string? | Environment variable for Basic auth password | |
[[resources]] | name | string | Resource name (used in ctx_provider query) |
path | string | URL path with {param} placeholders | |
method | string? | HTTP method (default: GET) | |
[resources.response] | items_path | string | Dot-notation path to items array (e.g. data.issues[]) |
[resources.response.fields] | title | string | JSON path for item title |
id | string | JSON path for item ID | |
description | string? | JSON path for item body/description |
Authentication
Five authentication methods are supported out of the box. Secrets are read from environment variables at runtime — never stored in config files.
Type Header Sent Config Fields bearerAuthorization: Bearer $TOKENtoken_env api_key_headerX-Api-Key: $KEY (customizable)key_env, header_name api_key_queryAppended as ?key=$KEY key_env, query_param_name basicAuthorization: Basic base64(user:pass)username_env, password_env headerCustom header with custom value key_env, header_name noneNo authentication —
Response Extraction
Use dot-notation paths to extract data from JSON responses. Array iteration is supported with [] syntax.
[x] [-] [o] Extraction Examples # Simple array at root items_path = "[]" # → response is the array # Nested object path items_path = "data.issues[]" # → response.data.issues # Field mapping with dot-notation title = "fields.summary" # → item.fields.summary id = "key" # → item.key Auto-Discovery
lean-ctx scans two directories for provider configs on startup:
Directory Scope Formats ~/.config/lean-ctx/providers/Global providers (available in all projects) .toml, .json .lean-ctx/providers/Project-local providers (scoped to current repo) .toml, .json
Built-in Providers
lean-ctx ships with built-in providers that activate automatically when their environment variables are set:
Provider Env Variables Resources GitHub GITHUB_TOKEN, GITHUB_REPOSITORYIssues, Pull Requests, Actions Jira JIRA_BASE_URL, JIRA_TOKEN, JIRA_EMAILIssues, Sprints, Projects PostgreSQL DATABASE_URLTables, Schema, Queries
Examples
Jira Tickets
[x] [-] [o] ~/.config/lean-ctx/providers/jira.toml [provider] id = "jira" name = "Jira" base_url = "https://your-org.atlassian.net" [auth] type = "basic" username_env = "JIRA_EMAIL" password_env = "JIRA_TOKEN" [[resources]] name = "issues" path = "/rest/api/3/search?jql=project={project}" [resources.response] items_path = "issues[]" [resources.response.fields] title = "fields.summary" id = "key" description = "fields.description" Custom REST API
[x] [-] [o] .lean-ctx/providers/internal-api.toml [provider] id = "internal" name = "Internal Service" base_url = "https://api.internal.company.com" [auth] type = "api_key_header" key_env = "INTERNAL_API_KEY" header_name = "X-Service-Key" [[resources]] name = "deployments" path = "/v2/deployments?env={environment}" [resources.response] items_path = "data.deployments[]" [resources.response.fields] title = "service_name" id = "deploy_id" description = "status"