genkit Documentation

Open-source framework for building agentic apps in JavaScript, Go, Dart, and Python, built and used in production by Google

6,326 stars TypeScript TypeScript 1 file ยท ~11,775 tokens #agents#ai#embedders#genkit#llm#multimodal#rag#vector-database
RAW Doc

File: README.md

Genkit is an open-source framework for building full-stack AI-powered applications, built and used in production by Google's Firebase. It provides SDKs for multiple programming languages with varying levels of stability:

  • JavaScript/TypeScript: Production-ready with full feature support
  • Go: Production-ready with full feature support
  • Python (Beta): Wide feature support approaching production-readiness
  • Dart (Preview): Early development with core functionality

It offers a unified interface for integrating AI models from providers like Google, OpenAI, Anthropic, Ollama, and more. Rapidly build and deploy production-ready chatbots, automations, and recommendation systems using streamlined APIs for multimodal content, structured outputs, tool calling, and agentic workflows.

Get started with just a few lines of code:

ts
import { genkit } from 'genkit';
import { googleAI } from '@genkit-ai/google-genai';

const ai = genkit({ plugins: [googleAI()] });

const { text } = await ai.generate({
    model: googleAI.model('gemini-flash-latest'),
    prompt: 'What is the meaning of life?'
});

Explore & build with Genkit

Play with AI sample apps, with visualizations of the Genkit code that powers
them, at no cost to you.

Explore Genkit by Example

Key capabilities

| Broad AI model support | Use a unified interface to integrate with hundreds of models from providers like Google,
OpenAI,
Anthropic, Ollama, and more. Explore, compare, and use the best models for your needs. |

| --- | --- |
| Simplified AI development | Use streamlined APIs to build AI features with
structured output, agentic tool calling, context-aware generation, multi-modal input/output, and more. Genkit handles the complexity of AI development, so you can build and iterate faster. |
| Web and mobile ready | Integrate seamlessly with frameworks and platforms including Next.js, React, Angular, iOS, Android, using purpose-built client SDKs and helpers. |
| Cross-language support | Build with the language that best fits your project. Genkit provides SDKs for JavaScript/TypeScript, Go, Python (Beta), and Dart (Preview) with consistent APIs and capabilities across all supported languages. |
| Deploy anywhere | Deploy AI logic to any environment that supports your chosen programming language, such as Cloud Functions for Firebase,
Google Cloud Run, or third-party platforms,
with or without Google services. |
| Developer tools | Accelerate AI development with a purpose-built, local CLI and Developer UI. Test prompts and
flows against individual inputs or datasets, compare outputs from different models, debug with detailed execution traces, and use immediate visual feedback to iterate rapidly on prompts. |
| Production monitoring | Ship AI features with confidence using comprehensive production monitoring. Track model performance, and request volumes, latency, and error rates in a purpose-built dashboard. Identify issues quickly with detailed observability metrics, and ensure your AI features meet quality and performance targets in real-world usage. |

How does it work?

Genkit simplifies AI integration with an open-source SDK and unified APIs that
work across various model providers and programming languages. It abstracts away complexity so you can focus on delivering great user experiences.

Some key features offered by Genkit include:

Genkit is designed for server-side deployment in multiple language environments, and also provides seamless client-side integration through dedicated helpers and client SDKs.

Implementation path

1 Choose your language and model provider Select the Genkit SDK for your preferred language (JavaScript/TypeScript, Go, Python (Beta), Dart (Preview)). Choose a model provider like Google Gemini or Anthropic, and get an API key. Some providers, like Vertex AI, may rely on a different means of authentication.
2 Install the SDK and initialize Install the Genkit SDK, model-provider package of your choice, and the Genkit CLI. Import the Genkit and provider packages and initialize Genkit with the provider API key.
3 Write and test AI features Use the Genkit SDK to build AI features for your use case, from basic text generation to complex multi-step workflows and agents. Use the CLI and Developer UI to help you rapidly test and iterate.
4 Deploy and monitor Deploy your AI features to Firebase, Google Cloud Run, or any environment that supports your chosen programming language. Integrate them into your app, and monitor them in production in the Firebase console.

Get started

Development tools

Genkit provides a CLI and a local UI to streamline your AI development workflow.

CLI

The Genkit CLI includes commands for running and evaluating your Genkit functions (flows) and collecting telemetry and logs.

  • Install: npm install genkit-cli
  • Run a command, wrapped with telemetry, a interactive developer UI, etc: genkit start -- <command to run your code>

Developer UI

The Genkit developer UI is a local interface for testing, debugging, and iterating on your AI application.

Key features:

  • Run: Execute and experiment with Genkit flows, prompts, queries, and more in dedicated playgrounds.
  • Inspect: Analyze detailed traces of past executions, including step-by-step breakdowns of complex flows.
  • Evaluate: Review the results of evaluations run against your flows, including performance metrics and links to relevant traces.

Connect with us

Contributing

