Akin 0.6.0

dotnet tool install --global Akin --version 0.6.0
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local Akin --version 0.6.0
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=Akin&version=0.6.0
                    
nuke :add-package Akin --version 0.6.0
                    

Akin

Tests NuGet Version License: MIT

Semantic code search for AI agents and CLI users. Finds code by meaning rather than exact text match. Works as both a CLI tool and an MCP (Model Context Protocol) server. Runs entirely locally — no API keys, no external services.

Built on the VectorSharp libraries, using the Nomic Embed Text v1.5 model via ONNX for embeddings and VectorSharp.Chunking for structure-aware chunking of Markdown, C#, JavaScript/TypeScript/JSX/TSX, HTML, CSS, Python, and plain text.

Installation

Install script (macOS / Linux)

curl -fsSL https://raw.githubusercontent.com/AdamTovatt/akin/master/install-akin.sh | bash

This detects your platform, downloads the latest release, verifies its SHA256 checksum, and installs the akin binary to /usr/local/bin. Requires only curl, unzip, and sha256sum/shasum — all standard on macOS and Linux. Run the same command again to update.

Updaemon (Linux)

If you use updaemon for managing tools:

updaemon new akin --from github --remote AdamTovatt/akin/akin-linux-arm64.zip --type cli
updaemon set-exec-name akin Akin.Cli
updaemon init akin

Replace akin-linux-arm64.zip with akin-linux-x64.zip on x86_64 systems. Future updates via updaemon update.

.NET tool

dotnet tool install --global Akin

After installation, the akin command is available globally.

Update: dotnet tool update --global Akin. Uninstall: dotnet tool uninstall --global Akin.

MCP registration

To register as an MCP server in Claude Code:

claude mcp add akin -- akin --mcp

For Cursor or other MCP clients, add to your MCP configuration:

{
  "mcpServers": {
    "akin": {
      "command": "akin",
      "args": ["--mcp"]
    }
  }
}

Usage

akin search <query> [--max N] [--snippets] [--max-per-file N]   # Semantic search
akin status                                                     # Show index status
akin reindex                                                    # Force a full reindex
akin pause                                                      # Pause indexing in all running MCP servers
akin resume                                                     # Resume indexing
akin auto-pause on|off                                          # Toggle pause-on-battery (default on, macOS)
akin --mcp                                                      # Run as MCP server
akin --version                                                  # Show version
akin help                                                       # Show help

Pausing indexing

akin pause flips a machine-wide switch that every running akin MCP server for the current user observes within a few seconds, stopping all background indexing (incremental reindexes, periodic reconciliation, and any in-progress initial build). Searches keep working from whatever is already on disk. akin resume flips it back; servers catch up on changes made while paused.

The switch lives in ~/.akin/state.json (a user-level file, distinct from the per-repository .akin/ index folders). It is useful when several MCP servers are indexing different repositories and you want to stop the CPU/battery cost — for example when unplugging a laptop.

Auto-pause on battery

By default, Akin also pauses indexing automatically whenever the machine is on battery power and resumes it when plugged back in, so the CPU cost of indexing several repositories doesn't quietly drain a laptop. The check piggybacks on the same poll cadence as the manual pause switch, so a plug/unplug is observed within a few seconds.

