🚀. Socket Launch Week Day 2:Introducing Manifest Alerts.Learn more
Sign In

@lrilai/gemini-cli-sdk

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lrilai/gemini-cli-sdk

TypeScript SDK for gemini-cli

latest
Source
npmnpm
Version
1.0.0
Version published
Maintainers
1
Created
Source

Gemini CLI SDK

TypeScript and Python SDK for driving gemini-cli programmatically. Mirrors the shape of @anthropic-ai/claude-agent-sdk and @openai/codex-sdk so you can swap providers without rewiring your application.

npm PyPI License: MIT

Contents

Features

  • Subprocess-based — wraps gemini-cli via child_process (TS) / anyio (Python); no library entry point required
  • Streaming-firstquery() is an async generator yielding typed MessageChunk events
  • Convenience wrapperqueryFull() / query_full() accumulates chunks into a single result object
  • Session resume — multi-turn conversations via --resume with automatic fallback to transcript injection
  • MCP passthrough — inject Model Context Protocol servers per-query without touching ~/.gemini/settings.json
  • Structured output — best-effort JSON schema validation with one automatic retry
  • Auth chain — four auth modes with documented precedence; no interactive prompts in headless contexts
  • Archon-ready — ships an IAssistantClient adapter enabling DEFAULT_AI_ASSISTANT=gemini in Archon
  • Parity-enforced — TypeScript and Python consume the same fixture corpus in CI

Prerequisites

DependencyVersionNotes
gemini-cli0.37.xInstall separately — not bundled
Node.js>=18 (20 or 22 recommended)TypeScript SDK only
Python>=3.10Python SDK only

Install gemini-cli first:

npm install -g @google/gemini-cli
gemini --version  # should print 0.37.x

Installation

TypeScript

npm install @lrilai/gemini-cli-sdk

Python

pip install gemini-sdk

Quickstart

TypeScript

Streaming response

import { query } from '@lrilai/gemini-cli-sdk';

for await (const chunk of query({ prompt: 'Explain async generators in one paragraph.' })) {
  if (chunk.type === 'assistant') {
    process.stdout.write(chunk.content);
  }
}

Accumulated result

import { queryFull } from '@lrilai/gemini-cli-sdk';

const result = await queryFull({ prompt: 'What is the capital of France?' });
console.log(result.text);     // "Paris"
console.log(result.sessionId); // session ID for resume

Python

Streaming response

import asyncio
from gemini_sdk import query

async def main():
    async for chunk in query(prompt="Explain async generators in one paragraph."):
        if chunk["type"] == "assistant":
            print(chunk["content"], end="", flush=True)

asyncio.run(main())

Accumulated result

import asyncio
from gemini_sdk import query_full

async def main():
    result = await query_full(prompt="What is the capital of France?")
    print(result.text)
    print(result.session_id)

asyncio.run(main())

Multi-turn sessions

Pass the Session object returned by queryFull() / query_full() directly into the next call.

TypeScript

import { queryFull, query } from '@lrilai/gemini-cli-sdk';

const first = await queryFull({ prompt: 'Remember the number 7.' });

for await (const chunk of query({
  prompt: 'What number did I ask you to remember?',
  session: first.session,  // resumes via --resume <sessionId>
})) {
  if (chunk.type === 'assistant') process.stdout.write(chunk.content);
}

Python

import asyncio
from gemini_sdk import query_full, query

async def main():
    first = await query_full(prompt="Remember the number 7.")

    async for chunk in query(
        prompt="What number did I ask you to remember?",
        session=first.session,
    ):
        if chunk["type"] == "assistant":
            print(chunk["content"], end="", flush=True)

asyncio.run(main())

You can also pass a bare session ID string when restoring a session from storage:

const result = await queryFull({ prompt: 'Next question.', session: 'abc-123-session-id' });

Authentication

The SDK does not implement its own auth layer — it passes credentials through to gemini-cli. Set one of the following environment variables before running:

VariableAuth modeNotes
GEMINI_API_KEYGemini API keyDefault. Recommended for headless/SDK use.
GOOGLE_APPLICATION_CREDENTIALSVertex AI service accountPath to JSON key file
GOOGLE_API_KEYVertex AI alternativeAlternative Vertex path
(none)ADC / Sign-in-with-GoogleInteractive; not recommended for automation

Precedence (highest to lowest): ADC (CLI Auth) → GEMINI_API_KEYGOOGLE_APPLICATION_CREDENTIALSGOOGLE_API_KEY.

If more than one is set, the SDK emits a single warning naming the winner and reprinting the full chain. The SDK never calls gemini auth login or any interactive OAuth flow.

export GEMINI_API_KEY="your-key-from-ai.google.dev"

For Vertex AI, also set project/region if needed:

export GOOGLE_APPLICATION_CREDENTIALS="/path/to/service-account.json"
export GOOGLE_CLOUD_PROJECT="my-project"
export GOOGLE_CLOUD_LOCATION="us-central1"

MCP passthrough (experimental)

Inject Model Context Protocol servers into a single query without touching your real ~/.gemini/settings.json. The SDK writes a temp settings.json into an isolated GEMINI_CONFIG_DIR and cleans it up in finally.

import { query } from '@lrilai/gemini-cli-sdk';

for await (const chunk of query({
  prompt: 'Use the time tool to report the current UTC time.',
  mcpServers: {
    time: { command: 'node', args: ['./time-mcp-server.js'] },
  },
  allowedMcpServerNames: ['time'],  // required when mcpServers is set
})) {
  console.log(chunk);
}

Note: allowedMcpServerNames is required when mcpServers is set. Omitting it throws InvalidPromptError before the subprocess spawns. See docs/mcp.md for known limitations.

Structured output (experimental)

Pass a JSON Schema to queryFull() / query_full(). The SDK injects the schema into the system prompt, validates the response, and retries once on failure.

import { queryFull } from '@lrilai/gemini-cli-sdk';

const result = await queryFull({
  prompt: 'What is the capital of France? Respond as JSON.',
  outputSchema: {
    type: 'object',
    properties: {
      capital: { type: 'string' },
      country: { type: 'string' },
    },
    required: ['capital', 'country'],
  },
});

console.log(result.structured); // { capital: 'Paris', country: 'France' }
console.log(result.text);       // raw assistant text (always available)

Only supported on queryFull() — calling query() or queryRaw() with outputSchema throws UnsupportedFeatureError immediately. See docs/structured-output.md for caveats.

Archon integration

The @lrilai/adapter-archon package implements Archon's IAssistantClient interface, enabling Gemini as a first-class provider alongside Claude and Codex.

Set in your Archon .env:

DEFAULT_AI_ASSISTANT=gemini
GEMINI_API_KEY=your-key-here

Then apply the adapter bundle from .planning/phases/10-archon-adapter-ts-only/pr-artifacts/ to your Archon fork. Full instructions: docs/archon-integration.md.

The Archon dev branch is the integration target. Branch from dev, not main.

Error handling

All SDK errors extend GeminiError. Each error carries a bucket (for Archon routing) and a retryable flag.

ClassBucketRetryableCause
GeminiErrorunknownNoBase class
RateLimitErrorrate_limitYes429 / quota exceeded
AuthErrorauthNoAuth misconfiguration
NotConfiguredauthNoNo auth variable set
Forbidden403authNoAPI key lacks permission
ModelAccessErrormodel_accessNoModel not available
ProcessErrorcrashNoSubprocess crashed
ProcessCrashErrorcrashNoNon-zero exit
AbortErrorcrashNoAbortSignal fired
InvalidPromptErrorcrashNoBad option combination
UnsupportedFeatureErrorcrashNoFeature not available
SchemaValidationErrorcrashNoStructured output failed after retry
import { query, RateLimitError, AuthError } from '@lrilai/gemini-cli-sdk';

try {
  for await (const chunk of query({ prompt: 'Hello' })) { /* ... */ }
} catch (err) {
  if (err instanceof RateLimitError) {
    console.log(`Rate limited. Retry after ${err.retryAfterMs}ms`);
  } else if (err instanceof AuthError) {
    console.error('Auth failed — check GEMINI_API_KEY');
  } else {
    throw err;
  }
}

Compatibility

ComponentTested rangeCI enforcement
gemini-cli0.37.xPinned in .gemini-cli-compat
Node.js18, 20, 22Matrix job per release
Python3.10, 3.11, 3.12, 3.13Matrix job per release
PlatformsWindows, macOS, LinuxWindows is a hard-required job

On the first query() call per process, the SDK spawns gemini --version once and validates the version against the pinned range. Control this with:

# Default: warn and continue
# GEMINI_SDK_COMPAT=strict  → throw on version mismatch
# GEMINI_SDK_COMPAT=silent  → suppress the warning
export GEMINI_SDK_COMPAT=strict

Contributing

# Clone and install
git clone https://github.com/seanrobertwright/Gemini-CLI-SDK.git
cd Gemini-CLI-SDK
pnpm install

# Run TypeScript tests
cd ts && pnpm test

# Run Python tests
cd python && pip install -e ".[dev]" && pytest

# Validate fixtures
pnpm validate:all

Contributions welcome. Please open an issue before submitting a large PR.

MIT License — see LICENSE.

Keywords

gemini

FAQs

Package last updated on 09 May 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts