Skip to content

h4ks-com/kinesthesia

Repository files navigation

Kinesthesia

ci docker image size license

Kinesthesia playing a song

A piano roll for the web, inspired by Synthesia. Search a song and its MIDI falls onto an 88 key piano to watch, learn, or play someone else.

Live at kinesthesia.h4ks.com.

Run it

cp .env.example .env
bun install
bun run dev

With Docker, built here:

docker compose up

or from the published image, built for amd64 and arm64:

docker run -p 3000:3000 -v kinesthesia:/app/data ghcr.io/h4ks-com/kinesthesia:latest

.env.example documents every setting.

API

The API documents itself at /api/docs, with the OpenAPI spec at /api/openapi.json.

MCP

The same tools run over MCP at /api/mcp (streamable HTTP), so an agent can search for songs, read a file's length and tracks, build player links, and edit MIDI projects.

The endpoint takes a bearer token. The server stores only the token's SHA-256 hash, so generate the pair and keep the key:

key=$(openssl rand -hex 32)
echo "key: $key"
printf %s "$key" | shasum -a 256 | cut -d' ' -f1

Put the hash in MCP_TOKEN_HASH and give clients the key. Add it to a client:

claude mcp add --transport http kinesthesia https://kinesthesia.h4ks.com/api/mcp \
  --header "Authorization: Bearer $key"

or with JSON config:

{
  "mcpServers": {
    "kinesthesia": {
      "type": "http",
      "url": "https://kinesthesia.h4ks.com/api/mcp",
      "headers": { "Authorization": "Bearer <key>" }
    }
  }
}

Swap in http://localhost:3000/api/mcp when running locally. Leaving MCP_TOKEN_HASH unset keeps the endpoint open in development and refuses every request in production.

MIDI files come from several sources, listed at /sources. A ?url= player link also plays a direct .mid from the app's own origin or an origin set in MIDI_TRUSTED_ORIGINS; player_link accepts such a url too.

About

A piano roll for the web. Search MIDI songs and watch them play, inspired by Synthesia.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages