---
title: Contributing
description: Contribute to ktx through code, docs, connectors, and examples.
---

**ktx** is an open-source context layer for data agents. The project welcomes
focused contributions that improve setup, integrations, CLI behavior,
documentation, connector coverage, and examples.

## Where to start

| Goal | Start here |
|------|------------|
| Prepare a local development checkout | [Development setup](#development-setup) |
| Understand the workspace layout | [Repository structure](#repository-structure) |
| Run verification before a pull request | [Running tests](#running-tests) |
| Add a database connector | [Adding a connector](#adding-a-connector) |
| Update docs for a user-visible CLI or setup change | [PR guidelines](#pr-guidelines) |

## Contribution areas

| Area | Good first context |
|------|--------------------|
| CLI and setup | `packages/cli`, especially setup steps, command definitions, status checks, and smoke tests |
| Context engine | `packages/cli/src/context`, including project config, ingest orchestration, and semantic search |
| Connectors | `packages/cli/src/connectors/<driver>`, plus connector-specific tests and integration docs |
| Python semantic layer | `python/ktx-sl` for planning and SQL compilation |
| **ktx** daemon | `python/ktx-daemon` for the portable runtime API |
| Documentation | `docs-site/content/docs` for public docs and `docs-site/tests` for docs behavior |

## Development setup

This page is for contributors working on the **ktx** repository. To install **ktx** for
an analytics project, use the published
[`@kaelio/ktx`](https://www.npmjs.com/package/@kaelio/ktx) package in the
[Quickstart](/docs/getting-started/quickstart).

### Prerequisites

- **Node.js 22+** and **pnpm** - for the TypeScript workspace
- **Python 3.11+** and **uv** - for the Python semantic layer and daemon
- **Git** - for version control

### Clone and install

```bash
git clone https://github.com/kaelio/ktx.git
cd ktx
pnpm install
uv sync --all-groups
```

`pnpm install` sets up the TypeScript workspace.
`uv sync --all-groups` installs Python dependencies for the semantic layer and
daemon, including dev and test groups.

### Build

```bash
pnpm run build
```

This builds the TypeScript package. You can also build the package directly:

```bash
pnpm --filter @kaelio/ktx run build
```

### Link the CLI for local testing

```bash
pnpm run setup:dev
pnpm run link:dev
```

This makes the `ktx-dev` command available globally, pointing at your local
build. Use this development binary when you need to test unpublished repository
changes.

## Repository structure

**ktx** is a pnpm + uv workspace. TypeScript source lives in `packages/cli`,
and Python projects live in `python/`.

```text
packages/
  cli/                  # CLI package and published npm package source
    src/context/        # Core context engine (scan, ingest, MCP, semantic layer)
    src/llm/            # LLM client abstraction
    src/connectors/     # Database connectors

python/
  ktx-sl/               # Semantic layer - grain-aware query planning and SQL compilation
  ktx-daemon/           # Daemon - portable API server around the semantic layer

examples/               # Example projects and fixtures
scripts/                # Workspace scripts (benchmarks, verification, release)
docs-site/              # Documentation site (Fumadocs)
```

The TypeScript package is ESM (`"type": "module"`) and uses `NodeNext` module
resolution. The Python projects use `pyproject.toml` for dependency management.

## Running tests

### TypeScript

```bash
# Run all tests
pnpm run test

# Run tests for the TypeScript package
pnpm --filter @kaelio/ktx run test

# Type-check all packages
pnpm run type-check

# Type-check the TypeScript package
pnpm --filter @kaelio/ktx run type-check

# CLI smoke test
pnpm --filter @kaelio/ktx run smoke
```

### Python

```bash
# Run all Python tests
uv run pytest -q

# Semantic layer tests
uv run pytest python/ktx-sl/tests -q

# Daemon tests
uv run pytest python/ktx-daemon/tests -q
```

### Pre-commit checks

After modifying Python files, run pre-commit on the changed files:

```bash
uv run pre-commit run --files python/ktx-sl/src/changed_file.py
```

### Full verification

For cross-cutting changes that affect package exports or shared contracts:

```bash
pnpm run build
pnpm run type-check
pnpm run test
uv run pytest -q
```

## Adding a connector

Database connectors live in `packages/cli/src/connectors/<driver>/`. Each
connector implements the `KtxScanConnector` interface from the internal context
modules.

### Step 1: Scaffold the connector

Create a new directory at `packages/cli/src/connectors/<driver>/` with:

```text
packages/cli/src/connectors/<driver>/
  index.ts          # Internal connector exports
  connector.ts      # KtxScanConnector implementation
  dialect.ts        # SQL dialect handling
```

Add any connector-specific npm dependency to `packages/cli/package.json`.

### Step 2: Implement the connector

Your connector class must implement `KtxScanConnector`, which requires:

- **`id`** - a string identifier, typically `"<driver>:<connectionId>"`
- **`driver`** - the `KtxConnectionDriver` value for your database
- **`capabilities`** - a `KtxConnectorCapabilities` object declaring what your connector supports: `tableSampling`, `columnSampling`, `columnStats`, `readOnlySql`, `nestedAnalysis`, `eventStreamDiscovery`, `formalForeignKeys`, `estimatedRowCounts`
- **`introspect()`** - discovers tables, columns, types, and constraints, returning a `KtxSchemaSnapshot`

Optional methods for richer scanning:

- **`sampleColumn()`** - sample values from a specific column
- **`sampleTable()`** - sample rows from a table
- **`columnStats()`** - compute column statistics
- **`executeReadOnly()`** - execute arbitrary read-only SQL

### Step 3: Add a dialect

The dialect class handles database-specific concerns: identifier quoting, type
mapping from native types to normalized types, and query generation for sampling
and statistics.

### Step 4: Wire it up

Register the new connector in `packages/cli/src/local-scan-connectors.ts` and
`packages/cli/src/local-adapters.ts` so the CLI and scan engine can instantiate
it. Keep runtime loading dynamic when the connector is optional.

### Step 5: Test

```bash
pnpm --filter @kaelio/ktx run build
pnpm --filter @kaelio/ktx run type-check
pnpm --filter @kaelio/ktx run test
```

Use `packages/cli/src/connectors/sqlite/` as a minimal reference and
`packages/cli/src/connectors/postgres/` as a full-featured one.

## Code conventions

- **TypeScript**: strict types, no `any`, no `as unknown as`. Use `zod` schemas for runtime validation at CLI and config boundaries. Follow the `camelCaseSchema` / `PascalCaseType` naming convention for Zod schemas and inferred types.
- **Python**: type hints on all new code, `pathlib` over `os.path`, explicit exception types over broad `except Exception`, `logger.exception()` for caught exceptions. Use `sqlglot` for SQL parsing - never regex.
- **Dependencies**: `pnpm` for Node packages, `uv` for Python.
- **Dead code**: remove it. Don't leave commented-out code, unused wrappers, or empty directories.

## PR guidelines

Before submitting a pull request:

1. **Run the relevant checks** - at minimum, `pnpm run type-check` and `pnpm run test` for TypeScript changes, `uv run pytest -q` and `uv run pre-commit run --files [FILES]` for Python changes.
2. **Build if you changed exports** - run `pnpm run build` to verify package exports and `dist/` expectations still align.
3. **Keep changes focused** - one logical change per PR. Don't bundle unrelated refactors.
4. **Follow existing patterns** - match the style and conventions of surrounding code. The codebase favors explicit over clever.
5. **Update docs for user-visible changes** - update `docs-site/content/docs/` when setup, CLI, configuration, or integration behavior changes.
6. **Don't commit artifacts** - `node_modules/`, `.venv/`, `dist/`, coverage output, and local databases should not be committed.

For larger features or architectural changes, open an issue first to discuss the
approach.

## Agent usage notes

Use this page when an agent is modifying the **ktx** repository itself rather than
using **ktx** in an analytics project.

| Agent task | Command or section |
|------------|--------------------|
| Prepare the workspace | `pnpm install`, `pnpm run setup:dev`, `uv sync --all-groups` |
| Verify TypeScript changes | `pnpm run type-check`, `pnpm run test`, or package-filtered equivalents |
| Verify Python changes | `uv run pytest -q` and `uv run pre-commit run --files <files>` |
| Add a connector | [Adding a connector](#adding-a-connector) |
| Check style expectations | [Code conventions](#code-conventions) |

Common recovery path: if a check fails because generated files or local
runtimes are missing, run the setup commands first. If a check fails because of
a real type, lint, or test error, fix the source file and rerun the smallest
failing check before broadening verification.
