This vignette provides a comprehensive end-to-end guide for setting up a ClickHouse _database for TKCat, preparing and loading data as MDBs (Modeled Databases), querying them, exploring available resources, and finally configuring an MCP (Model Context Protocol) server to enable AI assistant integration.
The workflow covered includes:
This document references and builds upon the information provided in the main Introduction to TKCat vignette and the Querying a chTKCat instance with an AI assistant (MCP server) vignette.
Scripts are provided in the ClickHouse folder, to easily set up a ClickHouse instance ready for TKCat usage.
The following bash chunks can be copy-pasted and run directly in your
terminal. They will clone the TKCat repository to
/home/$(whoami)/tmp, modify the configuration files, and
initialize a ClickHouse instance with the specified parameters.
26.9.19"2026-10-17""tkcat_2026_10_17""admin"91039113/home/$(whoami)/tmpcat > launch-tkcat-instance.sh << 'EOF'
#!/bin/bash
##################################################################
## Customize parameters
IMAGE_BASE_NAME="tkcat"
TKCAT_INSTANCE="tkcat_test"
TKCAT_VERSION="2026-10-17"
TKCAT_ADMIN="admin"
## Don't forget to create a password for the TKCAT_ADMIN user
## In R: ?TKCat::change_chTKCat_password()
TKCAT_NAT_PORT=9103
TKCAT_HTTP_PORT=9113
TKCAT_HOSTDIR=/home/$(whoami)/tmp
######################
## Automatic parameters
IMAGE=${IMAGE_BASE_NAME}:${TKCAT_VERSION}
CONTAINER=${TKCAT_INSTANCE}_${TKCAT_VERSION}
TKCAT_HOME=${TKCAT_HOSTDIR}/${CONTAINER}
TKCAT_DATA=${TKCAT_HOME}/data
TKCAT_LOG=${TKCAT_HOME}/log
if [ -e "$TKCAT_HOME" ]; then
echo "File $TKCAT_HOME already exists. Exiting without doing anything."
exit 1
fi
######################
docker build -t ${IMAGE} .
######################
mkdir -p ${TKCAT_HOME}
chmod a+rwx ${TKCAT_HOME}
mkdir -p ${TKCAT_DATA}
chmod a+rwx ${TKCAT_DATA}
mkdir -p ${TKCAT_LOG}
chmod a+rwx ${TKCAT_LOG}
######################
docker run -d \
--name ${CONTAINER} \
--ulimit nofile=262144:262144 \
--publish=${TKCAT_NAT_PORT}:9000 \
--publish=${TKCAT_HTTP_PORT}:8123 \
--volume ${TKCAT_DATA}:/var/lib/clickhouse \
--volume ${TKCAT_LOG}:/var/log/clickhouse-server \
-e TKCAT_INSTANCE="${TKCAT_INSTANCE}" \
-e TKCAT_VERSION="${TKCAT_VERSION}" \
-e TKCAT_ADMIN="${TKCAT_ADMIN}" \
--restart=always \
${IMAGE}
EOF
chmod +x launch-tkcat-instance.shNote: This step requires Docker to be installed on
your system. The script will: - Build a Docker image with ClickHouse
version 26.9.19 - Create the necessary directories in
/home/$(whoami)/tmp/tkcat_test_2026-10-17 - Launch a Docker
container with the proper configuration
Important: When connecting to this ClickHouse
instance from R or MCP clients, use: - Host: localhost -
Native TCP port: 9103 (not the default 9101) - HTTP port:
9113 (not the default 9111) - Admin user:
admin
The following R code shows how to connect to this instance, change the admin password, and add additional users:
library(TKCat)
# Connect to your ClickHouse instance with the custom ports
k <- chTKCat(
host = "localhost",
port = 9113L, # Using the custom HTTP port
user = "admin", # The admin user created by the docker-init script
password = "", # No password after initialization !!
drv = ClickHouseHTTP::ClickHouseHTTP()
)
# Change the admin password (you will be prompted for the new password)
change_chTKCat_password(k, "admin")
db_reconnect(k)
# Add additional users with appropriate permissions
# Create a regular user with read-only access
create_chTKCat_user(k, login = "read_only_user", contact = NA, admin = FALSE)
# Grant access to specific MDBs (after creating them)
# add_chMDB_user(k, mdb = "HPO", login = "read_only_user", admin = FALSE)After initialization, you can create a password for the admin user
using the change_chTKCat_password() function as shown
above.
Upgrading ClickHouse: To upgrade an existing ClickHouse instance, use the scripts in the
ClickHouse/docker-upgradedirectory. Set theCH_VERSIONparameter to26.9.19and update the TKCAT parameters (TKCAT_VERSION, TKCAT_INSTANCE, TKCAT_NAT_PORT, TKCAT_HTTP_PORT, TKCAT_HOSTDIR) as needed, then run the upgrade script.
In this section, we prepare three example MDBs: 1. HPO (Human Phenotype Ontology) from ReDaMoR 2. ClinVar from TKCat package data 3. ChEMBL from TKCat package data
Important: These are old subsets of the respective databases, provided for illustration purposes. For production use, you should download and prepare current versions of these resources.
The Human Phenotype Ontology (HPO) aims to provide a standardized vocabulary of phenotypic abnormalities encountered in human diseases (Köhler et al. 2019).
As described in the main vignette, a subset of HPO is provided within the ReDaMoR package as the following tables:
# List available tables in the HPO subset
hpo_files <- list.files(system.file("examples/HPO-subset", package = "ReDaMoR"))
hpo_files## [1] "HPO_altId.txt" "HPO_descendants.txt"
## [3] "HPO_diseaseHP.txt" "HPO_diseaseSynonyms.txt"
## [5] "HPO_diseases.txt" "HPO_hp.txt"
## [7] "HPO_parents.txt" "HPO_sourceFiles.txt"
## [9] "HPO_synonyms.txt"
An MDB (Modeled Database) in TKCat is a self-describing container that packages:
A data model for the HPO data is provided within the ReDaMoR package. Refer to package documentation and also to the TKCat main vignette to learn how to create such data model.
hpo_model <- ReDaMoR::read_json_data_model(system.file(
"examples/HPO-model.json",
package = "ReDaMoR"
))
plot(hpo_model)Data can be loaded before being encapsulated in a
memoMDB object as shown below.
## Reading the data
hpo_data <- lapply(hpo_files, function(x) {
readr::read_tsv(
file.path(
system.file("examples/HPO-subset", package = "ReDaMoR"),
x
),
## Column types taken from the data model
col_types = ReDaMoR::col_types(hpo_model[[sub("[.]txt", "", x)]])
)
}) |>
setNames(sub("[.]txt", "", hpo_files))
## Creating the MDB
memo_hpo <- memoMDB(
dataTables = hpo_data,
dataModel = hpo_model,
dbInfo = list(
"name" = "HPO",
"title" = "Data extracted from the HPO database",
"description" = paste(
"This is a very small subset of the HPO!",
"Visit the reference URL for more information."
),
"url" = "http://human-phenotype-ontology.github.io/"
)
)We can also document the collection members for HPO tables to enable integration with other resources:
memo_hpo <- memo_hpo |>
add_collection_member(
collection = "Condition",
table = "HPO_hp",
condition = list(value = "Phenotype", static = TRUE),
source = list(value = "HP", static = TRUE),
identifier = list(value = "id", static = FALSE)
) |>
add_collection_member(
collection = "Condition",
table = "HPO_diseases",
condition = list(value = "Disease", static = TRUE),
source = list(value = "db", static = FALSE),
identifier = list(value = "id", static = FALSE)
)ClinVar is a freely accessible, public archive of reports of the relationships among human variations and phenotypes, with supporting evidence (Landrum et al. 2018).
An MDB with a subset of ClinVar is provided within the TKCat package.
It can be read directly as a fileMDB: the data are not
loaded in memory.
# Load ClinVar data from TKCat
file_clinvar <- read_fileMDB(
path = system.file("examples/ClinVar", package = "TKCat")
)## ClinVar
## SUCCESS
##
## Check configuration
## - Optional checks:
## - Maximum number of records: 10
Reference: This is a small subset of ClinVar data. For the complete database, visit https://www.ncbi.nlm.nih.gov/clinvar/.
CHEMBL is a manually curated chemical database of bioactive molecules with drug-like properties (Mendez et al. 2019).
A subset of ChEMBL is also provided within the TKCat package:
# Load ChEMBL data from TKCat
file_chembl <- read_fileMDB(
path = system.file("examples/CHEMBL", package = "TKCat")
)## CHEMBL
## SUCCESS
##
## Check configuration
## - Optional checks:
## - Maximum number of records: 10
Reference: This is a small subset of ChEMBL data. For the complete database, visit https://www.ebi.ac.uk/chembl/.
We now have three MDBs ready to be pushed to ClickHouse: -
memo_hpo: HPO database with phenotype and disease
information - file_clinvar: ClinVar database with variant
and clinical significance information - file_chembl: ChEMBL
database with compound and drug information
All three are subsets provided for demonstration purposes. The full databases should be downloaded and prepared for production use.
Once ClickHouse is set up and running, we can push our MDBs to create a centralized catalog.
First, establish a connection to your chTKCat instance:
# Connect to chTKCat (adjust parameters as needed)
k <- chTKCat(
host = "localhost",
port = 9113L, # Using the custom HTTP port
user = "admin", # The admin user created by the docker-init script
drv = ClickHouseHTTP::ClickHouseHTTP()
)Note: For the examples below to work, the user must have write permissions on the ClickHouse database. For more details about chTKCat operations, see the chTKCat operations section in the main TKCat vignette.
Each MDB needs to have its own database in ClickHouse. Use the
create_chMDB() function to prepare the database
structure:
# Create database for HPO
create_chMDB(k, "HPO", public = TRUE)
# Create database for ClinVar
create_chMDB(k, "ClinVar", public = TRUE)
# Create database for ChEMBL
create_chMDB(k, "CHEMBL", public = TRUE)The public=TRUE parameter makes the MDB accessible to
all users with read access to the ClickHouse instance. Set it to
FALSE for private MDBs.
Now we can push each MDB to ClickHouse using the
as_chMDB() function:
# Push HPO MDB
ch_hpo <- as_chMDB(memo_hpo, k)
# Push ClinVar MDB
ch_clinvar <- as_chMDB(file_clinvar, k)
# Push ChEMBL MDB
ch_chembl <- as_chMDB(file_chembl, k)The as_chMDB() function: - Creates the necessary tables
in the ClickHouse database - Loads the data from the fileMDB into
ClickHouse - Returns a chMDB object that can be used to query the
data
Note: The overwrite parameter (default:
FALSE) controls whether existing tables should be replaced.
Set it to TRUE to overwrite existing data.
Once the MDBs are in ClickHouse, we can query them efficiently.
For querying, we can connect with a user that has read-only access:
TKCat provides several functions to explore the available MDBs:
# List all MDBs
list_MDBs(k_readonly)
# Search for tables related to "disease"
search_MDB_tables(k_readonly, "disease")
# Search for fields related to "gene"
search_MDB_fields(k_readonly, "gene")
# Get collection members across all MDBs
collection_members(k_readonly)A Shiny app is also available to explore available resources:
Data model can be explored as following:
Get phenotype information:
Find variants in specific genes:
clinvar <- get_MDB(k_readonly, "ClinVar")
# Get the PIK3R2 gene
get_query(
clinvar,
query = "SELECT * FROM ClinVar_entrezNames WHERE symbol = 'PIK3R2'"
)
# Get pathogenic variants
get_query(
clinvar,
query = paste(
"SELECT * FROM ClinVar_ReferenceClinVarAssertion ",
"WHERE lower(clinicalSignificance) LIKE '%pathogen%' ",
"LIMIT 10"
)
)Search for drug targets:
You can also query across multiple MDBs in a single query by using
the `MDB`.`table` syntax:
The MCP (Model Context Protocol) server enables AI assistants to interact with your chTKCat instance. This section describes how to set it up in different configurations.
The local server runs on the user’s machine and connects to a chTKCat instance (local or remote).
Rscript command available in PATHThe server uses environment variables for configuration:
| Variable | Description | Default | For this guide |
|---|---|---|---|
TKCAT_HOST |
chTKCat host | localhost |
localhost |
TKCAT_PORT |
chTKCat HTTP port | 9111 |
9113 |
TKCAT_USER |
ClickHouse user | default |
mcp_user |
TKCAT_PASSWORD |
User password | "" |
Your password |
TKCAT_HTTPS |
Use HTTPS | FALSE |
FALSE |
For security, create a dedicated user with read-only access:
# Connect as admin
k_admin <- chTKCat(host = "localhost", port = 9113, user = "admin")
# Create a dedicated MCP user
create_chTKCat_user(
k_admin,
login = "mcp_user",
password = "XXXX",
contact = NA,
admin = FALSE
)
# All users have read access to public MDBs
# Give access to public MDBs (or specific private MDBs)
# Access to private MDBs can be given as follows
add_chMDB_user(k_admin, mdb = "HPO", login = "mcp_user", admin = FALSE)# Basic start (using the custom port 9113 for our ClickHouse instance)
TKCAT_HOST=localhost TKCAT_PORT=9113 TKCAT_USER=mcp_user TKCAT_PASSWORD=XXXX \
Rscript -e "TKCat::chTKCat_mcp_server()"
# With custom parameters
Rscript -e "TKCat::chTKCat_mcp_server(maxRows = 500, maxExecutionTime = 60)"The server parameters include: - maxRows: Maximum number
of rows returned (default: 1000) - maxChars: Maximum
characters returned (default: 60000) - maxExecutionTime:
Maximum query execution time in seconds (default: 300)
The remote server runs as a service, typically on the same machine as the chTKCat instance.
The recommended architecture uses: - Multiple R server instances running on local ports - nginx as a reverse proxy providing HTTPS and load balancing - Basic authentication via ClickHouse credentials
Start one or more instances:
# Instance 1 (using the custom port 9113 for our ClickHouse instance)
TKCAT_HOST=localhost TKCAT_PORT=9113 TKCAT_MCP_PORT=8801 \
Rscript -e "TKCat::chTKCat_mcp_http_server()"
# Instance 2
TKCAT_HOST=localhost TKCAT_PORT=9113 TKCAT_MCP_PORT=8802 \
Rscript -e "TKCat::chTKCat_mcp_http_server()"Server parameters: - mcpHost: Listening address
(default: 127.0.0.1) - mcpPort: Listening port
(default: 8800) - mcpPath: MCP endpoint path
(default: /mcp) - host, port,
https: chTKCat connection parameters -
anonymousUser: User for unauthenticated access (default:
NA) - anonymousPassword: Password for
anonymous user - allowedOrigins: Allowed Origin headers -
cacheTime: Connection cache time in seconds (default:
3600)
Test the remote server with curl:
Create a systemd service for automatic management:
[Unit]
Description=chTKCat MCP server (port %i)
After=network-online.target
Wants=network-online.target
[Service]
User=tkcat-mcp
Group=tkcat-mcp
Environment=TKCAT_HOST=localhost
Environment=TKCAT_PORT=9113
Environment=TKCAT_MCP_HOST=127.0.0.1
Environment=TKCAT_MCP_PORT=%i
EnvironmentFile=-/etc/tkcat-mcp.env
ExecStart=/usr/local/bin/Rscript -e "TKCat::chTKCat_mcp_http_server()"
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=read-only
[Install]
WantedBy=multi-user.targetAdditional environment variables can be put in the
/etc/tkcat-mcp.env file, such as
TKCAT_MCP_ANONYMOUS_USER and
TKCAT_MCP_ANONYMOUS_PASSWORD.
Create the system user and enable multiple instances:
Configure nginx to proxy requests to the R server instances:
limit_req_zone $binary_remote_addr zone=tkcat_mcp:10m rate=5r/s;
upstream tkcat_mcp_inst {
least_conn;
server 127.0.0.1:8801;
server 127.0.0.1:8802;
server 127.0.0.1:8803;
server 127.0.0.1:8804;
keepalive 8;
}
server {
# ... other configuration ...
location = /tkcat_mcp {
limit_req zone=tkcat_mcp burst=20 nodelay;
client_max_body_size 1m;
proxy_pass http://tkcat_mcp_inst/mcp;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 330s;
proxy_send_timeout 330s;
proxy_buffering off;
}
}
Reload nginx:
When configuring the MCP server:
Use dedicated users: Create dedicated users with read-only access to specific MDBs only.
Secure credentials: Never hardcode credentials in configuration files. Use environment variables or secure credential stores.
Use HTTPS: Always use HTTPS for remote connections to prevent credential interception.
Limit access: Restrict access to trusted networks when possible.
Data sensitivity: Only expose MDBs whose content can be shared with the AI service according to your organization’s policies.
Monitor usage: Check server logs for suspicious activity.
This section shows how to configure different MCP clients to connect to your chTKCat instance.
claude mcp add tkcat --scope user \
-e TKCAT_HOST=localhost -e TKCAT_PORT=9113 \
-e TKCAT_USER=mcp_user -e TKCAT_PASSWORD=XXXX \
-- Rscript -e "TKCat::chTKCat_mcp_server()"Check the connection:
Or use the /mcp command within Claude Code.
Create a .mcp.json file at your project root:
Add to claude_desktop_config.json (Settings >
Developer > Edit Config):
{
"mcpServers": {
"tkcat": {
"command": "Rscript",
"args": ["-e", "TKCat::chTKCat_mcp_server()"],
"env": {
"TKCAT_HOST": "localhost",
"TKCAT_PORT": "9113",
"TKCAT_USER": "mcp_user",
"TKCAT_PASSWORD": "XXXX"
}
}
}
}Restart Claude Desktop after making changes.
Once configured, AI assistants can query your chTKCat instance using natural language.
The MCP server provides the following tools:
| Tool | Description |
|---|---|
list_mdbs |
List all MDBs with metadata |
search_tkcat |
Search MDBs, tables, and fields by keyword |
describe_mdb |
Get MDB information, tables, relationships |
describe_tables |
Get detailed data model of tables |
preview_table |
Get first records of a table |
query_mdb |
Run a read-only SQL query on an MDB |
get_matrix_values |
Get values from matrix tables |
list_collections |
List collections and their members |
This vignette has demonstrated a complete end-to-end workflow:
For more details on any of these topics, refer to: - Introduction to TKCat - Main vignette - Querying a chTKCat instance with an AI assistant (MCP server) - MCP server details
Important reminder: The MDBs used in this guide are subsets provided for demonstration. For production use, ensure you download and prepare current versions of the databases, and properly document all data sources and versions.