> ## Documentation Index
> Fetch the complete documentation index at: https://www.algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Add Algolia to your app with DevEx MCP

> Generate Algolia API client code that matches the version in your project, using DevEx MCP and a coding agent.

DevEx MCP is a remote MCP server for coding agents.
It returns Algolia API client snippets that match the client version installed in your project, so the agent uses methods and parameters that exist in that release.

You connect it once, then ask the agent to add Algolia to your app.
The agent fetches the snippet for each operation it needs, such as setting up the client, saving records, or searching an index, and adapts it to your code, your index name, and your credentials.
Each snippet arrives with the matching import and client initialization, so the agent has everything it needs to write a working call.

Under the hood, DevEx MCP exposes two tools.
The agent calls `algolia_snippets_list_operations` to find the operation for a task, then calls `algolia_snippets_get_snippet` with the language and client version to fetch the code.
Snippets cover all Algolia APIs, including Search, Analytics, Recommend, Insights, and Ingestion, in every API client language.

DevEx MCP doesn't require you to sign in, and it doesn't access data in your Algolia applications.
To search or analyze your indices from an AI assistant, pick a server in the [MCP overview](/doc/guides/model-context-protocol).

The examples on this page use JavaScript API client v5, Python API client v4, and Go API client v4.
If your project pins another version, name it in the prompt so the agent fetches the matching snippet.

## Before you begin

To use DevEx MCP, make sure you have:

