> For the complete documentation index, see [llms.txt](https://docs.tabnine.com/main/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tabnine.com/main/getting-started/tabnine-plugin-for-opencode/migrating-from-tabnine-cli.md).

# Migrating from Tabnine CLI

If you were using **Tabnine CLI** (the Gemini-CLI-based coding agent that Tabnine shipped before) and want to bring your configuration into `tabnine`, use the migration helper. It reads your Tabnine CLI configuration and installs the equivalent settings into opencode, one category at a time, without changing your Tabnine CLI files.

This guide covers:

* What the migration helper is and what it moves
* Installing the helper
* Running the migration and approving each write
* What is left behind on purpose
* Migrating your context files (`TABNINE.md`)

{% hint style="info" %}
**Coming from something else?** The migration helper is only for Tabnine CLI. If you were using upstream Gemini CLI or another agent, follow [Install](/main/getting-started/tabnine-plugin-for-opencode/install.md) and configure `tabnine` from scratch.
{% endhint %}

## What the migration helper is

The migration helper is a pair of interactive skills that run **inside `tabnine` itself**. Once installed, you launch them with `/migrate` and `/migrate-context`. Each wizard scans your Tabnine CLI configuration, shows you what it found, prints exactly what it intends to write, and waits for your approval before touching anything.

Nothing is deleted from your Tabnine CLI installation. If you want to keep using Tabnine CLI in parallel while you evaluate `tabnine`, you can.

The helper is distributed as an open-source repository, separately from the plugin, so you can inspect it before installing:

* Repository: [github.com/codota/tabnine-opencode-public](https://github.com/codota/tabnine-opencode-public)

## What gets migrated

`/migrate` covers five categories:

* **MCP servers** from your Tabnine CLI `settings.json`, translated into `opencode.json`'s `mcp` object.
* **Skills** from `~/.tabnine/agent/skills/`, copied into opencode's skills directory.
* **Agents** (local subagents) from `~/.tabnine/agent/agents/`, translated into opencode agent files. Tool-restricted agents keep their restrictions.
* **Slash commands** from `~/.tabnine/agent/commands/`, translated from TOML to opencode's markdown format.
* **Extension contents** — the MCP servers, skills, agents, and commands bundled inside a Tabnine CLI extension. The extension manifest itself is not migrated (opencode has no equivalent), but its contents are.

`/migrate-context` handles your **context files** separately: `TABNINE.md` files at the repository root, in ancestor directories, and in subdirectories are copied into opencode's `AGENTS.md` format.

## What is left behind on purpose

A few things do not migrate, and shouldn't:

* **Your Tabnine sign-in.** `tabnine` uses its own credential storage, so a Tabnine CLI sign-in cannot be reused. Sign in to `tabnine` the way you would on a fresh install. See [Sign-in and Models](/main/getting-started/tabnine-plugin-for-opencode/sign-in-and-models.md).
* **The built-in Tabnine MCP servers** (`tabnine-context`, `tabnine-coaching`). The plugin registers them automatically, so migrating them would create duplicates. If you had either disabled in Tabnine CLI, the wizard tells you the equivalent switch here — see [MCP Servers](/main/getting-started/tabnine-plugin-for-opencode/mcp-servers.md#turn-the-built-in-servers-off).
* **OAuth tokens for other MCP servers.** These are not portable. You re-authenticate each remote MCP server on first use.
* **Themes, keybindings, and general settings** (model selection, approval mode). Configure those directly in `tabnine`; see [Configuration](/main/getting-started/tabnine-plugin-for-opencode/configuration.md).

## Installing the helper

Clone the repository and run its installer, or copy its files by hand.

{% stepper %}
{% step %}

### Install with the script

```bash
git clone https://github.com/codota/tabnine-opencode-public
cd tabnine-opencode-public/migration_helper
./install.sh
```

By default this installs globally into `~/.config/opencode/`, so `tabnine` picks up the helper on next launch. To install into the current project instead, pass `--project`.

<img src="https://3436682446-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY2qxVf5VTm3fmwP4B4Gx%2Fuploads%2FLyn6L8glsfxcV6cGtB4a%2Fopencode-migrate-helper-install.gif?alt=media&amp;token=72fb0c47-31f5-48fb-81f2-23094ad9530d" alt="The installer places two skills and two commands into the global OpenCode configuration directory" data-size="original">
{% endstep %}

{% step %}

### Install manually

Copy the two skill folders and two command files into the corresponding places under `~/.config/opencode/` (or your project's `.opencode/`). The repository's [`README`](https://github.com/codota/tabnine-opencode-public/blob/main/migration_helper/README.md) has copy-and-paste commands for macOS, Linux, and Windows.
{% endstep %}

{% step %}

### Restart

Exit any running `tabnine` session and launch a new one. Skills and slash commands are loaded at startup.
{% endstep %}
{% endstepper %}

## Running the migration

Open `tabnine` in a directory where you want the migration scoped (or any directory, for a global migration), then run the slash command.

```
/migrate
```

You can also ask in natural language ("migrate my tabnine cli config to opencode"); either entry point activates the same wizard.

The wizard runs in four steps.

{% stepper %}
{% step %}

### Discover

The wizard scans the standard Tabnine CLI locations and prints an inventory: how many MCP servers, skills, agents, commands, and extensions it found, and where each came from. If a category is empty, it says so and moves on.
{% endstep %}

{% step %}

### Ask

You are asked one question per category — target scope first (global or project), then MCP servers, skills, agents, slash commands, and extensions. Selecting an item here **does not authorize a write**; you are only telling the wizard what you might want to migrate.
{% endstep %}

{% step %}

### Plan

The wizard resolves every selection to an absolute destination and prints a plan. This includes the target directory, every file it will create, overwrite, or back up, the MCP servers it will connect (so you can see which endpoints are being granted to the agent), and any change to an agent's permissions.

Nothing has been written at this point. Read the plan and either approve it, ask for changes, or stop. If you only wanted to preview a migration, ask for the plan and stop — that is the wizard's dry-run mode.
{% endstep %}

{% step %}

### Write

Once you approve, the wizard performs the writes and then reports what happened, including any file it did not write and any warning worth acting on (for example, agents whose tool restrictions were translated).

Existing files are never replaced without your consent, and any file the wizard overwrites is backed up first to `<path>.bak-<YYYYMMDD-HHMMSS>`.
{% endstep %}
{% endstepper %}

After the wizard finishes, exit `tabnine` and start a new session so the migrated items are loaded.

<figure><img src="https://3436682446-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY2qxVf5VTm3fmwP4B4Gx%2Fuploads%2FmJdTJZTpHwRdxaWEE6u4%2Fopencode-migrate-plan-and-write.gif?alt=media&amp;token=db12fd03-7b4f-48d5-a955-4b31bb1db2fe" alt=""><figcaption></figcaption></figure>

### Two translations worth knowing

Most fields copy verbatim. Two change in ways worth surfacing, and the wizard reports both:

* **Agent tool restrictions.** A Tabnine CLI agent that allowlists a specific set of tools becomes a `tabnine` agent with an equivalent `permission` block, so a restricted agent stays restricted. The two systems name their tools differently and a few names cover more ground in opencode than in Tabnine CLI, so the wizard lists the resulting permissions and flags any tool that gains access it did not have before.
* **MCP timeouts.** Tabnine CLI defaults an MCP request to 10 minutes; `tabnine` defaults to 5 seconds. When a Tabnine CLI server has no explicit timeout, the wizard writes 10 minutes into `opencode.json` so a slow server does not appear broken after migration.

### Credentials never end up in `opencode.json`

If a Tabnine CLI MCP server had a password or token written directly into its configuration (rather than as a `$VAR` environment reference), the wizard prints only the header or variable name and offers to replace the value with an `{env:VAR}` reference. Credentials are never copied into `opencode.json` unless you ask.

<figure><img src="https://3436682446-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY2qxVf5VTm3fmwP4B4Gx%2Fuploads%2FzD9qmpYjUgVKZc0P7sTg%2Fopencode-migrate-credential.png?alt=media&amp;token=efe6b0c5-616b-4539-91a5-a46a9cb47b2c" alt=""><figcaption><p>The raw token is never transcribed. The wizard writes an <code>{env:VAR}</code> reference and names the variable you must export</p></figcaption></figure>

## Migrating context files

Context files are handled by a separate wizard.

```
/migrate-context
```

It follows the same plan-then-approve flow as `/migrate`, and because a merge appends to an `AGENTS.md` you may already rely on, it backs up the existing file first.

Context in a subdirectory is worth a moment's attention. Both Tabnine CLI and opencode read your global context file and every context file from the current directory up to the project root. They differ further down: **Tabnine CLI** picks up a subdirectory's context whenever the agent works in that subtree, while **opencode** reads context from the session's directory upward only. A file migrated to `packages/api/AGENTS.md` therefore applies when you start `tabnine` inside `packages/api`, but not from the repository root. The wizard points this out for each such file and offers to fold its content into the project-root `AGENTS.md` instead, which makes it always apply at the cost of widening the instruction to the whole repository. You choose per file.

`/migrate-context` is scoped per repository, so run it in each project whose context files you want to bring over. The global `~/.tabnine/agent/TABNINE.md` file is offered too and only needs migrating once.

## Uninstalling the helper

The helper is only there so you can run the migration. Once you're happy with your migrated configuration, you can remove it:

```bash
rm -rf ~/.config/opencode/skills/migrate-from-tabnine-cli \
       ~/.config/opencode/skills/migrate-tabnine-context
rm ~/.config/opencode/commands/migrate.md \
   ~/.config/opencode/commands/migrate-context.md
```

For a project install, replace `~/.config/opencode` with `.opencode`. Restart `tabnine` after.

Your migrated MCP servers, skills, agents, and commands stay where the wizard wrote them — removing the helper does not remove them.

## Troubleshooting

* **`ConfigInvalidError` at startup** after a migration means one of the migrated fields is not accepted by opencode's config schema. The wizard reports which file it wrote; open it and fix the offending field, using the mapping tables in the [helper's reference docs](https://github.com/codota/tabnine-opencode-public/tree/main/migration_helper/skills/migrate-from-tabnine-cli/references) as a guide. For project-scoped issues, you can start `tabnine` with project config disabled while you fix it: `OPENCODE_DISABLE_PROJECT_CONFIG=1 tabnine`.
* **A migrated MCP server returns auth errors** on first use. This is expected — OAuth tokens do not carry over. Re-authenticate through the server's normal flow.
* **A migrated skill or agent doesn't appear** in `tabnine`. Confirm the migration wrote to the same config directory the plugin reads. You can list what opencode has loaded with `opencode debug skill` and `opencode agent list`; the wizard can also verify this for you if you ask.

For general `tabnine` troubleshooting, see [Troubleshooting](/main/getting-started/tabnine-plugin-for-opencode/troubleshooting.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.tabnine.com/main/getting-started/tabnine-plugin-for-opencode/migrating-from-tabnine-cli.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