Detection is currently macOS-only (via IOKit's IOPSGetProvidingPowerSourceType). On Linux and Windows the power source is treated as AC, so auto-pause is a silent no-op there until detection is added.

To opt out and keep indexing active regardless of power source:

akin auto-pause off
akin auto-pause on    # restore the default

Manual akin pause always wins: if you've manually paused, plugging in does not auto-resume. Run akin resume to clear the manual pause.

Examples

# Natural-language query across the current repository (paths and line ranges only)
akin search "where do we handle authentication failures"

# Cap the number of files returned
akin search "database connection pooling" --max 5

# Drill in on a focused query — include the chunk text inline
akin search "error handling" --snippets

# Only show the single best match per file (most compact survey)
akin search "cosine similarity" --max-per-file 1

# Check whether the index is built and current
akin status

Search output

Results are grouped by file. Each file carries an aggregate score (the maximum score across its matching chunks) and up to --max-per-file matching regions with their own line ranges. Defaults are tuned for cheap survey output: paths and line ranges only (no snippet text), capped at 3 regions per file. Excess matches in a file are summarized as +N more matches not shown. Pass --snippets for the inline chunk text when drilling in, and raise --max-per-file (or set it to 1) to widen or narrow per-file detail.

How it works

Akin stores its index in a .akin/ folder at the repository root. Add .akin/ to your .gitignore to keep it out of version control. The folder contains three files:

  • vectors.bin — the vector store in VectorSharp's binary format
  • chunks.json — chunk metadata (file path, line range, content hash, text)
  • manifest.json — embedding model identifier, dimension, chunker fingerprint, schema version

On startup, Akin compares the stored manifest against its current configuration. If the embedding model or chunker has changed, the index is rebuilt automatically. If copied to a new worktree (e.g. via worktree-initializer), the index is reused and only the changed files are re-embedded.

Files indexed

Akin runs git ls-files to enumerate tracked files, so the set of indexed files exactly matches what you have chosen to version. Binary files are detected by scanning the first 8KB for null bytes and skipped. Files larger than 1MB are skipped.

Chunking

Files are chunked using the predefined VectorSharp.Chunking format for their extension:

Extension Format
.md, .markdown Markdown
.cs C#
.js, .jsx, .ts, .tsx, .mjs, .cjs JavaScript
.html, .htm HTML
.css, .scss CSS
.py, .pyi Python
anything else plain text

Incremental updates (MCP mode)

When running as an MCP server, Akin watches the repository for file changes via FileSystemWatcher and debounces events into batched incremental reindexes. A periodic reconciliation every five minutes diffs the current tracked set against the index to catch events the watcher may have dropped, as well as files that have become gitignored or newly tracked.

All of this background work honours the global pause switch described under Pausing indexing: while paused, watcher events are queued but not processed, reconciliation ticks are skipped, and an in-progress initial build parks until you resume.

In CLI mode (short-lived invocations), no watcher is used — each invocation opens the existing index, runs the command, and exits.

As MCP server

akin --mcp

When running as an MCP server, the following tools are available:

  • akin_search(query, maxResults?, includeSnippets?, maxRegionsPerFile?, paths?, excludePaths?, includeTypes?) — Semantic code search
  • akin_status() — Report index state, file and chunk counts, compatibility
  • akin_reindex() — Force a full rebuild of the index

When to use akin vs. grep

Akin and grep are complementary, not alternatives. The right mental model is akin for discovery, grep for completeness:

  • Use akin when you don't yet know the vocabulary the codebase uses. Questions like "how do we handle backwards compatibility" or "where do we deal with rate limiting" are good fits — the concept has no single keyword to grep for.
  • Use grep when the concept has a unique, greppable marker: an attribute name ([JsonPolymorphic]), a distinctive identifier, an exact error string. Grep is faster and more precise when you already know what to search for.
  • Combine them. Semantic ranking has silent recall gaps — a relevant file may be missing from the results without any indication, so don't treat akin's output as exhaustive. A common workflow is akin first to learn the vocabulary (attribute names, doc-comment phrasing, type names), then grep on those terms to enumerate every occurrence.

Development

git clone <repository-url>
cd akin
dotnet build Akin.slnx
dotnet test Akin.slnx

Run as MCP server during development:

dotnet run --project Akin.Cli/Akin.Cli.csproj -- --mcp

Package locally:

dotnet pack Akin.Cli/Akin.Cli.csproj --configuration Release

License

MIT License

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
0.6.0 54 5/29/2026
0.5.0 56 5/28/2026
0.4.0 110 5/8/2026
0.3.0 107 4/24/2026
0.2.0 105 4/20/2026
0.1.6 104 4/19/2026
0.1.5 96 4/19/2026
0.1.4 106 4/19/2026
0.1.3 104 4/19/2026
0.1.2 109 4/19/2026
0.1.1 94 4/19/2026
0.1.0 102 4/19/2026