* An Algolia account with an [Application ID](https://dashboard.algolia.com/account/api-keys) and API keys.
* A coding agent that supports remote MCP, such as Claude Code, Cursor, VS Code, Gemini CLI, ChatGPT, or Claude.
* A project where you want to add search, indexing, or both.

## Connect from your MCP client

Add DevEx MCP as a remote HTTP server.
You don't sign in, and you don't need an OAuth client ID or secret.

<Tabs>
  <Tab title="Claude Code">
    ```sh icon=square-terminal theme={"system"}
    claude mcp add --transport http algolia-devex https://mcp.algolia.com/1/snippets/mcp
    ```
  </Tab>

  <Tab title="Cursor">
    [**Add DevEx MCP to Cursor**](cursor://anysphere.cursor-deeplink/mcp/install?name=algolia-devex\&config=eyJ1cmwiOiJodHRwczovL21jcC5hbGdvbGlhLmNvbS8xL3NuaXBwZXRzL21jcCJ9) (requires Cursor 1.0+).

    Or add this to `.cursor/mcp.json` in your project, or to `~/.cursor/mcp.json` for a global setup:

    ```json .cursor/mcp.json icon=braces theme={"system"}
    {
      "mcpServers": {
        "algolia-devex": {
          "url": "https://mcp.algolia.com/1/snippets/mcp"
        }
      }
    }
    ```
  </Tab>

  <Tab title="VS Code">
    Add this to `~/.vscode/mcp.json` (macOS, Linux) or `%USERPROFILE%\.vscode\mcp.json` (Windows):

    ```json ~/.vscode/mcp.json icon=braces theme={"system"}
    {
      "servers": {
        "algolia-devex": {
          "type": "http",
          "url": "https://mcp.algolia.com/1/snippets/mcp"
        }
      }
    }
    ```
  </Tab>

  <Tab title="Gemini CLI">
    ```sh icon=square-terminal theme={"system"}
    gemini mcp add algolia-devex https://mcp.algolia.com/1/snippets/mcp -s user -t http
    ```
  </Tab>

  <Tab title="ChatGPT">
    In [Connectors settings](https://chatgpt.com/#settings/Connectors), create a connector with:

    * **Server URL:** `https://mcp.algolia.com/1/snippets/mcp`
    * **Authentication:** none.
  </Tab>

  <Tab title="Claude AI & Desktop">
    In [Connectors settings](https://claude.ai/new#settings/customize-connectors), add a custom connector with:

    * **Remote MCP server URL:** `https://mcp.algolia.com/1/snippets/mcp`
    * **Authentication:** none.
  </Tab>
</Tabs>

For more about connecting AI assistants to Algolia, see [Build with AI agents](/doc/guides/get-started/build-with-ai).

## Add Algolia to your app

Connect DevEx MCP, then tell the agent the language, the client version, and where credentials live.
If you skip the version, agents often use `initIndex`, which the JavaScript API client removed in v5.

```txt Prompt theme={"system"}
Add Algolia search to this app.

1. Read the algoliasearch version from the package manifest. If the package isn't installed, install JavaScript API client v5.
2. Use DevEx MCP for every Algolia client method.
3. Load ALGOLIA_APPLICATION_ID, ALGOLIA_WRITE_API_KEY, and ALGOLIA_SEARCH_API_KEY from the environment.
4. Update index settings before saving records.
5. Save records with saveObjects and wait until indexing finishes.
6. Add a server-side search with searchSingleIndex and the Search API key.
7. Keep the Write API key off the client.
```

Once connected, you can also ask for a single operation.
Name the language and the client version:

* *"Show how to save records with the JavaScript API client v5."*
* *"Get a Python v4 snippet for searching an index with filters."*
* *"Return a Go v4 snippet for `setSettings` with searchable attributes and custom ranking."*
* *"Create a search-only API key with the C# API client."*

Replace placeholder values such as `indexName` with your index name, and swap demo records for your schema.

### Store credentials

Create an environment file for local development.
Use a **Write API key** for indexing and settings.
Use a **Search API key** in the browser or any other client you don't control.

```dotenv .env.local icon=lock-keyhole theme={"system"}
ALGOLIA_APPLICATION_ID=
ALGOLIA_WRITE_API_KEY=
ALGOLIA_SEARCH_API_KEY=
```

<Warning>
  Don't commit `.env.local`, paste API keys into the prompt, or ship a Write API key or Admin API key in frontend code.
</Warning>

## Initialize the API client

For example: *"Initialize the Algolia API client in this language, matching the installed version."*

<CodeGroup>
  ```js JavaScript theme={"system"}
  import { algoliasearch } from "algoliasearch";

  const appID = process.env.ALGOLIA_APPLICATION_ID;
  const apiKey = process.env.ALGOLIA_WRITE_API_KEY;

  if (!appID || !apiKey) {
    throw new Error("Missing ALGOLIA_APPLICATION_ID or ALGOLIA_WRITE_API_KEY.");
  }

  const client = algoliasearch(appID, apiKey);
  ```

  ```python Python theme={"system"}
  import os
  from algoliasearch.search.client import SearchClientSync

  app_id = os.environ["ALGOLIA_APPLICATION_ID"]
  api_key = os.environ["ALGOLIA_WRITE_API_KEY"]
  client = SearchClientSync(app_id, api_key)
  ```

  ```go Go theme={"system"}
  package main

  import (
    "os"

    "github.com/algolia/algoliasearch-client-go/v4/algolia/search"
  )

  func main() {
    appID := os.Getenv("ALGOLIA_APPLICATION_ID")
    apiKey := os.Getenv("ALGOLIA_WRITE_API_KEY")

    client, err := search.NewClient(appID, apiKey)
    if err != nil {
      panic(err)
    }
    _ = client
  }
  ```
</CodeGroup>

For Python, `SearchClientSync` is the synchronous client.
In an asynchronous context, use `SearchClient` instead. It exposes the same methods, awaited.

For a search-only JavaScript bundle, import `liteClient` from `algoliasearch/lite` and alias it as `algoliasearch`.
The lite client can search, but it can't index records or change settings.

```js JavaScript icon=code theme={"system"}
import { liteClient as algoliasearch } from "algoliasearch/lite";
```

## Update index settings

For example: *"Set searchable attributes, facets, and custom ranking on INDEX\_NAME with `setSettings`."*

Update settings before the first `saveObjects` call.
Changing searchable attributes later reindexes existing records.

<CodeGroup>
  ```js JavaScript expandable theme={"system"}
  const indexName = "INDEX_NAME";

  const { taskID } = await client.setSettings({
    indexName,
    indexSettings: {
      searchableAttributes: ["name", "description", "brand"],
      attributesForFaceting: [
        "searchable(brand)",
        "category",
        "filterOnly(in_stock)",
      ],
      customRanking: ["desc(popularity)"],
    },
  });

  await client.waitForTask({ indexName, taskID });
  ```

  ```python Python expandable theme={"system"}
  index_name = "INDEX_NAME"

  response = client.set_settings(
      index_name=index_name,
      index_settings={
          "searchableAttributes": ["name", "description", "brand"],
          "attributesForFaceting": [
              "searchable(brand)",
              "category",
              "filterOnly(in_stock)",
          ],
          "customRanking": ["desc(popularity)"],
      },
  )

  client.wait_for_task(index_name=index_name, task_id=response.task_id)
  ```

  ```go Go expandable theme={"system"}
  indexName := "INDEX_NAME"

  response, err := client.SetSettings(client.NewApiSetSettingsRequest(
    indexName,
    search.NewEmptyIndexSettings().
      SetSearchableAttributes(
        []string{"name", "description", "brand"}).
      SetAttributesForFaceting(
        []string{"searchable(brand)", "category", "filterOnly(in_stock)"}).
      SetCustomRanking(
        []string{"desc(popularity)"}),
  ))
  if err != nil {
    panic(err)
  }

  _, err = client.WaitForTask(indexName, response.TaskID)
  if err != nil {
    panic(err)
  }
  ```
</CodeGroup>

For the full settings object, see [Update index settings](/doc/libraries/sdk/methods/search/set-settings).

## Save records

For example: *"Save these product records to INDEX\_NAME with `saveObjects` and wait for the task."*

`saveObjects` batches writes for you.
Pass `waitForTasks: true` so you don't search before indexing finishes.

<CodeGroup>
  ```js JavaScript expandable theme={"system"}
  const records = [
    {
      objectID: "prod-42",
      name: "Trail Running Shoes",
      brand: "Salomon",
      category: "Footwear",
      description: "Waterproof trail shoes with a sticky outsole.",
      price: 129.99,
      in_stock: true,
      popularity: 87,
    },
  ];

  await client.saveObjects({
    indexName: "INDEX_NAME",
    objects: records,
    waitForTasks: true,
  });
  ```

  ```python Python expandable theme={"system"}
  records = [
      {
          "objectID": "prod-42",
          "name": "Trail Running Shoes",
          "brand": "Salomon",
          "category": "Footwear",
          "description": "Waterproof trail shoes with a sticky outsole.",
          "price": 129.99,
          "in_stock": True,
          "popularity": 87,
      },
  ]

  client.save_objects(
      index_name="INDEX_NAME",
      objects=records,
      wait_for_tasks=True,
  )
  ```

  ```go Go expandable theme={"system"}
  records := []map[string]any{
    {
      "objectID":     "prod-42",
      "name":         "Trail Running Shoes",
      "brand":        "Salomon",
      "category":     "Footwear",
      "description":  "Waterproof trail shoes with a sticky outsole.",
      "price":        129.99,
      "in_stock":     true,
      "popularity":   87,
    },
  }

  _, err := client.SaveObjects(
    "INDEX_NAME",
    records,
    search.WithWaitForTasks(true),
  )
  if err != nil {
    panic(err)
  }
  ```
</CodeGroup>

Every record needs an `objectID`.
Reuse the same `objectID` to update a record in place.

For bulk imports, keep `saveObjects` instead of writing your own batch loop, unless you need a custom batch size.
See [Save records](/doc/libraries/sdk/methods/search/save-objects).

## Search an index

For example: *"Search INDEX\_NAME for trail shoes that are in stock, using searchSingleIndex."*

Use a client initialized with `ALGOLIA_SEARCH_API_KEY` for this call.

<CodeGroup>
  ```js JavaScript theme={"system"}
  const response = await client.searchSingleIndex({
    indexName: "INDEX_NAME",
    searchParams: {
      query: "trail shoes",
      filters: "in_stock:true",
      hitsPerPage: 20,
    },
  });

  console.log(response.hits);
  ```

  ```python Python theme={"system"}
  response = client.search_single_index(
      index_name="INDEX_NAME",
      search_params={
          "query": "trail shoes",
          "filters": "in_stock:true",
          "hitsPerPage": 20,
      },
  )

  print(response.hits)
  ```

  ```go Go theme={"system"}
  response, err := client.SearchSingleIndex(client.NewApiSearchSingleIndexRequest(
    "INDEX_NAME").WithSearchParams(search.SearchParamsObjectAsSearchParams(
    search.NewEmptySearchParamsObject().
      SetQuery("trail shoes").
      SetFilters("in_stock:true").
      SetHitsPerPage(20))))
  if err != nil {
    panic(err)
  }

  print(response)
  ```
</CodeGroup>

`filters` only works on attributes listed in `attributesForFaceting`.
If a filter doesn't return any hits, check that setting first.

For one request across several indices, use [`search`](/doc/libraries/sdk/methods/search/search) instead of `searchSingleIndex`.

## Restrict API keys

For example: *"Create a search-only API key restricted to INDEX\_NAME."*

Creating keys requires an [Admin API key](/doc/guides/security/api-keys).
Run this on a server.

<CodeGroup>
  ```js JavaScript theme={"system"}
  const response = await client.addApiKey({
    acl: ["search"],
    description: "Search-only key for INDEX_NAME",
    indexes: ["INDEX_NAME"],
  });

  console.log(response.key);
  ```

  ```python Python theme={"system"}
  response = client.add_api_key(
      api_key={
          "acl": ["search"],
          "description": "Search-only key for INDEX_NAME",
          "indexes": ["INDEX_NAME"],
      },
  )

  print(response.key)
  ```

  ```go Go theme={"system"}
  response, err := client.AddApiKey(client.NewApiAddApiKeyRequest(
    search.NewEmptyApiKey().
      SetAcl([]search.Acl{search.Acl("search")}).
      SetDescription("Search-only key for INDEX_NAME").
      SetIndexes([]string{"INDEX_NAME"})))
  if err != nil {
    panic(err)
  }

  print(response)
  ```
</CodeGroup>

To scope a key per user without another Algolia API call, generate a [secured API key](/doc/libraries/sdk/methods/search/generate-secured-api-key) on your server from a Search API key.

For example: *"Generate a secured API key that can only query INDEX\_NAME and expires in one hour."*

```js JavaScript icon=code theme={"system"}
const securedApiKey = client.generateSecuredApiKey({
  parentApiKey: process.env.ALGOLIA_SEARCH_API_KEY,
  restrictions: {
    restrictIndices: ["INDEX_NAME"],
    validUntil: Math.round(Date.now() / 1000) + 3600,
  },
});
```

Don't use an Admin API key as the parent.

## Other Algolia tools

DevEx MCP writes API client calls.
It doesn't generate InstantSearch widgets, and it doesn't query analytics on your account.

| Need                                                           | Use                                                                                                                                                     |
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Search UI with autocomplete, hits, and facets                  | [`instantsearch` skill](https://github.com/algolia/skills/tree/main/skills/instantsearch) or the [React quickstart](/doc/guides/get-started/quickstart) |
| Create an account, index, or settings from a terminal          | [Algolia CLI](/doc/tools/cli/get-started)                                                                                                               |
| Upgrade an existing API client across a breaking major version | [`algolia-migration` skill](https://github.com/algolia/skills/tree/main/skills/algolia-migration)                                                       |
| Inspect live searches and no-results queries                   | [Productivity MCP](/doc/guides/model-context-protocol/productivity-mcp)                                                                                 |

## Guidelines

* **Name the version**. Point the agent at `package.json`, `pyproject.toml`, `go.mod`, or the lock file.
* **Treat snippets as starting code**. OpenAPI samples often use placeholder names and demo records. Replace them with yours.
* **Keep write operations on the server**. Search API keys belong in the frontend. Write and Admin API keys don't.
* **Wait for indexing tasks**. Don't search records you just saved until the task finishes.
* **Read the diff**. If a method doesn't exist on the installed client, reject it and ask the agent to fetch the snippet again.

## See also

* [Install the API clients](/doc/libraries/sdk/install)
* [`algolia-migration` skill](https://github.com/algolia/skills/tree/main/skills/algolia-migration) for upgrading an API client across a major version
