# How Instagit Handles Token Authentication and Anonymous Token Registration

> Discover how Instagit handles token authentication and anonymous token registration. Learn about securing API requests with environment variables or local token persistence.

- Repository: [Instalabs AI/instagit](https://github.com/instalabsai/instagit)
- Tags: how-to-guide
- Published: 2026-02-16

---

**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`](https://github.com/instalabsAI/instagit/blob/main/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`](https://github.com/instalabsAI/instagit/blob/main/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`](https://github.com/instalabsAI/instagit/blob/main/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`](https://github.com/instalabsAI/instagit/blob/main/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`](https://github.com/instalabsAI/instagit/blob/main/src/api.ts)) as shown in lines 65-70. The request includes retry logic defined in [`src/retry.js`](https://github.com/instalabsAI/instagit/blob/main/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`](https://github.com/instalabsAI/instagit/blob/main/src/index.ts), the MCP server orchestrates token acquisition immediately before API calls:

```typescript
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.

```bash
export INSTAGIT_API_KEY="ig_abc123def456"

```

## Practical Implementation Examples

### Using Explicit API Authentication

The server picks up the key automatically from the environment:

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

```

### Auto-Registering Anonymous Tokens

Run commands without setting the environment variable:

```bash

# No INSTAGIT_API_KEY defined

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

```

Behind the scenes, the fallback flow executes:

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

```

The token is cached for future invocations:

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

```

### Manual Token Management

```typescript
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`](https://github.com/instalabsAI/instagit/blob/main/src/token.ts) checks `INSTAGIT_API_KEY`, then `~/.instagit/token.json`, then triggers registration.
- **Anonymous registration**: Uses machine fingerprinting via [`src/fingerprint.ts`](https://github.com/instalabsAI/instagit/blob/main/src/fingerprint.ts) and POSTs to `/v1/auth/anonymous` with retry logic from [`src/retry.js`](https://github.com/instalabsAI/instagit/blob/main/src/retry.js).
- **Automatic recovery**: 401 responses trigger `clearStoredToken()` and re-registration in [`src/index.ts`](https://github.com/instalabsAI/instagit/blob/main/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`](https://github.com/instalabsAI/instagit/blob/main/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`](https://github.com/instalabsAI/instagit/blob/main/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`](https://github.com/instalabsAI/instagit/blob/main/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`](https://github.com/instalabsAI/instagit/blob/main/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.