How Instagit Handles Token Authentication and Anonymous Token Registration

Instagit authenticates every API request using either an explicit API key from the INSTAGIT_API_KEY environment variable or by automatically registering an anonymous token that persists locally in ~/.instagit/token.json for subsequent calls.

Instagit is a Model Context Protocol (MCP) server that interfaces with the Instagit API to provide repository analysis capabilities. Understanding how token authentication and anonymous token registration function is essential for both paid users with API keys and those using the free tier. The system implements a seamless fallback mechanism in src/token.ts that prioritizes explicit credentials while automatically provisioning anonymous access when needed.

Token Retrieval Priority in getOrCreateToken

The authentication flow begins in src/token.ts with the getOrCreateToken() function (lines 51-55), which evaluates credentials in strict priority order:

  1. Environment Variable: Checks process.env.INSTAGIT_API_KEY and returns it immediately if present.
  2. Stored Token: Reads ~/.instagit/token.json via getStoredToken() (lines 22-30) if the environment variable is absent.
  3. Null Trigger: Returns null if neither source exists, signaling that anonymous registration is required.

This hierarchy ensures paid users' explicit keys always take precedence over cached anonymous tokens.

Anonymous Token Registration Flow

When getOrCreateToken() returns null, the system initiates the anonymous registration process via registerAnonymousToken() in src/token.ts (lines 60-78). This process involves three critical steps:

Machine Fingerprint Generation

The client generates a unique machine identifier using getMachineFingerprint() from src/fingerprint.ts (lines 31-38). This fingerprint ensures tokens are bound to specific hardware instances.

API Registration Request

The fingerprint is POSTed to the /v1/auth/anonymous endpoint (resolved via getApiUrl() in src/api.ts) as shown in lines 65-70. The request includes retry logic defined in src/retry.js to handle transient network failures and specific HTTP status codes.

Token Storage and Retry Logic

Upon receiving a 200 OK response containing { token: "<jwt>" }, the JWT is persisted to ~/.instagit/token.json via storeToken() and returned to the caller (lines 72-78). If all retry attempts exhaust (lines 81-99), the function returns null and the request terminates with an error message.

Request Flow and Automatic Token Refresh

In src/index.ts, the MCP server orchestrates token acquisition immediately before API calls:

let token = getOrCreateToken();
if (!token) {
  await sendProgress(formatMessage(tracker, "Registering anonymous token..."));
  token = await registerAnonymousToken(apiUrl);
  if (!token) { /* handle registration failure */ }
}

Handling 401 Unauthorized Responses

If the API returns a 401 Unauthorized status, the server assumes the stored anonymous token has been revoked. It invokes clearStoredToken() to remove ~/.instagit/token.json and attempts a fresh anonymous registration before retrying the request (lines 73-88). This automatic recovery mechanism ensures seamless re-authentication without user intervention.

Token Persistence and Cross-Language Support

Anonymous tokens are stored in a JSON file at ~/.instagit/token.json with the structure { "token": "<jwt>" }. This location is shared with the Python MCP client implementation, enabling token reuse across different language bindings. The file is created automatically upon first anonymous registration and updated whenever tokens are refreshed.

Environment Variable Configuration

Paid users can bypass anonymous registration entirely by setting the INSTAGIT_API_KEY environment variable. When this variable is present, Instagit skips the local storage check and anonymous registration flow, sending the provided key with every request. This configuration method supports higher rate limits and quotas associated with paid accounts.

export INSTAGIT_API_KEY="ig_abc123def456"

Practical Implementation Examples

Using Explicit API Authentication

The server picks up the key automatically from the environment:

// src/index.ts – token acquisition
const token = getOrCreateToken(); // returns the env var value

Auto-Registering Anonymous Tokens

Run commands without setting the environment variable:


# No INSTAGIT_API_KEY defined

instagit ask_repo --repo "facebook/react" --prompt "Explain the rendering pipeline"

Behind the scenes, the fallback flow executes:

// src/index.ts – fallback flow
if (!token) {
  token = await registerAnonymousToken(apiUrl); // registers and stores token
}

The token is cached for future invocations:

// src/token.ts – persisting token
storeToken(token); // writes ~/.instagit/token.json

Manual Token Management

import { getOrCreateToken, registerAnonymousToken, clearStoredToken } from "./token.js";

async function ensureToken(apiUrl) {
  let token = getOrCreateToken();
  if (!token) {
    token = await registerAnonymousToken(apiUrl);
  }
  return token;
}

// Clear corrupted or revoked tokens
clearStoredToken(); // removes ~/.instagit/token.json

Summary

  • Priority-based retrieval: getOrCreateToken() in src/token.ts checks INSTAGIT_API_KEY, then ~/.instagit/token.json, then triggers registration.
  • Anonymous registration: Uses machine fingerprinting via src/fingerprint.ts and POSTs to /v1/auth/anonymous with retry logic from src/retry.js.
  • Automatic recovery: 401 responses trigger clearStoredToken() and re-registration in src/index.ts without user action.
  • Cross-language storage: Token JSON format enables sharing between TypeScript and Python MCP clients.
  • Explicit override: Environment variables disable anonymous flows for paid tier access.

Frequently Asked Questions

How does Instagit store anonymous tokens locally?

Instagit writes anonymous tokens to ~/.instagit/token.json in JSON format containing a single token field with the JWT value. This file is read by getStoredToken() in src/token.ts (lines 22-30) on subsequent invocations and is shared across the Python and TypeScript client implementations.

What happens if my anonymous token is revoked?

When the API returns a 401 Unauthorized response, Instagit automatically calls clearStoredToken() to delete ~/.instagit/token.json, then attempts to register a new anonymous token via registerAnonymousToken(). This retry logic is implemented in src/index.ts (lines 73-88) and requires no manual intervention unless the registration itself fails.

Can I use Instagit without setting an environment variable?

Yes. If INSTAGIT_API_KEY is not set, Instagit automatically falls back to anonymous token registration. The system generates a machine fingerprint in src/fingerprint.ts, registers with the /v1/auth/anonymous endpoint, and caches the resulting JWT for future requests. This enables immediate usage without configuration, subject to anonymous tier rate limits.

Where is the machine fingerprint generated for anonymous registration?

The machine fingerprint is generated in src/fingerprint.ts by the getMachineFingerprint() function (lines 31-38). This stable identifier is sent to the Instagit API during anonymous registration to uniquely identify the client machine and prevent token abuse.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →