---
title: "TypeScript SDK for Grafana plugins | Grafana Cloud documentation"
description: "Use the @grafana/assistant package to integrate AI assistance into your Grafana plugins and apps."
---

> For a curated documentation index, see [llms.txt](/llms.txt). For the complete documentation index, see [llms-full.txt](/llms-full.txt).

# TypeScript SDK for Grafana plugins

The `@grafana/assistant` package provides a lightweight TypeScript SDK for integrating Grafana Assistant into your Grafana plugins and applications.

## What you’ll achieve

This article helps you integrate the Assistant into your plugin UI in a few targeted ways:

- Check availability: Detect whether the Assistant is available before rendering UI.
- Open the Assistant: Trigger the Assistant with prompts and context.
- Use React hooks: Work with Assistant state and actions in components.
- Use UI components: Add prebuilt buttons and prompt cards that open the Assistant.
- Generate inline content: Add AI-powered text inputs and text areas to forms.
- Register page context: Provide dashboard, data source, or structured context.
- Update context dynamically: Adjust context in response to user actions.

## Before you begin

Make sure you have the following:

- A Grafana deployment with the Grafana Assistant app installed and enabled. This can be a Grafana Cloud stack or a self-managed Grafana instance connected to a Grafana Cloud Assistant backend.
- An existing Grafana plugin or app project to integrate with.
- Node.js 22 and npm installed locally.
- Access to install the `@grafana/assistant` package from npm.

## When to use the TypeScript SDK

Use the TypeScript SDK when:

- Building Grafana plugins or extensions
- Adding AI assistance to custom Grafana apps
- Integrating Assistant features into Grafana UI workflows
- Creating context-aware help experiences based on page location

## Install the SDK

Install the package from npm:

Bash ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```bash
npm install @grafana/assistant
```

The package contains TypeScript type definitions, helper functions, hooks, and UI components for Grafana plugin code.

## Key capabilities

Use these capabilities to integrate Assistant entry points and context into your plugin:

### Check availability

Detect if the Assistant is available in the current environment before showing UI elements:

typescript ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```typescript
import { isAssistantAvailable } from '@grafana/assistant';
import { firstValueFrom } from 'rxjs';

async function checkAvailability() {
  const available = await firstValueFrom(isAssistantAvailable());
  console.log('Assistant available:', available);
}
```

### Open the Assistant programmatically

Open the Assistant with custom prompts and context from your code:

typescript ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```typescript
import { openAssistant } from '@grafana/assistant';

openAssistant({
  origin: 'grafana/my-plugin',
  prompt: 'Show me CPU usage over the last hour',
  autoSend: true,
});
```

**Parameters:**

- `origin` (required): Namespace identifying your plugin (e.g., `grafana/my-plugin/feature`)
- `prompt` (optional): Pre-filled prompt text
- `autoSend` (optional): Automatically send the prompt when opening
- `context` (optional): Additional context items (dashboards, datasources, structured data)

### Use React hooks

Use the `useAssistant()` hook for reactive integration in React components:

typescript ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```typescript
import { useAssistant } from '@grafana/assistant';

export function MyComponent() {
  const { isLoading, isAvailable, openAssistant, closeAssistant } = useAssistant();

  if (isLoading || !isAvailable) {
    return null;
  }

  return (
    <button onClick={() => openAssistant?.({
      origin: 'grafana/my-plugin',
      prompt: 'Help me analyze this data'
    })}>
      Ask Assistant
    </button>
  );
}
```

### Use UI components

Use the `OpenAssistantButton` component for drop-in integration:

typescript ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```typescript
import { OpenAssistantButton } from '@grafana/assistant';

export function MyComponent() {
  return (
    <OpenAssistantButton
      prompt="Analyze this dashboard"
      origin="grafana/my-plugin/dashboard"
    />
  );
}
```

The button automatically hides when the Assistant is unavailable.

#### Add query-editor assistance

Use `QueryWithAssistantButton` in data source query editors. The component passes the selected data source, current query, and other non-empty queries to Assistant:

typescript ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```typescript
import { CoreApp } from '@grafana/data';
import { QueryWithAssistantButton } from '@grafana/assistant';

export function QueryEditorActions() {
  return (
    <QueryWithAssistantButton
      currentQuery={query}
      queries={queries}
      dataSourceInstanceSettings={dataSourceInstanceSettings}
      datasourceApi={datasourceApi}
      app={CoreApp.Explore}
      title="Query with Assistant"
    />
  );
}
```

The component opens Assistant with a prompt to create or update a query and automatically hides when Assistant is unavailable.

#### Add a prompt card

Use `AssistantPromptCard` to embed an Assistant prompt entry point in a plugin surface:

typescript ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```typescript
import { AssistantPromptCard, createAssistantContextItem } from '@grafana/assistant';

const context = [
  createAssistantContextItem('dashboard', {
    dashboardUid: 'abc123',
    dashboardTitle: 'Service health',
  }),
];

export function AssistantEntryPoint() {
  return (
    <AssistantPromptCard
      origin="grafana/my-plugin/dashboard"
      context={context}
      mode="dashboarding"
      placeholder="Ask Assistant about this dashboard"
      examplePrompts={[
        'Find panels with high error rates',
        'Suggest dashboard improvements',
      ]}
    />
  );
}
```

The prompt card opens Assistant with the user’s typed prompt and provided context. It renders nothing when Assistant is unavailable.

#### Generate inline form content

Use `AITextInput` and `AITextArea` when you want Assistant to generate content inside an existing form instead of opening the Assistant sidebar. These components are controlled inputs and call your `onChange` handler as generated text is applied.

typescript ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```typescript
import { AITextInput, AITextArea } from '@grafana/assistant';
import { useState } from 'react';

export function PanelMetadataEditor() {
  const [title, setTitle] = useState('');
  const [description, setDescription] = useState('');

  return (
    <>
      <AITextInput
        value={title}
        onChange={setTitle}
        origin="grafana/my-plugin/panel-title"
        systemPrompt="Generate a concise panel title. Return only the title text."
        placeholder="Ask AI to generate a title"
        autoGenerate
        streaming
      />
      <AITextArea
        value={description}
        onChange={setDescription}
        origin="grafana/my-plugin/panel-description"
        systemPrompt="Generate a clear panel description in 2 sentences."
        getUserPrompt={(text) => `Write a panel description using this context: ${text}`}
        rows={4}
        streaming
      />
    </>
  );
}
```

Use `autoGenerate` to generate once on mount when the value is empty, `streaming` to stream generated text into the input, and `getUserPrompt` to transform the user’s input into the prompt sent to Assistant.

### Register page context

Automatically provide context to the Assistant based on the current URL:

typescript ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```typescript
import { providePageContext, createAssistantContextItem } from '@grafana/assistant';

// Register context for dashboard pages
const dashboardContext = createAssistantContextItem('structured', {
  data: {
    name: 'Dashboard Context',
    pageType: 'dashboard',
    capabilities: ['analyze', 'troubleshoot', 'optimize'],
    help: 'I can help you analyze dashboard data and optimize performance.',
  },
});

// Register for all dashboard URLs
providePageContext('/d/*', [dashboardContext]);
```

**URL pattern matching:**

- Wildcards: `/d/*` matches `/d/abc`
- Glob patterns: `/explore**` matches `/explore` and all subpaths
- Regex: `/^\/datasources\/edit\/[^\/]+$/` for complex patterns

### Update context dynamically

Update context as users interact with your application:

typescript ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```typescript
const setContext = providePageContext('/d/*', [dashboardContext]);

// Update when user selects a panel
function onPanelSelect(panelId: string, panelTitle: string) {
  const panelContext = createAssistantContextItem('structured', {
    data: {
      name: 'Selected Panel',
      panelId,
      panelTitle,
      actions: ['edit', 'duplicate', 'inspect'],
    },
  });

  setContext([dashboardContext, panelContext]);
}
```

## Choose context item types

Use context items to provide relevant information to the Assistant. The SDK supports three context types:

### Dashboard context

Provide the current dashboard to give the Assistant page awareness:

typescript ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```typescript
createAssistantContextItem('dashboard', {
  dashboardUid: 'abc123',
  dashboardTitle: 'My Dashboard',
});
```

### Data source context

Provide the active data source to scope Assistant suggestions:

typescript ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```typescript
createAssistantContextItem('datasource', {
  datasourceUid: 'prom-123',
});
```

### Structured data context

Provide arbitrary JSON to describe custom state or metadata:

typescript ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```typescript
createAssistantContextItem('structured', {
  data: {
    // Any JSON-serializable data
    name: 'Custom Context',
    metadata: { ... }
  }
})
```

All context item helpers accept `bypassLimits`. Use `bypassLimits: true` only for fixed-size static content such as bounded metadata, static instructions, or small configuration objects. Keep the default for query results, logs, user-generated content, or any content that can grow unexpectedly.

## Try interactive examples

Explore interactive, working examples in Grafana Assistant:

1. Open **Grafana Assistant** from the main navigation
2. Click **Integration hub**
3. Explore the TypeScript SDK section with:
   
   - Live code examples you can modify and test
   - Complete working samples for each API
   - Copy-to-clipboard code snippets
   - Interactive forms to try different parameters

## Next steps

Continue by exploring these resources:

- Open **Grafana Assistant** and click **Integration hub** to try interactive SDK examples
- View the [package on npm](https://www.npmjs.com/package/@grafana/assistant)
- Learn about [Grafana plugin development](/docs/grafana/latest/developers/plugins/)
