Thanks to visit codestin.com
Credit goes to github.com

Skip to content

kosolabs/koso

Development Environment (MacOS)

First Time Setup

  1. Install Homebrew.

    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  2. Install and start PostgreSQL.

    POSTGRESQL_VERSION=18
    brew install postgresql@$POSTGRESQL_VERSION
    brew services start postgresql@$POSTGRESQL_VERSION
  3. Install Rust.

    brew install rustup
    rustup-init
  4. The backend uses SQLx to interact with PostgreSQL. Install the SQLx in order to run migrations and perform other administrative operations.

    cargo install sqlx-cli --no-default-features --features rustls,postgres
  5. Configure SQLx with the DATABASE_URL.

    export DATABASE_URL=postgresql://localhost/koso

    Also, add the environment variable to the appropriate profile file (~/.profile, ~/.bash_profile, ~/.bashrc, ~/.zshrc, ~/.zshenv) so you don't have to run it every time.

  6. Create the database and run the DB migrations.

    In the backend folder, run:

    sqlx database create
    sqlx migrate run
  7. Install Node.js.

    brew install node pnpm
  8. Install the Stripe CLI.

    brew install stripe/stripe-cli/stripe
    stripe login
  9. Configure secrets.

    In the koso root folder, run:

    mkdir -p .secrets/koso
    openssl rand -hex 256 > .secrets/koso/hmac

Once A Day / After Every Pull

  1. Run the most recent DB migrations.

    In the backend folder, run:

    sqlx migrate run
  2. Install the latest frontend dependencies.

    In the frontend folder, run:

    pnpm install

Start Backend and Frontend

  1. Start the backend server.

    In the backend folder, run:

    cargo run
  2. Start the frontend server.

    In the frontend folder, run:

    pnpm dev
  3. Navigate to http://localhost:5173/

VS Code

The Koso Workspace is configured for development in VS Code.

The following plugins are recommended:

Backend Interactions

Once a server has been started, you can interact with it at http://localhost:3000. There are example requests in koso.http which you can run with httpBook.

Running a Built Frontend with the Backend

This setup is similar to how the app will run in production. A single server serves the API, WebSocket, and static frontend files.

  1. In the frontend folder, run:

    pnpm build
  2. In the backend folder, run the server:

    cargo run

This will create a frontend/build folder. The backend/static folder is symlinked to that folder and will serve the compiled frontend directly from the backend.

Running playwright tests

Playwright tests, i.e. integration tests, flex the entire system end-to-end via the frontend testing framework Playwright. The tests run as part of CI, but you may also run them locally.

Option A: Iterate quickly by running against your development server

Make changes and run the tests quickly without rebuilding the world. Start a frontend and backend server in the usual manner, see above, and run the tests in VSCode using the Playwright extension or via the CLI:

pnpm exec playwright test

Option B: Mimic production and run against a built frontend with production

Follow "Running a Built Frontend with the Backend" above to build the frontend and run the backend. Run the tests:

PW_SERVER_PORT=3000 pnpm exec playwright test

Option C: Mimic CI and build things from scratch

This is what our CI workflows do. playwright will build the frontend and run a backend for the duration of the tests:

CI=true pnpm exec playwright test

Development Docker builds

Build and run the docker image defined in Dockerfile.

One-time setup

  1. Download and install Docker: https://www.docker.com/products/docker-desktop/

Build & run

  1. Build the image:

    DOCKER_DEFAULT_PLATFORM=linux/amd64 docker build -t ghcr.io/kosolabs/koso .
  2. Configure the DATABASE_URL.

    export DATABASE_URL=postgresql://localhost/koso

    Also, add the environment variable to the appropriate profile file (~/.profile, ~/.bash_profile, ~/.bashrc, ~/.zshrc, ~/.zshenv) so you don't have to run it every time.

  3. Run database migrations:

    DOCKER_DEFAULT_PLATFORM=linux/amd64 docker run \
       --env DATABASE_URL \
       --network=host \
       --rm -it \
       ghcr.io/kosolabs/koso:latest \
       "./sqlx" migrate run
  4. Run the server:

    DOCKER_DEFAULT_PLATFORM=linux/amd64 docker run \
       --env KOSO_ENV=dev \
       -v $HOME/.secrets:/.secrets \
       --network=host \
       --rm -it \
       ghcr.io/kosolabs/koso:latest

Server setup

Commands for setting up a new server are in setup_server.sh

Environment

We use a Github Environment configured on the Deploy workflow which exposes a KOSO_KEY to access the server.

Postgres

Migrations

Add a migration:

sqlx migrate add some-meaningful-name

Run migrations

sqlx migrate run

Backups

psql_backup.sh exports backups of our Postgresql DB to cloud storage.

The script is ran by a daily cron and logs are available at koso-psql-backups/backups.log.

Backups are stored in a GCP cloud storage bucket named koso-psql-backups. The bucket has soft deletion and object versioning configured, along with lifecycle rules to auto-delete objects after 30 days.

Restore

Identify the backup to restore in the cloud console and update backup_name below with the target object name.

backup_name=TARGET-backup.sql.gz

Download and unzip the backup:

backup_object=gs://$koso-psql-backups/$backup_name
gcloud storage cp --print-created-message $backup_object ./
gzip -dk $backup_name

Restore the backup:

PGPASSWORD=$PSQL_PASSWORD pg_restore \
   --host="$PSQL_HOST" \
   --port="$PSQL_PORT" \
   --db="$PSQL_DB" \
   --username="$PSQL_USER" \
   -f \
   $backup_name

Upgrade

Upgrade Postgres to a new major version. In the example below, from 17 to 18.

  1. Update the postgres image version from postgres:17 to postgres:18 in ci.yml and merge.

  2. Install the new version of posgres:

    sudo apt update
    sudo apt install postgresql-18
    pg_lsclusters
  3. Backup the cluster just in case:

    pg_dumpall > ~/postgres-dump-$(date -u "+%Y-%m-%dT%H-%M-%S-%3NZ")
  4. Upgrade the cluster:

    sudo service postgresql stop
    sudo pg_renamecluster 18 main main_pristine
    sudo pg_upgradecluster 17 main
    sudo service postgresql start
    
    pg_lsclusters
    
  5. Verify the new cluster is working by visiting our app and verifying things work. Look at backend logs as well for anything suspicious.

    pg_lsclusters
  6. Drop the old and transition version:

    sudo pg_dropcluster 17 main --stop
    sudo pg_dropcluster 18 main_pristine --stop

Integrations

Cloudflare Reverse Proxy

One-time Setup

Local development of integrations requires that external services be able to talk to your locally running server. This is accomplished via a reverse proxy.

  1. Install cloudflared.

    brew install cloudflared
  2. Login to Cloudflare.

    cloudflared login
  3. Authorize Cloudflare Tunnel to the koso.app domain.

  4. Click Authorize.

  5. Create a tunnel.

    cloudflared tunnel create koso
  6. Copy the tunnel ID to the clipboard.

  7. Configure the DNS for the tunnel. Replace namespace with an appropriate name, e.g. shad-dev.

    cloudflared tunnel route dns koso ${namespace}.koso.app
  8. Write the following file to ~/.cloudflared/config.yaml. Replace ${tunnel-id} with the value from the output of the tunnel create command.

    url: http://localhost:3000
    tunnel: ${tunnel-id}
    credentials-file: ~/.cloudflared/${tunnel-id}.json

Testing locally

  1. Start the reverse proxy server.

    cloudflared tunnel run koso

Github Webhooks

References:

One-time setup

Install Smee

npm install --global smee-client

Testing locally

After starting your local server:

  1. Configure your development webhook secret in: .secrets/github/webhook_secret
  2. Start a new Smee channel: https://smee.io/
  3. Start smee locally with the new channel smee -u $CHANNEL_URL --port 3000 --path /plugins/github/app/webhook
  4. Trigger or redeliver some events

Stripe

One-time setup

  1. Install the CLI:

    brew install stripe/stripe-cli/stripe
    stripe login
  2. Configure your sandbox secret API key in .secrets/stripe/secret_key

  3. Configure your sandbox webhook secret

    stripe listen --api-key $(cat .secrets/stripe/secret_key) --print-secret > .secrets/stripe/webhook_secret

Testing locally

We use the Koso Labs Sandbox Stripe sandbox for testing. Login to Stripe and switch to the Sandbox to find API keys and webhook details. Feel free to create a new sandbox if needed.

Start a local listener with stripe listen:

./backend/scripts/stripe_listen.sh

With this in place and your local servers running, you can:

Discord

One-time setup

  1. Variables used in this section:

    • ${title}, e.g. ShadDev
    • ${namespace}, e.g. shad-dev
  2. Navigate to https://discord.com/developers/applications.

  3. Click New Application.

  4. Set the name of the app to ${title}Koso, e.g. ShadDevKoso.

  5. Copy the Application ID and save it for later (${application-id}).

  6. Copy the public key into .secrets/discord/public_key.

  7. Set the Interactions Endpoint URL to: https://${namespace}.koso.app/api/notifiers/discord/interaction

  8. Click Save Changes.

  9. Click Bot.

  10. Click Reset Token.

  11. Click Yes, do it!.

  12. Enter your password and click Submit if necessary.

  13. Copy the Token into .secrets/discord/token.

  14. Install the /token command into your discord app:

    curl -X POST "https://discord.com/api/v10/applications/${application-id}/commands" \
      -H "Authorization: Bot $(cat .secrets/discord/token)" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "token",
        "description": "Start the authorization flow for Koso"
      }'
  15. Replace ${application-id} in the link below with the value from above, then follow the link to install the app.

    https://discord.com/oauth2/authorize?client_id=${application-id}&permissions=2048&integration_type=0&scope=bot

  16. Start a conversation with the bot (@${title}Koso).

  17. Click the Commands button.

  18. Click the Send button corresponding to the /token command.

  19. Follow the link to authorize your local Koso to send notifications via Discord.

Slack

One-time setup

  1. Variables used in this section:

    • ${title}, e.g. ShadDev
    • ${namespace}, e.g. shad-dev
  2. Navigate to https://api.slack.com/apps.

  3. Click Create New App.

  4. Click From a manifest.

  5. Set your workspace to: Koso Labs.

  6. Click Next.

  7. Copy / paste the following manifest replacing the variables as necessary:

    {
      "display_information": {
        "name": "${title}Koso",
        "description": "Receive notification updates from ${title}Koso"
      },
      "features": {
        "bot_user": {
          "display_name": "${title}Kosobot",
          "always_online": true
        },
        "slash_commands": [
          {
            "command": "/${namespace}-token",
            "url": "https://${namespace}.koso.app/api/notifiers/slack/command",
            "description": "Start the authorization flow",
            "should_escape": false
          }
        ]
      },
      "oauth_config": {
        "scopes": {
          "bot": ["chat:write", "im:history", "im:read", "im:write", "commands"]
        }
      },
      "settings": {
        "interactivity": {
          "is_enabled": true,
          "request_url": "https://${namespace}.koso.app/api/notifiers/slack/interact"
        },
        "org_deploy_enabled": false,
        "socket_mode_enabled": false,
        "token_rotation_enabled": false
      }
    }
  8. Copy the Signing Secret into .secrets/slack/signing_secret.

  9. Click Install App.

  10. Click Install to Koso Labs.

  11. Click Allow.

  12. Copy the Bot User OAuth Token into .secrets/slack/token.

  13. Click App Home.

  14. In the Show Tabs section, check the box Allow users to send Slash commands and messages from the messages tab.

  15. In Slack, click your app in the Apps section.

  16. Click on About.

  17. Next to the token command, click Start command.

  18. Click the Send button.

  19. Click Authorize Koso to authorize your local Koso to send notifications via Slack.

Testing locally

You can send a test message from the profile page.

Telegram

One-time setup

Create a new bot and configure the secrets.

  1. Variables used in this section:

    • ${title}, e.g. ShadDev
    • ${namespace}, e.g. shad-dev
  2. Send a Telegram message to @BotFather: /newbot.

  3. Name the bot ${title}Kosobot.

  4. Copy the access token into .secrets/telegram/token.

  5. Generate a secret token that will authorize Telegram to call the webhook and save it into .secrets/telegram/secret_token.

    openssl rand -base64 256 | tr -dc 'A-Za-z0-9' | head -c 256 > .secrets/telegram/secret_token
  6. Configure your Telegram bot to use the secret_token with your webhook.

    curl -X POST "https://api.telegram.org/bot$(cat .secrets/telegram/token)/setWebhook" \
      -d "url=https://${namespace}.koso.app/api/notifiers/telegram/webhook" \
      -d "secret_token=$(cat .secrets/telegram/secret_token)"
  7. Send a /token message to your bot: ${title}Kosobot.

  8. Follow the link to authorize your local Koso to send notifications via Telegram.

Testing locally

With setup complete you can interact with tasks and generate notifications. Note though that most self notifications are suppressed. Use login_test_user.sh to login as a test user, interact with tasks and trigger notifications.

MCP

docs

One-time setup

After starting your local server:

VS Code

docs

  1. Open the command palette (cmd+shift+p) and run MCP: Open User Configuration
  2. Insert the Koso server
    {
      "servers": {
        "koso-mcp": {
          "url": "http://localhost:3000/api/mcp/sse",
          "type": "http"
        }
      },
      "inputs": []
    }
  3. Open a Copilot chat, click on Configure tools and enable Koso

Claude Code

Claud docs

  1. Install Claude Code: npm install -g @anthropic-ai/claude-code
  2. Run the setup flow: claude
  3. Add Koso
    • Local: claude mcp add --transport http koso-local-mcp http://localhost:3000/api/mcp/sse
    • Remote: claude mcp add --transport http koso-mcp https://koso.app/api/mcp/sse
  4. Run claude and then /mcp to authenticate

MCP Inspector

Use the MCP Inspector to test the server without a model.

Setup:

  1. Run the inspector: npx @modelcontextprotocol/inspector
  2. Enter the server URL ()http://localhost:3000/api/mcp/sse) and click Connect

About

Plan Less. Ship More.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 5