# IDE Extension Source: https://docs.symbioticsec.ai/code/basics/IDE_extension Use the IDE extension to get AI assistance directly in your editor The Symbiotic Code IDE extension brings the coding agent into VS Code-based editors. It provides AI assistance for code generation, debugging, refactoring, and repository exploration. The extension runs the same Symbiotic Code engine as the CLI, so both share the same configuration files (`~/.config/symbiotic/`, `symbiotic.json`, `.symbiotic/`), agents, permissions, and security modes. ## Supported IDEs Symbiotic Code supports IDEs based on VS Code, such as VS Code, VSCodium, Cursor, Windsurf, and Kiro. ## Getting Started 1. **Install the extension**: [download the VSIX](https://app.symbioticsec.ai/symbiotic-code.vsix) and install it in your IDE (**Extensions** view → **...** → **Install from VSIX...**). The extension downloads the Symbiotic Code engine it needs on first start; you don't need to install the CLI separately. 2. **Sign in** with your Symbiotic Security account from the Symbiotic Code sidebar (or run **Symbiotic Code: Sign In** from the command palette). 3. **Start coding** from the Symbiotic Code view in the activity bar. ## Key features ### Agent modes In the chat input, you can select the most appropriate agent for your current task: * **Build:** The default agent. Edits files, runs commands, and uses tools according to your permissions. Best for active development. * **Plan:** A planning agent that analyzes the codebase and drafts plans. File edits are denied (except plan files) and it is instructed not to make changes. * **Ask:** A read-only agent that answers questions and explains code without modifying anything. * **Debug:** A specialized agent that diagnoses and fixes bugs using runtime evidence. See [Agents](/code/basics/agents) for details. You can also create your own modes in **Settings > Agent Behaviour > Agents** with **Create New Mode** (name, description, and system prompt), or **Import** an existing agent definition. ### Security modes and guardrails The security mode selector in the chat input controls how much security workflow runs during a session: | Security Level | Description | Recommended For | | :- | :- | :- | | **Permissive** | Security tools only run when you ask for them. | Writing documentation, exploration, and non-sensitive tasks. | | **Balanced** (Default) | Scans after feature implementations; fixes critical/high issues in new code and asks about the rest. | Daily development, refactoring, and general engineering. | | **Strict** | Scans after every file edit, runs the OWASP checkpoint on every feature, and fixes critical/high/medium issues. | Sensitive codebases, credential management, and high-audit environments. | See [Security modes](/code/security/security_modes) for details. Organization and repository guardrails are separate Markdown instructions. Symbiotic Code fetches active guardrails from the backend on startup and refreshes them every 5 minutes. **Settings > Guardrails** shows which guardrails are active and lets you refresh or clear them. See [AI Guardrails](/flow/admins/guardrails). ### Editor integration * **Code actions:** Select code and right-click to **Explain Code**, **Fix Code**, **Improve Code**, or **Add to Context** (`Ctrl+K Ctrl+A` / `Cmd+K Cmd+A`). * **Terminal actions:** Right-click in the terminal to add its content to the context or ask the agent to fix or explain a command. * **Commit messages:** Use **Generate Commit Message** from the Source Control view. * **Agent Manager** (`Ctrl+Shift+M` / `Cmd+Shift+M`): run and switch between multiple sessions, including in separate git worktrees. * **Toggle auto-approve** (`Ctrl+Alt+A` / `Cmd+Alt+A`): while enabled, permission requests are approved automatically (once each). ## Settings Open **Settings** from the gear icon in the Symbiotic Code sidebar. Changes made in the Settings panel are saved to your global configuration file (`~/.config/symbiotic/symbiotic.jsonc` or `symbiotic.json`). Use the **Local Config** and **Global Config** buttons to open the project or global configuration file directly. The main categories are described below. Other tabs cover Browser automation, Checkpoints, Display, Autocomplete, Context, Guardrails, Commit Message, Experimental features, and Language. ### Models Configure which AI models power your development workflow: * **Default Model:** The primary model used for conversations (`model` in the configuration file). * **Small Model:** A lightweight model for title generation, commit message generation, prompt enhancement, and other quick tasks (`small_model`). When not set, a small model from the same provider is picked automatically. * **Model per Mode:** Assign a specific model to each agent mode (Build, Plan, Ask, Debug, and your custom modes). When not set, the Default Model is used. ### Providers Manage and configure your AI model providers: * **Symbiotic:** The default managed provider using Symbiotic's curated models, authenticated through the Symbiotic gateway. Sign in or out from here. * **Connected providers:** View connected third-party providers (including those detected from environment variables), edit custom providers, and disconnect them. * **Popular providers:** Anthropic, GitHub Copilot, OpenAI, Google, OpenRouter, and Vercel AI Gateway. Click **Connect** and enter your credentials. Use **View all** for the full provider list. * **Custom provider:** Add any OpenAI-compatible provider by base URL, for example a local model server such as Ollama. See [Models and providers](/code/basics/models_and_providers). ### Agent Behaviour Customize how agents behave with multiple tabs: **Agents:** Choose the **Default Agent** and view all available agents and subagents: * **ask:** Get answers and explanations without making changes to the codebase * **build:** The default agent. Executes tools based on configured permissions * **debug:** Diagnose and fix software issues with systematic debugging methodology * **explore:** Fast subagent specialized for exploring codebases and finding files by patterns * **general:** General-purpose subagent for researching complex questions and executing multi-step tasks * **owasp-security-review:** Subagent that reviews code against the OWASP Top 10 and reports findings * **plan:** Plan mode that disallows all edit tools * **triage:** Security engineer subagent for triaging static analysis findings Select an agent to override its model, add a custom prompt, set temperature, top P, or max steps, or mark it as hidden or disabled. Use **Create New Mode** or **Import** to add your own. **MCP Servers, Rules, Workflows, Skills:** Manage [MCP servers](/code/configuration/mcp), [rules](/code/basics/rules) and additional instruction files, workflows (your [custom commands](/code/customize/custom_commands)), and [skills](/code/customize/skills) including extra skill folder paths and URLs. ### Auto-Approve Define whether each tool runs automatically with `permission` rules. Each tool can be set to **Allow**, **Ask**, or **Deny**, and some tools accept pattern-based exceptions. See [Tool permissions](/code/security/tool_permissions). * **External Directory:** Accessing files outside the workspace is set to **Ask** by default. * **Bash:** Set a default for all commands (`*`), then add exceptions with patterns such as `git *`, `npm *`, or `rm *` (for example, allow `grep *` but ask for `git push`). * **Read:** `*.env` and `*.env.*` files require confirmation by default; `*.env.example` is allowed. * **Edit:** Set a default for file edits, with path exceptions. * **Other tools:** Glob, Grep, List, Task (subagents), Skill, LSP, todo, web search, web fetch, and doom loop detection (set to **Ask** by default). Add exceptions with **Add path** or **Add command**. # Terminal UI Source: https://docs.symbioticsec.ai/code/basics/TUI Use Symbiotic Code in your terminal: layout, prompt, permissions, navigation, and themes Running `symbiotic` opens the terminal UI (TUI). It runs the same engine as the [IDE extension](/code/basics/IDE_extension), so both share the same [configuration files](/code/basics/configuration_file), agents, permissions, and security modes. ## Launch ```bash theme={null} symbiotic # start in the current directory symbiotic path/to/project # start in another directory symbiotic -c # continue the last session symbiotic -s # open a specific session ``` | Option | Description | | - | - | | `-m, --model` | Model to use, as `provider/model` | | `--agent` | Agent to start with | | `-c, --continue` | Continue the most recent session | | `-s, --session` | Open a session by ID | | `--fork` | Fork the session instead of continuing it (requires `--continue` or `--session`) | | `--prompt` | Prompt to submit as soon as the TUI is ready | | `--port`, `--hostname` | Start a local HTTP server that other clients can [attach](#attach-to-a-running-server) to (hostname defaults to `127.0.0.1`) | If you pipe text into `symbiotic`, it is added in front of `--prompt`: ```bash theme={null} git diff | symbiotic --prompt "Review this diff" ``` On first launch, Symbiotic Code asks you to sign in with your Symbiotic Security account in the browser. See [Authentication](/code/get_started#authentication). When you quit from a session, the TUI prints the command to resume it (`symbiotic -s `). *** ## Layout ### Home screen Before your first message you see the home screen: the logo, a short explanation of the security modes, the prompt, and tips (hide them with `Ctrl+X H`). The bottom bar shows the current directory and git branch, the number of connected MCP servers, and the version. ### Session screen Once you send a message, the session screen shows the conversation, the prompt, and a sidebar. **Sidebar.** Shown automatically when the terminal is wider than 120 columns. Toggle it with `Ctrl+X B`; on narrow terminals it opens as an overlay. It contains: | Section | What it shows | | - | - | | **Context** | Tokens used, percentage of the model's context window, and cost (cost is hidden for Symbiotic models) | | **MCP** | Each MCP server and its status: connected, failed, disabled, or needs authentication | | **LSP** | Active [language servers](/code/configuration/lsp) | | **Todo** | The agent's current task list, while items are pending | | **Guardrails** | Whether organization and repository [guardrails](/flow/admins/guardrails) are active | | **Security** | Security scans and checkpoints run in the session, and the issues they found | | **Modified Files** | Files changed in the session, with lines added and removed | **Header.** When the sidebar is hidden, a header shows the session title, context usage, and cost instead. Hide it with **Hide header** in the command palette. **Prompt box.** The prompt box shows the current state of the session: * Above the input: the active agent, the [security mode](/code/security/security_modes) (`● Strict`, `◐ Balanced`, `○ Permissive`), and the `tab` / `ctrl+s` hints. * Below the input: the model, its provider, and the selected variant. * While the agent works: a spinner, retry messages, and the `esc interrupt` hint. The border color follows the active agent's color. *** ## Write a prompt | Action | How | | - | - | | Send | `Enter` | | New line | `Shift+Enter`, `Ctrl+J`, `Alt+Enter`, or `Ctrl+Enter` | | Previous / next prompt | `Up` at the start of the input / `Down` at the end | | Clear the input | `Ctrl+C` | | Write in your editor | `/editor` or `Ctrl+X E`: opens `$VISUAL` or `$EDITOR`; the text is loaded back into the prompt when you close the file | | Stop the agent | Press `Esc` twice | If `Shift+Enter` sends the message instead of adding a new line, your terminal isn't sending the modifier. Use `Ctrl+J`, or see [Keybinds](/code/configuration/keybinds) to configure your terminal. ### Mention files, agents, and resources with `@` Type `@` to open autocomplete. It lists: * **Subagents**, such as `@explore` or `@general`, to delegate a task directly * **Files and directories** in the project. Press `Tab` on a directory to browse into it. Add a line range with `#`, for example `@src/auth/login.ts#10-40` * **MCP resources** from your connected [MCP servers](/code/configuration/mcp) Use `Up`/`Down` to move through suggestions, `Enter` or `Tab` to select, and `Esc` to close. ### Run commands with `/` Type `/` at the start of the input to autocomplete built-in commands, your [custom commands](/code/customize/custom_commands), and MCP prompts (marked `:mcp`). [Skills](/code/customize/skills) don't appear in this list, but you can still run one by typing `/` in full, or pick one with `/skills`. See [Common commands](/code/basics/common_commands) for the full list. ### Run shell commands with `!` Type `!` at the start of the input to switch to shell mode. The prompt label changes to **Shell**. Press `Enter` to run the command directly, without going through the model. The output is added to the conversation, so the agent can see it in later messages. Long output is collapsed to 10 lines; click it to expand. Press `Esc`, or `Backspace` on an empty input, to leave shell mode. ### Attach images and paste text * **Images:** paste an image from the clipboard with `Ctrl+V`, or drag and drop an image file onto the terminal. It appears as `[Image 1]` in the prompt. * **Long text:** pasting 3 or more lines (or more than 150 characters) shows a placeholder such as `[Pasted ~42 lines]`. The full text is sent with the message. To paste text as is, set `experimental.disable_paste_summary` to `true` in your [configuration file](/code/basics/configuration_file). ### Stash a prompt To set aside a prompt you're writing, open the command palette (`Ctrl+P`) and select **Stash prompt**. Use **Stash pop** to restore the last one, or **Stash list** to pick one (press `Ctrl+D` twice to delete an entry). Up to 50 prompts are kept. *** ## Switch agent, model, and security mode | Action | Keybind | Command | | - | - | - | | Cycle primary agents (Build, Plan, Ask, Debug, and your custom agents) | `Tab` / `Shift+Tab` | `/agents` | | Cycle recently used models | `F2` / `Shift+F2` | `/models` | | Cycle model variants (for example reasoning effort) | `Ctrl+T` | | | Cycle security mode (permissive → balanced → strict) | `Ctrl+S` | `/security-mode` | The model you pick is remembered per agent, and the variant per model. If an agent defines its own `security_mode`, it applies while that agent is active. In the model list, press `Ctrl+F` to mark a model as a favorite and `Ctrl+A` to connect a provider. See [Agents](/code/basics/agents), [Models and providers](/code/basics/models_and_providers), and [Security modes](/code/security/security_modes). *** ## Permissions and questions When the agent needs approval for a tool call (based on your [tool permissions](/code/security/tool_permissions)), the prompt is replaced by a **Permission required** panel. File edits show the diff. | Option | Effect | | - | - | | **Allow once** | Allow this call only | | **Allow always** | Allow this permission (or these patterns) for the rest of the session. It lasts until you restart Symbiotic Code; to make it permanent, add a rule to your configuration file | | **Reject** | Deny the call. Other pending requests in the session are also rejected | Use `←`/`→` (or `h`/`l`) and `Enter`, or click an option. `Esc` rejects. `Ctrl+F` shows the request full screen. When a subagent's request is rejected, you can tell the agent what to do instead. When the agent asks you a question, pick an answer with `1`-`9` or the arrow keys and press `Enter`, or choose **Type your own answer**. `Esc` dismisses the question. With several questions, use `Tab` to move between them and review your answers in the **Confirm** tab. *** ## Work with messages Click one of your messages to open **Message Actions**: * **Revert:** undo this message and everything after it, including the file changes, and put the message back in the prompt * **Copy:** copy the message text * **Fork:** start a new session from this point | Action | Keybind | Command | | - | - | - | | Undo the last message and its file changes | `Ctrl+X U` | `/undo` | | Redo | `Ctrl+X R` | `/redo` | | Jump to a message | `Ctrl+X G` | `/timeline` | | Fork from a message | | `/fork` | | Copy the last assistant message | `Ctrl+X Y` | | | Copy the whole transcript | | `/copy` | | Export the session to Markdown | `Ctrl+X X` | `/export` | | Summarize the session to free up context | `Ctrl+X C` | `/compact` | ### Scroll | Action | Keybind | | - | - | | Scroll up / down | `PageUp` / `PageDown`, or the mouse wheel | | Scroll up / down by a smaller step | `Ctrl+Alt+U` / `Ctrl+Alt+D` | | Go to the first / last message | `Ctrl+G` or `Home` / `Ctrl+Alt+G` or `End` | The view follows new output while you're at the bottom. ### Display options | Option | How to toggle | Default | | - | - | - | | Thinking blocks | `/thinking` | Shown | | Message timestamps | `/timestamps` | Hidden | | Completed tool call details | **Hide tool details** in the command palette | Shown | | Generic tool output | **Show generic tool output** in the command palette | Hidden | | Code concealment in messages | `Ctrl+X H` | On | | Diff line wrapping | **Disable diff wrapping** in the command palette | On | These choices are saved between sessions, except code concealment. Diffs are shown side by side when the terminal is wider than 120 columns, and stacked otherwise. Set `diff_style` to `"stacked"` in [`tui.json`](#configuration) to always stack them. To browse all your git changes, use `/diff`. It opens a full-screen diff viewer; press `?` in it to see its keybinds. *** ## Subagents When the agent delegates work to a [subagent](/code/basics/agents), the task appears in the conversation. Click it to open the subagent's session. | Action | Keybind | | - | - | | List active and recent subagents | `Ctrl+O` (or `/subagents`) | | Move running subagents to the background | `Ctrl+Y` | | Stop background subagents | `Ctrl+Shift+Y` twice | | Open the first subagent session | `Ctrl+X Down` | | In a subagent session: go to the parent session | `Up` | | In a subagent session: next / previous subagent | `Right` / `Left` | In the subagent list, press `Ctrl+A` to abort a running subagent. Subagent sessions are read-only: permission requests from subagents appear in the parent session. *** ## Sessions Use `/sessions` (`Ctrl+X L`) to switch sessions. Sessions are grouped by date. In the list: * `Ctrl+F` pins a session (up to 9). Jump to pinned sessions with `Ctrl+X 1` to `Ctrl+X 9` * `Ctrl+R` renames a session * `Ctrl+D` twice deletes a session Start a new session with `/new` (`Ctrl+X N`). *** ## Command palette Press `Ctrl+P` to open the command palette. It lists every available action with its keybind, and a **Suggested** section at the top. Type to filter. Some actions are only available here, including: * **Stash prompt**, **Stash pop**, and **Stash list** * **Toggle appearance** (switch between dark and light) * **Show/Hide header**, **Hide tool details**, **Show generic tool output**, and **Toggle session scrollbar** * **Disable/Enable terminal title**, **Disable/Enable animations**, and **Disable/Enable diff wrapping** * **Open docs** *** ## Themes Use `/themes` (`Ctrl+X T`) to pick a theme. The list previews each theme as you move through it; press `Esc` to keep your current theme. The default theme is `symbiotic`. Built-in themes: `symbiotic`, `aura`, `ayu`, `carbonfox`, `catppuccin`, `catppuccin-frappe`, `catppuccin-macchiato`, `cobalt2`, `cursor`, `dracula`, `everforest`, `flexoki`, `github`, `gruvbox`, `kanagawa`, `lucent-orng`, `material`, `matrix`, `mercury`, `monokai`, `nightowl`, `nord`, `one-dark`, `opencode`, `orng`, `osaka-jade`, `palenight`, `rosepine`, `solarized`, `synthwave84`, `tokyonight`, `vercel`, `vesper`, and `zenburn`. The `system` theme uses your terminal's color palette. It's only listed if your terminal reports its palette. Symbiotic Code detects whether your terminal has a dark or light background. To override it, use **Toggle appearance** in the command palette. ### Set a theme in the configuration Set `theme` in [`tui.json`](#configuration). It takes precedence over the theme picked with `/themes`. ```json tui.json theme={null} { "$schema": "https://config.symbioticsec.ai/tui.json", "theme": "tokyonight" } ``` ### Create a custom theme Add a JSON file to a `themes` folder. The file name is the theme name. ``` ~/.config/symbiotic/themes/my-theme.json ← available everywhere .symbiotic/themes/my-theme.json ← this project only ``` A theme defines a color for each key under `theme`. A color can be a hex value, the name of an entry in `defs`, a `{ "dark": ..., "light": ... }` pair, an ANSI color number (0-255), or `"none"` for transparent. ```json .symbiotic/themes/my-theme.json theme={null} { "defs": { "pink": "#C45D97", "dark0": "#181818", "light0": "#FAFAFB" }, "theme": { "primary": "pink", "background": { "dark": "dark0", "light": "light0" }, "text": { "dark": "light0", "light": "dark0" } } } ``` The example above is shortened. A theme must define every color key below; only `selectedListItemText`, `backgroundMenu`, and `thinkingOpacity` (a number, default `0.6`) are optional. * **Base:** `primary`, `secondary`, `accent`, `error`, `warning`, `success`, `info`, `text`, `textMuted`, `background`, `backgroundPanel`, `backgroundElement`, `border`, `borderActive`, `borderSubtle` * **Diff:** `diffAdded`, `diffRemoved`, `diffContext`, `diffHunkHeader`, `diffHighlightAdded`, `diffHighlightRemoved`, `diffAddedBg`, `diffRemovedBg`, `diffContextBg`, `diffLineNumber`, `diffAddedLineNumberBg`, `diffRemovedLineNumberBg` * **Markdown:** `markdownText`, `markdownHeading`, `markdownLink`, `markdownLinkText`, `markdownCode`, `markdownBlockQuote`, `markdownEmph`, `markdownStrong`, `markdownHorizontalRule`, `markdownListItem`, `markdownListEnumeration`, `markdownImage`, `markdownImageText`, `markdownCodeBlock` * **Syntax:** `syntaxComment`, `syntaxKeyword`, `syntaxFunction`, `syntaxVariable`, `syntaxString`, `syntaxNumber`, `syntaxType`, `syntaxOperator`, `syntaxPunctuation` *** ## Configuration TUI settings live in `tui.json` (or `tui.jsonc`), separate from `symbiotic.json`: * Global: `~/.config/symbiotic/tui.json` * Project: `tui.json` at the root of your project, or `.symbiotic/tui.json` * Custom path: the `SYMBIOTIC_TUI_CONFIG` environment variable Project files override global ones. | Key | Description | Default | | - | - | - | | `theme` | Theme name | `symbiotic` | | `keybinds` | Keybind overrides. See [Keybinds](/code/configuration/keybinds) | | | `scroll_speed` | Lines scrolled per mouse wheel step | `3` | | `scroll_acceleration.enabled` | Enable macOS-style scroll acceleration (replaces `scroll_speed`) | `false` | | `diff_style` | `"auto"` (side by side on wide terminals) or `"stacked"` | `"auto"` | ```json tui.json theme={null} { "$schema": "https://config.symbioticsec.ai/tui.json", "theme": "symbiotic", "scroll_speed": 5, "diff_style": "stacked", "keybinds": { "leader": "ctrl+x" } } ``` `tui.json` is validated strictly. If it contains an unknown key, the whole file is ignored and a warning is written to the log. If you still have `theme` or `keybinds` in `symbiotic.json`, they are moved automatically to a `tui.json` next to it on startup. ### Leader key Most shortcuts start with the leader key, `Ctrl+X` by default. Press `Ctrl+X`, release it, then press the next key within 2 seconds. For example, `Ctrl+X N` starts a new session. See [Keybinds](/code/configuration/keybinds) to change it or any other shortcut. ### Environment variables | Variable | Effect | | - | - | | `SYMBIOTIC_TUI_CONFIG` | Path to an additional `tui.json` | | `SYMBIOTIC_DISABLE_TERMINAL_TITLE` | Don't change the terminal title (by default it shows `SC \| `) | | `SYMBIOTIC_EXPERIMENTAL_DISABLE_COPY_ON_SELECT` | Disable copy on select (disabled by default on Windows) | | `VISUAL` / `EDITOR` | Editor used by `/editor` and `/export` | *** ## Mouse and clipboard The TUI supports the mouse: click messages, tool calls, buttons, list items, and sidebar sections, and scroll with the wheel. **Copy text:** select it with the mouse. It's copied to the clipboard when you release the button, and a **Copied to clipboard** notification appears. On Windows, copy on select is off by default: select the text, then press `Ctrl+C` or right-click to copy it. Clipboard copy works over SSH and in tmux or screen, through the OSC 52 terminal sequence (your terminal must support it). *** ## Exit * Press `Ctrl+C` on an empty prompt (`Ctrl+C` first clears the input if it isn't empty) * Press `Ctrl+D` on an empty prompt, or `Ctrl+X Q` * Type `/exit` (or `/quit`, `/q`), or type `exit`, `quit`, or `:q` and press `Enter` `Ctrl+Esc` suspends the TUI and returns you to the shell. Run `fg` to resume. *** ## Attach to a running server The TUI can connect to a Symbiotic Code server started with `symbiotic serve` or `symbiotic web`, for example on a remote machine or in a container: ```bash theme={null} symbiotic serve --port 4096 symbiotic attach http://localhost:4096 ``` `attach` accepts `--dir` (directory to work in on the server), `-c`, `-s`, `--fork`, and `-p, --password`. The password defaults to the `SYMBIOTIC_SERVER_PASSWORD` environment variable. *** ## Next steps All slash commands and CLI commands. Customize every shortcut. Build, Plan, Ask, Debug, and subagents. # Agents Source: https://docs.symbioticsec.ai/code/basics/agents Use specialized agents for different development tasks Agents are specialized assistants with their own prompt, model, and tool permissions. There are two types: * **Primary agents** are the assistants you interact with directly and handle your main conversation. * **Subagents** are invoked by primary agents for specific tasks, or manually by **@ mentioning** them in your message (e.g. `@explore find where sessions are created`). Each agent has different permissions and tool access; for example, `Build` uses all tools according to your [permissions](/code/security/tool_permissions) while `Plan` and `Ask` are restricted. Use `Tab` (or `Shift+Tab` to go backwards) to cycle through primary agents, or `/agents` (`Ctrl+X` then `A`) to pick one. Symbiotic Code comes with **4 primary agents**, **4 subagents**, and **a dedicated mode for running shell commands.** ## Primary agents ### Build The **default** agent. It can use all tools, following your configured [permissions](/code/security/tool_permissions). Use Build for standard development work where you need full access to file operations and system commands. ### Plan A restricted agent designed for planning and analysis. **We use a permission system to give you more control and prevent unintended changes:** * **file edits** are denied, except for plan files (Markdown files in `.symbiotic/plans/`) * the agent is instructed to only read and inspect, and not to run commands that modify your system This agent is useful when you want the LLM to analyze code, suggest changes, or create plans without making any actual modifications to your codebase. When the plan is ready, switch to **Build** to implement it. ### Ask A read-only agent for **getting answers and explanations without any risk of modifying your codebase.** It can read and search files, search the web, and run security scans, but cannot edit files or run shell commands. Use Ask when you want to understand code before changing it, or when learning about patterns in your codebase. ### Debug A specialized agent for **diagnosing and fixing bugs** using an evidence-based methodology. Debug mode never fixes bugs based on code alone. It requires actual runtime evidence. The debug agent follows a systematic workflow: 1. Gather context (errors, stack traces, logs) 2. Form hypotheses about the cause 3. Add instrumentation to test all hypotheses 4. Reproduce and analyze logs 5. Fix only with log proof of the root cause 6. Verify with logs, then remove the instrumentation Use Debug when you're investigating unexpected behavior, tracking down errors, or need a methodical approach to complex bugs. ## Subagents | Subagent | What it does | | - | - | | `general` | General-purpose agent for researching complex questions and executing multi-step tasks, including running several units of work in parallel. Has full tool access except the todo list. | | `explore` | Fast, read-only agent for exploring codebases: finding files by pattern, searching code, and answering questions about the codebase. | | `triage` | Security engineer specialist that reviews static analysis findings and separates true positives from false positives by reading the code. Used in **Strict** [security mode](/code/security/security_modes). | | `owasp-security-review` | Reviews code against the OWASP Top 10 and reports findings, without editing. Used by the `/owasp-security-review` command. | Use `/subagents` (`Ctrl+O`) to view the subagents running in the current session. ### Shell mode Type `!` at the start of the prompt to switch to shell mode, then enter a command to run it directly without any AI processing. Press `Esc` to exit shell mode. *** ### Custom agents You can create custom agents as Markdown files in `~/.config/symbiotic/agents/` (global) or `.symbiotic/agents/` (project), in the `agent` section of your configuration file, or interactively with `symbiotic agent create`. You can also override built-in agents (for example their `model`), or disable them with `"disable": true`. Run `symbiotic agent list` to see all available agents. To change the agent used when none is specified, set `default_agent` to a primary agent in your configuration file. See [custom agents](/code/customize/custom_agents) for more information. # Common commands Source: https://docs.symbioticsec.ai/code/basics/common_commands Common commands for Symbiotic Code ## Slash commands Type `/` in the prompt to autocomplete slash commands, or press `Ctrl+P` to open the command palette. Most commands also have a [keybind](/code/configuration/keybinds); `Ctrl+X` is the leader key (e.g. `Ctrl+X` then `N` for a new session). See [Terminal UI](/code/basics/TUI) for prompt features, navigation, and themes. ### Session | Command | Description | Keybind | | - | - | - | | `/new` (alias `/clear`) | Create a new session | `Ctrl+X N` | | `/sessions` (aliases `/resume`, `/continue`) | Switch between sessions | `Ctrl+X L` | | `/rename` | Rename the current session | `Ctrl+R` | | `/timeline` | Jump to a message in the session | `Ctrl+X G` | | `/fork` | Fork the session from a message | | | `/compact` (alias `/summarize`) | Summarize the session to free up context | `Ctrl+X C` | | `/undo` | Undo the last message and revert its file changes | `Ctrl+X U` | | `/redo` | Redo an undone message | `Ctrl+X R` | | `/copy` | Copy the session transcript to the clipboard | | | `/export` | Export the session transcript to a Markdown file | `Ctrl+X X` | | `/subagents` | View the subagents running in the session | `Ctrl+O` | | `/timestamps` | Show or hide message timestamps | | | `/thinking` | Show or hide thinking blocks | | | `/editor` | Compose your prompt in your external editor (`$VISUAL` / `$EDITOR`) | `Ctrl+X E` | ### Agents, models, and tools | Command | Description | Keybind | | - | - | - | | `/agents` | Switch between agents (build, plan, ask, debug, and custom agents) | `Ctrl+X A`, `Tab` to cycle | | `/models` | Choose which model you're using | `Ctrl+X M` | | `/connect` | Connect to a provider | | | `/security-mode` | Choose the [security mode](/code/security/security_modes) (permissive, balanced, strict) | `Ctrl+S` to cycle | | `/mcps` | Enable or disable MCP servers | | | `/skills` | Pick a skill to invoke | | ### Project and security | Command | Description | | - | - | | `/init` | Create or update the `AGENTS.md` file for the project | | `/review` | Review changes in a subtask: uncommitted changes by default, or a commit, branch, or PR | | `/local-review` | Review the current branch against its base branch | | `/local-review-uncommitted` | Review uncommitted changes | | `/scan-codebase` | Scan the project (or a path) for vulnerabilities. See [Security tools](/code/security/security_tools) | | `/owasp-security-review` | Run an OWASP Top 10 review of the project, a path, a commit, a branch, or a PR in the background | | `/generate-guardrails` | Generate security guardrails for the project | | `/diff` | Open the diff viewer for your git changes | ### Application | Command | Description | Keybind | | - | - | - | | `/status` | See the status of MCP servers, LSP servers, formatters, and plugins | `Ctrl+X S` | | `/themes` | Switch between themes | `Ctrl+X T` | | `/help` | Show the help dialog | | | `/exit` (aliases `/quit`, `/q`) | Quit the application | `Ctrl+X Q`, or `Ctrl+C` / `Ctrl+D` on an empty prompt | Your [custom commands](/code/customize/custom_commands), MCP prompts, and [skills](/code/customize/skills) are also available as slash commands. ## CLI commands Running `symbiotic` starts the terminal UI. It accepts an optional project path and these options: | Option | Description | | - | - | | `-m, --model` | Model to use, as `provider/model` | | `--agent` | Agent to use | | `-c, --continue` | Continue the last session | | `-s, --session` | Continue a specific session by ID | | `--fork` | Fork the session when continuing (with `--continue` or `--session`) | | `--prompt` | Prompt to start with | Other commands: | Command | Description | | - | - | | `symbiotic run [message..]` | Run a prompt non-interactively and print the result. Supports `--model`, `--agent`, `--continue`, `--session`, `--file`, `--format json`, `--security-mode`, `--variant`, and `--attach` | | `symbiotic providers` (alias `auth`) | Manage provider credentials: `list`, `login`, `logout` | | `symbiotic models [provider]` | List available models (`--verbose` for details, `--refresh` to update the cache) | | `symbiotic agent` | Manage agents: `create`, `list` | | `symbiotic mcp` | Manage MCP servers: `add`, `list`, `auth`, `logout`, `debug`. See [MCP](/code/configuration/mcp) | | `symbiotic plugin ` | Install a plugin and add it to your config (`-g` for global) | | `symbiotic session` | Manage sessions: `list`, `delete` | | `symbiotic export [sessionID]` / `symbiotic import ` | Export a session as JSON, or import one | | `symbiotic stats` | Show token usage and cost statistics | | `symbiotic pr ` | Check out a GitHub PR branch (requires `gh`), then start Symbiotic Code | | `symbiotic serve` | Start a headless server | | `symbiotic web` | Start a server and open the web interface | | `symbiotic attach ` | Attach the terminal UI to a running server. See [Terminal UI](/code/basics/TUI#attach-to-a-running-server) | | `symbiotic acp` | Start an [ACP](/code/configuration/acp) server for editor integrations | | `symbiotic upgrade [target]` | Upgrade to the latest or a specific version | | `symbiotic uninstall` | Uninstall Symbiotic Code and remove related files (`--keep-config`, `--keep-data`, `--dry-run`) | | `symbiotic debug` | Troubleshooting tools, e.g. `symbiotic debug config` (resolved configuration) and `symbiotic debug paths` | | `symbiotic db` | Open the local database, or run a query | Run `symbiotic --help` or `symbiotic --help` for all options. Global options include `--print-logs` and `--log-level`. # Configuration file Source: https://docs.symbioticsec.ai/code/basics/configuration_file Configuration file for Symbiotic Code You can configure Symbiotic Code using a JSON or JSONC (JSON with comments and trailing commas) config file named `symbiotic.json` or `symbiotic.jsonc`. ```jsonc symbiotic.jsonc theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "model": "anthropic/claude-sonnet-4-5", "autoupdate": true, } ``` The `$schema` field enables validation and autocompletion in your editor. If a config file doesn't have one, Symbiotic Code adds it automatically the first time it loads the file. The config is validated strictly: **unknown top-level keys are rejected** and Symbiotic Code will report `Configuration is invalid at ` with the offending key. Check spelling if you see this error. ## Locations You can place your config in a couple of different locations and they have a different order of precedence. Configuration files are **merged together**, not replaced. Sources are loaded in this order, each one overriding the previous ones (later wins): 1. **Remote config** (from `/.well-known/symbiotic`) - organizational defaults, loaded for each URL you logged in to with `symbiotic providers login ` 2. **Global config** (`~/.config/symbiotic/symbiotic.json` or `symbiotic.jsonc`) - user preferences 3. **Custom config** (file path in the `SYMBIOTIC_CONFIG` env var) - custom overrides 4. **Project config** (`symbiotic.json` / `symbiotic.jsonc`, searched from the current directory up to the Git root) - project-specific settings 5. **`.symbiotic` directories** - `.symbiotic/symbiotic.json(c)` plus agents, commands, plugins, tools, and skills (see below) 6. **Inline config** (JSON content in the `SYMBIOTIC_CONFIG_CONTENT` env var) - runtime overrides 7. **Account organization config** - fetched from Symbiotic for your active account's organization 8. **Managed config files** (see [Managed settings](#managed-settings)) - admin-controlled, highest priority This means **project configs can override global defaults**, and **global configs can override remote organizational defaults**. Objects are deep-merged; for the `instructions` and `plugin` arrays, entries from all sources are **combined** (with duplicates removed) instead of replaced. Set `SYMBIOTIC_DISABLE_PROJECT_CONFIG=1` to ignore project config files, project `.symbiotic/` directories, and project rule files. ### .symbiotic directories Besides JSON files, Symbiotic Code loads additional configuration from these directories: * `~/.config/symbiotic/` * `.symbiotic/` in the current directory and each parent directory up to the Git root * `~/.symbiotic/` * The directory set in `SYMBIOTIC_CONFIG_DIR` Each directory can contain: | Path | Content | | - | - | | `symbiotic.json` / `symbiotic.jsonc` | Config file (not read from `~/.config/symbiotic/` a second time) | | `agents/*.md` | [Custom agents](/code/customize/custom_agents) | | `commands/*.md` | [Custom commands](/code/customize/custom_commands) | | `skills/*/SKILL.md` | [Skills](/code/customize/skills) | | `plugins/*.{ts,js}` | [Plugins](/code/customize/plugins) | | `tools/*.{ts,js}` | [Custom tools](/code/customize/custom_tools) | Singular folder names (`agent/`, `command/`, `skill/`, `plugin/`, `tool/`) are also accepted. ### Managed settings Organizations can **enforce configuration that users cannot override**. Managed settings are loaded at the highest priority tier. Drop a `symbiotic.json` or `symbiotic.jsonc` file in the system managed config directory: | Platform | Path | | - | - | | macOS | `/Library/Application Support/symbiotic/` | | Linux | `/etc/symbiotic/` | | Windows | `%ProgramData%\symbiotic` | These directories require admin/root access to write, so users cannot modify them. Only the config file is read from the managed directory; agents, commands, skills, and plugins placed there are ignored. A few environment variables are applied on top of the merged config, after managed settings: `SYMBIOTIC_PERMISSION` (merged into `permission`), `SYMBIOTIC_DISABLE_AUTOCOMPACT` and `SYMBIOTIC_DISABLE_PRUNE`. See [Environment variables](#environment-variables). ### Checking the resolved config To see the final merged configuration for the current directory, run: ```bash theme={null} symbiotic debug config ``` ## Variables You can reference environment variables and files inside any config file. ### Env vars Use `{env:VARIABLE_NAME}` to substitute an environment variable. If the variable is not set, it is replaced with an empty string. ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "provider": { "anthropic": { "options": { "apiKey": "{env:ANTHROPIC_API_KEY}" } } } } ``` ### Files Use `{file:path/to/file}` to substitute the contents of a file (leading and trailing whitespace is trimmed). Paths can be absolute, start with `~/`, or be relative to the directory of the config file. ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "provider": { "openai": { "options": { "apiKey": "{file:~/.secrets/openai-key}" } } } } ``` If the referenced file doesn't exist, loading the config fails with a `bad file reference` error. References on lines commented out with `//` are ignored. ## Configuration ### Top-level keys | Key | Description | | - | - | | `$schema` | JSON schema URL for editor validation | | `model` | Default model, as `provider/model` | | `small_model` | Model for lightweight tasks (titles, commit messages, prompt enhancement) | | `default_agent` | Primary agent used when none is specified | | `provider` | Provider options and model overrides | | `enabled_providers` / `disabled_providers` | Provider allowlist / denylist | | `agent` | Agent configuration ([Custom agents](/code/customize/custom_agents)) | | `command` | Custom commands ([Custom commands](/code/customize/custom_commands)) | | `permission` | Tool permissions ([Tool permissions](/code/security/tool_permissions)) | | `tools` | Legacy tool toggles (use `permission` instead) | | `mcp` | MCP servers ([MCP](/code/configuration/mcp)) | | `instructions` | Additional instruction files, globs, or URLs ([Rules](/code/basics/rules)) | | `skills` | Extra skill locations: `paths` (folders) and `urls` ([Skills](/code/customize/skills)) | | `plugin` | npm or local plugins ([Plugins](/code/customize/plugins)) | | `lsp` | Language servers, or `false` to disable all ([LSP](/code/configuration/lsp)) | | `formatter` | Code formatters, or `false` to disable all | | `compaction` | Context compaction behavior | | `watcher` | File watcher ignore patterns | | `snapshot` | Set to `false` to stop recording file snapshots (undo/revert won't restore file changes). Default `true` | | `autoupdate` | `true`, `false`, or `"notify"` | | `username` | Name displayed in conversations instead of your system username | | `subagent_depth` | Maximum nesting depth for subagents launched via the task tool. Default `1` | | `attachment` | Image attachment limits: `image.auto_resize` (default `true`), `image.max_width` / `image.max_height` (default `2000`), `image.max_base64_bytes` (default `5242880`) | | `server` | `port`, `hostname`, `mdns`, `mdnsDomain`, `cors` for `symbiotic serve` / `symbiotic web` | | `commit_message` | `prompt`: custom prompt for commit message generation | | `enterprise` | `url`: enterprise server URL used for session sharing | | `experimental` | Experimental options (see below) | | `logLevel` | Accepted but currently not applied; use the `--log-level` CLI flag instead | TUI settings such as `theme` and `keybinds` live in a separate `tui.json` file (see [Keybinds](/code/configuration/keybinds)). If these keys are found in `symbiotic.json`, they are automatically moved to a `tui.json` next to it (a `.tui-migration.bak` backup is kept). The deprecated `mode` and `layout` keys are still accepted; use `agent` instead of `mode`. ### Tools You can manage the tools an LLM can use through the legacy `tools` option, but new configurations should use `permission`. `true` maps to `allow` and `false` to `deny`; `write`, `patch`, and `multiedit` map to the `edit` permission. ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "tools": { "write": false, "bash": false } } ``` ### Models You can configure the providers and models you want to use in your Symbiotic Code config through the `provider`, `model` and `small_model` options. ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "provider": {}, "model": "anthropic/claude-sonnet-4-5", "small_model": "anthropic/claude-haiku-4-5" } ``` The `small_model` option configures a separate model for lightweight tasks like title generation. **By default, Symbiotic Code tries to use a cheaper model if one is available from your provider** (for example a Haiku, Flash, or nano model), otherwise it falls back to your main model. ### Provider options Provider options can include `apiKey`, `baseURL`, `timeout`, `chunkTimeout`, and `setCacheKey`: ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "provider": { "anthropic": { "options": { "timeout": 600000, "chunkTimeout": 30000, "setCacheKey": true } } } } ``` | Option | Description | | - | - | | `apiKey` | API key for the provider. Use `{env:...}` or `{file:...}` rather than a literal secret. | | `baseURL` | Custom API endpoint URL | | `timeout` | Total request timeout in milliseconds. No timeout is applied unless set; `false` disables it explicitly. | | `chunkTimeout` | Timeout in milliseconds between streamed response chunks (default: 300000). If no chunk arrives in time, the request is aborted. | | `setCacheKey` | Always send a prompt cache key for this provider (default: `false`). | You can also restrict the models a provider exposes with `whitelist` / `blacklist` (arrays of model IDs), and override or add models under `models`. ### Provider-specific options Some providers support additional configuration options beyond the generic timeout and apiKey settings. #### Amazon Bedrock Amazon Bedrock supports AWS-specific configuration: ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "provider": { "amazon-bedrock": { "options": { "region": "us-east-1", "profile": "my-aws-profile", "endpoint": "https://bedrock-runtime.us-east-1.vpce-xxxxx.amazonaws.com" } } } } ``` | Option | Description | Notes | | - | - | - | | `region` | AWS region for Bedrock | Defaults to the `AWS_REGION` env var, then `us-east-1` | | `profile` | AWS named profile from `~/.aws/credentials` | Defaults to the `AWS_PROFILE` env var | | `endpoint` | Custom endpoint URL for VPC endpoints | This is an alias for the generic `baseURL` option using AWS-specific terminology. If both are specified, `endpoint` takes precedence. | Bearer tokens (`AWS_BEARER_TOKEN_BEDROCK` or `/connect`) take precedence over profile-based authentication. ### Agents You can configure specialized agents for specific tasks through the agent option. ```jsonc symbiotic.jsonc theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "agent": { "code-reviewer": { "description": "Reviews code for best practices and potential issues", "model": "anthropic/claude-sonnet-4-5", "prompt": "You are a code reviewer. Focus on security, performance, and maintainability.", "permission": { // Disable file modification tools for review-only agent "edit": "deny", }, }, }, } ``` You can also define agents using markdown files in `~/.config/symbiotic/agents/` or `.symbiotic/agents/`. See [Custom agents](/code/customize/custom_agents). ### Default agent You can set the default agent using the `default_agent` option. This determines which agent is used when none is explicitly specified. ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "default_agent": "plan" } ``` The default agent must be a **primary agent** (not a subagent or hidden agent). This can be a built-in agent like `build` or `plan`, or a custom agent you’ve defined. When `default_agent` is not set, `build` is used. **If the specified agent doesn’t exist, is a subagent, or is hidden, there is no silent fallback**: the TUI just selects the first primary agent, and requests that don't name an agent (for example `symbiotic run` without `--agent`, or ACP clients) fail with an error such as `default agent "x" not found`. Fix or remove the setting. This setting applies across interfaces: TUI, CLI (`symbiotic run`), and ACP clients. ### Commands You can configure custom commands for repetitive tasks through the `command` option. ```jsonc symbiotic.jsonc theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "command": { "test": { "template": "Run the full test suite with coverage report and show any failures.\nFocus on the failing tests and suggest fixes.", "description": "Run tests with coverage", "agent": "build", "model": "anthropic/claude-haiku-4-5", }, "component": { "template": "Create a new React component named $ARGUMENTS with TypeScript support.\nInclude proper typing and basic structure.", "description": "Create a new component", }, }, } ``` You can also define commands using markdown files in `~/.config/symbiotic/commands/` or `.symbiotic/commands/`. See [Custom commands](/code/customize/custom_commands). ### Auto-update Symbiotic Code checks for a new version when the TUI starts and automatically installs it. You can disable this with the `autoupdate` option. ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "autoupdate": false } ``` If you don’t want updates but want to be notified when a new version is available, set `autoupdate` to `"notify"`. `autoupdate` is only read from your **global** config (`~/.config/symbiotic/`); setting it in a project config has no effect. You can also disable updates with `SYMBIOTIC_DISABLE_AUTOUPDATE=1`. Automatic installation works for the install script and for global npm, pnpm, yarn, and bun installs. ### Formatters You can configure code formatters through the formatter option. Use `$FILE` as a placeholder for the file path. Set `"formatter": false` to disable all formatters. ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "formatter": { "prettier": { "disabled": true }, "custom-prettier": { "command": ["npx", "prettier", "--write", "$FILE"], "environment": { "NODE_ENV": "development" }, "extensions": [".js", ".ts", ".jsx", ".tsx"] } } } ``` ### Permissions By default, all tools are allowed except for a few safety exceptions that ask for confirmation: accessing files outside the project (`external_directory`), reading `.env` files (`*.env`, `*.env.*`; `*.env.example` is allowed), and repeated identical tool calls (`doom_loop`). You can change this using the `permission` option. For example, to ensure that the edit and bash tools require user approval: ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "permission": { "edit": "ask", "bash": "ask" } } ``` See [Tool permissions](/code/security/tool_permissions) for pattern-based rules. ### Compaction You can control context compaction behavior through the `compaction` option. ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "compaction": { "auto": true, "prune": true, "reserved": 10000 } } ``` | Option | Description | Default | | - | - | - | | `auto` | Automatically compact the session when context is full | `true` | | `prune` | Remove old tool outputs to save tokens | `true` | | `reserved` | Token buffer for compaction. Leaves enough window to avoid overflow during compaction | 20000, or the model's max output tokens if lower | | `tail_turns` | Number of recent user turns (with their responses) kept verbatim during compaction | `2` | | `preserve_recent_tokens` | Maximum number of tokens from recent turns kept verbatim after compaction | Based on the model's context size | `SYMBIOTIC_DISABLE_AUTOCOMPACT=1` and `SYMBIOTIC_DISABLE_PRUNE=1` force `auto` and `prune` to `false`. ### Watcher You can configure file watcher ignore patterns through the `watcher` option. ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "watcher": { "ignore": ["node_modules/**", "dist/**", ".git/**"] } } ``` Patterns follow glob syntax. Use this to exclude noisy directories from file watching. ### MCP servers You can configure MCP servers you want to use through the `mcp` option. See [MCP](/code/configuration/mcp) for the full format and the `symbiotic mcp` commands. ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "mcp": {} } ``` ### Plugins Plugins extend Symbiotic Code with custom tools, hooks, and integrations. Place plugin files in `.symbiotic/plugins/` or `~/.config/symbiotic/plugins/`. You can also load plugins from npm through the plugin option. See [Plugins](/code/customize/plugins). ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "plugin": ["@my-org/custom-plugin"] } ``` ### Instructions You can configure the instructions for the model you’re using through the `instructions` option. ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "instructions": ["CONTRIBUTING.md", "docs/guidelines.md", ".cursor/rules/*.md"] } ``` This takes an array of paths, glob patterns, and URLs to instruction files. See [Rules](/code/basics/rules). ### Disabled providers You can disable providers that are loaded automatically through the `disabled_providers` option. This is useful when you want to prevent certain providers from being loaded even if their credentials are available. ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "disabled_providers": ["openai", "gemini"] } ``` The `disabled_providers` option accepts an array of provider IDs. When a provider is disabled: * It won’t be loaded even if environment variables are set. * It won’t be loaded even if API keys are configured through the `/connect` command. * The provider’s models won’t appear in the model selection list. ### Enabled providers You can specify an allowlist of providers through the `enabled_providers` option. When set, only the specified providers will be enabled and all others will be ignored. ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "enabled_providers": ["anthropic", "openai"] } ``` This is useful when you want to restrict Symbiotic Code to only use specific providers rather than disabling them one by one. If a provider appears in both `enabled_providers` and `disabled_providers`, `disabled_providers` takes priority. ### Experimental The `experimental` object contains options that may change or be removed: | Option | Description | | - | - | | `batch_tool` | Enable the batch tool | | `continue_loop_on_deny` | Continue the agent loop when a tool call is denied | | `mcp_timeout` | Timeout in milliseconds for MCP requests | | `primary_tools` | Tools that should only be available to primary agents | | `disable_paste_summary` | Don't summarize large pasted content | | `openTelemetry` | Enable OpenTelemetry spans for AI SDK calls | ## Environment variables Boolean variables accept `1` or `true`. | Variable | Description | | - | - | | `SYMBIOTIC_CONFIG` | Path to an additional config file (loaded after the global config) | | `SYMBIOTIC_CONFIG_DIR` | Additional config directory (config file, agents, commands, skills, plugins, tools, `AGENTS.md`) | | `SYMBIOTIC_CONFIG_CONTENT` | Inline JSON config, applied after all file-based configs | | `SYMBIOTIC_TUI_CONFIG` | Path to an additional `tui.json` file | | `SYMBIOTIC_DISABLE_PROJECT_CONFIG` | Ignore project config files, `.symbiotic/` directories, and project rule files | | `SYMBIOTIC_PERMISSION` | JSON object merged into `permission`, on top of all config sources | | `SYMBIOTIC_DISABLE_AUTOUPDATE` | Disable automatic updates | | `SYMBIOTIC_DISABLE_AUTOCOMPACT` | Disable automatic compaction | | `SYMBIOTIC_DISABLE_PRUNE` | Disable pruning of old tool outputs | | `SYMBIOTIC_DISABLE_CLAUDE_CODE` | Disable `~/.claude/CLAUDE.md` and Claude Code skills | | `SYMBIOTIC_DISABLE_CLAUDE_CODE_PROMPT` | Disable only `~/.claude/CLAUDE.md` | | `SYMBIOTIC_DISABLE_CLAUDE_CODE_SKILLS` | Disable skills from `.claude/` (and `.agents/`) | | `SYMBIOTIC_DISABLE_EXTERNAL_SKILLS` | Disable skills from `.claude/` and `.agents/` | | `SYMBIOTIC_DISABLE_LSP_DOWNLOAD` | Don't download language servers automatically | | `SYMBIOTIC_DISABLE_MODELS_FETCH` | Don't fetch the model catalog from models.dev | | `SYMBIOTIC_DISABLE_TERMINAL_TITLE` | Don't update the terminal title | | `SYMBIOTIC_PURE` | Skip loading external plugins configured in `plugin` | | `SYMBIOTIC_SERVER_PASSWORD` | Enable HTTP basic auth on `symbiotic serve` / `symbiotic web` | | `SYMBIOTIC_SERVER_USERNAME` | Basic auth username (default: `symbiotic`) | | `SYMBIOTIC_GIT_BASH_PATH` | Windows: path to the Git Bash executable used for shell commands | # Models and providers Source: https://docs.symbioticsec.ai/code/basics/models_and_providers Choose your models and providers ## Models By default you have access to Symbiotic's models through the **Symbiotic** provider. List and switch between models with the `/models` command (or press `Ctrl+X` then `M`). To use a different model, add or connect another provider with the `/connect` command. In the `/models` dialog, press `Ctrl+F` to mark a model as a favorite and `Ctrl+A` to open the provider list. Press `F2` / `Shift+F2` to cycle through recently used models, and `Ctrl+T` to cycle through the model's variants (for example reasoning effort levels), when available. Models are identified as `provider/model`, for example `anthropic/claude-sonnet-4-5`. To list the available model IDs, run: ```bash theme={null} symbiotic models # all models symbiotic models anthropic # models from one provider ``` ### Set a default model Set `model` in your [configuration file](/code/basics/configuration_file). You can also set `small_model`, used for lightweight tasks like title generation. When `small_model` is not set, a cheaper model from the same provider is picked automatically. ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "model": "anthropic/claude-sonnet-4-5", "small_model": "anthropic/claude-haiku-4-5" } ``` When starting, Symbiotic Code picks the model in this order: 1. The `--model` / `-m` flag, e.g. `symbiotic -m anthropic/claude-sonnet-4-5` 2. The `model` key in your configuration 3. The default model of the Symbiotic provider (or of the first available provider) 4. Your most recently used model The model you pick in `/models` applies to the current agent. You can also assign a model to a specific agent with its `model` option. See [Custom agents](/code/customize/custom_agents). ## Providers Symbiotic Code **supports 75+ LLM providers and it supports running local models**. To add a provider, run the `/connect` command and enter the API key (or sign in) for the provider of your choice. You can also do it from the command line: ```bash theme={null} symbiotic providers login # add credentials (alias: symbiotic auth login) symbiotic providers list # list stored credentials and environment variables symbiotic providers logout # remove credentials ``` Credentials are stored in `~/.local/share/symbiotic/auth.json`. Providers are also enabled automatically when their API key environment variable is set (for example `ANTHROPIC_API_KEY` or `OPENAI_API_KEY`). **Most popular providers are preloaded by default.** If you’ve added the credentials for a provider through the `/connect` command, they’ll be available when you start Symbiotic Code. ### Restrict providers Use `enabled_providers` to allow only specific providers, or `disabled_providers` to hide providers that would otherwise be loaded automatically: ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "enabled_providers": ["symbiotic", "anthropic"], "disabled_providers": ["openai"] } ``` ### Configure a provider Each entry under `provider` can set `options` (such as `apiKey`, `baseURL`, `timeout`, `chunkTimeout`, and `setCacheKey`), and restrict its models with `whitelist` or `blacklist`: ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "provider": { "anthropic": { "options": { "apiKey": "{env:MY_ANTHROPIC_KEY}", "timeout": 600000 }, "whitelist": ["claude-sonnet-4-5", "claude-haiku-4-5"] } } } ``` `{env:VAR}` and `{file:path}` are replaced with the value of an environment variable or the content of a file. See [Provider options](/code/basics/configuration_file#provider-options) for details. ### Create a custom provider If you want to use a local model or a model hosted in your own infrastructure, you can create a custom provider by **adding a "provider" section to your symbiotic.json configuration file**. ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "provider": { "myprovider": { "npm": "@ai-sdk/openai-compatible", "name": "My AI Provider Display Name", "options": { "baseURL": "https://api.myprovider.com/v1" }, "models": { "my-model-name": { "name": "My Model Display Name" } } } } } ``` * `npm`: the AI SDK package used to talk to the provider. Use `@ai-sdk/openai-compatible` for any OpenAI-compatible API (Ollama, LM Studio, vLLM, llama.cpp…). * `options.baseURL`: the API endpoint, for example `http://localhost:11434/v1` for a local Ollama server. * `models`: the models to expose. The key is the model ID sent to the API. The model is then available as `myprovider/my-model-name`. If the provider requires an API key, set `options.apiKey` or store it with `symbiotic providers login` (select **Other** and enter `myprovider` as the provider ID). # Rules Source: https://docs.symbioticsec.ai/code/basics/rules Rules for Symbiotic Code You can provide **custom instructions to Symbiotic Code by creating an AGENTS.md file.** This is similar to Cursor’s rules. It contains instructions that will be included in the LLM’s context to **customize its behavior for your specific project.** ## Initialize To create a new `AGENTS.md` file, you can run the `/init` command in Symbiotic Code. You can pass extra focus or constraints as arguments, for example `/init focus on the backend services`. You should commit your project’s `AGENTS.md` file to Git. **`/init` scans the important files in your repo** (README, manifests, build/test/lint config, CI workflows, and existing instruction files such as `CLAUDE.md`, `.cursor/rules/`, `.cursorrules`, or `.github/copilot-instructions.md`), may ask a couple of targeted questions when the codebase cannot answer them, and then creates or updates `AGENTS.md` with **concise project-specific guidance.** It focuses on the things future agent sessions are most likely to need: * build, lint, and test commands * command order and focused verification steps when they matter * architecture and repo structure that are not obvious from filenames alone * project-specific conventions, setup quirks, and operational gotchas * references to existing instruction sources like Cursor or Copilot rules **If you already have an `AGENTS.md` file, `/init` will improve it in place instead of blindly replacing it.** ## Types Symbiotic Code also supports reading the AGENTS.md file from multiple locations. And this serves different purposes. ### Project Place an `AGENTS.md` in your project root for project-specific rules. These only apply when you are working in this directory or its sub-directories. At startup, Symbiotic Code walks up from the current directory to the root of the Git repository and loads **every** `AGENTS.md` it finds along the way. This means that in a monorepo, starting a session in `packages/api/` loads both `packages/api/AGENTS.md` and the root `AGENTS.md`. #### Nested AGENTS.md files `AGENTS.md` files located in sub-directories below the directory you started Symbiotic Code in are loaded **on demand**: when the agent reads a file, Symbiotic Code looks for an `AGENTS.md` (or `CLAUDE.md`) in that file's directory and each parent directory up to your working directory, and attaches any it has not already loaded to the read result. Each file is only injected once per conversation. ### Global You can also have global rules in a `~/.config/symbiotic/AGENTS.md` file. This gets applied across all Symbiotic Code sessions. Since this isn’t committed to Git or shared with your team, we recommend using this to specify any personal rules that the LLM should follow. If the `SYMBIOTIC_CONFIG_DIR` environment variable is set, `$SYMBIOTIC_CONFIG_DIR/AGENTS.md` is checked first and takes precedence over `~/.config/symbiotic/AGENTS.md`. ### Claude Code Compatibility For users migrating from Claude Code, Symbiotic Code supports Claude Code’s file conventions as fallbacks: * **Project rules**: `CLAUDE.md` in your project directory (used if no `AGENTS.md` exists) * **Global rules**: `~/.claude/CLAUDE.md` (used if no `~/.config/symbiotic/AGENTS.md` exists) * **Skills**: `~/.claude/skills/` and `.claude/skills/` in your project — see [Agent Skills](/code/customize/skills) for details To disable Claude Code compatibility, set one of these environment variables: ```bash theme={null} export SYMBIOTIC_DISABLE_CLAUDE_CODE=1 # Disable ~/.claude/CLAUDE.md and Claude Code skills export SYMBIOTIC_DISABLE_CLAUDE_CODE_PROMPT=1 # Disable only ~/.claude/CLAUDE.md export SYMBIOTIC_DISABLE_CLAUDE_CODE_SKILLS=1 # Disable only .claude/skills (also disables .agents/skills) ``` These variables do not affect a project-level `CLAUDE.md`, which is always used as a fallback when no `AGENTS.md` exists. In the VS Code extension, Claude Code files are **not** loaded by default. Enable **Load Claude Code Files** in **Settings > Agent Behaviour > Rules** (requires a restart). ## Precedence When Symbiotic Code starts, it looks for rule files in this order: * **Local files** by traversing up from the current directory to the Git root: `AGENTS.md`, then `CLAUDE.md`, then `CONTEXT.md` (deprecated) * **Global file** at `$SYMBIOTIC_CONFIG_DIR/AGENTS.md` (if set), then `~/.config/symbiotic/AGENTS.md` * **Claude Code file** at `~/.claude/CLAUDE.md` (unless disabled) The first matching file name wins in each category: one local file name (all matching files up the tree are loaded), and one global file. For example, if you have both `AGENTS.md` and `CLAUDE.md`, only `AGENTS.md` is used. Similarly, `~/.config/symbiotic/AGENTS.md` takes precedence over `~/.claude/CLAUDE.md`. Local and global rules are both loaded; they don't replace each other. Other tools' rule files such as `.cursorrules`, `.cursor/rules/`, `.github/copilot-instructions.md`, or `GEMINI.md` are **not** loaded automatically. Add them through `instructions` (see below). Setting `SYMBIOTIC_DISABLE_PROJECT_CONFIG=1` disables local rule files (and relative `instructions` paths, unless `SYMBIOTIC_CONFIG_DIR` is set). ### Custom Instructions You can specify custom instruction files in your `symbiotic.json` or the global `~/.config/symbiotic/symbiotic.json`. This allows you and your team to reuse existing rules rather than having to duplicate them to AGENTS.md. **Example:** ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "instructions": ["CONTRIBUTING.md", "docs/guidelines.md", ".cursor/rules/*.md"] } ``` Each entry can be: * A **relative path or glob**: matched in the current directory and in every parent directory up to the Git root * An **absolute path or glob**, or a path starting with `~/` * A **remote URL** (`http://` or `https://`) You can also use remote URLs to load instructions from the web. ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "instructions": ["https://raw.githubusercontent.com/my-org/shared-rules/main/style.md"] } ``` Remote instructions are fetched with a 5 second timeout. If a URL fails to load, it is silently skipped. All instruction files are combined with your `AGENTS.md` files. When several config files define `instructions`, the lists are merged (not replaced). ## Referencing External Files While Symbiotic Code doesn’t automatically parse file references in AGENTS.md, you can achieve similar functionality in two ways: ### Using symbiotic.json The recommended approach is to use the instructions field in symbiotic.json: ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "instructions": ["docs/development-standards.md", "test/testing-guidelines.md", "packages/*/AGENTS.md"] } ``` ### Manual Instructions in AGENTS.md You can teach Symbiotic Code to read external files by providing explicit instructions in your AGENTS.md. Here’s a practical example: ```markdown AGENTS.md theme={null} # TypeScript Project Rules ## External File Loading CRITICAL: When you encounter a file reference (e.g., @rules/general.md), use your Read tool to load it on a need-to-know basis. They're relevant to the SPECIFIC task at hand. Instructions: - Do NOT preemptively load all references - use lazy loading based on actual need - When loaded, treat content as mandatory instructions that override defaults - Follow references recursively when needed ## Development Guidelines For TypeScript code style and best practices: @docs/typescript-guidelines.md For React component architecture and hooks patterns: @docs/react-patterns.md For REST API design and error handling: @docs/api-standards.md For testing strategies and coverage requirements: @test/testing-guidelines.md ## General Guidelines Read the following file immediately as it's relevant to all workflows: @rules/general-guidelines.md. ``` This approach allows you to: * Create modular, reusable rule files * Share rules across projects via symlinks or git submodules * Keep AGENTS.md concise while referencing detailed guidelines * Ensure Symbiotic Code loads files only when needed for the specific task For monorepos or projects with shared standards, using `symbiotic.json` with glob patterns (like `packages/*/AGENTS.md`) is more maintainable than manual instructions. # Troubleshooting Source: https://docs.symbioticsec.ai/code/basics/troubleshooting Common issues and how to solve them ## Quick reference | Issue | Solution | | - | - | | `command not found: symbiotic` | Make sure the install location is in your PATH and restart your terminal: the npm global bin directory (`npm config get prefix`, then `bin/`) for npm installs, or `~/.symbiotic/bin` for the install script | | Authentication fails | Verify your token is valid in the portal and hasn't expired | | Permission denied | Run `chmod +x ~/.symbiotic/bin/symbiotic` (install script), or see [Installation issues](#installation-issues) for npm installs | | `Configuration is invalid at ...` | A config file contains an unknown key or a wrong value type. The message lists the file and the offending key; see [Configuration issues](#configuration-issues) | | `Config file at ... is not valid JSON(C)` | Fix the syntax error at the reported line and column | | Can't go to the next line | Use one of these keybindings: `shift+return`, `ctrl+return`, `alt+return`, or `ctrl+j` | *** ## Logs Symbiotic Code writes log files to: * **macOS/Linux**: `~/.local/share/symbiotic/log/` * **Windows**: `%USERPROFILE%\.local\share\symbiotic\log` Log files are named with a timestamp (e.g., `2026-01-09T123456.log`) and only the most recent 10 are kept. To get more detail, raise the log level or print logs directly to your terminal: ```bash theme={null} symbiotic --log-level DEBUG # DEBUG, INFO (default), WARN, ERROR symbiotic run "hello" --print-logs # print logs to stderr instead of a file ``` *** ## Storage Symbiotic Code uses these directories (on Windows, under `%USERPROFILE%`): | Directory | Content | | - | - | | `~/.config/symbiotic/` | Global config (`symbiotic.json`, `tui.json`, `AGENTS.md`, agents, commands, plugins...) | | `~/.local/share/symbiotic/` | Data: `auth.json` (credentials), `mcp-auth.json`, `symbiotic.db` (sessions), `log/`, `snapshot/`, `bin/` (downloaded tools and language servers) | | `~/.cache/symbiotic/` | Cache: model catalog, installed npm packages for plugins | | `~/.local/state/symbiotic/` | TUI state: recent models, prompt history, key-value settings (such as the current security mode) | Run `symbiotic debug paths` to print the exact paths on your machine. These follow `XDG_CONFIG_HOME`, `XDG_DATA_HOME`, `XDG_CACHE_HOME`, and `XDG_STATE_HOME` if set. `auth.json` contains your API keys and tokens. Don't share it or include it in bug reports. *** ## Configuration issues * **See the final config:** `symbiotic debug config` prints the fully merged configuration for the current directory, so you can check which value actually wins. See [Configuration file](/code/basics/configuration_file#locations) for precedence. * **Unknown key errors:** the config schema is strict. Typos or keys from other tools cause `Configuration is invalid`. `theme` and `keybinds` belong in `tui.json`, not `symbiotic.json`. * **`bad file reference`:** a `{file:...}` substitution points to a file that doesn't exist. Relative paths are resolved from the directory of the config file. * **Settings not applied in a project:** a project `symbiotic.json`, a `.symbiotic/symbiotic.json`, `SYMBIOTIC_CONFIG_CONTENT`, or a managed config may override your global value. * **Isolate project config:** start with `SYMBIOTIC_DISABLE_PROJECT_CONFIG=1 symbiotic` to ignore all project-level config and rule files. * **Check agents and skills:** `symbiotic debug agent ` shows an agent's resolved configuration, and `symbiotic debug skill` lists the skills that were discovered. ### Plugins causing crashes or hangs If Symbiotic Code crashes on startup or behaves strangely after adding plugins: 1. Start once with `SYMBIOTIC_PURE=1 symbiotic` to skip external plugins listed in `plugin`. 2. If that fixes it, remove entries from `plugin` in your config, or temporarily move plugin files out of `~/.config/symbiotic/plugins/` and `.symbiotic/plugins/`, then re-enable them one at a time. 3. If a plugin install is stuck, quit Symbiotic Code and delete `~/.cache/symbiotic/` so it is rebuilt on the next start. *** ## Installation issues ### Windows If you have trouble installing Symbiotic Code on PowerShell, try launching the install command with Git Bash, which you can download [here](https://gitforwindows.org/). If the issue is related to PowerShell execution policy, run PowerShell as Administrator and execute: ```powershell theme={null} Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser ``` On Windows, shell commands run in Git Bash when it is found next to your `git` installation, otherwise in `cmd.exe`. If Git Bash is installed in a non-standard location, set `SYMBIOTIC_GIT_BASH_PATH` to the full path of `bash.exe`. ### Permission denied (macOS/Linux) If you get a permission error when installing globally: ```bash theme={null} # Option 1: Use sudo sudo npm install -g @symbioticsec/code # Option 2: Configure npm to use a user directory mkdir ~/.npm-global npm config set prefix "~/.npm-global" echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc source ~/.bashrc ``` ### Automatic updates Symbiotic Code checks for updates when the TUI starts and upgrades itself using the same method it was installed with (npm, pnpm, yarn, bun, or the install script). If automatic updates fail (for example because the global npm directory is not writable), update manually with `npm install -g @symbioticsec/code`, or disable updates with `"autoupdate": false` in `~/.config/symbiotic/symbiotic.json` or `SYMBIOTIC_DISABLE_AUTOUPDATE=1`. *** ## Platform-specific issues ### Copy/paste not working on Linux Linux users need one of the following clipboard utilities installed for copy/paste to work. **X11 systems:** ```bash theme={null} apt install -y xclip # or apt install -y xsel ``` **Wayland systems:** ```bash theme={null} apt install -y wl-clipboard ``` **Headless environments:** ```bash theme={null} apt install -y xvfb # and run: Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & export DISPLAY=:99.0 ``` Symbiotic Code will detect if you're using Wayland and prefer `wl-clipboard`, otherwise it will try `xclip` then `xsel`. ### Using Symbiotic Code in a Docker container 1. Download the script and Dockerfile [here](https://github.com/SymbioticSec/mintlify-docs/raw/refs/heads/main/assets/symbiotic_code_docker.zip) 2. Unzip the file 3. Launch Docker Desktop 4. Make the script executable: ```bash theme={null} chmod +x run-symbiotic.sh ``` 5. Run the script: ```bash theme={null} ./run-symbiotic.sh ``` 6. You are now inside the container and can run the `symbiotic` command to launch the coding agent. *** ## Network and connectivity If you're behind a corporate firewall or proxy, you may need to allowlist the following domains for Symbiotic Code to connect to the API: * `api.symbioticsec.ai:443` * `llm-proxy.symbioticsec.ai:443` * `app.symbioticsec.ai:443` (browser sign-in) Symbiotic Code also fetches the model catalog from `models.dev`. If it is blocked, set `SYMBIOTIC_DISABLE_MODELS_FETCH=1`. Language servers are downloaded on demand from GitHub and npm; set `SYMBIOTIC_DISABLE_LSP_DOWNLOAD=1` to turn this off. **Proxy configuration:** Symbiotic Code honors the standard `HTTPS_PROXY` / `HTTP_PROXY` environment variables. To install through a corporate proxy, also configure npm: ```bash theme={null} npm config set proxy http://proxy.company.com:8080 npm config set https-proxy http://proxy.company.com:8080 ``` **npm registry blocked:** If the npm registry is inaccessible: * Check proxy settings: `npm config get proxy` * Verify your firewall allows access to `registry.npmjs.org:443` * Contact IT to whitelist the npm registry *** ## Health check script Run the following command to verify that your system is ready for Symbiotic Code: ```bash theme={null} curl -fsSL https://raw.githubusercontent.com/SymbioticSec/mintlify-docs/refs/heads/main/assets/symbiotic-health-check.js | node ``` The script checks: 1. **Node.js** — Ensures Node.js is installed (v14+ recommended) 2. **npm** — Verifies npm is available 3. **Global install permissions** — Tests ability to install global npm packages 4. **Execution policy** (Windows only) — Checks PowerShell execution policy 5. **Proxy configuration** — Displays current proxy settings 6. **npm registry access** — Tests connectivity to `registry.npmjs.org:443` 7. **Required endpoints** — Tests connectivity to: * `api.symbioticsec.ai:443` * `llm-proxy.symbioticsec.ai:443` Once all checks pass, install with: ```bash theme={null} npm install -g @symbioticsec/code ``` **If issues persist**, save the health check output and contact support: ```bash theme={null} curl -fsSL https://raw.githubusercontent.com/SymbioticSec/mintlify-docs/refs/heads/main/assets/symbiotic-health-check.js -o symbiotic-health-check.js node symbiotic-health-check.js > healthcheck-results.txt 2>&1 ``` ***

