Skip to the page

Genkit

Connect Genkit's MCP plugin to SpecStream and a Genkit flow or agent can search the live web, read pages and return structured rows. It is one url entry in JavaScript and one StreamableHTTP config in Go, with your API key as a header.

SpecStream for GenkitAgent frameworks & builders

What you need

  • A Genkit app in JavaScript (Node.js) or Go, with a model plugin that supports tool calls.
  • A SpecStream account and an API key. New accounts start with $10 of credit, no card. Create one.
  1. 1. Create a SpecStream API key

    Open Agents & API in the workspace, go to API keys and select Create API key. Give it the access the app needs and a spending limit, then set it as SPECSTREAM_API_KEY where the app runs.

  2. 2. Install the MCP plugin

    In JavaScript, the plugin is @genkit-ai/mcp. Install it with Genkit and your model plugin:

    Terminal
    npm i genkit @genkit-ai/mcp @genkit-ai/google-genai
  3. 3. Add SpecStream to createMcpHost

    SpecStream is a remote server over Streamable HTTP, so its entry takes url in place of command. The plugin passes the other transport options through, and requestInit carries the key as a Bearer header. Then hand the tools to generate:

    index.ts
    import { googleAI } from '@genkit-ai/google-genai';
    import { createMcpHost } from '@genkit-ai/mcp';
    import { genkit } from 'genkit';
    const mcpHost = createMcpHost({
    name: 'webData',
    mcpServers: {
    // The key becomes the namespace: specstream/search_web, specstream/read_pages, ...
    specstream: {
    url: 'https://api.specstream.ai/mcp',
    requestInit: {
    headers: { Authorization: `Bearer ${process.env.SPECSTREAM_API_KEY}` },
    },
    },
    },
    });
    const ai = genkit({ plugins: [googleAI()] });
    (async () => {
    const { text } = await ai.generate({
    model: googleAI.model('gemini-flash-latest'),
    prompt: 'Find the latest stable Node.js release, read its release notes and list three changes.',
    tools: await mcpHost.getActiveTools(ai),
    });
    console.log(text);
    await mcpHost.close();
    })();
  4. 4. Or connect from Go

    The Go plugin is github.com/firebase/genkit/go/plugins/mcp. StreamableHTTPConfig takes BaseURL and Headers, and GetActiveTools returns the tools for ai.WithTools:

    main.go
    package main
    import (
    "context"
    "fmt"
    "log"
    "os"
    "github.com/firebase/genkit/go/ai"
    "github.com/firebase/genkit/go/genkit"
    "github.com/firebase/genkit/go/plugins/googlegenai"
    "github.com/firebase/genkit/go/plugins/mcp"
    )
    func main() {
    ctx := context.Background()
    g := genkit.Init(ctx, genkit.WithPlugins(&googlegenai.GoogleAI{}))
    client, err := mcp.NewGenkitMCPClient(mcp.MCPClientOptions{
    Name: "specstream",
    StreamableHTTP: &mcp.StreamableHTTPConfig{
    BaseURL: "https://api.specstream.ai/mcp",
    Headers: map[string]string{"Authorization": "Bearer " + os.Getenv("SPECSTREAM_API_KEY")},
    },
    })
    if err != nil {
    log.Fatal(err)
    }
    tools, err := client.GetActiveTools(ctx, g)
    if err != nil {
    log.Fatal(err)
    }
    refs := make([]ai.ToolRef, len(tools))
    for i, t := range tools {
    refs[i] = t
    }
    resp, err := genkit.Generate(ctx, g,
    ai.WithModelName("googleai/gemini-flash-latest"),
    ai.WithPrompt("Find the latest stable Go release, read its release notes and list three changes."),
    ai.WithTools(refs...),
    )
    if err != nil {
    log.Fatal(err)
    }
    fmt.Println(resp.Text())
    }
  5. 5. Run it

    The model can call specstream/search_web to find the page and specstream/read_pages to read it, then answer from what it read. With createMcpHost every tool is named after the key you gave the server, so a second server never collides with SpecStream.

The tools Genkit gets

getActiveTools turns each SpecStream tool into a Genkit tool. The ones an app uses most:

  • search_web answers a question from the live web, with the results and their pages. Each search is one Search API call at $5 per 1,000 searches of up to 10 results.
  • read_pages returns the main text of up to 20 web pages or documents (PDF, Word, Excel) in one call. Each page read is one Extract API page at $0.80 per 1,000 pages, and a page with no text is not charged.
  • compile, quote_capacity_work and authorize_capacity_work turn a request for many records into a quoted Deep Search run. get_find follows it, and list_find_rows reads the rows, with a source URL and read time on every value.

Tool replies

The plugin parses a tool reply that is valid JSON text into an object before the model sees it, and passes other text through as it is. Set rawToolResponses: true on the host to get the MCP content array as it came.

Spending

Searches and page reads take their price from your balance as they run. A Deep Search run starts only after the most it can cost is approved and sent as confirm_max_cents, and it never charges past that amount. A key with read or prepare access can price a request but cannot start one, so an app that only searches and reads should get that access. A key with execute access can start runs, up to the spending limit you set on it. See how quotes and billing work.

Close the connection

Call mcpHost.close() in JavaScript when the app shuts down. A server entry with disabled: true stays in the config without connecting. Revoke the key in Agents & API to cut access. Questions: [email protected].

More

SpecStream for Genkit covers what it does in Genkit on one page. Every other tool has its guide in Connect your tools. You see the most a request can cost before it starts, and the matches are paid from your balance. Billing has the details. For help, email [email protected].