Contributions to Genkit are welcome and highly appreciated! See our Contribution Guide to get started.

Authors

Genkit is built by Google with contributions from the Open Source Community.


File: docs/model-spec.md

Genkit Model Action Specification

This document specifies the contract for Genkit Model Actions. Genkit models are implemented as actions with specific input, output, and streaming schemas. They encapsulate the logic for communicating with AI models, handling multimodal input, tool calling, and structured output.

Model Action Definition

A Genkit Model is an Action with the following characteristics:

  • Action Type: model
  • Input Schema: GenerateRequest
  • Output Schema: GenerateResponse
  • Streaming Schema: GenerateResponseChunk

Metadata

Model actions should define the following metadata:

  • model: Object containing model capability information.
    • label: Human-readable name (e.g., "Google AI - Gemini Pro").
    • versions: Array of supported version strings.
    • supports: Object defining supported capabilities:
      • multiturn: Boolean (history support).
      • media: Boolean (multimodal input support).
      • tools: Boolean (tool calling support).
      • systemRole: Boolean (system message support).
      • output: Array of supported output formats (e.g., ['json', 'text']).
      • contentType: Array of supported output content types.
      • context: Boolean (document context support).
      • constrained: Enum ('none', 'all', 'no-tools') - native constrained generation support.
      • toolChoice: Boolean (forcing tool selection).
      • longRunning: Boolean (long running operation support).
    • stage: Development stage ('featured', 'stable', 'unstable', 'legacy', 'deprecated').
    • customOptions: JSON Schema for model-specific configuration (exposed as config in request).

Data Structures

GenerateRequest

The input to a model action.

Field Type Description
messages Message[] (Required) List of messages in the conversation history.
config any Model-specific configuration options (e.g., temperature, topK). Validated against the model's config schema.
tools ToolDefinition[] List of tools available for the model to call.
toolChoice enum Tool selection strategy: 'auto', 'required', or 'none'.
output OutputConfig Configuration for the desired output format/schema.
docs DocumentData[] Retrieved documents to be used as context.

OutputConfig

Field Type Description
format string Desired format (e.g., 'json', 'text').
schema Record<string, any> JSON schema defining the expected output structure.
constrained boolean Whether to enforce the schema constraints natively.
contentType string Specific content type for the output.

GenerateResponse

The output from a model action.

Field Type Description
message Message The generated message.
finishReason enum Reason for generation completion: 'stop', 'length', 'blocked', 'interrupted', 'other', 'unknown'.
finishMessage string Additional information about the finish reason.
usage GenerationUsage Token and character usage statistics.
latencyMs number Time taken for generation in milliseconds.
custom any Model-specific extra information.
request GenerateRequest The request that triggered this response.

GenerateResponseChunk

The chunk format for streaming responses.

Field Type Description
role Role Role of the message being generated (usually 'model').
index number Index of the message in the response (typically 0).
content Part[] (Required) Content parts in this chunk.
aggregated boolean If true, this chunk contains the full accumulated content so far.
custom any Model-specific extra information.

Message

Field Type Description
role enum (Required) The role of the message sender: 'system', 'user', 'model', 'tool'.
content Part[] (Required) The content of the message, composed of one or more parts.
metadata Record<string, any> Arbitrary metadata associated with the message.

Parts

Genkit uses a unified Part structure to represent different types of content. A Part is a union of specific part types.

Text Part

Represents plain text content.

json
{
  "text": "Hello, world!"
}

Media Part

Represents multimodal content. Inline data should be encoded as data: URIs (base64).

Image:

json
{
  "media": {
    "url": "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
    "contentType": "image/jpeg"
  }
}

Audio:

json
{
  "media": {
    "url": "data:audio/L16;codec=pcm;rate=24000;base64,AAAAAA...",
    "contentType": "audio/L16;codec=pcm;rate=24000"
  }
}

Video:

json
{
  "media": {
    "url": "https://example.com/video.mp4",
    "contentType": "video/mp4"
  }
}

Metadata:
All parts can include a metadata field for provider-specific information that doesn't fit into the main schema. Common uses include mediaResolution for images/video, videoMetadata (e.g. duration, offset), or internal signatures like thoughtSignature.

json
{
  "media": { "url": "..." },
  "metadata": {
    "mediaResolution": { "level": "MEDIA_RESOLUTION_HIGH" },
    "videoMetadata": { "startOffset": { "seconds": 10 } }
  }
}

Tool Request Part

Represents a request from the model to execute a tool.

json
{
  "toolRequest": {
    "name": "weatherTool",
    "ref": "call_123", // Optional correlation ID
    "input": { "city": "New York" }
  }
}

Tool Response Part

Represents the result of a tool execution, sent back to the model.

json
{
  "toolResponse": {
    "name": "weatherTool",
    "ref": "call_123", // Must match the request ref
    "output": { "temperature": 72 }, // Structured output
    "content": [ ... ] // Optional content parts (e.g. if tool returns artifacts)
  }
}

Custom Part

