skill
hoja
Type-safe Linear CLI built on Pydantic v2 + httpx + Typer. Designed for humans, agents, and CI/CD pipelines.
Set up
Skills are installed by placing their folder where your agent loads skills.
The download comes from github.com/hoja-work/hoja itself, not from our server, so what you get is exactly what its author published.
Install instructions come from the README
README
synced Oct 22, 2026Hoja
A self-hosted workspace for issues, projects, cycles, and team work. Hoja includes a browser UI and a Python CLI. It can run against its own SQLite or PostgreSQL-backed service; the GraphQL API also implements a Linear-compatible surface for clients that use it.
The Python distribution and commands are named Cliniar: cliniar, cliniar-serve, and the optional cliniar-mcp.
What you can do
- Sign in to a workspace, switch between memberships, and create workspaces, teams, and members.
- Create, search, filter, assign, and update issues; browse team boards and cycles; open issue details and comment.
- Organize projects, review project issues and updates, and manage initiatives.
- Use Inbox for future issue notifications, with unread/read and archive controls. Existing historical events are not backfilled.
- Save issue and project views in the browser. These views are local to that browser, not shared workspace records.
- Use the CLI for shell workflows and automation. Responses are validated models;
--output jsonand--output idsare suitable for scripts.
Hoja does not require Linear Cloud. The API uses Linear-compatible GraphQL names and accepts LINEAR_TOKEN and LINEAR_API_URL so compatible clients can target a Hoja server. Compatibility does not mean every Linear feature is implemented. Unsupported screens or controls are presented as unavailable rather than simulated as working.
Run the workspace locally with Docker
This is the recommended way to try Hoja locally. Docker Compose builds the web app and starts it with PostgreSQL. You will need Docker Desktop (or Docker Engine with the Compose plugin) installed and running. The first build needs internet access to download the base images and frontend/Python dependencies.
-
In the repository root, create a
.envfile with a password for the local PostgreSQL database:POSTGRES_PASSWORD=replace-with-a-long-random-passwordKeep this file private; do not commit it. Compose currently has a development fallback password, so setting your own avoids relying on that default. If port
8787is already in use, addCLINIAR_PORT=8788to this same file and use port 8788 in the browser URL below. -
Build and start the services:
docker compose up --build -dThe first build can take a few minutes. Compose waits for PostgreSQL to become healthy; the app applies database migrations when it starts.
-
Open http://localhost:8787 (or the port you chose). On a fresh database, the browser wizard guides you through choosing a language preference, creating your admin profile/password, and naming your workspace and first team. Existing databases go to the sign-in screen.
To confirm the server responds before opening the UI, run
curl -i http://localhost:8787/health; a healthy server returns HTTP 200 with a JSON status body. The/readyendpoint reports whether the database schema is ready; if it is not, inspect the app logs below. -
When prompted, optionally add teammates. Hoja creates each member and provides a copyable invite link. Share it with that person; they can open it, enter the invited email, and set their password. Links expire after 72 hours and work once. Hoja does not email invitations. You can skip this and invite people later from Members. The finish step can show the admin API key for CLI setup. Browser sign-in uses an HttpOnly cookie.
Stop, restart, and reset
Stop the containers while keeping your workspace data:
docker compose down
Start them again later with docker compose up -d. PostgreSQL data is stored
in the named cliniar-postgres volume and survives ordinary container stops
and rebuilds. To permanently delete the local database and all demo data, use
docker compose down -v; this is destructive and the data cannot be recovered
without a backup.
Troubleshooting
- Docker is unavailable: start Docker Desktop / Docker Engine, then retry.
docker composeis not a command: install or enable the Docker Compose v2 plugin (included with current Docker Desktop), then verify withdocker compose version. This guide uses thedocker composesubcommand, not the legacy standalonedocker-composecommand.- Port is already allocated: set
CLINIAR_PORT=8788in.envand browse tohttp://localhost:8788. - The app cannot connect to PostgreSQL: check
docker compose psanddocker compose logs db app; Compose starts the app only after the database health check passes. Correct.envchanges may require recreating services withdocker compose up -d. - The app starts but is not ready: check
docker compose logs app dbandcurl -i http://localhost:8787/ready. The app runs migrations at startup; wait for the app container to finish starting, then retry. Do not remove the PostgreSQL volume as a first troubleshooting step. - The wizard reports that the instance is already set up: use the existing
sign-in screen. Bootstrap is only available on a fresh database. To restart a
disposable demo from scratch, use the destructive
docker compose down -vcommand above.
This Compose setup is intended for a local demo. The fallback database password
in docker-compose.yml is for development only; set a private password in
.env before using the configuration beyond a disposable local instance. Use
letters and numbers in that password because Compose interpolates it into the
PostgreSQL connection URL.
See deployment for database setup, migrations, readiness checks, and multi-organization token provisioning.
For an isolated SQLite instance instead:
python -m pip install 'cliniar[server]'
cliniar-serve seed --tenant local --org "Local Workspace" \
--org-key local --team-key ENG --email user@example.test
cliniar-serve serve --tenant local --host 127.0.0.1 --port 8787
Use the CLI
Install the CLI from PyPI or from a checkout:
python -m pip install cliniar
# or, from this repository:
uv sync --extra dev --extra server
Configure an account in ~/.config/cliniar/config.toml:
[accounts.local]
base_url = "http://127.0.0.1:8787/graphql"
token_env = "LINEAR_TOKEN"
[defaults]
default_account = "local"
Export the token as LINEAR_TOKEN (or choose a different token_env for the
account), then try:
cliniar me
cliniar team list
cliniar issue list --assignee me
cliniar issue create --team ENG --title "Review onboarding flow"
cliniar -o json issue list --state Todo
The CLI also supports projects, cycles, comments, labels, raw GraphQL queries, and dry-run previews for supported mutations. Run cliniar --help or cliniar <command> --help for the current command and option list. For compatibility with existing Linear accounts, LINEAR_TOKEN and LINEAR_API_URL remain supported.
Agent integrations
The optional MCP server provides one guide tool, seven read-only resources, and six workflow prompts. It does not expose mutation tools; make changes through the CLI.
python -m pip install 'cliniar[mcp]'
Register cliniar-mcp as a stdio MCP server in your client, passing the needed token through that client's environment configuration. The server reads the same account configuration as the CLI. See the MCP section below for a complete example.
The repository also includes an installable agent skill:
bash skills/install.sh --claude-only
It installs the skills/cliniar instructions into the selected agent skill directory; --copy copies rather than symlinks.
MCP server setup
Install the optional MCP dependency alongside the CLI:
python -m pip install 'cliniar[mcp]'
For Claude Desktop, add a server entry to its MCP configuration. Use an absolute
executable path if the GUI does not inherit your shell PATH:
{
"mcpServers": {
"cliniar": {
"command": "/absolute/path/to/cliniar-mcp",
"env": {
"LINEAR_TOKEN": "<workspace-token>"
}
}
}
}
Replace the command path with the result of which cliniar-mcp. If the selected
account sets a custom token_env, pass that variable instead. The MCP server
provides one guide tool, seven read-only resources, and six workflow prompts;
it does not provide mutation tools.
Development
Python 3.10 or newer is required. Install development and backend dependencies, then run the tests:
uv sync --extra dev --extra server
uv run pytest
Build the browser app with npm ci && npm run build in frontend/. The local backend integration script is bash scripts/e2e-local-backend.sh; it uses a disposable local database. The live API CLI matrix in scripts/e2e-test.sh requires LINEAR_TOKEN, CLINIAR_TEST_TEAM, and CLINIAR_TEST_ISSUE.
Product architecture is described in Design; deployment instructions are in Deployment. The changelog records release-level behavior changes.
First run in the browser
On a fresh database, open Hoja in your browser to start the setup wizard. Choose a language preference (English is currently available), create your admin profile and password, then name your workspace and first team. You’ll be signed in when setup completes. Existing workspaces continue to show the sign-in screen.
The wizard can create teammates and show each generated API key once for you to share. It does not send invitation email. Save or share each key securely; it is not shown again. You can skip invitations and add people later from Members. Your admin API key is available once in the finish step for CLI configuration.