Need help?

Contact us using the dedicated Slack channel or email us at [support@symbioticsec.ai](mailto:support@symbioticsec.ai) with your health check results, the latest log file from `~/.local/share/symbiotic/log/`, your OS version, and network environment.

# ACP Source: https://docs.symbioticsec.ai/code/configuration/acp Use Symbiotic Code in editors and IDEs Symbiotic Code supports the [Agent Client Protocol](https://agentclientprotocol.com) or (ACP), allowing you to use it directly in compatible editors and IDEs. For a list of editors and tools that support ACP, check out the [ACP progress report](https://zed.dev/blog/acp-progress-report#available-now). ACP is an open protocol that standardizes communication between code editors and AI coding agents. *** ## Configure To use Symbiotic Code via ACP, configure your editor to run the `symbiotic acp` command. The command starts Symbiotic Code as an ACP-compatible subprocess that communicates with your editor over JSON-RPC via stdio. The project directory is provided by your editor when it opens a session. If you aren't logged in, the editor offers a **Login with symbiotic** option, which runs `symbiotic auth login`. Below are examples for popular editors that support ACP. *** ### Zed Add to your [Zed](https://zed.dev) configuration (`~/.config/zed/settings.json`): ```json title="~/.config/zed/settings.json" theme={null} { "agent_servers": { "Symbiotic": { "command": "symbiotic", "args": ["acp"] } } } ``` To open it, use the `agent: new thread` action in the **Command Palette**. You can also bind a keyboard shortcut by editing your `keymap.json`: ```json title="keymap.json" theme={null} [ { "bindings": { "cmd-alt-o": [ "agent::NewExternalAgentThread", { "agent": { "custom": { "name": "Symbiotic Code", "command": { "command": "symbiotic", "args": ["acp"] } } } } ] } } ] ``` *** ### JetBrains IDEs Add `acp.json` to your [JetBrains IDE](https://www.jetbrains.com/) according to the [documentation](https://www.jetbrains.com/help/ai-assistant/acp.html): ```json title="acp.json" theme={null} { "agent_servers": { "Symbiotic Code": { "command": "symbiotic", "args": ["acp"] } } } ``` To open it, use the new **'Symbiotic Code'** agent in the AI Chat agent selector. *** ## Support Symbiotic Code works the same via ACP as it does in the terminal. The following features are supported: * Built-in tools (file operations, terminal commands, etc.) * Custom tools and slash commands, including skills, MCP prompts, and `/compact` * MCP servers configured in your Symbiotic Code config, plus MCP servers sent by your editor * Project-specific rules from `AGENTS.md` * Custom formatters and linters * Agents and permissions system: primary agents appear as session modes, and permission prompts are shown by your editor with **Allow once**, **Always allow**, and **Reject** options * Model and variant selection, and loading, resuming, and forking previous sessions Slash commands that only exist in the TUI, like `/undo`, `/redo`, and `/security-mode`, are not available. Sessions use the agent's configured `security_mode`, or **Balanced** by default. The `question` tool is disabled by default in ACP. Set `SYMBIOTIC_ENABLE_QUESTION_TOOL=1` in the command's environment if your editor supports interactive question prompts. # Keybinds Source: https://docs.symbioticsec.ai/code/configuration/keybinds Customize your keybinds. Symbiotic Code supports custom keybinds that you configure in the `keybinds` section of `tui.json` (or `tui.jsonc`). * Global: `~/.config/symbiotic/tui.json` * Project: `tui.json` at the root of your project (or any directory between your working directory and the git root), or `.symbiotic/tui.json` * Custom path: set the `SYMBIOTIC_TUI_CONFIG` environment variable Files are merged, with project files overriding global ones. You only need to list the keybinds you want to change. If you still have `keybinds` in `symbiotic.json`, they are moved automatically to a `tui.json` next to it on startup (a `.tui-migration.bak` backup is kept). The defaults are: ```json title="tui.json" theme={null} { "$schema": "https://config.symbioticsec.ai/tui.json", "keybinds": { "leader": "ctrl+x", "app_exit": "ctrl+c,ctrl+d,q", "editor_open": "e", "theme_list": "t", "sidebar_toggle": "b", "scrollbar_toggle": "none", "username_toggle": "none", "status_view": "s", "tool_details": "none", "session_export": "x", "session_new": "n", "session_list": "l", "session_timeline": "g", "session_fork": "none", "session_rename": "ctrl+r", "session_delete": "ctrl+d", "session_pin_toggle": "ctrl+f", "session_quick_switch_1": "1", "session_quick_switch_2": "2", "session_quick_switch_3": "3", "session_quick_switch_4": "4", "session_quick_switch_5": "5", "session_quick_switch_6": "6", "session_quick_switch_7": "7", "session_quick_switch_8": "8", "session_quick_switch_9": "9", "session_share": "none", "session_unshare": "none", "session_interrupt": "escape", "session_subagent_interrupt": "ctrl+shift+y", "session_compact": "c", "session_child_first": "down", "session_child_cycle": "right", "session_child_cycle_reverse": "left", "session_parent": "up", "session_background": "ctrl+y", "session_subagent_list": "ctrl+o", "stash_delete": "ctrl+d", "messages_page_up": "pageup,ctrl+alt+b", "messages_page_down": "pagedown,ctrl+alt+f", "messages_line_up": "ctrl+alt+y", "messages_line_down": "ctrl+alt+e", "messages_half_page_up": "ctrl+alt+u", "messages_half_page_down": "ctrl+alt+d", "messages_first": "ctrl+g,home", "messages_last": "ctrl+alt+g,end", "messages_next": "none", "messages_previous": "none", "messages_copy": "y", "messages_undo": "u", "messages_redo": "r", "messages_last_user": "none", "messages_toggle_conceal": "h", "model_list": "m", "model_cycle_recent": "f2", "model_cycle_recent_reverse": "shift+f2", "model_cycle_favorite": "none", "model_cycle_favorite_reverse": "none", "model_provider_list": "ctrl+a", "model_favorite_toggle": "ctrl+f", "variant_cycle": "ctrl+t", "security_mode_cycle": "ctrl+s", "command_list": "ctrl+p", "agent_list": "a", "agent_cycle": "tab", "agent_cycle_reverse": "shift+tab", "input_clear": "ctrl+c", "input_paste": "ctrl+v", "input_submit": "return", "input_newline": "shift+return,ctrl+return,alt+return,ctrl+j", "input_move_left": "left,ctrl+b", "input_move_right": "right,ctrl+f", "input_move_up": "up", "input_move_down": "down", "input_select_left": "shift+left", "input_select_right": "shift+right", "input_select_up": "shift+up", "input_select_down": "shift+down", "input_line_home": "ctrl+a", "input_line_end": "ctrl+e", "input_select_line_home": "ctrl+shift+a", "input_select_line_end": "ctrl+shift+e", "input_visual_line_home": "alt+a", "input_visual_line_end": "alt+e", "input_select_visual_line_home": "alt+shift+a", "input_select_visual_line_end": "alt+shift+e", "input_buffer_home": "home", "input_buffer_end": "end", "input_select_buffer_home": "shift+home", "input_select_buffer_end": "shift+end", "input_delete_line": "ctrl+shift+d", "input_delete_to_line_end": "ctrl+k", "input_delete_to_line_start": "ctrl+u", "input_backspace": "backspace,shift+backspace", "input_delete": "ctrl+d,delete,shift+delete", "input_undo": "ctrl+-,super+z,ctrl+z", "input_redo": "ctrl+.,super+shift+z,ctrl+shift+z", "input_word_forward": "alt+f,alt+right,ctrl+right", "input_word_backward": "alt+b,alt+left,ctrl+left", "input_select_word_forward": "alt+shift+f,alt+shift+right", "input_select_word_backward": "alt+shift+b,alt+shift+left", "input_delete_word_forward": "alt+d,alt+delete,ctrl+delete", "input_delete_word_backward": "ctrl+w,ctrl+backspace,alt+backspace", "history_previous": "up", "history_next": "down", "terminal_suspend": "ctrl+esc", "terminal_title_toggle": "none", "tips_toggle": "h", "display_thinking": "none" } } ``` *** ## Leader key Symbiotic Code uses a `leader` key for most keybinds. This avoids conflicts in your terminal. By default, `ctrl+x` is the leader key and most actions require you to first press the leader key and then the shortcut. For example, to start a new session you first press `ctrl+x` and then press `n`. The leader key stays active for 2 seconds. You don't need to use a leader key for your keybinds but we recommend doing so. *** ## Keybind syntax * Combine modifiers and a key with `+`, for example `ctrl+shift+a`. Supported modifiers are `ctrl`, `alt` (also `meta` or `option`), `shift`, and `super`. * Use `` to reference the leader key, for example `n`. * Separate alternative bindings with commas, for example `"pageup,ctrl+alt+b"`. Some keybinds only apply inside a specific dialog: `session_delete` and `session_pin_toggle` in the session list, `stash_delete` in the stash dialog, and `model_provider_list` and `model_favorite_toggle` in the model list. That's why they can share keys with other actions. Keybind names are validated. If `tui.json` contains an unknown keybind name, the whole file is ignored and a warning is written to the log. *** ## Disable keybind You can disable a keybind by adding the key to `tui.json` with a value of "none". ```json title="tui.json" theme={null} { "$schema": "https://config.symbioticsec.ai/tui.json", "keybinds": { "session_compact": "none" } } ``` *** ## Shift+Enter Some terminals don't send modifier keys with Enter by default. You may need to configure your terminal to send `Shift+Enter` as an escape sequence. ### Windows Terminal Open your `settings.json` at: ``` %LOCALAPPDATA%\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json ``` Add this to the root-level `actions` array: ```json theme={null} "actions": [ { "command": { "action": "sendInput", "input": "\u001b[13;2u" }, "id": "User.sendInput.ShiftEnterCustom" } ] ``` Add this to the root-level `keybindings` array: ```json theme={null} "keybindings": [ { "keys": "shift+enter", "id": "User.sendInput.ShiftEnterCustom" } ] ``` Save the file and restart Windows Terminal or open a new tab. # LSP Source: https://docs.symbioticsec.ai/code/configuration/lsp Help the LLM understand your codebase with Language Server Protocol (LSP) Symbiotic Code integrates with your [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) (LSP) to help the LLM interact with your codebase. It uses diagnostics to provide feedback to the LLM: after the agent edits or writes a file, any errors reported by the language server are added to the tool result so the agent can fix them. *** ## Built-in LSP Servers Symbiotic Code comes with several built-in LSP servers for popular languages: | LSP Server | Extensions | Requirements | | - | - | - | | astro | .astro | `typescript` dependency in project; auto-installs `@astrojs/language-server` | | bash | .sh, .bash, .zsh, .ksh | Auto-installs `bash-language-server` | | biome | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts, .json, .jsonc, .vue, .astro, .svelte, .css, .graphql, .gql, .html | `biome` installed in the project or on your `PATH` | | clangd | .c, .cpp, .cc, .cxx, .c++, .h, .hpp, .hh, .hxx, .h++ | Auto-downloads from GitHub releases | | clojure-lsp | .clj, .cljs, .cljc, .edn | `clojure-lsp` command available | | csharp | .cs | `.NET SDK` installed; auto-installs `csharp-ls` | | dart | .dart | `dart` command available | | deno | .ts, .tsx, .js, .jsx, .mjs | `deno` command available and a `deno.json`/`deno.jsonc` file | | dockerfile | .dockerfile | Auto-installs `dockerfile-language-server-nodejs` | | elixir-ls | .ex, .exs | `elixir` command available; auto-downloads elixir-ls | | eslint | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts, .vue | `eslint` dependency in project | | fsharp | .fs, .fsi, .fsx, .fsscript | `.NET SDK` installed; auto-installs `fsautocomplete` | | gleam | .gleam | `gleam` command available | | gopls | .go | `go` command available; auto-installs `gopls` | | haskell-language-server | .hs, .lhs | `haskell-language-server-wrapper` command available | | jdtls | .java | `Java SDK (version 21+)` installed; auto-downloads JDTLS | | julials | .jl | `julia` and `LanguageServer.jl` installed | | kotlin-ls | .kt, .kts | Auto-downloads from GitHub releases | | lua-ls | .lua | Auto-downloads from GitHub releases | | nixd | .nix | `nixd` command available | | ocaml-lsp | .ml, .mli | `ocamllsp` command available | | oxlint | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts, .vue, .astro, .svelte | `oxlint` dependency in project | | php intelephense | .php | Auto-installs `intelephense` | | prisma | .prisma | `prisma` command available | | pyright | .py, .pyi | Auto-installs `pyright` | | ruby-lsp (rubocop) | .rb, .rake, .gemspec, .ru | `ruby` and `gem` commands available; auto-installs `rubocop` | | rust | .rs | `rust-analyzer` command available | | sourcekit-lsp | .swift, .objc | `swift` installed (`xcode` on macOS) | | svelte | .svelte | Auto-installs `svelte-language-server` | | terraform | .tf, .tfvars | Auto-downloads from HashiCorp releases | | texlab | .tex, .bib | Auto-downloads from GitHub releases | | tinymist | .typ, .typc | Auto-downloads from GitHub releases | | typescript | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts | `typescript` dependency in project | | vue | .vue | Auto-installs `@vue/language-server` | | yaml-ls | .yaml, .yml | Auto-installs Red Hat `yaml-language-server` | | zls | .zig, .zon | `zig` command available; auto-downloads zls | LSP servers are automatically enabled when one of the above file extensions are detected and the requirements are met. Auto-installed servers are stored in `~/.local/share/symbiotic/bin/`. You can disable automatic LSP server downloads by setting the `SYMBIOTIC_DISABLE_LSP_DOWNLOAD` environment variable to `true`. Servers that are already installed or available on your `PATH` still work. To use [ty](https://github.com/astral-sh/ty) instead of pyright for Python, set `SYMBIOTIC_EXPERIMENTAL_LSP_TY=true`. `ty` must be on your `PATH` or in your project's virtual environment. *** ## How it works When Symbiotic Code opens a file, it: 1. Checks the file extension against all enabled LSP servers. 2. Finds the project root for each matching server (for example the nearest lockfile, `go.mod`, or `Cargo.toml`). 3. Starts the appropriate LSP server for that root if not already running. If a server fails to start, it isn't retried for that root until Symbiotic Code restarts. ### LSP tool (experimental) Set `SYMBIOTIC_EXPERIMENTAL_LSP_TOOL=true` (or `SYMBIOTIC_EXPERIMENTAL=true`) to give the agent an `lsp` tool for code navigation: go to definition, find references, hover, document and workspace symbols, go to implementation, and call hierarchy. It's controlled by the `lsp` [permission](/code/security/tool_permissions). *** ## Configure You can customize LSP servers through the `lsp` section in your Symbiotic Code config. ```json title="symbiotic.json" theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "lsp": {} } ``` Each LSP server supports the following: | Property | Type | Description | | - | - | - | | `disabled` | boolean | Set this to `true` to disable the LSP server | | `command` | string\[] | The command to start the LSP server. Required unless `disabled` is `true` | | `extensions` | string\[] | File extensions this LSP server should handle. Required for custom servers | | `env` | object | Environment variables to set when starting server | | `initialization` | object | Initialization options to send to the LSP server | Configuring a built-in server replaces how it is started: your `command` is used instead of the built-in detection and auto-install, and built-in initialization options are not sent. The server keeps its built-in extensions and root detection unless you override `extensions`. Let's look at some examples. *** ### Environment variables Use the `env` property to set environment variables when starting the LSP server: ```json title="symbiotic.json" {6-8} theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "lsp": { "rust": { "command": ["rust-analyzer"], "env": { "RUST_LOG": "debug" } } } } ``` *** ### Initialization options Use the `initialization` property to pass initialization options to the LSP server. These are server-specific settings sent during the LSP `initialize` request: ```json title="symbiotic.json" {6-10} theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "lsp": { "pyright": { "command": ["pyright-langserver", "--stdio"], "initialization": { "python": { "pythonPath": ".venv/bin/python" } } } } } ``` Initialization options vary by LSP server. Check your LSP server's documentation for available options. *** ### Disabling LSP servers To disable **all** LSP servers globally, set `lsp` to `false`: ```json title="symbiotic.json" {3} theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "lsp": false } ``` To disable a **specific** LSP server, set `disabled` to `true`: ```json title="symbiotic.json" {5} theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "lsp": { "typescript": { "disabled": true } } } ``` *** ### Custom LSP servers You can add custom LSP servers by specifying the command and file extensions: ```json title="symbiotic.json" {4-7} theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "lsp": { "custom-lsp": { "command": ["custom-lsp-server", "--stdio"], "extensions": [".custom"] } } } ``` Custom servers are started in your current working directory. # MCP servers Source: https://docs.symbioticsec.ai/code/configuration/mcp Add MCP servers to Symbiotic Code You can add external tools to Symbiotic Code using the [Model Context Protocol](https://modelcontextprotocol.io/docs/getting-started/intro), or MCP. Symbiotic Code supports both local and remote servers. When you use an MCP server, it adds to the context. This can quickly add up if you have a lot of tools, as well as **become a potential security liability**. So we recommend being careful with which MCP servers you use. *** ## Add a server from the CLI The quickest way to add a server is the interactive `mcp add` command: ```bash theme={null} symbiotic mcp add ``` It asks for: 1. **Location**: the current project (`symbiotic.json` at the repository root) or global (`~/.config/symbiotic/symbiotic.json`). Inside a non-git directory, the server is always added globally. 2. **Name** of the server. 3. **Type**: `Local` (a command to run) or `Remote` (a URL). 4. For local servers, the **command** to run, for example `npx -y @modelcontextprotocol/server-everything`. 5. For remote servers, the **URL**, and whether the server uses **OAuth** (with an optional pre-registered client ID and secret). The entry is written to the chosen config file, keeping any existing comments and formatting. To add environment variables, headers, or a timeout, edit the entry afterwards. The command is split on spaces, so arguments that contain spaces must be edited in the config file afterwards. ### All `mcp` commands | Command | Description | | - | - | | `symbiotic mcp add` | Add a local or remote MCP server interactively | | `symbiotic mcp list` (or `ls`) | List configured servers with their connection status | | `symbiotic mcp auth [name]` | Authenticate with an OAuth server. Without a name, pick from a list | | `symbiotic mcp auth list` | List OAuth-capable servers and their authentication status | | `symbiotic mcp logout [name]` | Remove the stored OAuth credentials of a server | | `symbiotic mcp debug ` | Diagnose the connection and OAuth flow of a remote server | In the TUI, use `/mcps` to see your servers and press `Space` to enable or disable one for the current session. *** ## Configure You can define MCP servers in your [configuration file](/code/basics/configuration_file) under `mcp`. Add each MCP with a unique name. You can refer to that MCP by name when prompting the LLM. ```jsonc symbiotic.jsonc theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "mcp": { "name-of-mcp-server": { // ... "enabled": true, }, "name-of-other-mcp-server": { // ... }, }, } ``` You can also disable a server by setting `enabled` to `false`. This is useful if you want to temporarily disable a server without removing it from your config. MCP entries are validated strictly. Unknown fields such as `args`, `env`, or `cwd` (used by other tools) make the whole config file invalid. See [Migrating](/code/migrating#6-mcp-servers) to convert configs from Claude Code, Codex, Cursor, or VS Code. *** ## Local Add local MCP servers by setting `type` to `"local"` within the MCP object. ```jsonc symbiotic.jsonc theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "mcp": { "my-local-mcp-server": { "type": "local", // Or ["bun", "x", "my-mcp-command"] "command": ["npx", "-y", "my-mcp-command"], "enabled": true, "environment": { "MY_ENV_VAR": "my_env_var_value", }, }, }, } ``` `command` is an array holding the executable and each of its arguments. The server is started in the current project directory and inherits your shell environment; `environment` adds or overrides variables. For example, here's how you can add the test [`@modelcontextprotocol/server-everything`](https://www.npmjs.com/package/@modelcontextprotocol/server-everything) MCP server. ```jsonc symbiotic.jsonc theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "mcp": { "mcp_everything": { "type": "local", "command": ["npx", "-y", "@modelcontextprotocol/server-everything"], }, }, } ``` And to use it I can add `use the mcp_everything tool` to my prompts. ```txt theme={null} use the mcp_everything tool to add the number 3 and 4 ``` #### Options | Option | Type | Required | Description | | - | - | - | - | | `type` | String | Yes | Type of MCP server connection, must be `"local"`. | | `command` | Array | Yes | Command and arguments to run the MCP server. | | `environment` | Object | | Environment variables to set when running the server. | | `enabled` | Boolean | | Enable or disable the MCP server on startup. | | `timeout` | Number | | Timeout in ms for connecting to the server and for tool calls. See [Timeouts](#timeouts). | *** ## Remote Add remote MCP servers by setting `type` to `"remote"`. Symbiotic Code connects with Streamable HTTP and falls back to SSE automatically, so the same config works for both transports. ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "mcp": { "my-remote-mcp": { "type": "remote", "url": "https://my-mcp-server.com/mcp", "enabled": true, "headers": { "Authorization": "Bearer {env:MY_API_KEY}" } } } } ``` The `url` is the URL of the remote MCP server and with the `headers` option you can pass in a list of headers. #### Options | Option | Type | Required | Description | | - | - | - | - | | `type` | String | Yes | Type of MCP server connection, must be `"remote"`. | | `url` | String | Yes | URL of the remote MCP server. | | `enabled` | Boolean | | Enable or disable the MCP server on startup. | | `headers` | Object | | Headers to send with each request. | | `oauth` | Object or `false` | | OAuth configuration, see [OAuth](#oauth). Set to `false` to disable OAuth detection. | | `timeout` | Number | | Timeout in ms for connecting to the server and for tool calls. See [Timeouts](#timeouts). | *** ## Keep secrets out of your config Don't write API keys directly in `symbiotic.json`, especially in a project config that is committed. Use variable substitution instead: | Syntax | Replaced with | | - | - | | `{env:VAR_NAME}` | The value of the environment variable, or an empty string if it isn't set | | `{file:path/to/file}` | The contents of the file. Relative paths are resolved from the config file's directory, and `~/` from your home directory | ```json symbiotic.json theme={null} { "mcp": { "github": { "type": "remote", "url": "https://api.githubcopilot.com/mcp/", "oauth": false, "headers": { "Authorization": "Bearer {env:GITHUB_TOKEN}" } }, "my-db": { "type": "local", "command": ["npx", "-y", "my-db-mcp"], "environment": { "DB_PASSWORD": "{file:~/.secrets/db-password}" } } } } ``` *** ## OAuth Symbiotic Code handles OAuth for remote servers automatically. When a server responds with `401 Unauthorized`, the server shows **needs authentication** and you can start the flow: ```bash theme={null} symbiotic mcp auth my-remote-mcp ``` A browser window opens so you can sign in. If it can't be opened, the URL is printed so you can open it manually. The redirect is received on `http://127.0.0.1:19876/mcp/oauth/callback`. By default, Symbiotic Code uses [dynamic client registration](https://datatracker.ietf.org/doc/html/rfc7591). If the server requires a pre-registered application, provide its credentials: ```json symbiotic.json theme={null} { "mcp": { "my-remote-mcp": { "type": "remote", "url": "https://my-mcp-server.com/mcp", "oauth": { "clientId": "{env:MY_CLIENT_ID}", "clientSecret": "{env:MY_CLIENT_SECRET}", "scope": "read write" } } } } ``` | Option | Description | | - | - | | `clientId` | OAuth client ID. If omitted, dynamic client registration is attempted. | | `clientSecret` | OAuth client secret, if the authorization server requires one. | | `scope` | Scopes to request during authorization. | For servers that authenticate with an API key in a header, set `"oauth": false` so no OAuth flow is attempted. Tokens are stored in `~/.local/share/symbiotic/mcp-auth.json`, readable only by your user, and refreshed automatically. Use `symbiotic mcp logout ` to remove them, and `symbiotic mcp debug ` to troubleshoot a failing flow. *** ## Timeouts `timeout` applies both to connecting to the server and to each tool call. It defaults to 30 seconds for connecting. To set a default for all servers, use `experimental.mcp_timeout`: ```json symbiotic.json theme={null} { "experimental": { "mcp_timeout": 60000 }, "mcp": { "slow-server": { "type": "local", "command": ["npx", "-y", "slow-mcp"], "timeout": 120000 } } } ``` Long-running tool calls that report progress don't time out while they keep sending progress updates. *** ## Security scanning Before connecting to a new server, Symbiotic Code scans it for risky prompts, tools, and resources. If the scan finds a vulnerability, the server is **blocked** and shows as blocked in `symbiotic mcp list` and `/mcps`. Scan results are cached, so a server is only scanned again when its config changes. Your organization can also allow or deny specific MCP servers from the Symbiotic Portal. Servers denied by your organization show as **blocked by organizational policy**. *** ## Use MCP tools, prompts, and resources * **Tools** are named `_`, for example `mcp_everything_add`. Characters other than letters, digits, `_`, and `-` are replaced with `_`. * **Prompts** exposed by a server appear as slash commands named `/:`. Prompt arguments map to `$1`, `$2`, and so on. * **Resources** exposed by a server can be attached to a message with `@`, like files. ### Control access with permissions MCP tools follow [tool permissions](/code/security/tool_permissions), using the tool name as the permission key. Wildcards let you target a whole server: ```json symbiotic.json theme={null} { "permission": { "mcp_everything_*": "ask", "github_delete_*": "deny" } } ``` A tool denied with `"deny"` is removed from the list of tools sent to the model. You can also do this per agent, for example to only give one [agent](/code/customize/custom_agents) access to a server: ```json symbiotic.json theme={null} { "permission": { "github_*": "deny" }, "agent": { "reviewer": { "permission": { "github_*": "allow" } } } } ``` *** ## Troubleshooting * Run `symbiotic mcp list` to see the status of every server. `failed` entries include the error returned by the server. * For local servers, run the `command` yourself in a terminal to check that it starts. * For remote servers, run `symbiotic mcp debug ` to check connectivity and the OAuth configuration. * If the whole config fails to load, check for unsupported fields in your `mcp` entries. # Custom agents Source: https://docs.symbioticsec.ai/code/customize/custom_agents Configure and use specialized agents Custom agents are specialized AI assistants that you can configure to **perform specific tasks and workflows.** Each agent can have its own prompt, model and [tool permissions](/code/security/tool_permissions). Symbiotic Code has [built-in agents](/code/basics/agents) for common tasks, but you can also create your own custom agents or customize the built-in ones. ## Agent types Each agent has a `mode`: | Mode | Behavior | | - | - | | `primary` | A main agent you talk to directly. Switch between primary agents with `tab` / `shift+tab` or the `/agents` command | | `subagent` | A specialized assistant that primary agents call through the `task` tool for focused tasks. You can also invoke one manually by mentioning it with `@name` in your message | | `all` | Both: available as a primary agent and as a subagent. **This is the default for custom agents** | ### Built-in agents | Agent | Mode | Description | | - | - | - | | `build` | primary | The default agent. Executes tools based on configured permissions | | `plan` | primary | Plan mode. Disallows all edit tools, except plan files | | `debug` | primary | Diagnoses and fixes issues with a systematic debugging methodology | | `ask` | primary | Answers questions without changing the codebase: it can read, search and browse the web, but not edit files or run shell commands | | `general` | subagent | General-purpose agent for research and multi-step tasks, can run several units of work in parallel | | `explore` | subagent | Fast agent for exploring codebases: searches and reads code, can't edit files | | `triage` | subagent | Triages static analysis findings to separate true and false positives | | `owasp-security-review` | subagent | OWASP Top 10 reviewer used by `/owasp-security-review`: investigates code and reports findings, can't edit files | Symbiotic Code also uses hidden internal agents (`title`, `summary`, `compaction`) for session titles, summaries and context compaction. You can override their `model` or `prompt` like any other agent. *** ## Creating agents ### Markdown files (recommended) Create a `.md` file in one of these directories: | Scope | Directory | | - | - | | Global | `~/.config/symbiotic/agents/` | | Project | `.symbiotic/agents/` | The file path (without `.md`) becomes the agent name, and the file body becomes the agent's system prompt. The singular folder name `agent/` also works. ```markdown ~/.config/symbiotic/agents/review.md theme={null} --- description: Reviews code for quality and best practices mode: subagent model: anthropic/claude-sonnet-4-5 temperature: 0.1 permission: edit: deny bash: deny --- You are in code review mode. Focus on: - Code quality and best practices - Potential bugs and edge cases - Performance implications - Security considerations Provide constructive feedback without making direct changes. ``` Here `review.md` creates a `review` subagent that primary agents can delegate to, and that you can invoke with `@review`. Invalid frontmatter values (for example `color: blue` or `mode: agent`) prevent Symbiotic Code from loading its configuration. Migrating from Claude Code? See [Migrating](/code/migrating) for how to convert agent files. ### JSON config You can also define agents under the `agent` key in `symbiotic.json`, `.symbiotic/symbiotic.json` or `~/.config/symbiotic/symbiotic.json`: ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "agent": { "docs-writer": { "description": "Writes and maintains project documentation", "mode": "primary", "model": "anthropic/claude-sonnet-4-5", "prompt": "{file:./prompts/docs-writer.md}", "permission": { "bash": "deny" } } } } ``` `{file:path}` inserts the content of a file, resolved relative to the config file (`~/` is also supported). `{env:VAR}` inserts an environment variable. ### Generate an agent with the CLI ```bash theme={null} symbiotic agent create ``` This interactive command asks where to save the agent (current project or global; global only outside a git repository), what it should do, which tools to enable and its mode, then uses the LLM to generate the agent name, description and system prompt. The file is written to `.symbiotic/agent/` or `~/.config/symbiotic/agent/`. You can also pass everything as options to run it non-interactively: ```bash theme={null} symbiotic agent create --path .symbiotic --description "Reviews SQL migrations" --mode subagent --tools "read,grep,glob" ``` | Option | Description | | - | - | | `--path` | Directory in which an `agent/` folder is created for the file | | `--description` | What the agent should do | | `--mode` | `all`, `primary` or `subagent` | | `--tools` | Comma-separated list of tools to enable (`bash`, `read`, `write`, `edit`, `list`, `glob`, `grep`, `webfetch`, `task`, `todowrite`, `todoread`). Defaults to all | | `--model`, `-m` | Model used to generate the agent, in `provider/model` format | Use `symbiotic agent list` to list all available agents with their mode and permissions. *** ## Options | Field | Type | Description | | - | - | - | | `description` | string | What the agent does and when to use it. Primary agents read it to decide when to call a subagent | | `mode` | `primary` \| `subagent` \| `all` | See [Agent types](#agent-types). Default: `all` | | `prompt` | string | System prompt (JSON config only; in Markdown files, the file body is the prompt). Replaces the default system prompt | | `model` | string | Model in `provider/model` format, for example `anthropic/claude-sonnet-4-5`. Defaults to the current model; subagents default to the model of the agent that calls them | | `variant` | string | Default model variant, applied only when the agent uses its configured `model` | | `temperature` | number | Sampling temperature | | `top_p` | number | Nucleus sampling value | | `permission` | object | Tool permissions for this agent, merged over your global [tool permissions](/code/security/tool_permissions) | | `security_mode` | `permissive` \| `balanced` \| `strict` | [Security mode](/code/security/security_modes) applied when you switch to this agent | | `steps` | integer | Maximum number of agentic iterations before the agent must respond with text only | | `color` | string | Color in the UI: a hex code (`"#FF5733"`) or a theme color: `primary`, `secondary`, `accent`, `success`, `warning`, `error`, `info` | | `hidden` | boolean | Hide the agent from the `@` autocomplete menu and the agent list. A hidden subagent can still be called by other agents | | `disable` | boolean | Remove the agent | | `options` | object | Extra options passed to the model provider | | `tools` | object | **Deprecated**, use `permission`. Map of tool name to `true`/`false`, converted to `allow`/`deny` | | `maxSteps` | integer | **Deprecated**, use `steps` | Any other key is passed to the model provider as an option, like the keys in `options`. ### Permissions The `permission` field accepts the same values as the top-level [tool permissions](/code/security/tool_permissions): `allow`, `ask` or `deny` for a tool, or a map of patterns where the last matching rule wins. ```markdown .symbiotic/agents/git-helper.md theme={null} --- description: Helps with git operations mode: primary permission: edit: deny bash: "*": ask "git status*": allow "git log*": allow "git diff*": allow --- You help the user inspect and manage their git history. ``` A tool denied with `"*": deny` is not sent to the model at all. Use the `task` permission to control which subagents an agent can call, by subagent name: ```json symbiotic.json theme={null} { "agent": { "build": { "permission": { "task": { "*": "allow", "general": "deny" } } } } } ``` *** ## Customize built-in agents Configure a built-in agent with its name as the key. Only the fields you set are changed: ```json symbiotic.json theme={null} { "agent": { "build": { "model": "anthropic/claude-sonnet-4-5", "security_mode": "strict" }, "plan": { "disable": true } } } ``` Set `disable: true` to remove an agent. The same works for custom agents defined in another config file. ### Default agent `default_agent` sets the primary agent selected on startup and used when none is specified. It must be an existing `primary` or `all` agent that isn't hidden. If it isn't set, `build` is used. ```json symbiotic.json theme={null} { "default_agent": "docs-writer" } ``` *** ## Priority When an agent is defined in multiple places, the definitions are merged field by field, the higher-priority source winning for each field: project Markdown files, then `.symbiotic/symbiotic.json`, then global Markdown files, then the project `symbiotic.json`, then the global `symbiotic.json`. See [Configuration file](/code/basics/configuration_file) for the full load order. # Custom commands Source: https://docs.symbioticsec.ai/code/customize/custom_commands Create custom commands to automate tasks & actions Custom commands let you define reusable prompts that run when you type `/command-name` in the TUI. They support dynamic flow via arguments, shell output, and file references. ## Built-in commands Symbiotic Code ships with these commands: | Command | Description | | - | - | | `/init` | Create or update `AGENTS.md` for the project | | `/review` | Review changes (commit, branch or PR); defaults to uncommitted changes. Runs as a subtask | | `/local-review` | Review the current branch | | `/local-review-uncommitted` | Review uncommitted changes | | `/scan-codebase` | Scan the codebase for vulnerabilities (optional path); defaults to the entire project | | `/owasp-security-review` | OWASP Top 10 review (path, commit, branch or PR); defaults to the whole project. Runs in the background with the `owasp-security-review` subagent | | `/generate-guardrails` | Generate security guardrails for the project. See [Security tools](/code/security/security_tools) | A custom command with the same name as a built-in command replaces it. ## Creating commands ### Markdown files (recommended) Create `.md` files in one of two directories: | Scope | Directory | | - | - | | Global | `~/.config/symbiotic/commands/` | | Project | `.symbiotic/commands/` | The file path (without `.md`) becomes the command name. Subfolders are part of the name: `.symbiotic/commands/frontend/component.md` is invoked as `/frontend/component`. The singular folder name `command/` also works. Project commands are only available when you launch Symbiotic Code inside that project (from the directory containing `.symbiotic/` or one of its subdirectories). #### Example 1. Create a file named `test.md` in `.symbiotic/commands/` with the following content: ```markdown .symbiotic/commands/test.md theme={null} --- description: Run tests with coverage model: anthropic/claude-sonnet-4-5 --- Run the full test suite with coverage report and show any failures. Focus on the failing tests and suggest fixes. ``` 2. Use it in Symbiotic Code TUI: ``` /test ``` ### JSON config Alternatively, define commands under the `command` key in `symbiotic.json` (project root), `.symbiotic/symbiotic.json` (project), or `~/.config/symbiotic/symbiotic.json` (global). `.jsonc` variants are also supported. The prompt goes in the required `template` field: ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "command": { "fix": { "template": "Fix all issues in @$ARGUMENTS and explain each change.", "description": "Fix a file" }, "review-file": { "template": "Review $1 focusing on $2.\n\nRecent changes:\n!`git diff HEAD~1 HEAD -- $1`", "description": "Review a file with git context" }, "test": { "template": "Run the full test suite with coverage report and show any failures.\nFocus on the failing tests and suggest fixes.", "description": "Run tests with coverage", "model": "anthropic/claude-sonnet-4-5" } } } ``` Supports `//` single-line comments (`.jsonc` style). *** ## Frontmatter options The same fields are available in Markdown frontmatter and in JSON config. Other frontmatter keys (for example Claude Code's `allowed-tools` or `argument-hint`) are ignored. | Field | Type | Description | | - | - | - | | `description` | string | Short description shown in the command palette | | `agent` | string | [Agent](/code/customize/custom_agents) that runs the command. Defaults to the current agent | | `model` | string | Model in `provider/model` format, for example `anthropic/claude-sonnet-4-5`. A bare model name fails when the command runs. Defaults to the model of the command's `agent` if it has one, otherwise the current model | | `subtask` | boolean | Run the command in a separate subagent session so it doesn't fill your main conversation's context. Commands whose `agent` is a subagent run as subtasks unless you set `subtask: false` | | `background` | boolean | When the command runs as a subtask, run it in the background so you can keep working. You're notified when it finishes | A field with the wrong type (for example `subtask: "yes"`) prevents the configuration from loading. A file with malformed YAML frontmatter is skipped and an error is shown. *** ## Template syntax Use these placeholders in your command templates: #### `$ARGUMENTS`: full argument string Pass the entire argument string as a value in the prompt. **Example:** ```markdown theme={null} --- description: Fix a file --- Fix all issues in $ARGUMENTS and explain each change. ``` ``` /fix src/core/session.ts ``` ↪ `$ARGUMENTS` is replaced with `src/core/session.ts` in the prompt. *** #### `$1`, `$2`, `$3`...: positional arguments Pass the argument at the specified position as a value in the prompt. Arguments are split on whitespace. **Example:** ```markdown theme={null} --- description: Create a component --- Create a TUI component named $1 in $2. Follow the existing patterns in that directory. ``` ``` /create-component Sidebar src/cli/tui/components ``` * `$1` → `Sidebar` * `$2` → `src/cli/tui/components` Arguments also support quoting: ``` /create-component "My Component" src/cli/tui/components ``` The highest-numbered placeholder receives all remaining arguments: with `/create-component Sidebar src/components with tests`, `$2` becomes `src/components with tests`. Placeholders without a matching argument are replaced with an empty string. If a template contains neither `$ARGUMENTS` nor a `$N` placeholder, the arguments you type are appended to the end of the prompt. *** #### `` !`command` ``: shell output injection Inject the output of a shell command into the prompt. ```markdown theme={null} --- description: Review recent git changes --- Recent git changes: !`git diff HEAD~1 HEAD --stat` Review these changes and suggest improvements. ``` The command runs in the current working directory, before the prompt is sent to the model. Its stdout is injected inline into the prompt. A failing shell command doesn't stop the custom command. Shell commands in templates run directly on your machine: they don't go through [tool permissions](/code/security/tool_permissions) or the [agents container](/code/security/containers). Arguments are substituted **before** the shell command runs, so a template like `` !`git log $1` `` executes whatever you pass as `$1`. Only use argument placeholders inside shell commands with input you trust. *** #### `@path`: file references Reference a file or directory with `@` followed by its path. It is attached to the prompt. ```markdown theme={null} --- description: Review a component --- Review the component in @src/components/Button.tsx and check for accessibility issues. ``` Paths are resolved relative to the project root; `~/` refers to your home directory. If no file exists at that path but an agent has that name (for example `@explore`), that agent is invoked as a subagent. References to missing files are ignored. *** ## MCP prompts and skills Prompts exposed by [MCP servers](/code/configuration/mcp) are also available as commands, named `server:prompt` (characters other than letters, digits, `_` and `-` are replaced with `_`). Prompt arguments map to `$1`, `$2`, and so on, in order. [Skills](/code/customize/skills) can also be invoked as `/skill-name`, unless a command with that name already exists. *** ## Commands priority When the same command name exists in multiple sources, the highest-priority source wins: | Priority | Scope | Source | | - | - | - | | 1 | Project | Markdown file in `.symbiotic/commands/` | | 2 | Project | `.symbiotic/symbiotic.json(c)` | | 3 | Global | Markdown file in `~/.config/symbiotic/commands/` | | 4 | Project | `symbiotic.json(c)` at the project root | | 5 | Global | `~/.config/symbiotic/symbiotic.json(c)` | | 6 | — | Built-in commands | Definitions are merged field by field: if a higher-priority definition omits a field (for example `description`), the value from the lower-priority source is kept. Configuration managed by your organization takes precedence over all of these sources. # Custom tools Source: https://docs.symbioticsec.ai/code/customize/custom_tools Create functions that the LLM can call during conversations Custom tools are functions you create that the LLM can call during conversations. They work alongside Symbiotic Code's built-in tools like `read`, `write`, and `bash`. ## Creating a tool Tools are defined as **TypeScript** or **JavaScript** files. However, the tool definition can invoke scripts written in **any language** — TypeScript or JavaScript is only used for the tool definition itself. ### Location They can be defined: * Locally by placing them in the `.symbiotic/tools/` directory of your project. * Or globally, by placing them in `~/.config/symbiotic/tools/`. Only `.ts` and `.js` files placed directly in these folders are loaded (subfolders are not scanned). The singular folder name `tool/` also works. ### Structure The easiest way to create tools is using the `tool()` helper from the `@symbioticsec/plugin` package, which provides type-safety and validation. ```ts title=".symbiotic/tools/database.ts" {1} theme={null} import { tool } from "@symbioticsec/plugin" export default tool({ description: "Query the project database", args: { query: tool.schema.string().describe("SQL query to execute"), }, async execute(args) { // Your database logic here return `Executed query: ${args.query}` }, }) ``` The **filename** becomes the **tool name**. The above creates a `database` tool. `execute` must return a **string**: it is the result sent back to the model. Long results are truncated (2,000 lines or 50 KB) and the full output is saved to a file the agent can read. #### Dependencies You don't need to install `@symbioticsec/plugin` yourself: at startup, Symbiotic Code creates a `package.json` in the config folder (`.symbiotic/` or `~/.config/symbiotic/`) with `@symbioticsec/plugin` as a dependency and installs it with Bun. It also adds a `.gitignore` for these generated files. To use other npm packages in your tools, add them to the `dependencies` of that same `package.json`. Package install scripts are not run. #### Multiple tools per file You can also export multiple tools from a single file. Each export becomes **a separate tool** with the name **`_`**: ```ts title=".symbiotic/tools/math.ts" theme={null} import { tool } from "@symbioticsec/plugin" export const add = tool({ description: "Add two numbers", args: { a: tool.schema.number().describe("First number"), b: tool.schema.number().describe("Second number"), }, async execute(args) { return String(args.a + args.b) }, }) export const multiply = tool({ description: "Multiply two numbers", args: { a: tool.schema.number().describe("First number"), b: tool.schema.number().describe("Second number"), }, async execute(args) { return String(args.a * args.b) }, }) ``` This creates two tools: `math_add` and `math_multiply`. Every export of a tool file is loaded as a tool. Don't export helper functions or constants from these files: move them to a separate file outside the `tools/` folder. #### Name collisions with built-in tools Custom tools are keyed by tool name. If a custom tool uses the same name as a built-in tool, the custom tool takes precedence. For example, this file replaces the built-in `bash` tool: ```ts title=".symbiotic/tools/bash.ts" theme={null} import { tool } from "@symbioticsec/plugin" export default tool({ description: "Restricted bash wrapper", args: { command: tool.schema.string(), }, async execute(args) { return `blocked: ${args.command}` }, }) ``` Prefer unique names unless you intentionally want to replace a built-in tool. If you want to disable a built-in tool but not override it, use [tool permissions](/code/security/tool_permissions). ### Arguments You can use `tool.schema`, which is just [Zod](https://zod.dev), to define argument types. ```ts "tool.schema" theme={null} args: { query: tool.schema.string().describe("SQL query to execute") } ``` You can also import [Zod](https://zod.dev) directly and export a plain object: ```ts {6} theme={null} import { z } from "zod" export default { description: "Tool description", args: { param: z.string().describe("Parameter description"), }, async execute(args, context) { // Tool implementation return "result" }, } ``` ### Context Tools receive context about the current session: ```ts title=".symbiotic/tools/project.ts" {8} theme={null} import { tool } from "@symbioticsec/plugin" export default tool({ description: "Get project information", args: {}, async execute(args, context) { // Access context information const { agent, sessionID, messageID, directory, worktree } = context return `Agent: ${agent}, Session: ${sessionID}, Message: ${messageID}, Directory: ${directory}, Worktree: ${worktree}` }, }) ``` | Property | Description | | - | - | | `directory` | The session working directory | | `worktree` | The git worktree root | | `agent` | Name of the agent calling the tool | | `sessionID`, `messageID` | Identifiers of the current session and message | | `abort` | An `AbortSignal` triggered when the user interrupts the session | | `ask(...)` | Request a permission from the user, see below | ### Permissions Custom tools follow [tool permissions](/code/security/tool_permissions) using their tool name as the permission key. Setting a tool to `"deny"` (globally or for an [agent](/code/customize/custom_agents)) removes it from the tools sent to the model: ```json symbiotic.json theme={null} { "permission": { "database": "deny" } } ``` `"ask"` doesn't prompt the user automatically: a custom tool runs without confirmation unless it calls `context.ask()` itself. The call resolves when the action is allowed (by a rule or by the user) and throws when it is denied: ```ts title=".symbiotic/tools/deploy.ts" theme={null} import { tool } from "@symbioticsec/plugin" export default tool({ description: "Deploy the application to an environment", args: { env: tool.schema.enum(["staging", "production"]), }, async execute(args, context) { await context.ask({ permission: "deploy", patterns: [args.env], always: [args.env], metadata: { env: args.env }, }) // Deployment logic here return `Deployed to ${args.env}` }, }) ``` With this tool, `"deploy": { "*": "ask", "staging": "allow" }` deploys to staging without asking and asks before deploying to production. `always` lists the patterns saved when the user chooses to always allow the request. Custom tools run on your machine with your user's privileges, outside the [agents container](/code/security/containers). Only add tools from sources you trust, and validate arguments before passing them to shell commands or queries. ## Examples ### Write a tool in Python You can write your tools in any language you want. Here's an example that adds two numbers using Python. First, create the tool as a Python script: ```python title=".symbiotic/tools/add.py" theme={null} import sys a = int(sys.argv[1]) b = int(sys.argv[2]) print(a + b) ``` Then create the tool definition that invokes it: ```ts title=".symbiotic/tools/python-add.ts" {10} theme={null} import { tool } from "@symbioticsec/plugin" import path from "path" export default tool({ description: "Add two numbers using Python", args: { a: tool.schema.number().describe("First number"), b: tool.schema.number().describe("Second number"), }, async execute(args, context) { const script = path.join(context.worktree, ".symbiotic/tools/add.py") const result = await Bun.$`python3 ${script} ${args.a} ${args.b}`.text() return result.trim() }, }) ``` Here we are using the [`Bun.$`](https://bun.com/docs/runtime/shell) utility to run the Python script. Interpolated values are escaped by `Bun.$`, so arguments can't inject extra shell commands. ## Tools from plugins [Plugins](/code/customize/plugins) can also provide tools with their `tool` hook, using the same `tool()` helper. Plugin tools are named after their key in the `tool` object, without a file name prefix. # Plugins Source: https://docs.symbioticsec.ai/code/customize/plugins Add plugins to Symbiotic Code Plugins allow you to extend Symbiotic Code by hooking into various events and customizing behavior. You can create plugins to **add new features, integrate with external services, or modify Symbiotic Code's default behavior.** *** ## Use plugins There are two ways to load plugins: ### 1. From local files Place JavaScript or TypeScript files in the plugin directory. * `.symbiotic/plugins/` (or `.symbiotic/plugin/`) - Project-level plugins * `~/.config/symbiotic/plugins/` (or `~/.config/symbiotic/plugin/`) - Global plugins `.ts` and `.js` files directly in these directories are automatically loaded at startup (subdirectories aren't scanned). *** ### 2. From npm or a path Specify npm packages or local paths in the `plugin` array of your config file. Relative paths are resolved from the config file that declares them. To pass options to a plugin, use a `[specifier, options]` tuple; the options are passed as the second argument of the plugin function. ```json title="symbiotic.json" theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "plugin": [ "@my-org/custom-plugin", "some-plugin@1.2.0", "./plugins/local-plugin.ts", ["@my-org/configurable-plugin", { "level": "strict" }] ] } ``` Both regular and scoped npm packages are supported. Without a version, the latest version is used. You can install an npm plugin and add it to your config with `symbiotic plugin ` (alias `symbiotic plug`). By default it's added to `.symbiotic/` in your project; use `--global` (`-g`) to add it to `~/.config/symbiotic/` instead, and `--force` (`-f`) to replace an existing version. *** ### How plugins are installed * **npm plugins** are installed automatically using Bun at startup, with install scripts disabled. Packages and their dependencies are cached in `~/.cache/symbiotic/node_modules/`. If a package declares `engines.symbiotic` in its `package.json` and the running version doesn't match, the plugin is skipped. * **Local plugins** are loaded directly from the plugin directory. To use external packages, add a `package.json` with your dependencies to the config directory (`.symbiotic/` or `~/.config/symbiotic/`); Symbiotic Code runs `bun install --ignore-scripts` there at startup. You can also publish the plugin to npm and [add it to your config](/code/basics/configuration_file#plugins). *** ### Load order Plugins are loaded from all sources and all hooks run in sequence. The load order is: 1. Global config (`~/.config/symbiotic/symbiotic.json`) 2. Project config (`symbiotic.json`) 3. Global plugin directory (`~/.config/symbiotic/plugins/`) 4. Project plugin directory (`.symbiotic/plugins/`) If the same npm package is listed more than once, it's loaded once, and the last occurrence (highest priority) wins, whatever its version. Local files are deduplicated by path, so a local plugin and an npm plugin with similar names are both loaded. Set `SYMBIOTIC_PURE=1` to skip all external plugins. *** ### Organization policy Plugins aren't security-scanned, but your organization can allow or deny specific plugins from the Symbiotic Portal. A plugin blocked by organizational policy is loaded but its hooks and tools are discarded. *** ## Create a plugin A plugin is a **JavaScript/TypeScript module** that exports one or more plugin functions. Each function receives a context object and returns a hooks object. ```ts title=".symbiotic/plugins/example.ts" theme={null} import type { Plugin } from "@symbioticsec/plugin" export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }, options) => { return { "tool.execute.before": async (input, output) => { if (input.tool === "read" && output.args.filePath.includes(".env")) { throw new Error("Do not read .env files") } }, } } ``` The plugin function receives: * `project`: The current project information. * `directory`: The current working directory. * `worktree`: The git worktree path. * `client`: A Symbiotic Code SDK client connected to the local server. * `serverUrl`: The URL of the local server. * `$`: Bun's [shell API](https://bun.com/docs/runtime/shell) for executing commands. Types come from the `@symbioticsec/plugin` package, which is installed automatically in your config directories. ### Hooks | Hook | When it runs | | - | - | | `event` | For every event published on the bus (for example `session.idle`, `session.error`, `message.updated`, `permission.asked`, `file.edited`, `todo.updated`) | | `config` | Once at startup, with the resolved config | | `tool` | Registers custom tools (use the `tool()` helper from `@symbioticsec/plugin`) | | `auth`, `provider` | Adds authentication methods or models for a provider | | `chat.message` | When a new user message is received | | `chat.params`, `chat.headers` | Before calling the model, to change parameters or HTTP headers | | `chat.complete` | When a model completion finishes, with token usage and cost | | `command.execute.before` | Before a slash command runs | | `tool.execute.before`, `tool.execute.after` | Before and after each tool call; throw in `before` to block the call | | `tool.definition` | To change a tool's description or parameters sent to the model | | `shell.env` | To inject environment variables into shell commands | | `session.start`, `session.stop` | When a session starts, resumes, or is compacted, and when an assistant turn ends | | `experimental.chat.messages.transform`, `experimental.chat.system.transform` | To transform messages or the system prompt before they are sent | | `experimental.session.compacting`, `experimental.compaction.autocontinue` | To customize compaction | | `experimental.text.complete` | When a text part finishes | ### Some interesting plugins * `btw-opencode`: Replicates the `/btw` command of Claude Code that allows you to ask questions while the agent is working. * `@symbioticsec/rtk-plugin`: Rewrites bash commands using the rtk CLI for token optimization. # Skills Source: https://docs.symbioticsec.ai/code/customize/skills Add skills to your agents [Agent skills](https://skills.sh/) let Symbiotic Code discover reusable instructions from your repo or home directory. Skills are loaded on-demand via the native `skill` tool—agents see available skills and can load the full content when needed. You can also browse and invoke skills yourself: run `/skills` in the TUI to pick one, or type `/` directly, like a [custom command](/code/customize/custom_commands). *** ## Place files Create one folder per skill and put a `SKILL.md` inside it. Symbiotic Code searches these locations: * Project config: `.symbiotic/skills//SKILL.md` (or `.symbiotic/skill/`) * Global config: `~/.config/symbiotic/skills//SKILL.md` (or `~/.config/symbiotic/skill/`) * Project Claude-compatible: `.claude/skills//SKILL.md` * Global Claude-compatible: `~/.claude/skills//SKILL.md` * Project agent-compatible: `.agents/skills//SKILL.md` * Global agent-compatible: `~/.agents/skills//SKILL.md` Skill folders can be nested: any `SKILL.md` below a `skills/` directory is picked up. *** ## Understand discovery For project-local paths, Symbiotic Code walks up from your current working directory until it reaches the git worktree. It loads any matching `skills/**/SKILL.md` in `.symbiotic/` and any matching `.claude/skills/**/SKILL.md` or `.agents/skills/**/SKILL.md` along the way. Global definitions are also loaded from `~/.config/symbiotic/skills/**/SKILL.md`, `~/.claude/skills/**/SKILL.md`, and `~/.agents/skills/**/SKILL.md`. If two skills share the same `name`, the one loaded last wins and a warning is logged. ### Disable Claude/agent-compatible skills Set one of these environment variables to `true` or `1` to skip the `.claude/` and `.agents/` locations (project and global): * `SYMBIOTIC_DISABLE_EXTERNAL_SKILLS` * `SYMBIOTIC_DISABLE_CLAUDE_CODE_SKILLS` * `SYMBIOTIC_DISABLE_CLAUDE_CODE` (also disables other Claude Code compatibility features) Skills in `.symbiotic/` and `~/.config/symbiotic/` are always loaded. *** ## Load skills from other places Use the `skills` option in your [config file](/code/basics/configuration_file) to add more sources: ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "skills": { "paths": ["~/my-skills", "./team-skills"], "urls": ["https://example.com/.well-known/skills/"] } } ``` * `paths`: extra directories scanned for `**/SKILL.md`. Paths can be absolute, start with `~/`, or be relative to your working directory. Missing directories are skipped with a warning. * `urls`: remote skill indexes. Symbiotic Code fetches `index.json` from each URL, downloads the listed files of every skill that includes a `SKILL.md`, and caches them in `~/.cache/symbiotic/skills/`. Files already in the cache aren't downloaded again. The `index.json` format is: ```json index.json theme={null} { "skills": [ { "name": "git-release", "files": ["SKILL.md", "scripts/release.sh"] } ] } ``` Each file is downloaded from `//`. *** ## Security scanning Every skill is scanned by the Symbiotic security scanner before it can be used. If the scan reports findings above informational severity, or the scan can't complete, the skill is **blocked**. Scan verdicts are cached, so skills aren't rescanned on every start. Your organization can also allow or deny specific skills from the Symbiotic Portal. Blocked skills: * are hidden from the agent and can't be loaded with the `skill` tool * are shown as **Blocked** in the `/skills` dialog * aren't available as `/` commands *** ## Control access with permissions Skills follow [tool permissions](/code/security/tool_permissions) with the `skill` key. Patterns match the skill name: ```json symbiotic.json theme={null} { "permission": { "skill": { "*": "allow", "internal-*": "ask", "experimental-*": "deny" } } } ``` Skills denied with `"deny"` are hidden from the agent. Setting `"skill": "deny"` removes the `skill` tool entirely. You can also set this per [agent](/code/customize/custom_agents). *** ## Write frontmatter Each `SKILL.md` must start with YAML frontmatter containing: * `name` (required): the name used to invoke the skill * `description` (required): shown to the agent so it can decide when to load the skill A `SKILL.md` without both fields is ignored. Other frontmatter fields (for example `license`, `compatibility`, or `metadata`) are allowed but not used by Symbiotic Code. Everything after the frontmatter is the skill content given to the agent. *** ## Name and describe your skill Names and descriptions aren't strictly validated, but for compatibility with other tools we recommend that `name`: * Is 1–64 characters * Is lowercase alphanumeric with single hyphen separators, for example `git-release` * Matches the directory name that contains `SKILL.md` Keep `description` short (under 1024 characters) and specific enough for the agent to choose correctly. *** ## Example Create `.symbiotic/skills/git-release/SKILL.md` like this: ```markdown theme={null} --- name: git-release description: Create consistent releases and changelogs license: MIT compatibility: symbiotic code metadata: audience: maintainers workflow: github --- ## What I do - Draft release notes from merged PRs - Propose a version bump - Provide a copy-pasteable `gh release create` command ## When to use me Use this when you are preparing a tagged release. Ask clarifying questions if the target versioning scheme is unclear. ``` When the agent loads a skill, it also receives the skill's base directory and a sample of the other files in it, so a skill can reference bundled scripts or templates with relative paths. # Get started Source: https://docs.symbioticsec.ai/code/get_started Boost your developers' productivity while keeping your code secure *** Symbiotic Code is a security-first coding agent that runs in your terminal. To use it you will need: * **A terminal**: Use the default terminal, or a modern terminal emulator like [iTerm](https://iterm2.com) or [Warp](https://warp.dev). It can also run in an IDE terminal (e.g., VS Code terminal). * **A Symbiotic Security account**: Ask your admin or Symbiotic point of contact for access. ## Installation ### CLI install Install Symbiotic Code with your preferred package manager: ```bash theme={null} npm install -g @symbioticsec/code ``` You can also use `pnpm install -g @symbioticsec/code`, `yarn global add @symbioticsec/code`, or `bun install -g @symbioticsec/code`. Check that **node** and **npm** are properly installed: ```bash theme={null} node -v npm -v ``` If they are not installed, install [them](https://nodejs.org/en/download/) and retry. See also [Troubleshooting](/code/basics/troubleshooting). To launch Symbiotic Code, use the `symbiotic` command in your terminal: ```bash theme={null} symbiotic ``` You can also pass a project path (`symbiotic path/to/project`), continue your last session with `symbiotic -c`, or pick a model with `symbiotic -m provider/model`. See [Terminal UI](/code/basics/TUI) for a tour of the interface, and [Common commands](/code/basics/common_commands) for all CLI commands. ### VSCode IDE extension install [Download](https://app.symbioticsec.ai/symbiotic-code.vsix) our extension and install it in all VSCode based IDEs. See [IDE Extension](/code/basics/IDE_extension). ### JetBrains IDE support You can use Symbiotic Code in your JetBrains IDE through [ACP](/code/configuration/acp). In the AI Chat window, click the three dots, then **Add Custom Agent**. This opens `~/.jetbrains/acp.json`, where you add Symbiotic Code under `agent_servers`: ```json acp.json theme={null} { "agent_servers": { "Symbiotic Code": { "command": "symbiotic", "args": ["acp"] } } } ``` If the IDE can't find the binary, use its absolute path (run `which symbiotic`) as `command`. ## Authentication A Symbiotic Security account is required. Create one for free at [app.symbioticsec.ai](https://app.symbioticsec.ai). If you don't have access, contact your administrator or Symbiotic point of contact. On first launch, Symbiotic Code opens an authentication dialog: Your browser opens the [Symbiotic Portal](https://app.symbioticsec.ai) to authorize Symbiotic Code. If it doesn't open, click the link in the dialog (press `c` to copy it). Once authorized, the dialog closes automatically and you can choose one of the Symbiotic models. Run `/connect`, select **Symbiotic**, then **API token**. Open the link shown in the dialog ([app.symbioticsec.ai/settings/api-token](https://app.symbioticsec.ai/settings/api-token)), create or copy a token, paste it and press `Enter`. For non-interactive environments (CI, containers), you can instead set the `SYMBIOTIC_API_KEY` environment variable. Credentials are stored in `~/.local/share/symbiotic/auth.json`, readable only by your user. ## Updates Symbiotic Code detects whether it was installed with npm, pnpm, yarn, Bun, or the install script and uses the same method when checking for and applying updates. To update manually, run `symbiotic upgrade` (or `symbiotic upgrade `). Set `"autoupdate": false` (or `"notify"`) in your global [configuration file](/code/basics/configuration_file) (`~/.config/symbiotic/symbiotic.json`) to control automatic updates, or set `SYMBIOTIC_DISABLE_AUTOUPDATE=1`. # Migrating to Symbiotic Code Source: https://docs.symbioticsec.ai/code/migrating Move from any coding agent to Symbiotic Code Already using Claude Code, Codex, Cursor, GitHub Copilot, or OpenCode? You can get started with Symbiotic Code in a few minutes. Your existing instructions, skills, commands, agents, and MCP servers can come with you. | | Automatic migration | Manual migration | | - | - | - | | Instructions | `AGENTS.md`, `CLAUDE.md`, `~/.claude/CLAUDE.md` | `.cursorrules`, `.cursor/rules/`, `.github/copilot-instructions.md`, `GEMINI.md`, `~/.codex/AGENTS.md` | | Skills | `.claude/skills/`, `.agents/skills/` (project and global) | Any other location | | MCP servers | — | All sources | | Commands | — | All sources (mostly a copy) | | Agents | — | All sources (frontmatter must be converted) | *** ## 1. Install Symbiotic Code You can install Symbiotic Code in 2 ways: **VS Code extension** or **CLI**. You can use both at the same time. ### VS Code extension [Download the `.vsix` extension](https://app.symbioticsec.ai/symbiotic-code.vsix) and install it in VS Code or another VS Code-based IDE. ### CLI Install the CLI globally with npm: ```bash theme={null} npm i -g @symbioticsec/code ``` Then launch Symbiotic Code with: ```bash theme={null} symbiotic ``` *** ## 2. Create your account You need a Symbiotic Security account to use Symbiotic Code. [Create an account](https://app.symbioticsec.ai/register) or [log in](https://app.symbioticsec.ai/login) through the Symbiotic Portal. | | Free plan | Paid plans | | - | - | - | | Members | Up to 8 | No limit | | Included models | One limited free model | Optimized frontier models | | Bring your own key | Use additional models from other providers with API keys | Use local models or specific models not offered with your plan with API keys | ## 3. Connect to a model ### Use the built-in models Depending on your plan, Symbiotic Code comes with optimized support for the most popular frontier models. The **Auto** model uses smart routing to select the right model for each request while helping manage costs. Use `/models` to switch models. ### Use your own provider To use an existing Claude, OpenAI, or Gemini subscription, or a local or custom model: 1. Run `/connect` and select your provider. 2. Enter your provider API key. 3. Use `/models` to list and switch between available models. See [Models and providers](/code/basics/models_and_providers) for supported providers and custom configuration. *** ## 4. Project memory / instructions ### Loaded automatically Symbiotic Code loads these instruction files without any configuration: | Scope | File | Tool it came from | | - | - | - | | Project | `AGENTS.md` | Codex, OpenCode, and most other agents | | Project | `CLAUDE.md` | Claude Code | | Global | `~/.config/symbiotic/AGENTS.md` | Symbiotic Code | | Global | `~/.claude/CLAUDE.md` | Claude Code | Project files are searched from your working directory up to the repository root. Only **one** project file name is used. If a repo contains both `AGENTS.md` and `CLAUDE.md`, only `AGENTS.md` is loaded and `CLAUDE.md` is ignored. The same applies globally: if `~/.config/symbiotic/AGENTS.md` exists, `~/.claude/CLAUDE.md` is not loaded. Merge the files, or add the second one to `instructions` (see below). ### Add instructions from other tools Rule files from Cursor, GitHub Copilot, Gemini, Windsurf, and Codex's global `AGENTS.md` are **not** loaded automatically. Reference them with the `instructions` key in `symbiotic.json`. It accepts paths and glob patterns: ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "instructions": [ ".cursorrules", ".cursor/rules/*.mdc", ".github/copilot-instructions.md", ".github/instructions/*.md", ".windsurfrules", "GEMINI.md" ] } ``` For global rules, add them to `~/.config/symbiotic/symbiotic.json` instead, for example `"instructions": ["~/.codex/AGENTS.md"]`. Paths that don't exist are skipped, so a single shared list works across repos that use different tools. *** ## 5. Skills Skills in these locations are picked up automatically, so no action is needed: * `.claude/skills//SKILL.md` and `~/.claude/skills//SKILL.md` * `.agents/skills//SKILL.md` and `~/.agents/skills//SKILL.md` For skills stored anywhere else, move them to `.symbiotic/skills//SKILL.md` (project) or `~/.config/symbiotic/skills//SKILL.md` (global), or point to their folder with `skills.paths`: ```json symbiotic.json theme={null} { "skills": { "paths": ["~/my-skills"] } } ``` A `SKILL.md` with missing `name` or `description` frontmatter is skipped. Check the [naming rules](/code/customize/skills#validate-names) if a skill does not show up. To stop loading files from other tools: | Variable | Disables | | - | - | | `SYMBIOTIC_DISABLE_CLAUDE_CODE_PROMPT=1` | `~/.claude/CLAUDE.md` | | `SYMBIOTIC_DISABLE_EXTERNAL_SKILLS=1` | Skills in `.claude/skills/` and `.agents/skills/` | | `SYMBIOTIC_DISABLE_CLAUDE_CODE=1` | Both of the above | *** ## 6. MCP servers MCP servers are configured under the `mcp` key of `symbiotic.json`: * **Global** servers (available in every project): `~/.config/symbiotic/symbiotic.json` * **Project** servers (shared with your team): `symbiotic.json` at the repo root ```json symbiotic.json theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "mcp": { "my-local-server": { "type": "local", "command": ["npx", "-y", "my-mcp-server"], "environment": { "API_KEY": "{env:MY_API_KEY}" } }, "my-remote-server": { "type": "remote", "url": "https://mcp.example.com/mcp", "headers": { "Authorization": "Bearer {env:MY_TOKEN}" } } } } ``` You can also add servers interactively with `symbiotic mcp add`. See [MCP servers](/code/configuration/mcp) for all options. ### Where your current config lives | Tool | Location | Key | | - | - | - | | Claude Code | `~/.claude.json` (user scope, and per project under `projects..mcpServers`), `.mcp.json` (project) | `mcpServers` | | Claude Desktop | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS), `%APPDATA%\Claude\claude_desktop_config.json` (Windows) | `mcpServers` | | Codex | `~/.codex/config.toml`, `.codex/config.toml` (project) | `[mcp_servers.]` tables (TOML) | | Cursor | `~/.cursor/mcp.json`, `.cursor/mcp.json` | `mcpServers` | | VS Code / GitHub Copilot | `.vscode/mcp.json`, or `mcp.json` in your VS Code user profile | `servers` | | Windsurf | `~/.codeium/windsurf/mcp_config.json` | `mcpServers` | | OpenCode | `opencode.json`, `~/.config/opencode/opencode.json` | `mcp` (same format, copy as-is) | ### Field mapping | Other tools | Symbiotic Code | | - | - | | `command` + `args` | `"type": "local"`, `"command": [command, ...args]` | | `env` | `environment` | | `url`, or `type` set to `http`, `sse`, or `streamable-http` | `"type": "remote"`, `url` | | `headers` / Codex `http_headers` | `headers` | | Codex `bearer_token_env_var = "X"` | `"headers": { "Authorization": "Bearer {env:X}" }` | | `${VAR}` / `$VAR` in values | `{env:VAR}` | | `disabled: true` / Codex `enabled = false` | `"enabled": false` | | Timeouts in seconds (Codex `startup_timeout_sec`, `tool_timeout_sec`) | `timeout`, in **milliseconds** (default 30000) | | `cwd`, `alwaysAllow`, `autoApprove`, tool allow/deny lists, VS Code `${input:...}` | Not supported. Remove the field and set secrets through `{env:VAR}` | MCP entries are validated strictly. A single unsupported field such as `args`, `env`, or `cwd` in **any** entry prevents the whole config file from loading. Copying a `mcpServers` block as-is will not work. Local servers inherit your shell environment, so variables already exported in your shell don't need to be listed in `environment`. OAuth tokens are not transferred between tools. After migrating a remote server that uses OAuth, run: ```bash theme={null} symbiotic mcp auth ``` ### Migrate your existing MCP config automatically Paste this prompt into Symbiotic Code (or your current coding agent) to find and convert your existing MCP servers: I want to migrate my MCP server configurations to Symbiotic Code. 1. Find all existing MCP configurations. Check these locations: * Claude Code: \~/.claude.json (top-level "mcpServers", and "projects.\.mcpServers" for the current project), and .mcp.json in the current project * Claude Desktop: \~/Library/Application Support/Claude/claude\_desktop\_config.json (macOS) or %APPDATA%\Claude\claude\_desktop\_config.json (Windows), key "mcpServers" * Codex: \~/.codex/config.toml and .codex/config.toml, TOML tables \[mcp\_servers.\] * Cursor: \~/.cursor/mcp.json and .cursor/mcp.json, key "mcpServers" * VS Code / GitHub Copilot: .vscode/mcp.json and the user-profile mcp.json, key "servers" * Windsurf: \~/.codeium/windsurf/mcp\_config.json, key "mcpServers" * OpenCode: opencode.json / opencode.jsonc in the project and \~/.config/opencode/, key "mcp" 2. Show me every server you found, grouped by source, before changing anything. 3. Convert each server to the Symbiotic Code format using exactly these rules: * If it has a "command": use "type": "local" and "command": \[command, ...args] as a single array. * If it has a "url" (or type http, sse, or streamable-http): use "type": "remote" and "url". * Rename "env" to "environment". Keep "headers" (Codex "http\_headers" becomes "headers"). * Codex "bearer\_token\_env\_var = X" becomes "headers": \{ "Authorization": "Bearer \{env:X}" }. * Replace $\{VAR\} or $VAR references with \{env:VAR}. Never write secret values in plain text: if a value is a literal secret, replace it with \{env:NAME} and tell me which variable to export. * "disabled": true becomes "enabled": false. * Timeouts go in "timeout" in milliseconds. * The only allowed fields are: type, command, environment, enabled, timeout (local) and type, url, headers, oauth, enabled, timeout (remote). Drop every other field (cwd, args, env, alwaysAllow, autoApprove, tool lists, ...) and list what you dropped. * OpenCode "mcp" entries are already in the right format: copy them unchanged. 4. Write user-level servers to \~/.config/symbiotic/symbiotic.json and project-level servers (.mcp.json, .cursor/mcp.json, .vscode/mcp.json, .codex/config.toml, project opencode.json) to symbiotic.json in the project root, under the "mcp" key. Create the file with "\$schema": "[https://config.symbioticsec.ai/config.json](https://config.symbioticsec.ai/config.json)" if it doesn't exist, and merge if it does. Never overwrite an existing entry with the same name. 5. Validate that each resulting file is valid JSON. 6. Report what was migrated, what was skipped and why, which fields were dropped, which environment variables I need to set, and which remote servers need "symbiotic mcp auth \". *** ## 7. Custom commands Symbiotic Code commands are Markdown files with optional YAML frontmatter, very close to Claude Code and Cursor commands: | Scope | Location | | - | - | | Project | `.symbiotic/commands/` | | Global | `~/.config/symbiotic/commands/` | | Tool | Where your commands live | Notes | | - | - | - | | Claude Code | `.claude/commands/`, `~/.claude/commands/` | Copy as-is, then check the frontmatter below | | Cursor | `.cursor/commands/` | Plain Markdown, copy as-is | | Codex | `~/.codex/prompts/` | Copy as-is. Named placeholders like `$FILE` are not supported; use `$1`, `$2`, or `$ARGUMENTS` | | GitHub Copilot | `.github/prompts/*.prompt.md` | Rename to `.md` and remove the `mode` and `tools` fields | | OpenCode | `.opencode/command/`, `~/.config/opencode/command/` | Copy as-is | These placeholders work the same way as in Claude Code: `$ARGUMENTS`, `$1`, `$2`, ..., `` !`shell command` `` and `@path/to/file`. **Frontmatter differences:** | Field | Behavior in Symbiotic Code | | - | - | | `description`, `agent`, `subtask` | Supported | | `model` | Must include the provider, for example `anthropic/claude-sonnet-4-5`. A bare model name like `claude-3-5-haiku-20241022` fails when the command runs. Remove the field to use the current model. | | `allowed-tools`, `argument-hint` | Ignored. Use [tool permissions](/code/security/tool_permissions) instead of `allowed-tools`. | Subfolders become part of the command name: `.symbiotic/commands/frontend/component.md` is invoked as `/frontend/component`. See [Custom commands](/code/customize/custom_commands) for details. *** ## 8. Custom agents Agents are also Markdown files with YAML frontmatter, but **the frontmatter is not compatible with Claude Code** and must be converted. | Scope | Location | | - | - | | Project | `.symbiotic/agents/` | | Global | `~/.config/symbiotic/agents/` | | Tool | Where your agents live | | - | - | | Claude Code | `.claude/agents/`, `~/.claude/agents/` | | GitHub Copilot | `.github/agents/*.agent.md`, or `.github/chatmodes/*.chatmode.md` (legacy) | | OpenCode | `.opencode/agent/`, `~/.config/opencode/agent/` (copy as-is) | Copying a Claude Code agent file without converting it prevents Symbiotic Code from loading its configuration: `tools: Read, Grep` and `color: blue` are rejected. **Frontmatter mapping:** | Claude Code | Symbiotic Code | | - | - | | `name` | Remove it. The agent name is the file name. | | `description` | `description` (unchanged) | | `tools: Read, Grep, Glob` (comma-separated list) | `permission` map, see the example below | | `model: inherit` | Remove the field | | `model: sonnet` / `opus` / `haiku` | A full `provider/model` id, for example `anthropic/claude-sonnet-4-5` | | `color: blue` | A hex color (`"#3B82F6"`) or a theme color: `primary`, `secondary`, `accent`, `success`, `warning`, `error`, `info` | | — | `mode: subagent` to keep the Claude Code behavior (invoked by other agents or with `@name`). Without it, the agent is also available as a primary agent. | **Example:** this Claude Code agent ```markdown .claude/agents/code-reviewer.md theme={null} --- name: code-reviewer description: Reviews code for quality and security issues tools: Read, Grep, Glob model: sonnet color: blue --- You are a senior code reviewer... ``` becomes: ```markdown .symbiotic/agents/code-reviewer.md theme={null} --- description: Reviews code for quality and security issues mode: subagent model: anthropic/claude-sonnet-4-5 color: "#3B82F6" permission: edit: deny bash: deny webfetch: deny --- You are a senior code reviewer... ``` Tools that aren't listed are allowed or ask for confirmation according to your [tool permissions](/code/security/tool_permissions), so deny explicitly the ones the agent should not use. Claude Code tools map to these permission keys: `Read` → `read`, `Edit`/`Write`/`MultiEdit` → `edit`, `Bash` → `bash`, `Grep` → `grep`, `Glob` → `glob`, `LS` → `list`, `WebFetch` → `webfetch`, `WebSearch` → `websearch`, `Task` → `task`, `TodoWrite` → `todowrite`. See [Custom agents](/code/customize/custom_agents) for all options. ### Migrate your existing commands and agents automatically I want to migrate my custom commands and agents to Symbiotic Code. 1. Find existing commands and agents in these locations only: * Claude Code commands: .claude/commands/ and \~/.claude/commands/ * Claude Code agents: .claude/agents/ and \~/.claude/agents/ * Cursor commands: .cursor/commands/ * Codex prompts: \~/.codex/prompts/ * GitHub Copilot prompts: .github/prompts/\*.prompt.md * GitHub Copilot agents: .github/agents/*.agent.md and .github/chatmodes/*.chatmode.md * OpenCode: .opencode/command/, .opencode/agent/, \~/.config/opencode/command/, \~/.config/opencode/agent/ 2. Show me every file you found, grouped by source tool, before changing anything. 3. Copy commands to .symbiotic/commands/ (project sources) or \~/.config/symbiotic/commands/ (global sources), keeping subfolders and file names. Copilot "\.prompt.md" files become "\.md". In the frontmatter: * Keep description, agent, and subtask. * If model has no provider prefix (no "/"), remove it. * Remove allowed-tools, argument-hint, mode, and tools. * Keep the body unchanged ($ARGUMENTS, $1, !`cmd` and @file work as-is). 4. Copy agents to .symbiotic/agents/ (project sources) or \~/.config/symbiotic/agents/ (global sources). Copilot "\.agent.md" / "\.chatmode.md" files become "\.md". Convert the frontmatter: * Remove name (the file name is the agent name). * Keep description. * Add "mode: subagent" for Claude Code agents. * model: remove "inherit"; replace sonnet/opus/haiku with a full "anthropic/\"; remove any other model without a "/" prefix. * color: convert color names to a quoted hex value like "#3B82F6". * tools (comma-separated list or array): replace with a "permission" map that sets "deny" for every tool that was NOT listed, using the keys read, edit, bash, grep, glob, list, webfetch, websearch, task, todowrite (Edit/Write/MultiEdit map to edit, LS maps to list). If tools was not set, add no permission map. * Remove any other field that isn't one of: description, mode, model, color, temperature, top\_p, steps, hidden, permission. * OpenCode agents are already in the right format: copy them unchanged. 5. Never overwrite an existing file in the Symbiotic Code directories. 6. Report what was migrated, what was skipped, every frontmatter field you changed or removed, and any body content that references tool-specific features that may need manual review. *** ## 9. Coming from OpenCode Symbiotic Code uses the same configuration format as OpenCode, but it does not read OpenCode's files. To migrate: 1. Rename `opencode.json` / `opencode.jsonc` to `symbiotic.json` / `symbiotic.jsonc`, and `~/.config/opencode/` to `~/.config/symbiotic/`. 2. Rename `.opencode/` to `.symbiotic/`. 3. Replace the `$schema` value with `https://config.symbioticsec.ai/config.json`. 4. Move skills from `.opencode/skills/` to `.symbiotic/skills/`. *** ## 10. What is not migrated * **Claude Code hooks:** use [plugins](/code/customize/plugins) instead. * **Permission rules in Claude Code `settings.json`** (for example `Bash(git diff:*)`): rewrite them as [tool permissions](/code/security/tool_permissions), for example `"bash": { "git diff *": "allow" }`. * **OAuth tokens and API keys:** reconnect with `/connect` for providers and `symbiotic mcp auth ` for MCP servers. * **Session history.** *** ## 11. Security modes Symbiotic Code adds a security mode that Claude Code and OpenCode don't have. Toggle it with `Ctrl+S` while running, or set a default per-agent in config: ```json theme={null} { "agent": { "build": { "security_mode": "balanced" } } } ``` Options: `permissive` (fastest, fewest confirmations), `balanced` (default), `strict` (most confirmations). See [Security Modes](/code/security/security_modes) for details. # Agents container Source: https://docs.symbioticsec.ai/code/security/containers Run the agent's shell commands in secure, isolated Docker Sandboxes Symbiotic Code integrates with **Docker Sandboxes (sbx)** to run the agent's shell commands in an isolated environment. When the sandbox is enabled, every command run by the `bash` tool executes inside a lightweight microVM instead of directly on your machine, so the agent can run tests and scripts without access to the rest of your system. ## Why use Agent Sandboxing? When AI agents run directly on a host machine, their shell commands have access to the user's files, SSH keys, shell history, environment variables, and local network. With the Agents container enabled: * **Isolated runtime:** Shell commands run inside a microVM with its own Linux kernel, filesystem and network. Only your project folder is shared with it. * **Workspace boundary:** File tools (`read`, `write`, `edit`, `glob`, `grep`, `apply_patch`) are blocked from accessing files outside your project folder. * **Network control:** Outbound connections from the sandbox follow a [network policy](#network-policies). * **Destructive command blocking:** Commands like `rm` or `git reset --hard` are blocked before they run. Only `bash` tool commands run inside the sandbox. File tools, [MCP servers](/code/configuration/mcp), [custom tools](/code/customize/custom_tools), [plugins](/code/customize/plugins) and `` !`command` `` placeholders in [custom commands](/code/customize/custom_commands) still run on your machine, and changes to your project folder are real changes. Keep using [tool permissions](/code/security/tool_permissions) alongside the sandbox. *** ## Requirements 1. **sbx CLI:** The standalone Docker Sandboxes CLI (version 0.26.0 or later). Docker Desktop is not required: sbx runs its own daemon. If sbx is missing, Symbiotic Code offers to install it for you with `brew install docker/tap/sbx` on macOS or `winget install Docker.sbx` on Windows. On Linux, [install it manually](https://www.docker.com/products/docker-sandboxes/). 2. **Docker account:** sbx requires you to sign in with a Docker account. If you aren't signed in, Symbiotic Code offers to run `sbx login`, which opens a browser to authenticate. *** ## Setup & Activation Agent sandboxing can be configured at two levels: * **Organization level:** Administrators define a security policy in the Symbiotic Security platform. They can force a setting (it shows as **Locked by org**) or restrict the values you can choose. * **Local level:** Developers change the settings that aren't locked with the `/agents-security` command. Local preferences are stored in `~/.local/share/symbiotic/user-prefs.json`. The sandbox starts in the background when Symbiotic Code launches. The first sandbox creation can take a while: you see a "Waiting for sbx to start..." notification if the agent runs a command before it's ready. A sandbox is reused for the same project across sessions. If sbx can't start (not installed, not signed in, daemon unavailable), shell commands are **blocked** rather than run on your machine, unless **Fallback to host** is enabled. If you decline the install or sign-in suggestion and your organization doesn't make the sandbox mandatory, commands run on your machine instead and you aren't asked again until the policy changes. *** ## Security Parameters These parameters can be set with the `/agents-security` command, or enforced by the organization policy: | Setting | Default | Description | | :- | :- | :- | | Agents sandbox | Depends on your organization's policy | Enable or disable the sandbox | | Fallback to host | Off | Run shell commands on your machine when the sandbox is unavailable, instead of blocking them | | Worktree isolation | On | Run the sandbox on a dedicated git branch, see [Worktree isolation](#worktree-isolation) | | Block destructive commands | On | Block destructive commands, see [Command guardrails](#command-guardrails) | | Network policy | `allow-all` | See [Network policies](#network-policies) | ### Network policies Control what outbound connections shell commands can make from inside the sandbox: | Policy | Description | | :- | :- | | `allow-all` | *(Default)* Outgoing network access is allowed, except for blocked hosts and IP ranges. | | `balanced` | *(Recommended)* sbx's curated preset: AI services, package registries, GitHub and cloud APIs are allowed; internal IP ranges and risky ports are denied. | | `deny-all` | All outgoing network access is blocked, except for allowed hosts and IP ranges. | By default, private and link-local IP ranges (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `169.254.0.0/16`) are blocked, and `api.github.com` and `registry.npmjs.org` are allowed. Admins can add organization-wide **allowlists** and **blocklists** of hosts and IP ranges (e.g., to prevent data exfiltration to unauthorized endpoints). A blocked host takes precedence over an allowed one. Shell commands that explicitly target a host blocked by your organization (for example `curl https://blocked.example.com`) are refused before they run. Network policies are global to sbx on your machine: Symbiotic Code resets and reapplies them each time it starts a sandbox, which overwrites policies you set manually with `sbx policy`. If the policy can't be applied, the sandbox is not used and shell commands are blocked. ### Command guardrails Prevent the execution of destructive or unsafe commands. * **Destructive command blocking:** When enabled, Symbiotic Code blocks these commands before they run: `rm`, `rmdir`, `unlink`, `shred`, `truncate`, `mkfs`, `dd … of=`, `chmod 777`, `git reset --hard`, `git clean -f`, `git checkout .` and redirections to block devices. The agent is told to use a safer alternative or ask you to run the command yourself. This check also applies when commands fall back to running on your machine. * **Organization blocklist:** Admins can block specific programs by name (for example `curl` or `ssh`). The agent is told the command is restricted by your organization. ### Worktree isolation Worktree isolation keeps the agent's changes off your current branch. * **How it works:** In a git repository, the sandbox is created on a new branch named after your current branch (`-agent1`, `-agent2`, …), using a git worktree stored in a `.sbx/` folder of your project. Add `.sbx/` to your `.gitignore`. * **Reviewing work:** Inspect the agent's branch with regular git commands, then run `/sandbox-merge` to merge it into the branch it was created from. * If the project isn't a git repository, or if your sbx version doesn't support branches, the project folder is mounted directly and the agent works on your current branch. *** ## Sandbox commands | Command | Description | | :- | :- | | `/agents-security` | View and change the sandbox settings | | `/sandbox-list` (or `/sandbox`) | List the sandbox sessions of the project and resume, merge or delete them | | `/sandbox-status` | Show how many sandboxes are running or stopped for the project | | `/sandbox-cp` | Copy a file between your machine and the running sandbox | | `/sandbox-secret` | List, add or remove API keys stored by sbx (for example for `github`, `openai` or `anthropic`), globally or for the running sandbox | | `/sandbox-pick` | Resume a stopped sandbox session | | `/sandbox-merge` | Merge a sandbox branch into the branch it was created from | | `/sandbox-delete` | Delete a sandbox session, including its worktree and branch | `/sandbox-pick`, `/sandbox-merge` and `/sandbox-delete` are only available when worktree isolation is on. Stopped sandboxes are never deleted automatically, so that you don't lose the agent's branch: use `/sandbox-delete` to clean them up. *** ## Technical Details For more details on how the underlying sandboxing technology operates, refer to the [Official Docker Sandboxes Documentation](https://docs.docker.com/ai/sandboxes/). # Security modes Source: https://docs.symbioticsec.ai/code/security/security_modes Configure security modes for Symbiotic Code Symbiotic Code can automatically check the code it writes for security issues. Security Modes let you control how thorough that checking is, so you can balance speed and safety depending on what you're working on. There are three modes: **Permissive**, **Balanced** (default), and **Strict**. Each mode changes the security workflow the agent is instructed to follow and whether Symbiotic Code enforces security tooling when files are modified. Security instructions are only added for agents that can edit files (for example, not for the read-only `ask` agent). ## How to switch modes | Method | How | | - | - | | Keybind (TUI) | The configurable `security_mode_cycle` keybind (default: `Ctrl+S`) cycles through the three modes | | TUI command | Run `/security-mode` to choose a mode | | CLI flag | `symbiotic run --security-mode permissive\|balanced\|strict` for non-interactive runs | | Agent config | Set `security_mode` on an [agent](/code/customize/custom_agents) definition to give it a fixed default | The current mode is shown below the prompt in the TUI and is remembered across restarts. You can change it at any point mid-conversation; it applies from the next message onward. When you switch to an agent that has `security_mode` set, the TUI uses that agent's mode. Switching back to an agent without one restores the mode you last selected. ```json symbiotic.json theme={null} { "agent": { "payments": { "security_mode": "strict" } } } ``` If an invalid or missing value is ever encountered, the system falls back to **`balanced`**. *** ## Permissive — fast iteration, security opt-in **Best for:** prototyping, throwaway scripts, demos, or early exploration where you just want to move fast. * The agent still writes reasonably secure code by default (input validation, no hardcoded secrets, etc.), but it won't stop to run security checks or scans on its own. * Security reviews only happen if you explicitly ask for one (e.g., "can you check this for vulnerabilities?"). * Nothing will interrupt your flow to run extra checks. > **Keep in mind:** Since checks aren't automatic, issues could slip through unless you ask for a review before shipping. *** ## Balanced — recommended default **Best for:** everyday development. This is the mode you'll use most of the time. * The agent thinks about security while planning your feature, not just after the fact. * After meaningful code changes, it automatically runs a security review — but skips it for things like documentation updates or purely cosmetic changes, so you're not slowed down unnecessarily. * If something serious is found (critical/high severity) in code it just wrote, it fixes it right away. * For less urgent findings, or issues in code it didn't just write, it will ask you what you'd like to do before making changes. > **Trade-off:** Good balance of safety and speed for typical feature work; trivial changes aren't slowed down by scanning. *** ## Strict — maximum protection, every change checked **Best for:** sensitive projects — authentication, payments, personal data, infrastructure, or anything under compliance requirements. * Security design tasks are planned upfront, before any code is written. * Every file change, no matter how small, triggers a full security review. * Low-confidence scanner findings are sent to the `triage` subagent to filter out false positives. * Critical, high, and medium severity issues are fixed immediately and re-checked to confirm resolution. * Low-severity issues are flagged and you're asked whether you want them addressed. * Switching to Strict mode mid-session also applies the stricter workflow to security findings from earlier turns in the current session. > **Keep in mind:** This is the most thorough option — expect more security-related steps and occasional questions as you work. *** ## Enforcement In Balanced and Strict modes, Symbiotic Code doesn't rely only on the agent following instructions: * **Forced security turn:** if the agent tries to finish after modifying files (other than documentation, images, and similar non-code files) without running both `securityscan` and `securitycheck`, it's given one extra turn with a reminder to run them. * **Automatic scan fallback:** if the agent still finishes without running `securityscan`, Symbiotic Code scans the modified files itself and shows an error if critical or high severity issues are found. This requires you to be logged in to Symbiotic. Neither happens in Permissive mode. *** ## Quick comparison | Behavior | Permissive | Balanced (default) | Strict | | - | - | - | - | | Security-design planning tasks | Not added | Added before implementation tasks | Mandatory, before all implementation tasks | | `securitycheck` | Opt-in only | Only for security-relevant changes | Every feature implementation | | `securityscan` | Opt-in only | After feature implementations (skips docs/cosmetic) | After **every** file edit | | Guardrail compliance check | Skipped unless requested | Checked for security-relevant files | Always checked | | Forced extra turn if security tools weren't run | No | Yes | Yes | | Automatic scan fallback | No | Yes | Yes | | Critical/high findings in new code | Reported only if you ask | Auto-fixed | Auto-fixed, blocks progress | | Medium findings in new code | Not surfaced automatically | Asks user | Auto-fixed | | Low findings in new code | Not surfaced automatically | Asks user | Asks user | | Pre-existing (untouched) code findings | Not surfaced automatically | Asks user, never auto-fixes | Asks user, never auto-fixes | | Relative speed | Fastest | Moderate | Slowest | ## Which mode should I use? | Situation | Recommended mode | | - | - | | Quick experiment, demo, or scratch code | Permissive | | Normal day-to-day feature work | Balanced (default) | | Auth, payments, personal data, infrastructure, compliance-sensitive work | Strict | **Tip:** If you start something in Permissive mode and decide to ship it, switch to Balanced or Strict and ask for a full review before merging — this ensures nothing gets missed just because you were moving fast earlier. # Security tools Source: https://docs.symbioticsec.ai/code/security/security_tools Security tools for Symbiotic Code Symbiotic Code comes with a set of security tools that the agent uses automatically to produce secure code. How often they run depends on the [security mode](/code/security/security_modes): in **Permissive** mode they only run when you ask for them. The agent is only instructed to run these tools automatically when it can edit files (for example `build`, not `plan` or `ask`). You can still ask any agent that has access to them to run a scan. ## Guardrails Guardrails are your organization's and repository's security requirements. When they are available, they are added to the agent's instructions so that all suggested implementations follow your company's standards and best practices: * **Organization guardrails** are defined in your Symbiotic Security organization and apply to all projects. * **Repository guardrails** are matched to the project using its git remote URL. Guardrails are loaded at startup and refreshed every 5 minutes. To generate guardrails for the current project, run `/generate-guardrails`. The Symbiotic CLI analyzes the repository and the result is saved for future sessions of this project. Guardrails generated locally take precedence over repository guardrails from your organization. ## Security checkpoint The `securitycheck` tool is a prompt-based security review: the agent reviews the files it created or edited against each of the **OWASP Top 10 (2025)** categories and reports whether each check passed. If risks are identified, the agent adjusts the implementation. It runs after the security scan, so its review can use the scan findings. In **Balanced** mode, it only runs when the change touches a security-relevant area. In **Strict** mode, it runs on every feature implementation. ## Security scan The `securityscan` tool runs a deterministic security scan with the Symbiotic CLI: * **Code scan (SAST)** for application source code * **Infrastructure scan** for infrastructure as code (Terraform, CloudFormation, Kubernetes, Dockerfiles, Ansible…) The agent runs one scan per type on the files it modified, then handles the findings according to the security mode. For example in **Balanced** mode, it fixes critical and high severity issues in code it just wrote, and asks you before fixing medium or low severity issues or issues in existing code. In **Strict** mode, it delegates low-confidence findings to the `triage` subagent to identify false positives. The scanner requires a Symbiotic API key: log in with the Symbiotic provider, or set the `SYMBIOTIC_API_KEY` environment variable. The Symbiotic CLI is downloaded and updated automatically. Files with no security-relevant code (documentation, images, fonts, archives, plain text…) are skipped. ### Ignore a false positive To ignore a finding in future scans, add a comment on the line above it with the rule ID and a reason: ```js theme={null} // nosymbiotic SYM_JSTS_0102 -fp -- path is application-controlled, not user input await fs.rename(extractedBinaryPath, binaryPath) ``` The agent may add these comments itself when it is sure a finding is a false positive, so review them in your diffs. ## Enforcement Outside of **Permissive** mode, if the agent modified files but didn't run `securityscan` and `securitycheck`, it is asked to run them before finishing. If it still ends its turn without a scan, a code scan runs automatically on the modified files and an error is shown if critical or high severity issues are found. ## Commands | Command | Description | | - | - | | `/scan-codebase` | Scan the whole project (or a given path) with code and infrastructure scans, run an OWASP Top 10 checkpoint, and list the true positive findings | | `/owasp-security-review` | Run an OWASP Top 10 review of the project, a path, a commit, a branch or a PR in the background | | `/generate-guardrails` | Generate security guardrails for the project | ## Permissions The security tools follow [tool permissions](/code/security/tool_permissions) with the `securityscan`, `securitycheck` and `generateguardrails` keys. They are allowed by default. # Tool permissions Source: https://docs.symbioticsec.ai/code/security/tool_permissions Control how tools interact with your system Symbiotic Code supports a layered permission configuration that controls whether the AI can run bash commands, edit files, read files, or use any other tool without prompting you every time. *** ## Defaults With no configuration, most tools are **allowed** without prompting. The exceptions are: | Permission | Default | | - | - | | `read` | `ask` for `*.env` and `*.env.*` files (`*.env.example` is allowed) | | `external_directory` | `ask` when a tool touches a path outside the project (skill directories and the tool-output directory are allowed) | | `doom_loop` | `ask` when the same tool is called with identical input 3 times in a row | | `question` | Allowed for the `build`, `plan`, `debug`, and `ask` agents; denied for other agents | Built-in agents add their own restrictions on top, for example the `plan` agent denies edits and the `ask` agent only allows read-only tools. See [Agents](/code/basics/agents). In non-interactive mode (`symbiotic run`), any permission that resolves to `ask` is automatically rejected. *** ## Load order Configs are deep-merged. **Later sources win.** | # | Source | Notes | | - | - | - | | 1 | Remote config | Organization defaults from `.well-known/symbiotic` | | 2 | Global config | `~/.config/symbiotic/symbiotic.json`/`symbiotic.jsonc` | | 3 | `SYMBIOTIC_CONFIG` env var | Custom config file path | | 4 | Project config | `symbiotic.json`/`symbiotic.jsonc`, from your git root down to your working directory | | 5 | `.symbiotic` directories | `.symbiotic/symbiotic.json`/`symbiotic.jsonc` | | 6 | `SYMBIOTIC_CONFIG_CONTENT` env var | Inline JSON/JSONC config content | | 7 | Organization account config | Loaded for the active account's organization | | 8 | Managed config | System administrator-controlled config | | 9 | `SYMBIOTIC_PERMISSION` env var | Inline JSON permission object, merged into `permission` last | Per-agent `permission` rules (in `agent..permission` or in the agent's markdown frontmatter) are applied after the global `permission` rules, so they win for that agent. See [Custom agents](/code/customize/custom_agents). *** ## Config schema ```json symbiotic.json theme={null} { "permission": { "bash": "ask", "edit": { "*": "allow", "*.lock": "deny" }, "read": "allow" } } ``` A rule is either: * A **string**: `"allow"`, `"ask"`, or `"deny"`, which applies to all inputs * A **pattern map**: `{ "": "allow" | "ask" | "deny", ... }`, evaluated in order; the **last matching pattern wins** You can also set `"permission": "ask"` (or `allow`/`deny`) to apply one action to every tool. ### Permission keys | Key | Pattern is matched against | | - | - | | `bash` | Each command, for example `git status` | | `edit` | File path relative to the project root. Covers the `edit`, `write`, `multiedit`, and `apply_patch` tools | | `read` | Absolute file path | | `glob`, `grep` | The search pattern | | `list` | The directory path | | `external_directory` | The directory outside the project, for example `/tmp/*` | | `task` | The subagent name | | `skill` | The skill name | | `webfetch` | The URL | | `websearch`, `codesearch` | The query | | `lsp` | Always `*` (only used when the experimental LSP tool is enabled) | | `todowrite`, `todoread`, `question`, `doom_loop` | Use a string action | Any other tool name is also accepted as a key, including [custom tools](/code/customize/custom_tools) and [MCP](/code/configuration/mcp) tools (for example `github_create_issue`). Keys support wildcards too, for example `"github_*": "deny"` or `"*": "ask"`. There is no separate `write` permission: file writes use the `edit` key. The legacy `tools` option (`"tools": { "bash": false }`) is still accepted and converted to `deny`/`allow` rules; `write`, `patch`, and `multiedit` map to `edit`. ### Pattern matching | Wildcard | Matches | | - | - | | `*` | Any sequence of characters, including spaces and `/` | | `?` | Exactly one character | * A pattern ending in ` *` also matches the command without arguments: `ls *` matches both `ls` and `ls -la`. * Path patterns starting with `~/` or `$HOME/` are expanded to your home directory. Rules are evaluated in order, with the **last matching rule winning**. Put broad rules first and more specific overrides after them. If no rule matches, the action is `ask`. ### Removed tools If the last rule for a tool is `"*": "deny"` (or the string `"deny"`), the tool is removed from the list of tools sent to the model, so the agent doesn't try to use it. *** ## Examples ### 1. Deny all bash, ask for edits, auto-allow `src/` `.symbiotic/symbiotic.json`: ```json theme={null} { "permission": { "bash": "deny", "edit": { "*": "ask", "src/*": "allow", "*.env": "deny" } } } ``` **What happens:** | Action | Result | | - | - | | `bash` | Tool removed, the agent can't run commands | | edit `src/core/tools/bash.ts` | Auto-allowed (matches `src/*`) | | edit `.env` | Denied immediately (matches `*.env`) | | edit `README.md` | Prompts you (matches `*`) | *** ### 2. Allow safe git commands, deny destructive ones ```json theme={null} { "permission": { "bash": { "*": "ask", "git *": "allow", "git commit *": "deny", "git push *": "deny", "grep *": "allow", "ls *": "allow" } } } ``` **What happens:** | Command | Last matching pattern | Result | | - | - | - | | `git status` | `git *` | Auto-allowed | | `git log --oneline` | `git *` | Auto-allowed | | `git commit -m "foo"` | `git commit *` | Denied | | `git push origin main` | `git push *` | Denied | | `grep -r "TODO" src/` | `grep *` | Auto-allowed | | `npm install` | `*` | Prompts you | Order matters. If `"git *": "allow"` were placed after `"git commit *": "deny"`, it would match last and allow `git commit`. Compound commands (`&&`, `||`, `;`, `|`) are split into individual commands and each one is checked. The command is denied if any part is denied, and only runs without a prompt if every part is allowed. *** ### 3. Trust the whole project, allow everything ```json theme={null} { "permission": { "bash": "allow", "edit": "allow", "external_directory": "allow" } } ``` No prompts, including for files outside the project. Useful for trusted personal projects. *** ### 4. Lock down everything, full review mode ```json theme={null} { "permission": { "bash": "ask", "edit": "ask", "webfetch": "ask" } } ``` Every command, file change, and web request requires your approval. *** ## Deep merge behavior When multiple sources define rules for the same tool, pattern maps are merged (a key redefined later keeps its original position but takes the new action; new keys are added at the end), and string rules replace entirely. **Example:** `symbiotic.json` defines bash rules, `.symbiotic/symbiotic.json` adds more specific ones: `symbiotic.json`: ```json theme={null} { "permission": { "bash": { "*": "ask", "ls *": "allow" } } } ``` `.symbiotic/symbiotic.json`: ```json theme={null} { "permission": { "bash": { "git push *": "deny" } } } ``` **Effective config:** ```json theme={null} { "permission": { "bash": { "*": "ask", "ls *": "allow", "git push *": "deny" } } } ``` *** ## "Allow always" When you choose **Allow always** at a permission prompt in the TUI, the approval applies to the current project **until Symbiotic Code is restarted**. Other pending requests covered by the approval are resolved automatically. To make an approval permanent, add the rule to your config. In the [IDE extension](/code/basics/IDE_extension), approved and denied patterns are saved to your global config file in `~/.config/symbiotic/`. ### Which patterns are approved For **bash commands**, the approved pattern is the command's "human-understandable" prefix followed by ` *`: | Command | Approved pattern | | - | - | | `git commit -m "feat: add x"` | `git commit *` | | `bun run dev` | `bun run dev *` | | `docker build -t app .` | `docker build *` | | `ls -la` | `ls *` | | `rm -rf dist/` | `rm *` | | `curl https://api.example.com` | `curl *` | Approving `rm -rf dist/` always allows **every** `rm` command. Choose **Allow once** for destructive commands. For most other tools (including `edit`, `read`, and `webfetch`), **Allow always** approves the tool for all inputs. For `external_directory`, it approves the requested directory. For `skill`, it approves that skill. *** ## Config changes Config files are read when Symbiotic Code starts. Restart it after editing `symbiotic.json` or `.symbiotic/symbiotic.json` for permission changes to take effect. *** ## File locations ``` your-project/ ├── symbiotic.json # project-level config (committed) └── .symbiotic/ └── symbiotic.json # additional project overrides ~/.config/symbiotic/ └── symbiotic.json # global config ``` **Recommendations** * Commit `symbiotic.json` with team-wide defaults * Use your global config for personal preferences * Use `SYMBIOTIC_PERMISSION` for one-off overrides, for example `SYMBIOTIC_PERMISSION='{"bash":"deny"}' symbiotic` # Use cases Source: https://docs.symbioticsec.ai/code/use_cases Simple use cases to showcase Symbiotic Code's security capabilities *** Symbiotic Code is a security-first coding agent. In the default **Balanced** [security mode](/code/security/security_modes) (and in **Strict**), **code it edits or creates is checked for security vulnerabilities** before it finishes. To test its capabilities, you can try the following scenarios: ### Implement a feature with guardrails Guardrails ensure all code generated follows your company’s security standards and best practices. 1. Connect your GitHub account in the [Symbiotic Portal](https://app.symbioticsec.ai) 2. Create [guardrails](/flow/admins/guardrails) for one of your repositories 3. Open a local clone of that repository in Symbiotic Code and ask it to implement a feature On startup, Symbiotic Code fetches your organization guardrails and the repository guardrails matching the project's git remote, then applies them while implementing. ### Security scanning while coding A deterministic scanner (`securityscan`) and an agentic OWASP Top 10 review (`securitycheck`) run while you code, providing feedback on your implementation. Create a new project from scratch to see all security features in action: 1. Ask the agent to create a simple project (e.g., a weather app, to-do list, or CRM) 2. Run `/generate-guardrails` to generate project-level security guardrails from the code 3. Ask for a new feature and watch security checks run during implementation 4. See the final security scan validate the code. Findings in code the agent just wrote are fixed or surfaced to you depending on their severity ### Audit an existing codebase * `/scan-codebase [path]` runs code and infrastructure scans, filters out false positives, and summarizes the true positives alongside an OWASP Top 10 audit. * `/owasp-security-review [path|commit|branch|pr]` runs a dedicated OWASP Top 10 reviewer subagent in the background. See [Security tools](/code/security/security_tools) for details. # Using Symbiotic Code Source: https://docs.symbioticsec.ai/code/using Everything you need to be productive with Symbiotic Code Walk through the essential Symbiotic Code workflows. *** ## Best practices ### How to prompt The quality of the agent's response depends directly on how clearly you communicate your intent. A few principles: * **Be specific about the goal**: say what you want to achieve, not just what to do * **Name the files or areas involved**: the agent searches your codebase, but pointing it in the right direction saves time and tokens * **Declare constraints upfront**: mention language versions, frameworks, or coding standards before they become a problem * **One task at a time**: break complex requests into focused steps rather than asking for everything at once ``` Fix the bug in auth ``` -> Too vague: no file, no context, no constraints. ``` In @src/auth/login.ts, the login function returns 200 even on invalid credentials. Fix it to return 401 and add a test. ``` -> Clear filepath, explicit problems, clear expected behavior. ### Provide rich content There are multiple ways to provide more context to your prompts and get better results: * Reference and include specific files from your project with `@` instead of describing where code is. * Paste URLs for documentation and API references. * Paste images directly. Copy/paste or drag and drop images into the prompt. This can be useful to show UI designs or error screenshots. Results may vary depending on which models you use. *** ## Agents Symbiotic Code has 4 primary agents. Cycle between them with `Tab` (`Shift+Tab` to go back) or pick one with the `/agents` command. | Agent | What it does | When to use it | | - | - | - | | **Build** | Default agent. Uses all tools according to your [permissions](/code/security/tool_permissions) | Default for development work | | **Plan** | Planning mode: file edits are denied (except plan files in `.symbiotic/plans/`) and the agent is instructed to stay read-only | Exploring a codebase or planning a feature or refactor | | **Ask** | Read-only: can read, search and browse the web, but cannot edit files or run shell commands | Understanding code or learning about patterns | | **Debug** | Evidence-based debugging: instruments code, reproduces the bug, and fixes only with runtime proof | Investigating unexpected behavior or tracking down errors | Primary agents can also delegate work to built-in subagents (`general`, `explore`, `triage`, `owasp-security-review`). You can call one yourself with `@`, for example `@explore where is the auth middleware?`. Start in **Plan** agent when working in an unfamiliar codebase, and then switch to **Build** once you have a clear plan. [Learn more about agents](/code/basics/agents) *** ## Command palette Press `Ctrl+P` to open the command palette, or type `/` in the prompt to autocomplete slash commands. | Command | What it does | | - | - | | `/new` | Start a fresh session | | `/agents` | Switch between agents | | `/models` | Change the active model | | `/security-mode` | Switch between permissive, balanced and strict [security modes](/code/security/security_modes) | | `/mcps` | Enable or disable MCP servers | | `/skills` | Pick a skill to invoke | | `/review` | Review uncommitted changes (or a commit, branch or PR) in a subtask | | `/sessions` | Switch between saved sessions | Start a message with `!` to run it as a shell command directly, without going through the model. [Full command reference](/code/basics/common_commands) · [Terminal UI guide](/code/basics/TUI) *** ## Add a Skill Skills are reusable instruction sets that the agent loads on demand. You install one by creating a `SKILL.md` file in the right place. Place your skill in one of these locations: ``` .symbiotic/skills//SKILL.md ← this project only ~/.config/symbiotic/skills//SKILL.md ← available everywhere ``` `.agents/skills/` and `.claude/skills/` (in the project or your home directory) are also discovered. Each `SKILL.md` starts with YAML frontmatter: ```markdown theme={null} --- name: git-release description: Create consistent releases and changelogs --- ## What I do - Draft release notes from merged PRs - Propose a version bump - Provide a copy-pasteable `gh release create` command ``` Type `/skills` to pick a skill, or invoke it directly with `/`. The agent can also load it on its own when relevant, or you can reference it in your prompt: ``` Use the git-release skill to prepare the v2.1.0 release notes. ``` [Learn more about skills](/code/customize/skills) *** ## Add an MCP server MCPs allow Symbiotic Code to connect to external data sources (e.g. local files, databases), tools (e.g. search engines, calculators) and workflows (e.g. specialized prompts). Each MCP server adds to the context window. Keep only what you actively use to avoid performance and security overhead. You can also run `symbiotic mcp add` to add a server interactively. Open (or create) `symbiotic.jsonc` at your project root or `~/.config/symbiotic/symbiotic.jsonc` for a global setup: ```jsonc title="symbiotic.jsonc" theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "mcp": { "my-mcp-server": { "type": "local", "command": ["npx", "-y", "my-mcp-package"], "enabled": true } } } ``` Relaunch Symbiotic Code. Use `/mcps` to confirm the server is connected and enabled, or `/status` to see its connection status. Call out the MCP by its config name: ``` Use my-mcp-server to fetch the latest schema and generate TypeScript types. ``` [Full MCP documentation](/code/configuration/mcp) *** ## Add a plugin Plugins let you hook into Symbiotic Code's events and extend or modify its behavior. There are two ways to load them: **Option 1 — Local file** Drop a `.js` or `.ts` file into the plugin directory: ``` .symbiotic/plugins/ ← this project only ~/.config/symbiotic/plugins/ ← available everywhere ``` Files in these directories are loaded automatically at startup. **Option 2 — npm package** Add the package name to your config file: ```json title="symbiotic.json" theme={null} { "$schema": "https://config.symbioticsec.ai/config.json", "plugin": ["@my-org/custom-plugin"] } ``` npm plugins are installed automatically on next launch. You can also run `symbiotic plugin ` (add `-g` for the global config) to install a plugin and add it to your config in one step. [Full plugin documentation](/code/customize/plugins) *** ## Next steps See Symbiotic Code in action with real security-focused scenarios. Full reference for local and remote MCP configuration. Write and distribute reusable agent instruction sets. Extend Symbiotic Code with hooks and custom behavior. Understand Build, Plan, Ask, and Debug agents in depth. Configure which AI model and provider you use. # Agent Security Source: https://docs.symbioticsec.ai/flow/admins/agent_security Configure prompt scanning policies and sandbox constraints for Symbiotic Code agents to prevent data exfiltration and enforce security controls Prompt scanning and agent sandboxing are configured under **Settings > Agents security**. These features work together to create a defense-in-depth approach to agent security. ## Overview Prompt scanning and sandboxing are complementary security features that protect your organization from security risks introduced by AI agents: * **Prompt Scanning**: Automatically detects and handles sensitive data patterns (credentials, PII, secrets) in user inputs and agent outputs before they're processed * **Agent Sandboxing**: Isolates agent execution environments with strict network, file system, and command-level restrictions For each configuration, you can enable or disable it and lock it or not. A locked configuration will be enforced to all users and cannot be overridden. ## Agent Sandboxing Agent sandboxing restricts what Symbiotic Code agents can do when executing tasks, creating isolated execution environments using docker SBX. ### Sandbox Environment When enabled, agents run inside Docker SBX containers with strict isolation: **Configuration**: **Settings > Agents security > Agents sandbox > Run agents in a sandbox** * Agents execute inside containerized environments * Host filesystem access is blocked (except via explicit allow-lists) * Network access is restricted unless explicitly allowed * Shell command execution is limited to approved operations ### Fallback Behavior **Configuration**: **Settings > Agents security > Agents sandbox > Fallback to host** When the sandbox is unavailable: * **Enabled**: Agents continue running on the host system * **Disabled**: Agents fail safely and request sandbox restoration Enabling fallback to host reduces security isolation. Enable only if sandbox availability is critical for your workflows. ### Worktree Isolation **Configuration**: **Settings > Agents security > Agents sandbox > Worktree isolation** When enabled: * Agents work within an isolated Git worktree * Host working directory and files are protected * Changes are confined to the sandboxed environment ### Command Restrictions Limit the types of shell commands agents can execute. **Configuration**: **Settings > Agents security > Agents sandbox > Block destructive shell commands** When enabled, agents cannot execute `rm -rf` and mass deletion commands You can also define custom commands to block. ### Network Controls Manage network access for agents executing code or making HTTP requests. **Access Mode**: Choose between **Balanced**, **Restrictive**, and **Open** network policies. #### Exceptions Define which hosts and networks agents can reach: | Type | Examples | Purpose | | - | - | - | | **Blocked Hosts** | `evil.com`, `malicious.org` | Prevent connections to known malicious sites | | **Blocked CIDRs** | `192.168.1.0/24`, `10.0.0.0/8` | Block private/internal network ranges | | **Allowed Hosts** | `api.github.com`, `registry.npmjs.org` | Whitelist trusted external services | | **Allowed CIDRs** | `172.16.0.0/12`, `203.0.113.0/24` | Permit specific IP ranges for integrations | **Important**: Agents can still make requests using built-in tools (e.g., WebFetch) regardless of these settings. Network exceptions control general code execution behavior. ## Prompt Scanner The prompt scanner analyzes user prompts and tool outputs for sensitive data patterns and applies your configured policy actions. ### How It Works When enabled, the prompt scanner: 1. Scans all user prompts before agents process them 2. Scans agent outputs and tool results in real-time 3. Detects patterns matching your configured categories 4. Applies actions based on your policy (warn, redact, or block) ### Configuration Access prompt scanner settings under **Settings > Agents security > Prompt scanner**. #### Sensitive Data Categories Configure which types of sensitive data to monitor: * **Credentials**: Passwords, GitHub tokens, API keys * **Cloud Keys**: AWS access keys, GCP service account keys, Azure secrets * **Secrets**: Private keys, encryption keys, environment variable values * **PII**: Email addresses, phone numbers, home addresses, social security numbers * **Payment Cards**: Credit/debit card numbers #### Policy Actions Choose how the scanner responds to detected sensitive data: | Action | Behavior | Use Case | | - | - | - | | **Warn** | Alerts the user but allows the prompt to proceed | Development/testing environments | | **Redact** | Removes or masks the sensitive data before processing | Production - prevents data leakage while allowing workflows | | **Block** | Rejects the prompt/output entirely | High-security environments requiring strict controls | ### Best Practices * Enable **Block secrets** by default for production environments * Use **Redact** for PII to balance security with functionality * Configure **Block credentials** to prevent accidental token exposure * Review and adjust settings based on false positive rates # AI Inventory Source: https://docs.symbioticsec.ai/flow/admins/ai_inventory Track and manage all assets used by coding agents in your organization You can access AI Inventory [here](https://app.symbioticsec.ai/ai-inventory). This feature provides complete visibility into all assets consumed by Symbiotic Code agents across your organization. ## Overview The AI Inventory feature provides administrators with a comprehensive view of all assets utilized by Symbiotic Code agents during code generation, review, and analysis tasks. This includes plugins, models, skills, integrations, and other resources that power your coding agents. ### What is tracked? The AI Inventory tracks: * **Plugins**: Code security and analysis plugins used during agent execution * **Skills**: Specialized capabilities and workflows (e.g., QA testing, PRD writing) Each asset includes: * **Usage metrics**: How many times the asset was used * **Last used**: When the asset was most recently used * **Repositories**: Which repositories used the asset * **Users**: Who triggered the asset usage ## Accessing the AI Inventory Navigate to the AI Inventory page from your organization dashboard View all available assets with filtering and search capabilities Click on any asset to see detailed usage information ## Filtering and Searching The AI Inventory provides multiple ways to find and organize assets: ### By Type Filter assets by category: * **Plugins**: Code analysis and security tools * **Skills**: Agent capabilities and workflows ### By Repository Filter to see which assets are used in specific repositories. This helps you understand: * Which repositories consume which assets * Repository-specific asset dependencies * Asset usage patterns across repositories ### By User Track which team members have triggered asset usage. This enables: * User-based usage insights * Identifying power users * Understanding adoption patterns ### By Last Used Sort assets chronologically to identify: * Most recently used assets * Unused or deprecated assets * Asset adoption trends over time ### Search Use the search bar to quickly find specific assets by name. This is useful when: * Looking up a specific plugin or skill * Verifying asset availability * Finding related assets ## Understanding Asset Details When you click on an asset, you'll see: * **Asset Name**: The identifier of the asset * **Type**: Category of the asset (Plugin, Skill, Integration, Model, etc.) * **First Seen**: When this asset was first used in your organization * **Last Used**: Most recent usage timestamp * **Total Usage**: Cumulative usage count * **Repositories**: List of repositories where this asset was used * **Users**: Team members who triggered asset usage * **Status**: Current deployment and operational status # Connect GitHub or GitLab Source: https://docs.symbioticsec.ai/flow/admins/github_integration Connect your GitHub organization or GitLab group and choose the repositories Symbiotic can scan Connect a source-control provider from the [Integrations page](https://app.symbioticsec.ai/settings/integrations). You can connect GitHub and GitLab independently. ## Connect GitHub 1. Go to the [Integrations page](https://app.symbioticsec.ai/settings/integrations). Integration Page 2. Select **Connect** for GitHub. 3. You will be redirected to GitHub. Github Repo Choice Page Web 4. Give the Symbiotic GitHub App access to all repositories in your organization or select specific repositories. You can change this scope later. 5. Select **Install & Authorize**. 6. You will return to Symbiotic, where selected repositories are scanned in the background. ### Change GitHub repository access 1. Go to the [Integrations page](https://app.symbioticsec.ai/settings/integrations). 2. Select **Manage** for GitHub. 3. You will be redirected to GitHub. Github Repo Choice Page Web 4. Change the repository scope, then select **Install & Authorize**. 5. You will return to Symbiotic, where newly added repositories are scanned in the background. ## Connect GitLab 1. Go to the [Integrations page](https://app.symbioticsec.ai/settings/integrations) and select **Connect** for GitLab. 2. Choose **GitLab Cloud** or **GitLab Self-Managed**. 3. Enter the GitLab group ID and a group access token. For GitLab Self-Managed, also enter the GitLab instance URL. 4. Select **Continue**. Symbiotic retrieves the projects available to the group. 5. Select the projects to scan and choose whether new projects are scanned automatically. 6. Complete the connection. Symbiotic scans the selected projects in the background. Store the GitLab group access token only in the integration form. Use a token with the minimum permissions needed to read the selected projects, and rotate or revoke it in GitLab if it is no longer needed. ### Manage or disconnect GitLab 1. Go to the [Integrations page](https://app.symbioticsec.ai/settings/integrations) and select **Manage** for GitLab. 2. Update the selected projects or automatic scanning setting, then select **Save**. 3. To remove the connection, select **Disconnect** and confirm. # AI Guardrails Source: https://docs.symbioticsec.ai/flow/admins/guardrails Secure AI generated code using guardrails tailored for your organization and repositories AI Guardrails generate Markdown instructions that coding agents can use when generating code. You can create rules for your whole organization or for a selected set of monitored repositories. Organization and repository configurations are managed separately and are applied together by Symbiotic Code when both are available. Only organization members with the required guardrail permissions can create, update, or delete configurations. In the portal, organization guardrails are available to organization administrators and owners. ## Create organization guardrails Organization guardrails apply your organization's security and development context across projects. You can optionally provide internal policy and requirements files in Markdown, text, or PDF format, answer the security questionnaire, and add custom policies. Open [AI Guardrails](https://app.symbioticsec.ai/guardrails) and select **Create organization AI guardrails**. Upload up to five internal policy or requirements files, if needed. Each file can be up to 50 MB and must be a `.md`, `.txt`, or `.pdf` file. This step is optional. Answer the security questions to provide context about your organization. Questions are optional, but completing the relevant questions produces more tailored rules. Add any additional code or infrastructure policies in **Custom policies**, then click **Generate guardrails**. The portal uploads and analyzes selected files before submitting the configuration. File-content generation runs asynchronously, so the generated `AGENTS.md` content may appear after the configuration is created. Review the generated `AGENTS.md` in the preview panel. You can edit and save the custom document content from the preview; generated file content is regenerated when the questionnaire answers or custom document content changes. ## Create repository guardrails Repository guardrails apply to one or more monitored repositories. A repository can belong to only one active repository guardrail configuration, and repositories that already have an active configuration cannot be selected again. When creating a configuration for multiple repositories, select repositories that share the same security and development context. When you connect Symbiotic to your Gihub, or Gitlab, all scanned repositories are analyzed and guardrails are automaticlaly generated for you. Open [AI Guardrails](https://app.symbioticsec.ai/guardrails) and select **Create repository AI guardrails**. Select the monitored repositories to which the rules should apply. If no repositories are available, configure repository monitoring in **Settings → Repositories** first. Answer the security questions and add any repository-specific code or infrastructure policies. Questions and custom policies are optional. Choose whether to include the organization's guardrails, then click **Generate guardrails**. Including organization guardrails combines organization-level instructions with the repository-specific rules. Review the generated `AGENTS.md` in the preview panel. You can rename, edit, save, or delete the configuration from the repository guardrail view. ## Deploy and use guardrails The generated file is named `AGENTS.md`. From the preview panel, use **Copy** to copy the complete Markdown file or **Download** to download it locally. Place the file where your coding agent expects its instructions: * **Agents that support `AGENTS.md`:** place it anywhere supported by the agent; the repository root is the recommended location. * **Claude Code:** place it at the repository root. * **GitHub Copilot:** use the instruction location supported by your Copilot setup, such as `.github/instructions`. [Symbiotic Code](https://docs.symbioticsec.ai/) automatically fetches active organization guardrails and repository guardrails when a project starts and refreshes them periodically. Repository matching uses the project's Git remote URL. Locally generated repository guardrails take precedence over the remotely fetched repository configuration. For other coding agents, copy or download the generated `AGENTS.md` and commit it to the repository so the team can share the same instructions. The generated file is a snapshot: update or regenerate the configuration when your organization's policies or repository context changes. # Monitored repositories Source: https://docs.symbioticsec.ai/flow/admins/monitored_repositories Select and manage which repositories are monitored for vulnerabilities, guardrails, and AI inventory ## Overview The Monitored repositories page allows you to control which repositories are actively monitored by Symbiotic Code. Your selections here determine: * Which repositories appear in the **Repositories** page * Which repositories **Vulnerabilities** you will see * Which repositories you can create **Guardrails** on * Which repositories are indexed in the **AI Inventory** ## Add and manage monitored repositories 1. Go to the [Monitored repositories](https://app.symbioticsec.ai/settings/repositories) page in Settings 2. You will see a list of all repositories slug authorized 3. In the New input you can add new repositories slug to monitor When you connect either to Github or Gitlab, repositories slug are automatically added to the monitored list. ## Impact on features ### Repositories page Only monitored repositories will be listed and their status will be tracked in real-time. ### Vulnerabilities Vulnerability scans run on all repositories, but you will see in your portal only the vulnerabilities of the monitored repositories. ### Guardrails You can create guardrails only for the monitored repositories. ### AI Inventory You will see assets and usage only for monitored repositories. When changing the list of monitored repositories, it may take up to 15 minutes for the AI inventory viex to take it into account. # Setup CI integration Source: https://docs.symbioticsec.ai/flow/admins/setup_CI_integration Create a security gate using our CLI or Github Action Our CI integration provides both infra and code scans, to help you identify vulnerabilities before they reach production. # Using Github Actions To make it easier for organizations using Github, we created a Github Action that can be easily integrated in your pipelines. By default, the action will launch a differential scan (only returning new vulnerabilities) when triggered by a pull request event. If you want to disable this behavior and always return all vulnerabilities, you can set the diff-scan input to false. ```yaml Infra Scan theme={null} code-security-scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Scan uses: SymbioticSec/actions/scan@v0.4.2 with: scan-type: infra api-token: ${{ secrets.SYMBIOTIC_API_TOKEN }} diff-scan: true ``` ```yaml Code Scan theme={null} code-security-scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Scan uses: SymbioticSec/actions/scan@v0.4.2 with: scan-type: code api-token: ${{ secrets.SYMBIOTIC_API_TOKEN }} diff-scan: true ``` ```yaml Full Scan theme={null} full-security-scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Scan uses: SymbioticSec/actions/scan@v0.4.2 with: api-token: ${{ secrets.SYMBIOTIC_API_TOKEN }} diff-scan: true ``` To run the differential scan, the action must be triggered by a pull request event. To do that, make sure to add the following to your workflow triggers: ```yaml expandable theme={null} on: pull_request: types: - opened - synchronize - reopened ``` Don't forget to retrieve your [organization token](https://app.symbioticsec.ai/settings/organization-token) and to set it as a secret in your Github setttings. # Using our CLI If you are not using Github you can still use our cli in your pipelines : ```bash theme={null} curl -sSL https://github.com/SymbioticSec/cli/releases/latest/download/install.sh | bash echo 'export PATH="$HOME/.local/bin:$PATH"' ``` We advise you to set `SYMBIOTIC_API_TOKEN` as an environment variable in your pipeline. You can create or retrieve this token [here](https://app.symbioticsec.ai/settings/organization-token). ```bash Launch infra scan theme={null} symbiotic-cli ci infra ./ --skip-upload-results ``` ```bash Launch code scan theme={null} symbiotic-cli ci code ./ --skip-upload-results ``` You can override the severity threshold defined in the configuration file using the *severity-threshold* option. Ex: `symbiotic-cli ci infra ./ --severity-threshold high` As of today scans must be launched on the root folder to correctly take into account the configuration file If you want your detected vulnerabilities to be uploaded to Symbiotic's backend to benefit from the dashboard, detailed reports, remediation suggestions and more: you need to provide information about your git repository to the command. See the example below : ```bash Launch infra scan theme={null} symbiotic-cli ci infra ./ \ --git-remote-url \ --git-first-commit-sha \ --git-latest-commit-sha \ --git-default-branch \ --git-current-branch ``` ```bash Launch code scan theme={null} symbiotic-cli ci code ./ \ --git-remote-url \ --git-first-commit-sha \ --git-latest-commit-sha \ --git-default-branch \ --git-current-branch ``` ```yaml theme={null} stages: - test test-full-script: stage: test image: ubuntu:latest before_script: - apt-get update && apt-get install -y curl bash git unzip - curl -sSL https://github.com/SymbioticSec/cli/releases/latest/download/install.sh | bash - export "PATH=$HOME/.local/bin:$PATH" script: - symbiotic-cli ci code ./ --skip-upload-results rules: - if: '$CI_COMMIT_BRANCH' ``` # Configuration You can configure what makes the CI fail using our [configuration file](/flow/devs/actions/configure_detection). ```yaml Minimal configuration for CI theme={null} # SYMBIOTIC SECURITY CONFIGURATION FILE blocking: severity_threshold: low ``` If there is no configuration file in the repository or if this configuration file has no blocking property, the CI will pass by default. # User management Source: https://docs.symbioticsec.ai/flow/admins/user_management Add, remove and manage users ## Add users Before adding users, you have to specify allowed domains in the dedicated section. You have 3 options to add users : 1. **Manually** by writing emails one by one and pressing enter between each email 2. **Via CSV,** by importing a CSV file with a column containing the email list. The file must contain only a column with the `email` as a name 3. **Via a registration link**, that can be shared and contains a token allowing any people with the link and an email of the authorized domains to create an account. # Webhooks Source: https://docs.symbioticsec.ai/flow/admins/webhooks Set up webhooks and connect Symbiotic to your ecosystem ## Configure a webhook To create a webhook, provide: * an HTTPS endpoint URL * one or more events to send Webhook URLs must not include query parameters and must resolve to a public address. HTTP, non-HTTPS schemes, private IP addresses, localhost, cloud metadata endpoints, and shell metacharacters are rejected. After creation, Symbiotic returns a signing secret. Store it securely: it is used to verify that requests came from Symbiotic. You can manage webhooks from the [Webhook settings](https://app.symbioticsec.ai/settings/webhook). Webhooks are shared across all users in an organization. Treat the signing secret as a credential and do not expose it in client-side code or logs. ## Available events You can subscribe to the following events: * `vulnerability.created` * `vulnerability.remediated` * `vulnerability.ignored` * `vulnerability.unignored` * `training.completed` ## Webhook format Webhook requests use JSON and have a common envelope: | Field | Type | Description | | - | - | - | | `event` | string | The event name. | | `timestamp` | integer | Unix timestamp for when the event was recorded. | | `data` | object | Event-specific data. | For vulnerability events, `data` includes the vulnerability identifiers and timestamps below, as well as nested `rule`, `finding`, and `remote_issue` objects. ### Vulnerability created ```json theme={null} { "event": "vulnerability.created", "timestamp": 1728463677, "data": { "pubkey": "0ef8ac7e-1b9d-48d9-82eb-2f2355ba2b31", "rule_id": "AVD-AWS-0088", "file_path": "infra/storage.tf", "vulnerability_id": "8a5f9d7e-0a59-4d7a-bc9b-4f28a7b89c1a", "created_at": 1728463677, "rule": { "pubkey": "3b7b2d18-4d0f-4e89-9c5d-3f9a7d2b6e11", "identifier": "AVD-AWS-0088", "version": "v1", "title": "S3 bucket allows public access", "description": "The S3 bucket is configured to allow public access.", "resolution_advice": "Restrict bucket access to authorized principals.", "impact": "Public access may expose sensitive data.", "severity": "2", "language": "terraform", "languages": ["terraform"], "active": true, "static_remediation": "" }, "finding": { "id": 12345, "fingerprint": "sha256:example-fingerprint", "anchor_text": "acl = \"public-read\"", "content_snippet": "resource \"aws_s3_bucket\" \"assets\" {", "is_historical": false, "created_at": "2024-10-09T12:47:57Z", "updated_at": "2024-10-09T12:47:57Z" }, "remote_issue": { "pubkey": "0ef8ac7e-1b9d-48d9-82eb-2f2355ba2b31", "status": "active", "branch": "main", "file_path": "infra/storage.tf", "line_start": 24, "line_end": 24, "author": "developer@example.com", "created_at": "2024-10-09T12:47:57Z", "updated_at": "2024-10-09T12:47:57Z" } } } ``` ### Vulnerability remediated The `data` object uses the same structure as `vulnerability.created`, with `remediated_at` instead of `created_at`. ### Vulnerability ignored and unignored The `data` object uses the same vulnerability structure, with `ignored_at` for `vulnerability.ignored` and `unignored_at` for `vulnerability.unignored`. ### Training completed The `data` object contains: | Field | Type | Description | | - | - | - | | `created_at` | integer | Unix timestamp for when the training record was created. | | `updated_at` | integer | Unix timestamp for the latest update. | | `user_id` | UUID | ID of the user who completed the training. | | `user_email` | string | Email address of the user. | | `user_first_name` | string | First name of the user. | | `user_last_name` | string | Last name of the user. | | `track_training_id` | UUID | ID of the training record. | | `type` | string | Training type. | | `state` | string | Training state. | | `state_description` | string | Description of the training state. | | `rule_title` | string | Title of the associated rule. | | `rule_identifier` | string | Identifier of the associated rule. | | `rule_severity` | string | Severity of the associated rule. | ## Verify webhooks Symbiotic sends the signature in the `X-SymbioticSec-Signature` header. Verify it with the signing secret shown in your [Webhook settings](https://app.symbioticsec.ai/settings/webhook). The signature is an HMAC-SHA256 digest. Symbiotic signs the JSON payload after sorting object keys and serializing with compact separators. Parse the request body as JSON, reproduce that canonical serialization, and compare the expected signature using a constant-time comparison. ```python theme={null} import hashlib import hmac import json def verify_signature(signing_secret: str, payload: dict, received_signature: str) -> bool: expected_signature = hmac.new( bytes.fromhex(signing_secret), json.dumps(payload, sort_keys=True, separators=(",", ":")).encode(), hashlib.sha256, ).hexdigest() return hmac.compare_digest(expected_signature, received_signature) ``` Reject the request when the header is missing or the signature does not match. Keep the signing secret private and use HTTPS for your receiving endpoint. # Configure detection Source: https://docs.symbioticsec.ai/flow/devs/actions/configure_detection Configure which vulnerabilities should block CI or be ignored, using our configuration file Using a configuration file you can tailor detection to your context and focus on what matters most. It lets you define which vulnerabilities are **blocking** in CI (and highlighted as Policy Breaching in the IDE) and which are **ignored** everywhere. To be taken into account the file must be named `symbiotic.yml` and placed at the root of the repository. Symbiotic will also search parent directories up to the current working directory if the file is not found at the root. Ignored rules always take priority over blocking rules. If a rule appears in both sections, it will be ignored. *** ## File structure The file has two top-level sections: `blocking` and `ignored`. Both are optional. Each section accepts the same set of filtering criteria. ```yaml theme={null} blocking: severity_threshold: ... providers: [...] services: {...} vulnerabilities: [...] ignored: severity_threshold: ... paths: [...] languages: [...] providers: [...] services: {...} vulnerabilities: [...] ``` *** ## `blocking` Defines which detections will **fail the CI pipeline** and appear as Policy Breaching in the IDE. ### `severity_threshold` Blocks all rules at this severity level **and above**. Accepted values (case-insensitive): `low`, `medium`, `high`, `critical` ```yaml theme={null} blocking: severity_threshold: high # blocks HIGH and CRITICAL ``` | threshold | Severities blocked | | - | - | | `critical` | CRITICAL | | `high` | CRITICAL, HIGH | | `medium` | CRITICAL, HIGH, MEDIUM | | `low` | CRITICAL, HIGH, MEDIUM, LOW | ### `providers` Blocks all rules associated with a cloud provider. ```yaml theme={null} blocking: providers: - Azure - AWS ``` ### `services` Blocks all rules for specific services within a cloud provider. ```yaml theme={null} blocking: services: AWS: - s3 - lambda Google: - compute - gke ``` ### `vulnerabilities` Blocks specific rules by their ID. ```yaml theme={null} blocking: vulnerabilities: - TF-0026 - SYM_PY_001 ``` *** ## `ignored` Defines what will be **silently ignored** in the IDE, CLI, and CI — no findings will be reported for these rules or files. ### `severity_threshold` Ignores all rules at this severity level **and below**. Accepted values (case-insensitive): `low`, `medium`, `high`, `critical` ```yaml theme={null} ignored: severity_threshold: low # ignores only LOW ``` | threshold | Severities ignored | | - | - | | `low` | LOW | | `medium` | MEDIUM, LOW | | `high` | HIGH, MEDIUM, LOW | | `critical` | CRITICAL, HIGH, MEDIUM, LOW | ### `paths` Ignores all findings in files matching these patterns. Uses Unix shell-style glob syntax (`*`, `?`, `[seq]`). Paths are relative to the location of `symbiotic.yml`. ```yaml theme={null} ignored: paths: - "terraform/azure/storage.tf" # exact file - "azure/sub_folder/*" # all files in a subdirectory - "*/provider.tf" # provider.tf anywhere in the tree ``` ### `languages` Ignores all rules for a given programming language. ```yaml theme={null} ignored: languages: - python - go - terraform ``` ### `providers` Ignores all rules associated with a cloud provider. ```yaml theme={null} ignored: providers: - AWS ``` ### `services` Ignores all rules for specific services within a cloud provider. ```yaml theme={null} ignored: services: AWS: - lambda - s3 ``` ### `vulnerabilities` Ignores specific rules by their ID. ```yaml theme={null} ignored: vulnerabilities: - TF-0022 - SYM_PY_001 ``` *** ## Templates ```yaml Minimal theme={null} # SYMBIOTIC SECURITY CONFIGURATION FILE ignored: vulnerabilities: # IDs of vulnerabilities you want to ignore in the repository - SYM_PY_001 - SYM_JSTS_003 ``` ```yaml Basic theme={null} # SYMBIOTIC SECURITY CONFIGURATION FILE blocking: vulnerabilities: # IDs of vulnerabilities that must block CI if detected - SYM_PY_001 - SYM_JSTS_003 ignored: vulnerabilities: # IDs of vulnerabilities you want to ignore in the repository - SYM_PY_099 - SYM_JSTS_010 ``` ```yaml Full theme={null} # SYMBIOTIC SECURITY CONFIGURATION FILE # ========================================= # -------------------------------------------- # SECTION: blocking # Defines what is considered blocking in CI. # -------------------------------------------- blocking: # Minimum severity level that will cause a detection to fail the CI pipeline. # Accepted values: low, medium, high, critical severity_threshold: high # List of cloud providers for which *all* related vulnerabilities # are treated as blocking, regardless of their individual severity. providers: - Azure # - AWS # - Google # Specific cloud services per provider where *all* vulnerabilities # are considered blocking. services: AWS: - s3 # Google: # - compute # - gke # Explicit list of vulnerability IDs that are always treated as blocking. # vulnerabilities: # - TF-0444 # - SYM_PY_001 # - SYM_JS_028 # ------------------------------------------------------------ # SECTION: ignored # Defines what will be ignored in the IDE and CLI. # Ignored rules take priority over blocking rules. # ------------------------------------------------------------ ignored: # Maximum severity level below which detections are ignored. # Accepted values: low, medium, high, critical severity_threshold: low # List of file paths or glob patterns to exclude from analysis. # Paths are relative to this config file. Wildcards are supported. paths: - "*/azure/*" # Languages to exclude from analysis. # languages: # - terraform # - go # Cloud providers to exclude entirely. # providers: # - Azure # - AWS # Specific cloud services to exclude from detection, per provider. # services: # AWS: # - documentdb # - elasticache # Vulnerability IDs to explicitly ignore. # vulnerabilities: # - TF-0010 # - SYM_GEN_027 # - SYM_PY_004 # ===================================================== # END OF CONFIGURATION # ===================================================== # Tips: # - Keep this file version-controlled and up to date. # - Use comments to document why each rule is ignored or blocked. ``` # False positive Source: https://docs.symbioticsec.ai/flow/devs/actions/false_positive How to declare a vulnerability as false positive ? False Positive Report Pn You can declare a false positive by adding a tag `-fp` in the ignore comment or by using the action available in the issue hover or the ignore button. In that case, you will be ask to select the scope of the false positive and give an explanation about it. Reporting false positives is really important as it allows us to review false positives with your admins and make the detection patterns evolve. Example of a false positive comment: ```javascript theme={null} // nosymbiotic SYM_JTS_0087 -fp ``` # Ignore Source: https://docs.symbioticsec.ai/flow/devs/actions/ignore Customize the detection by ignoring non-relevant vulnerabilities If a vulnerability is not relevant, you can ignore it directly from the IDE.\ Based on the scope of your ignore you have two possibilities : 1. If you want to ignore on this specific issues or issues in this file, click on the ignore button in the detailed view of a vulnerability and choose : * Ignore: The detection is correct but you want still to ignore this issue * [Declare a false positive](/flow/devs/actions/false_positive): The detection is incorrect and you want to flag a false positive 2. If you want to ignore this vulnerability on the whole repository, you can use the [Configuration File](/flow/devs/actions/configure_detection) ## Ignore a specific issue The ignore comment will be generated by clicking on the ignore button, but you can also write it yourself by following this syntax : ```python Using # theme={null} # nosymbiotic {rule_id} -- {ignore_comment} ``` ```javascript Or // theme={null} // nosymbiotic {rule_id} -- {ignore_comment} ``` Ignore Comment Pn To ignore multiple rules you can write all the rules you want to ignore separated by a comma : ```python theme={null} # nosymbiotic {rule_id},{rule_id} -- {ignore_comment} ``` # Ignore a vulnerability at the repository scope Using our [Configuration File](/flow/devs/actions/configure_detection) you can tailor the detection to your context and focus on what’s important to remediate. This file allow you to define `Policy Breaching` vulnerabilities (that will be highlighted in the IDE and blocking in CI) but also which vulnerabilities to ignore. Those configurations can be written based on the file path, severity, language, vulnerability id provider or service. # CLI Source: https://docs.symbioticsec.ai/flow/devs/discover_extension/CLI You can use our CLI to integrate our detection anywhere you want. ## Setup ### Downlod and Install To download and install the right version of our CLI, use the following command : ```bash theme={null} curl -sSL https://github.com/SymbioticSec/cli/releases/latest/download/install.sh | bash echo 'export PATH="$HOME/.local/bin:$PATH"' ``` If you encounter some problems and you need to reinstall the CLI you can use the command `symbiotic-cli install -f` ### Retrieve and set your token To use our CLI you will need a **personal access token**, that you can create and retrieve [here](https://app.symbioticsec.ai/settings/api-token). Once you have it, set the `SYMBIOTIC_API_TOKEN` environment variable with your token. ## Usage Discover available commands and options. ### Scan As of today, two types of scan are available in our CLI : 1. Infrastructure scan to review IaC files ```bash theme={null} symbiotic-cli infra scan [PATH_OF_THE_FOLDER_TO_SCAN] ``` 2. Code scan to review generic programming languages ```bash theme={null} symbiotic-cli code scan [PATH_OF_THE_FOLDER_TO_SCAN] ``` Both commands will return a JSON object with the following structure ```json theme={null} { "fail_results": [], "pass_results": [], "external_results": [], "files": { "files": [], "excluded_files": [], "excluded_folders": [] } } ``` Vulnerabilities found will be JSON objects in the fail\_results table with the following structure: ```json Structure expandable theme={null} { "rule_id": "", "rule_language": "", "type": "", "title": "", "severity": "", "description": "", "resource_path": "", "resource": "", "resource_name": "", "location": { "start_line": , "end_line": , "absolute_filename": "", "relative_filename": "", "start_col": , "end_col": }, "resolution_advice": "", "snippet": " ", "full_snippet": "", "static_remediation": "", "invocation_chain": [], "references": [], "impact": "", "confidence_level": "", "impact_level": "", "likelihood_level": "", "owasp": "", "cwe": "", "conf_status": "", "scan_status": "", "metadata": { "conf_file_status": "", "scan_status_origin": "", "ignore_comment": "", "false_positive": }, "fingerprint": { "version": "", "rule_id": "", "anchor_hash": "", "flow_hash": "", "ordinal": 0, "anchor_string": "", "flow_string": "", "full_fingerprint": "" }, "fingerprint_metadata": { "generation_time_ms": , "extraction_method": "", "warnings": [] } } ``` ```json Example expandable theme={null} { "rule_id": "SYM_JSTS_0102", "rule_language": "javascript", "type": "", "title": "Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')", "severity": "MEDIUM", "description": "The code uses user-provided input as a file path with Node.js 'fs' functions without proper validation. This allows attackers to manipulate file paths, potentially accessing or modifying unintended files on the server.", "resource_path": "", "resource": "", "resource_name": "", "location": { "start_line": 71, "end_line": 71, "absolute_filename": "/Users/symbiotic/mcp/src/tools/base-tool.ts", "relative_filename": "src/tools/base-tool.ts", "start_col": 20, "end_col": 27 }, "resolution_advice": "", "snippet": " await rm(tempDir, { recursive: true });", "full_snippet": " await rm(tempDir, { recursive: true });", "static_remediation": "", "invocation_chain": [], "references": [ "https://owasp.org/www-community/attacks/Path_Traversal" ], "impact": "If exploited, an attacker could read, overwrite, or delete sensitive files outside the intended directory, leading to data breaches, loss of critical information, or system compromise. This can expose confidential data and disrupt application functionality.", "confidence_level": "LOW", "impact_level": "MEDIUM", "likelihood_level": "HIGH", "owasp": "A05:2017 - Broken Access Control", "cwe": "CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')", "conf_status": "NO_CONF", "scan_status": "DEFAULT", "metadata": { "conf_file_status": "NO_CONF", "scan_status_origin": "NONE", "ignore_comment": "", "false_positive": false }, "fingerprint": { "version": "v1-typescript", "rule_id": "SYM_JSTS_0102", "anchor_hash": "rw9kQFu2FRo", "flow_hash": "Tg0j1b4uVfQmT2Atbg1E5A", "ordinal": 0, "anchor_string": "BaseScanTool.withTempDirectory", "flow_string": "awaitrm(tempDir,{recursive:true});", "full_fingerprint": "v1-typescript|SYM_JSTS_0102:rw9kQFu2FRo-Tg0j1b4uVfQmT2Atbg1E5A-0" }, "fingerprint_metadata": { "generation_time_ms": 3.365167183801532, "extraction_method": "tree_sitter", "warnings": [] } } ``` ### AI Services To use our AI services you will need to set the target LLM environement variable `SYMBIOTIC_TARGET_LLM_API=https://llm-proxy.symbioticsec.ai/` #### Remediate After detecting a vulnerability, you can use the our AI service to generate a tailored remediation using the following command. ```bash Command theme={null} symbiotic-cli airemediate remediate ``` ```bash Example theme={null} symbiotic-cli airemediate remediate "/Users/symbiotic/SymCodeGoat" \ "SYM_JAVA_0023" \ "/Users/symbiotic/SymCodeGoat/kotlin/Vulnerable.kt" \ 14 14 11 73 "kotlin" ``` ```json Answer format theme={null} { "found_vulnerability_rule_id": "", "original_file_path": "", "vuln_doc": "", "code_with_context": "", "project_scope_vuln_context": "", "remediated_code_with_context": "", "remediated_code": "", "status": "", "false_positive_status": "" } ``` #### Explain false positive reason If an issue is likely a false positive, remediation will not be generated and `false_positive_status` will be equal to `FALSE_POSITIVE`. In that case, you can use one of our AI services to know more about why this issues soudns like a false positive with the following command. ```bash Command theme={null} symbiotic-cli airemediate fp_reason ``` ```bash Example theme={null} symbiotic-cli airemediate fp_reason "/Users/symbiotic/SymCodeGoat" \ "SYM_JAVA_0023" \ "/Users/symbiotic/SymCodeGoat/kotlin/Vulnerable.kt" \ 14 14 11 73 "kotlin" ``` The answer will be a Markdown text explaining in details why this issue is likely a false positive. # MCP Source: https://docs.symbioticsec.ai/flow/devs/discover_extension/MCP Secure AI generated code using our MCP If you need an introduction on MCP, here is the [get Started article of the protocol](https://modelcontextprotocol.io/docs/getting-started/intro). MCP setup is independant from our extension (that you can download and install [here](/flow/devs/intro/intro)) ## Setup **Good news!** If you use Antigravity, Cursor, Kiro, VS Code, or Windsurf, and our extension is installed, everything is set up automatically. The MCP installs and configures itself, nothing for you to do. To use the Symbiotic Security MCP, you first need to download and install our CLI using the command below. The installer will automatically select the correct version for your environment. ```bash theme={null} curl -sSL https://github.com/SymbioticSec/cli/releases/latest/download/install.sh | bash echo 'export PATH="$HOME/.local/bin:$PATH"' ``` In your IDE, use `CTRL/CMD + P` and search for **MCP: Open User Configuration** to open the configuration file that should be called `settings.json`. Once the file opened, paste this configuration: ```json theme={null} { "mcpServers": { "symbiotic-security": { "command": "npx", "args": ["@symbioticsec/symbiotic-mcp-server"], "env": { "SYMBIOTIC_API_TOKEN": "your_token_here", "SYMBIOTIC_CLI_PATH": "cli_path_here" } } } } ``` Retrieve your personal access token [here](https://app.symbioticsec.ai/settings/api-token) and paste it in the `SYMBIOTIC_API_TOKEN` variable Retrieve the path of the CLI you installed in step 1 and paste it in the `SYMBIOTIC_CLI_PATH` variable You can retrieve it using the command `which symbiotic-cli ` in a terminal. Save the file and launch the MCP server by clicking on Start above the MCP name in the configuration file or by using the **MCP: List Servers** command and selecting **symbiotic-security**, and selecting **Start Server**. ### Examples #### Continue.dev 1. In continue.dev extension settings add a new MCP 2. Enter the following configuration: ```yaml theme={null} mcpServers: - name: Symbiotic Security command: node args: - "path_of_the_index.js_file" env: { "SYMBIOTIC_API_TOKEN": "your_token_here" } ``` #### Zed 1. `CMD + ,` to open Zed settings. 2. Add the following: ```json theme={null} { "mcpServers": { "symbiotic-security": { "command": "node", "args": ["path_of_the_index.js_file"], "env": { "SYMBIOTIC_API_TOKEN": "your_token_here" } } } } ``` #### Others Hundreds of other tools now support MCP servers, you can configure them to use the Symbiotic MCP server with the following settings: * **Command**: `npx` * **Arguments**: `"@symbioticsec/symbiotic-mcp-server"` * **Environment**: ```jsonc theme={null} "SYMBIOTIC_API_TOKEN": "your_api_token", "SYMBIOTIC_CLI_PATH": "cli_path" ``` ## Usage Once configured, you can use the MCP directly from your IDE’s chat interface by asking it to perform a security scan on a file. If you want your chat agent to automatically scan every piece of AI-generated code, we recommend adding the following MCP usage rule: ```markdown theme={null} ALWAYS use symbiotic-security MCP with the security_scan_files tool EACH time you generate code to scan for security vulnererabilities and remediate issues found. ALWAYS try to fix issues found by the scanner. ``` # Deep Remediation Source: https://docs.symbioticsec.ai/flow/devs/discover_extension/deep_remediation Remediate complex vulnerabilities using our agentic AI remediation service ## Launch a deep remediation When on the details view of a vulnerability, you can launch a deep remediation after the classical remediation has been generated by clicking on the icon. Deep remediation launch ## Track a deep remediation Once the deep remediation has been launched, you can track its progress in the details view of the vulnerability or in the dedicated view in the treeview. Deep remediation tracking If you click on the view details or in the treeview, you will be redirected to a new webview allowing you to stream the agentic process of remediation. Deep remediation streaming At the end of the deep remediation, you can accept or reject the generated remediation. Accepting the remediation will apply the changes to your codebase. # Details view Source: https://docs.symbioticsec.ai/flow/devs/discover_extension/details How to use the details view Extension Treeview When you click on an issue in the treeview or in the More details link in the hover, a details view will open with 3 tabs : This tab contains all the informations you need about the vulnerability, including its description, potential impacts, other vulnerable examples, links to documentation and an AI generated remediation suggestion. It also allow you to access trainings on the vulnerability, ignore it or report it as a false positive. This tab allows you to chat with our AI about this vulnerability. You can use presets to start a discussion or ask any question you have. If the same vulnerability appears on other resources in the opened workspace, you will find links to those vulnerable resources in this tab. # Detection Source: https://docs.symbioticsec.ai/flow/devs/discover_extension/detection How does the detection work ? Each time your code is saved (either manually or via the auto-save feature), a local detection scans for any vulnerabilities you may have created. When a vulnerability is found, it appears as a red underline beneath the vulnerable resource or property. Extension Overview As of October, 2025, we offer a full support of the following languages : ```markdown theme={null} apex, bash, c, clojure, csharp, dockerfile, go, html, java, javascript, json, kotlin, ocaml, php, python, ruby, rust, scala, solidity, swift, terraform, typescript, yaml ``` And a basic support for : ```markdown theme={null} cairo, circom, cpp, dart, elixir, hack, julia, lisp, lua, move, promql, protobuf, ql, r, scheme, vue, xml ``` # Hover Source: https://docs.symbioticsec.ai/flow/devs/discover_extension/hover How does the hover work ? Extension Hover When you hover a snippet of code underlined in red because we have detected an issue, you will have access to a quick view of the issue with : * The name of the issue * It's description * A tag to indicate whethe it's policy breaching or not * Links to some actions : * Open the details view * Generate a remediation # Status snippet Source: https://docs.symbioticsec.ai/flow/devs/discover_extension/status How does the status snippet work ? At the bottom of the editor, in the status bar, you can see our snippet that could indicate diverse statuses : * The extension is actually scanning * Issues have been found (the snippet is in red with the number of policy breaching issues detected) * No issues have been found * Errors or problems (the snippet is in yellow with the error message) # Treeview Source: https://docs.symbioticsec.ai/flow/devs/discover_extension/treeview How does the treeview work ? Our treeview allows you to see all vulnerabilities detected in the current workspace. By default issues are grouped by file and ordered by severity. Extension Treeview ## Icons Critical High Medium Low Ignored issues are shown using this icon ## Actions Using actions in the treeview you can filter issues, change the grouping or search for a specific vulnerability. ### Scopes To see only issues relevant on your context, you can change the scope of the treeview by either : * Clicking on the scope at the top of the treeview * Clicking on the icon at the top right of the treeview * Using the command `Symbiotic Security: Change Scope` It will open a selection menu to allow you to choose between : * All: Show all issues detected in the repository * Local: Show only issues detected in staged files * Branch: Show only issues detected in files modified in the current branch in the last 10 days * Recent: Show only issues detected in files modified in the last 10 days * Active: Show all non-historical issues If the scope you have selected is empty you will be invite to change the scope or to reset your filters ### Filters By clicking on the icon at the top right of the treeview you can filter the issues by severity, policy breaching or ignored. ### Grouping By clicking on the icon at the top right of the treeview you can change the grouping of the issues either by vulnerabilities or files. # Get started Source: https://docs.symbioticsec.ai/flow/devs/intro/get_started Let's make your code secure Symbiotic Security’s extension allows you to detect, remediate and learn directly when it matters the most : **while you’re writing code** ! We support all commons languages (Python, JS/TS, Java, C, C#, Go, Ruby, PHP, etc.) and the major cloud providers (AWS, GCP, Azure). ## Setting up Create your account, install our extension in your favorite IDE and make your code more secure in minutes. Follow our two steps quickstart guide. ## Learn the basics Understand how our extension works to make the most of it. When does it scan ? How to remediate ? Where to find more informations ? How to define what's should be ignored and what should block the CI ? How to ignore a non relevant issue in a file or in the whole repository ? How to declare a false positive and help us improve the detection ?
How we handle your data ? What's collected ? How we ensure a maximum security ? ## Get help If you have questions or need help, you can contact us using the dedicated Slack channel or email us at [support@symbioticsecurity.ai](mailto:support@symbioticsecurity.ai). If your problem concern the extension, we suggest you to generate a [Support Bundle](/flow/devs/support/support_bundle) before contacting us. # Quickstart Source: https://docs.symbioticsec.ai/flow/devs/intro/quickstart Start securing your code in minutes not hours ## Create your account To use Symbiotic Security, you must first create your account either by clicking on the invitation email you received or by using the link provided by an admin in your organization. ## Install extension If your are using another fork of VS Code like **Windsurf**, **VSCodium** or **Kiro** please refer to the VS Code installation guide. Our extension have an auto-update feature that will check if it need to be updated. But if you need to manually update the extension, follow the same steps as for the installation. # Available commands & Shortcuts Source: https://docs.symbioticsec.ai/flow/devs/support/commands All commands and shortcuts you can use in our extension ## Commands `> Login` Open the redirection link to log in using the application. `> Logout` `> Scan Current File` Scan the currently opened workspace `> Upload Support Bundle` Generate and upload the support bundle described [here](/flow/devs/support/support_bundle) `> Provide authentication token` Authenticate using your token without browser redirection. See[ Login issues with browser redirection ](/flow/devs/support/common_problems) `> Clear cache` Delete cached remediations, chats and feature flags. `> Change Scope` Allow you to change the scope of issues as defined [here](/flow/devs/discover_extension/treeview) `> Reinstall scanner` Reinstall scanner used to detect vulnerabilities. Can be useful if the detection is not working after the first installation. `> Reinstall extension` Reinstall the whole extension. Can be useful if the extension seems not working as expected. ## Shortcuts ### For AI Remediations diff suggestions `ctrl+z // cmd+z` Revert all suggestions `shift+ctrl+y // shift+cmd+y` Accept all suggestions # Common problems Source: https://docs.symbioticsec.ai/flow/devs/support/common_problems Common problems and solutions ### CLI is seen as a malware by Windows We've requested to be whitelisted by Microsoft, but depending on your system's update status, our CLI used by the IDE extension might be detected as malware. To force an update of Windows Defender's malware definitions, please follow these steps: 1. Open command prompt as administrator and change directory to c:\Program Files\Windows Defender 2. Run "MpCmdRun.exe -removedefinitions -dynamicsignatures" 3. Run "MpCmdRun.exe -SignatureUpdate" Alternatively, the latest definition is available for download [here](https://docs.microsoft.com/microsoft-365/security/defender-endpoint/manage-updates-baselines-microsoft-defender-antivirus) ### CLI is seen as a malware by your antivirus If you encounter issues installing our extension, it might be due to your antivirus flagging our CLI as malware. You can try to whitelist the following paths in your antivirus settings: * Windows: * `C:\Users\YourUsername\AppData\Local\symbioticsec` * `C:\Users\YourUsername\AppData\Roaming\YourIDEUser\globalStorage\symbiotic-security.symbiotic-security-vulnerability-scanner` * macOS: * `/Users/YourUsername/Library/Application Support/symbiotic` * `/Users/YourUsername/Library/Application Support/YourIDEUser/User/globalStorage/symbiotic-security.symbiotic-security-vulnerability-scanner` * Linux: * `/home/YourUsername/.config/YourIDEUser/User/globalStorage/symbiotic-security.symbiotic-security-vulnerability-scanner/` * `~/.local/share/symbiotic/` ### SSL Certificate issue / TLS Inspection If you encounter issues installing our extension with SSL certificate errors, it might be due to a TLS Inspection on your side. You can try to whitelist our domain `*.symbioticsec.ai` in your TLS Inspection settings. ### Login issues with browser redirection If you’re not able to log in using the browser redirection, you can do it by using your token : 1. Go [https://app.symbioticsec.ai/settings/api-token](https://app.symbioticsec.ai/settings/api-token) 2. Click on the token to open it on a side panel 3. Copy your token 4. In the IDE search the command `> Symbiotic Security : Provide authentication token` 5. Paste you token and press ENTER 🎉 You’re now authenticated. Wait a few seconds and a scan will be launched. # Share logs Source: https://docs.symbioticsec.ai/flow/devs/support/share_logs Share logs with Symbiotic Security If you’re experiencing some unexpected behavior with our IDE extension, you have the possibility to access logs and share it with us to help us investigate the issue. 1. In VS Code go to `View > Output` 2. Select `Symbiotic Security` 3. You have now access to the logs of the extension since you last opened VS Code 4. Click on the three dots and then on `Open in editor` to open the log file 5. You can now save this file and share it with us # Support bundle Source: https://docs.symbioticsec.ai/flow/devs/support/support_bundle How to generate and send a support bundle ## What’s a support bundle ? A support bundle is a diagnostic zip file generated when you encounter issues with the Symbiotic Security IDE extension. It helps us investigate and resolve your case more effectively. Once generated, the support bundle is securely stored on our servers and automatically deleted after the investigation is completed. The support bundle contains essential information for debugging, including: * **IDE Extension Logs**: Logs generated by the extension itself. * **Detection Scanner Logs**: Logs related to the scanner used for detecting vulnerabilities. * **Environment Logs**: System-level information such as machine type, operating system, and related environment details. * **Files From the Open Workspace**: Only the files involved in detection activities are included ## How to generate a support bundle ? There are two ways to generate a support bundle: 1. **Automatically After an Error**: If the extension encounters an error, you’ll see a notification in the extension tree view. This notification includes a button to generate a support bundle directly. 2. **Manually via Command**: Use the command palette in your IDE and run the following command: `> Symbiotic Security: Upload Support Bundle` ## How to configure support bundle flow ? You can customize the flow of the support bundle to suit your privacy preferences. In the extension settings, you can deactivate the inclusion of workspace files used during detection. This ensures that only log and environment details are included in the bundle.