Represents provider-specific content not covered by other types. A common use case is returning the result of server-side tools like Code Execution.

json
{
  "custom": {
    "executableCode": {
      "code": "print('Hello World')",
      "language": "PYTHON"
    },
    "codeExecutionResult": {
      "outcome": "OUTCOME_OK",
      "output": "Hello World\n"
    }
  }
}

Provider-Specific Features

Many models offer server-side features that go beyond standard text generation or client-side tool calling. These are typically handled via the config object or specific metadata.

Server-Side Tools

Features like Web Search (Grounding), Code Execution, or URL Context are often implemented as "server-side tools". Since the client does not execute them, they are configured in the config object rather than the tools list.

Example (Web Search Configuration):

json
{
  "config": {
    "googleSearch": {}, // Provider-specific key
    "tools": [{ "googleSearch": {} }] // Some providers might use a tools config key
  }
}

Example (URL Context):

json
{
  "config": {
    "urlContext": { "urls": ["https://example.com/article"] }
  }
}

Encoding Guidelines

  • Requests: Use config for enabling/configuring server-side features. Do not use ToolRequestPart unless the client is expected to execute the tool.
  • Responses:
    • If a server-side tool produces content (e.g., code execution output), it may appear as a TextPart (if integrated into the answer) or a CustomPart.
    • Metadata about the execution (e.g., search sources, grounding metadata) should be placed in the custom field of the GenerateResponse or Message metadata.

Reasoning Part

Represents chain-of-thought or reasoning text provided by the model.

json
{
  "reasoning": "First, I will calculate..."
}

Data Part

This part is reserved for future use and is not currently supported by any known plugins. Represents generic structured data.

json
{
  "data": { "key": "value" }
}

Behavior

Request Processing

  1. Validation: The model action validates the GenerateRequest.
  2. Context: If docs are provided, the model action should incorporate them into the context, typically by augmenting the message history.
  3. Tools: If tools are provided, they are converted to the format expected by the underlying model API.
  4. Configuration: config options are applied.

System Message Handling

Genkit standardizes system instructions as messages with role: 'system' within the messages array. However, many model providers (e.g., Google GenAI) require system instructions to be passed as a separate configuration field rather than part of the conversation history.

Implementation Requirement:

  • The model action MUST accept role: 'system' messages in the input messages array.
  • If the underlying provider requires separate system instructions:
    1. Extract the system message(s) from the messages array.
    2. Convert/format them as required by the provider (e.g., systemInstruction field).
    3. Ensure they are NOT passed in the regular conversation history if the provider doesn't support system role there.

Configuration Handling

Model plugins should follow the "passthrough" pattern for configuration options. This ensures that new features added to the underlying model API can be used immediately by users without requiring plugin updates.

  1. Extract Known Options: Explicitly destructure known configuration keys (e.g., temperature, topK, topP) to handle them according to Genkit's common schema or specific logic.
  2. Pass Through the Rest: Pass all remaining unknown keys directly to the underlying model API's configuration object.

Example (TypeScript):

typescript
const {
  temperature,
  topK,
  ...restOfConfig
} = request.config || {};

const apiRequest = {
  model: modelName,
  temperature: temperature, // Handle known keys
  top_k: topK,
  ...restOfConfig // Pass through unknown keys
};
  1. Merge Tools: If the provider supports passing tools via configuration (e.g., config.tools) in addition to the standard request.tools, these should be merged. This allows users to pass provider-specific tool definitions (like server-side tools) alongside standard Genkit tools.
typescript
const tools = request.tools?.map(toProviderTool) || [];
if (config.tools) {
  tools.push(...config.tools);
}

Response Generation

  1. Content: The model output is parsed into Part objects. Text is mapped to TextPart, function calls to ToolRequestPart.
  2. Streaming: When streaming, the model emits GenerateResponseChunks.
    • Chunks should ideally contain incremental updates.
    • If the underlying model only supports full responses during streaming, aggregated: true should be set.
  3. Finish Reason: The model must map provider-specific finish reasons to the standard Genkit enum.

Tool Handling

Tools are a central capability of Genkit models. Implementation involves converting definitions, handling requests (including streaming), and processing responses.

Tool Definition Conversion

The model action must convert Genkit's ToolDefinition into the format expected by the provider.

  • Name: Sanitize tool names if the provider has strict rules (e.g., replace / with __ for Gemini).
  • Input Schema: Convert the JSON Schema in inputSchema to the provider's schema format.
  • Description: Pass the tool description.

Tool Requests

When the model decides to call a tool, it emits a ToolRequestPart.

  • Ref: Assign a stable ref (call ID) if the provider supports it, to correlate with the response.
  • Input: The arguments for the tool.

Partial Tool Requests (Streaming)
Some models (like Gemini 3.0) support streaming tool calls. In this case, the model emits ToolRequestParts with partial: true.

  • The input field in a partial request should contain the accumulated arguments so far (if supported by the plugin logic) or the current delta, depending on how the plugin manages state.
  • The final chunk for the tool call should have partial: false (or omitted).

Tool Responses

The result of a tool execution is passed back to the model as a ToolResponsePart in a message with role: 'tool'.

  • Ref: Must match the ref of the corresponding ToolRequestPart.
  • Output: The result of the tool execution (usually a JSON object).
  • Content: Optional list of Parts (e.g., if the tool returns an image or other rich content).

Multi-turn Flow

Models supporting tools must handle the conversation loop:

  1. User Message
  2. Model Message (containing ToolRequestParts)
  3. Tool Message (containing ToolResponseParts)
  4. Model Message (Final Answer)

Structured Output

  • If output.schema is provided, the model should attempt to generate content matching that schema.
  • If output.constrained is true and the model supports it, the schema is enforced by the model generation process.
  • Otherwise, the schema may be included in the prompt instructions.
  • The resulting structured data should be typically serialized in a TextPart.

File: docs/README.md

Genkit Documentation

The source files for the official Genkit documentation (available at genkit.dev) have been moved to:

https://github.com/genkit-ai/docsite

Please refer to the new repository for all documentation updates, contributions, and issues.

Resources

The resources directory in this location contains assets that may still be referenced by other parts of the project.


File: docs/reflection-v2-protocol.md

Genkit Reflection Protocol V2 (WebSocket)

This document outlines the design for the V2 Reflection API, which uses WebSockets for bidirectional communication between the Genkit CLI (Runtime Manager) and Genkit Runtimes (User Applications).

Overview

In V2, the connection direction is reversed compared to V1:

  • Server: The Genkit CLI (RuntimeManagerV2) starts a WebSocket server.
  • Client: The Genkit Runtime connects to the CLI's WebSocket server.

This architecture allows the CLI to easily manage multiple runtimes (e.g., for multi-service projects) and eliminates the need for runtimes to manage their own HTTP servers and ports for reflection.

Transport

Feature Specification
Protocol WebSocket
Data Format JSON
Message Structure JSON-RPC 2.0 (modified for streaming)

Message Format

All messages follow the JSON-RPC 2.0 specification.

Request

json
{
  "jsonrpc": "2.0",
  "method": "methodName",
  "params": { ... },
  "id": 1
}

Note: The id is generated by the sender (Manager). It can be a number (auto-incrementing) or a string (UUID). It must be unique for the pending request within the WebSocket session.

Response (Success)

json
{
  "jsonrpc": "2.0",
  "result": { ... },
  "id": 1
}

Response (Error)

json
{
  "jsonrpc": "2.0",
  "error": {
    "code": -32000,
    "message": "Error message",
    "data": {
      "code": 13,
      "message": "Error message",
      "details": {
        "traceId": "...",
        "stack": "..."
      }
    }
  },
  "id": 1
}

The data field contains a Status object (matching V1 API) with:

  • code: Genkit canonical status code (e.g., 13 for INTERNAL, 3 for INVALID_ARGUMENT).
  • message: The error message.
  • details: Additional context, including traceId and stack trace.

Notification

A request without an id.

json
{
  "jsonrpc": "2.0",
  "method": "methodName",
  "params": { ... }
}

Streaming Extension

JSON-RPC 2.0 does not natively support streaming. We extend it by using Notifications from the Runtime to the Manager associated with a specific Request ID.

Message Type Method Direction Description
Stream Chunk streamChunk Runtime -> Manager Sent by the Runtime during a streaming runAction request.
State Update runActionState Runtime -> Manager Sent by the Runtime to provide status updates (e.g., trace ID) before the result.

Stream Chunk Notification

json
{
  "jsonrpc": "2.0",
  "method": "streamChunk",
  "params": {
    "requestId": 1,
    "chunk": { ... }
  }
}

Run Action State Notification

json
{
  "jsonrpc": "2.0",
  "method": "runActionState",
  "params": {
    "requestId": 1,
    "state": { "traceId": "..." }
  }
}

Protocol Methods Summary

Method Direction Type Description
register Runtime -> Manager Request Registers the runtime with the Manager and retrieves initial configuration.
listActions Manager -> Runtime Request Retrieves the list of available actions.
listValues Manager -> Runtime Request Retrieves the list of values (prompts, schemas, etc.).
runAction Manager -> Runtime Request Executes an action.
cancelAction Manager -> Runtime Request Cancels a running action.

Detailed API

1. Registration

Direction: Runtime -> Manager
Type: Request

Parameters:

Field Type Description
id string Unique Runtime ID.
pid number Process ID.
name string App name (optional).
genkitVersion string e.g., "0.9.0".
reflectionApiSpecVersion number Protocol version.
envs string[] Configured environments (optional).

Result:

Field Type Description
telemetryServerUrl string URL of the telemetry server (optional).

2. List Actions

Direction: Manager -> Runtime
Type: Request

Parameters: void

Result:

Type Description
{ actions: Record<string, Action> } Object with an actions field containing a map of action keys to Action definitions.

4. List Values

Direction: Manager -> Runtime
Type: Request

Parameters:

Field Type Description
type string The type of value to list (e.g., "model", "prompt", "schema").

Result:

Type Description
{ values: Record<string, any> } Object with a values field containing a map of value keys to value definitions.

5. Run Action

Direction: Manager -> Runtime
Type: Request

Parameters:

Field Type Description
key string Action key (e.g., "/flow/myFlow").
input any Input payload.
context any Context data (optional).
telemetryLabels Record<string, string> Telemetry labels (optional).
stream boolean Whether to stream results.
streamInput boolean Whether to stream input (for bidi actions).

Result (Non-Streaming):

Field Type Description
result any The return value.
telemetry object Telemetry metadata (e.g., { traceId: string }).

Streaming Flow:

  1. Runtime sends optional runActionState notifications.
  2. Runtime sends streamChunk notifications.
  3. Runtime sends final response with result (same structure as non-streaming).

Bidirectional Streaming Flow (if streamInput: true):

  1. Manager sends sendInputStreamChunk notifications.
  2. Manager sends endInputStream notification.
  3. Runtime behaves as per Streaming Flow.

6. Cancel Action

Direction: Manager -> Runtime
Type: Request

Parameters:

Field Type Description
traceId string The trace ID of the action to cancel.

Result:

Field Type Description
message string Confirmation message.

Health Checks

Check Type Description
Connection State The WebSocket connection state itself serves as a basic health check.
Heartbeats Standard WebSocket Ping/Pong frames should be used to maintain the connection and detect timeouts.

Compatibility

Version Architecture
V1 HTTP Server on Runtime, Polling/Request from CLI.
V2 WebSocket Server on CLI, Persistent Connection from Runtime.

The CLI will determine which mode to use based on configuration (e.g., --experimental-reflection-v2).


File: genkit-tools/cli/src/mcp/README.md

๐Ÿš€ Genkit MCP Server: Model Context Protocol Integration

The Genkit MCP (Model Context Protocol) Server bridges your Genkit projects with external AI tools and development environments. It exposes Genkit flows and functionalities via the Model Context Protocol, allowing LLM agents and IDEs to discover, interact with, and monitor your application.

Note: The Genkit MCP server is an experimental feature and may change.


What It Does

The MCP Server enables external tools to:

  • Discover Flows: List all available Genkit flows, including their input schemas.
  • Run Flows: Execute Genkit flows by providing inputs and receiving outputs.
  • Access Traces: Retrieve and analyze detailed execution traces for performance insights.
  • Look up Documentation: Access Genkit documentation directly.
  • Manage Runtime: Start, stop, and restart the Genkit runtime process.

Available MCP Tools

The following tools allow MCP-aware environments to interact with the Genkit server:

Tool Name Description
get_usage_guide Fetches the Genkit AI framework usage guide (specifiable by language). Intended for AI assistants.
list_genkit_docs Lists all available Genkit documentation files for discovery.
search_genkit_docs Searches Genkit documentation using keywords.
read_genkit_docs Reads the content of specific Genkit documentation files.
list_flows Discovers and lists all defined Genkit flows with their input schemas.
run_flow Executes a specified Genkit flow, requiring flowName and a JSON input conforming to the flow's schema.
get_trace Retrieves the detailed execution trace for a flow using a traceId.
start_runtime Starts a Genkit runtime process (e.g., npm run dev or go run main.go).
kill_runtime Kills the runtime process started by start_runtime.
restart_runtime Restarts the runtime process started by start_runtime.

Available Prompts

Prompt Name Description
genkit:init Helps initialize a new Genkit project with best practices and language-specific setup.

File: genkit-tools/cli/README.md

Genkit CLI

The package contains the CLI for Genkit, an open source framework with rich local tooling to help app developers build, test, deploy, and monitor AI-powered features for their apps with confidence. Genkit is built by Firebase, Google's app development platform that is trusted by millions of businesses around the world.

Review the documentation for details and samples.

To install the CLI:

bash
npm install genkit-cli

Available commands:

  • init [options]

    initialize a project directory with Genkit

  • start [options]

    run the app in dev mode and start a Developer UI

  • flow:run [options] <flowName> [data]

    run a flow using provided data as input

  • flow:batchRun [options] <flowName>

    batch run a flow using provided set of data from a file as input

  • flow:resume <flowName> <flowId> <data>

    resume an interrupted flow (experimental)

  • eval:extractData [options] <flowName>

    extract evaludation data for a given flow from the trace store

  • eval:run [options] <dataset>

    evaluate provided dataset against configured evaluators

  • eval:flow [options] <flowName> [data]

    evaluate a flow against configured evaluators using provided data as input

  • config

    set development environment configuration

  • help


File: genkit-tools/telemetry-server/README.md

Genkit

The sources for this package are in the main Genkit repo. Please file issues and pull requests against that repo.

Usage information and reference details can be found in official Genkit documentation.

License: Apache 2.0


File: go/plugins/postgresql/README.md

PostgreSQL plugin

PostgreSQL plugin provides indexer and retriever implementations that use PostgreSQL with the pgvector extension for vector similarity search.

Configuration

To use this plugin, first create a PostgresEngine instance:

go
// Create PostgresEngine instance
// with basic authentication
pEngine, err := NewPostgresEngine(ctx,
		WithUser('user'),
		WithPassword('password'),
		WithCloudSQLInstance('my-project', 'us-central1', 'my-instance'),
		WithDatabase('my-database')

// with email authentication
pEngine, err := NewPostgresEngine(ctx,
    WithCloudSQLInstance('my-project', 'us-central1', 'my-instance'),
    WithDatabase('my-database'),
    WithIAMAccountEmail('[email protected]'))

// with custom pool
pool, err := pgxpool.New(ctx, "add_your_connection_string")
if err != nil {
  return err
}

pEngine, err := NewPostgresEngine(ctx,
    WithDatabase("db_test"),
    WithPool(pool))

// Create the vector store table

err = pEngine.InitVectorstoreTable(ctx, VectorstoreTableOptions{
    TableName:          "documents",
    VectorSize:         768,
    SchemaName:         "public",
    ContentColumnName:  "content",
    EmbeddingColumn:    "embedding",
    MetadataJSONColumn: "custom_metadata",
    IDColumn: Column{
      Name:     custom_id,
      Nullable: false,
    },
    MetadataColumns: []Column{
      {
        Name:     "source",
        DataType: "text",
        Nullable: true,
      },
      {
        Name:     "category",
        DataType: "text",
        Nullable: true,
      },
    },
    OverwriteExisting: true,
    StoreMetadata:     true,
})

Then, specify the plugin when you initialize Genkit:

go
postgres := &Postgres{
		engine: pEngine,
	}

	g, err := genkit.Init(ctx, genkit.WithPlugins(postgres))
  if err != nil {
    return nil
}

// To use the table you configured when you loaded the plugin:

  cfg := &Config{
    TableName:             'documents',
    SchemaName:            'public',
    ContentColumn:         "content",
    EmbeddingColumn:       "embedding",
    MetadataColumns:       []string{"source", "category"},
    IDColumn:              "custom_id",
    MetadataJSONColumn:    "custom_metadata",
    Embedder:              embedder,
    EmbedderOptions:       nil,
  }

// To index and retrieve from the configured table:
doc, retriever, err := DefineRetriever(ctx, g, postgres, cfg)
if err != nil {
  retrun err
}

docs := []*ai.Document{{
  Content: []*ai.Part{{
    Kind:        ai.PartText,
    ContentType: "text/plain",
    Text:        "The product features include...",
  }},
  Metadata: map[string]any{"source": "website", "category": "product-docs", "custom_id": "doc-123"},
}}

if err := doc.Index(ctx, docs); err != nil {
 return err
}

d2 := ai.DocumentFromText( "The product features include..." , nil)

resp, err := retriever.Retrieve(ctx, &ai.RetrieverRequest{
    Query: d2,
    k:5,
    filter: "source='website' AND category='product-docs'"
})

if err != nil {
    retrun err
}

See the Retrieval-augmented generation page for a general discussion on indexers and retrievers.


File: go/plugins/ollama/README.md

Ollama Plugin

The Ollama plugin provides a unified interface to connect with locally hosted (or remote) models through the Ollama API.

The plugin supports a wide range of capabilities, relying on the models you have pulled:

  • Language Models: Chat and text generation models, including support for tools, vision (multimodal), and reasoning (thinking).
  • Embedding Models: Text embeddings.

Setup

Installation

bash
go get github.com/firebase/genkit/go/plugins/ollama

Configuration

You can configure the Ollama plugin with your server address. By default, Ollama runs on http://localhost:11434.

go
import (
 "context"

 "github.com/firebase/genkit/go/genkit"
 "github.com/firebase/genkit/go/plugins/ollama"
)

func main() {
 ctx := context.Background()

 // Initialize the Ollama plugin
 o := &ollama.Ollama{
  ServerAddress: "http://localhost:11434", // Required
  Timeout:       60,                       // Optional: Response timeout in seconds (default: 30)
 }

 g := genkit.Init(ctx, genkit.WithPlugins(o))
}

Language Models

Because Ollama models are locally hosted and the available models depend on what the user has pulled (ollama pull <model>), the plugin doesn't pre-initialize any default models. You must define them explicitly.

Defining a Model

To use an Ollama model, you must define it using DefineModel after initializing the plugin.

go
// Define a chat model (e.g., tinyllama)
o.DefineModel(g, ollama.ModelDefinition{
 Name: "tinyllama",
 Type: "chat", // Use "chat" for interactive models, or "" for text-completion only
}, nil)

// You can now retrieve and use it
m := ollama.Model(g, "tinyllama")

Basic Usage

go
import (
 "context"
 "fmt"
 "log"

 "github.com/firebase/genkit/go/ai"
 "github.com/firebase/genkit/go/genkit"
 "github.com/firebase/genkit/go/plugins/ollama"
)

func main() {
 // ... Init genkit with ollama plugin and define "tinyllama" ...

 m := ollama.Model(g, "tinyllama")
 resp, err := genkit.Generate(ctx, g,
  ai.WithModel(m),
  ai.WithPrompt("Explain how neural networks learn in simple terms."),
 )
 if err != nil {
  log.Fatal(err)
 }

 fmt.Println(resp.Text())
}

Configuration Options

You can pass advanced parameters to Ollama models using ollama.GenerateContentConfig.

:::note
The plugin provides an ollama.Ptr helper function to easily initialize optional numeric fields (like Temperature or Seed).
:::

go
import "github.com/firebase/genkit/go/plugins/ollama"

resp, err := genkit.Generate(ctx, g,
 ai.WithModel(m),
 ai.WithPrompt("Write a poem about the sea."),
 ai.WithConfig(&ollama.GenerateContentConfig{
  Temperature: ollama.Ptr(0.8),
  TopK:        ollama.Ptr(40),
  TopP:        ollama.Ptr(0.9),
  NumPredict:  ollama.Ptr(100), // Max output tokens
  KeepAlive:   "5m",           // Keep model loaded in memory for 5 minutes
  Seed:        ollama.Ptr(42),
 }),
)

Tool Calling

Ollama supports tool calling for specific models. Models like llama3.1 or mistral are excellent for this.

go
// Define a model that supports tools
o.DefineModel(g, ollama.ModelDefinition{
 Name: "llama3.1",
 Type: "chat",
}, nil)

m := ollama.Model(g, "llama3.1")

// Define a tool
weatherTool := genkit.DefineTool(g, "getWeather", "gets the weather",
 func(ctx *ai.ToolContext, input *WeatherInput) (*WeatherOutput, error) {
  return &WeatherOutput{Temp: 72}, nil
 },
)

resp, err := genkit.Generate(ctx, g,
 ai.WithModel(m),
 ai.WithPrompt("What is the weather in New York?"),
 ai.WithTools(weatherTool),
)

:::note
The Ollama plugin supports receiving text content alongside tool calls. If a model returns both a text response and a tool request, both will be preserved in the message content.
:::

Thinking and Reasoning

The plugin supports models with reasoning capabilities (like deepseek-r1).

go
resp, err := genkit.Generate(ctx, g,
 ai.WithModel(m),
 ai.WithPrompt("What is heavier, one kilo of steel or one kilo of feathers?"),
 ai.WithConfig(&ollama.GenerateContentConfig{
  Think: ollama.ThinkEnabled(true), // Enable thinking mode for supported models
 }),
)

// The model's reasoning process is returned as a specific part
fmt.Println("Reasoning:", resp.Reasoning())
fmt.Println("Final Answer:", resp.Text())

Note on Streaming Reasoning

For models that output reasoning using `` tags within standard text (instead of Ollama's native thinking API field), the tags will be automatically parsed and mapped to Genkit's ReasoningPart in non-streaming mode.

In streaming mode, due to the nature of token-by-token chunks, these tags will be streamed as standard TextPart content. Models that natively support Ollama's thinking field will stream ReasoningPart chunks correctly in both modes.

Multimodal Input Capabilities

The plugin supports multimodal models (like llava) for image analysis.

go
// Define a multimodal model
o.DefineModel(g, ollama.ModelDefinition{
 Name: "llava",
 Type: "chat",
}, nil)

m := ollama.Model(g, "llava")

// Using inline data (base64)
imagePart := ai.NewMediaPart("image/jpeg", "data:image/jpeg;base64,...")

resp, err := genkit.Generate(ctx, g,
 ai.WithModel(m),
 ai.WithMessages(
  ai.NewUserMessage(
   ai.NewTextPart("Describe this image"),
   imagePart,
  ),
 ),
)

Embedding Models

You can define and use text embedding models hosted on Ollama (e.g., nomic-embed-text).
dimensions is required and should match the model's embedding size. The embedder is
retrieved by model name.

Note: Existing callers should replace server-address lookups with model-name lookups and pass dimensions to DefineEmbedder

Defining an Embedder

go
// Define an embedder model
o.DefineEmbedder(g, "nomic-embed-text", 768, nil)

embedder := ollama.Embedder(g, "nomic-embed-text")

Usage

go
res, err := genkit.Embed(ctx, g,
 ai.WithEmbedder(embedder),
 ai.WithTextDocs("Machine learning models process data to make predictions."),
)
if err != nil {
 log.Fatal(err)
}

fmt.Printf("Embedding length: %d\n", len(res.Embeddings[0].Embedding))

File: go/plugins/mcp/README.md

Genkit MCP Plugin

Model Context Protocol (MCP) integration for Go Genkit

Connect to MCP servers and expose Genkit tools as MCP servers.

GenkitMCPClient - Single Server Connection

Connect to and use tools/prompts from a single MCP server:

go
package main

import (
  "context"
  "log"

  "github.com/firebase/genkit/go/genkit"
  "github.com/firebase/genkit/go/plugins/mcp"
)

func main() {
  ctx := context.Background()
  g := genkit.Init(ctx)

  // Connect to the MCP everything server
  client, err := mcp.NewGenkitMCPClient(mcp.MCPClientOptions{
    Name: "everything-server",
    Stdio: &mcp.StdioConfig{
      Command: "npx",
      Args:    []string{"-y", "@modelcontextprotocol/server-everything"},
    },
  })
  if err != nil {
    log.Fatal(err)
  }

  // Get specific prompts from the everything server
  simplePrompt, err := client.GetPrompt(ctx, g, "simple-prompt", nil)
  if err != nil {
    log.Fatal(err)
  }

  // Get all available tools
  tools, err := client.GetActiveTools(ctx, g)
  if err != nil {
    log.Fatal(err)
  }
}

GenkitMCPManager - Multiple Server Management

Manage connections to multiple MCP servers:

go
package main

import (
    "context"
    "log"

    "github.com/firebase/genkit/go/genkit"
    "github.com/firebase/genkit/go/plugins/mcp"
)

func main() {
    ctx := context.Background()
    g, _ := genkit.Init(ctx)

    // Create manager with multiple servers
    manager, err := mcp.NewMCPManager(mcp.MCPManagerOptions{
        Name: "my-app",
        MCPServers: map[string]mcp.MCPClientOptions{
            "everything": {
                Name: "everything-server",
                Stdio: &mcp.StdioConfig{
                    Command: "npx",
                    Args: []string{"-y", "@modelcontextprotocol/server-everything"},
                },
            },
            "filesystem": {
                Name: "fs-server",
                Stdio: &mcp.StdioConfig{
                    Command: "npx",
                    Args: []string{"@modelcontextprotocol/server-filesystem", "/tmp"},
                },
            },
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    // Connect to new server at runtime
    err = manager.ConnectServer(ctx, "weather", mcp.MCPClientOptions{
        Name: "weather-server",
        Stdio: &mcp.StdioConfig{
            Command: "python",
            Args: []string{"weather_server.py"},
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    // Temporarily disable/enable servers
    manager.DisableServer("filesystem")
    manager.EnableServer("filesystem")

    // Disconnect server
    manager.DisconnectServer("weather")

    // Get tools from all active servers
    tools, err := manager.GetActiveTools(ctx, g)
    if err != nil {
        log.Fatal(err)
    }
}

GenkitMCPServer - Expose Genkit Tools

Turn your Genkit app into an MCP server:

go
package main

import (
  "context"
  "log"

  "github.com/firebase/genkit/go/genkit"
  "github.com/firebase/genkit/go/plugins/mcp"
)

func main() {
  ctx := context.Background()
  g := genkit.Init(ctx)

  // Create a host with multiple servers
  host, err := mcp.NewMCPHost(g, mcp.MCPHostOptions{
    Name: "my-app",
    MCPServers: []mcp.MCPServerConfig{
      {
        Name: "everything-server",
        Config: mcp.MCPClientOptions{
          Name: "everything-server",
          Stdio: &mcp.StdioConfig{
            Command: "npx",
            Args:    []string{"-y", "@modelcontextprotocol/server-everything"},
          },
        },
      },
      {
        Name: "fs-server",
        Config: mcp.MCPClientOptions{
          Name: "fs-server",
          Stdio: &mcp.StdioConfig{
            Command: "npx",
            Args:    []string{"@modelcontextprotocol/server-filesystem", "/tmp"},
          },
        },
      },
    },
  })
  if err != nil {
    log.Fatal(err)
  }

  // Connect to new server at runtime
  err = host.Connect(ctx, g, "weather", mcp.MCPClientOptions{
    Name: "weather-server",
    Stdio: &mcp.StdioConfig{
      Command: "python",
      Args:    []string{"weather_server.py"},
    },
  })
  if err != nil {
    log.Fatal(err)
  }

  // Reconnect server
  host.Reconnect(ctx, "fs-server")

  // Disconnect server
  host.Disconnect(ctx, "weather")

  // Get tools from all active servers
  tools, err := host.GetActiveTools(ctx, g)
  if err != nil {
    log.Fatal(err)
  }
}

Testing Your Server

bash
# Run your server
go run main.go

# Test with MCP Inspector
npx @modelcontextprotocol/inspector go run main.go

Transport Options

Stdio (Standard)

go
Stdio: &mcp.StdioConfig{
    Command: "uvx",
    Args: []string{"mcp-server-time"},
    Env: []string{"DEBUG=1"},
}

SSE (Web clients)

go
SSE: &mcp.SSEConfig{
    BaseURL: "http://localhost:3000/sse",
}