# Billing Source: https://docs.devin.ai/admin/billing Devin has two pricing models: * **Self-serve**: Free, Pro, Max, and Teams plans you can sign up for directly at [app.devin.ai](https://app.devin.ai). Self-serve usage is billed through a mix of included quota and on-demand credits. See [Self-serve plans](/admin/billing/self-serve) for full details. * **Enterprise**: Devin Enterprise customers are billed in Agent Compute Units (ACUs) at the rate set in their order form. See [Enterprise](/admin/billing/enterprise) for how ACU consumption is tracked, or [contact sales](https://cognition.com/contact) for pricing. For how Devin meters work in general (how usage accrues, idle/sleep behavior, and tips for keeping consumption under control), see [Usage](/admin/billing/usage). The tips on that page apply to both pricing models. # Enterprise Source: https://docs.devin.ai/admin/billing/enterprise How Devin Enterprise contracts are billed and how admins track ACU consumption Devin Enterprise customers are billed in **Agent Compute Units (ACUs)** at the rate set in their order form. [Contact sales](https://cognition.com/contact) for pricing. For how Devin meters work in general (sleep behavior, what counts toward consumption, tips for keeping costs down), see [Usage](/admin/billing/usage). ## Tracking ACU consumption Enterprise customers can track ACU consumption at both the Enterprise and Organization level: * **Enterprise admins** view Enterprise ACU consumption at [Settings > Consumption](https://app.devin.ai/settings/consumption) in Enterprise Settings. * **Organization admins** view Organization ACU consumption at [Settings > Consumption Analytics](https://app.devin.ai/settings/analytics?tab=consumption) within Organization Settings. * **Any user** can see the ACU cost of a specific session from [Session Insights](/product-guides/session-insights). ## Setting Organization ACU limits Enterprise admins can set per-Organization ACU limits from [Settings > Organizations](https://app.devin.ai/settings/organizations) in Enterprise Settings. Devin Enterprise Org List
Devin Enterprise Org Management Once set, an Organization can only consume up to its limit. All Devin activity stops once the limit is reached, and users see a message indicating the Organization has hit its ACU limit and to contact the Enterprise admin to raise it. Devin Org ACU Limit Reached ## Frequently asked questions Enterprise customers are billed for ACUs as stated in their order form. Enterprise ACUs represent the work performed by Devin for customers on the Enterprise plan, which adheres more strictly to task planning and end-to-end testing. They are distinct from self-serve quota and on-demand credits, and are priced per the customer's Enterprise order form. Enterprise admins can break consumption down by Organization from the [Consumption](https://app.devin.ai/settings/consumption) page in Enterprise Settings. Org admins can break it down by user from [Consumption Analytics](https://app.devin.ai/settings/analytics?tab=consumption) inside Organization Settings. # Self-serve plans Source: https://docs.devin.ai/admin/billing/self-serve Compare Devin's self-serve plans and understand usage quota and on-demand credits Devin has four self-serve plans you can sign up for directly at [app.devin.ai](https://app.devin.ai). For authoritative pricing, see the [Devin pricing page](https://devin.ai/pricing). This page explains how the plans relate to each other and how billing mechanics work. ## Plan overview | Plan | For | Price | Members | | --------- | --------------------------------- | ------------------ | --------- | | **Free** | Individuals trying Devin | Free | 1 | | **Pro** | Individual users | \$20/month | 1 | | **Max** | Power users who need more quota | \$200/month | 1 | | **Teams** | Teams working with Devin together | \$80/month minimum | Unlimited | The **Pro** and **Max** plans are individual plans. They cannot be shared across multiple users. If you want multiple people to use Devin under a single subscription, you need the **Teams** plan. ## Free The Free plan lets you try Devin with limited usage. It includes: * Limited Devin usage * Access to [Devin Review](/work-with-devin/devin-review) * Access to [DeepWiki](/work-with-devin/deepwiki) Free users can upgrade to any paid plan at any time from [Settings > Plans](https://app.devin.ai/settings/plans). ## Pro Pro is Devin's entry-level individual plan. It's designed for a single developer who uses Devin regularly. Pro includes: * A daily and weekly usage quota that covers Devin sessions, [Devin CLI](/cli), and [Devin Desktop](https://windsurf.com) * Pay-as-you-go [on-demand credits](#on-demand-credits) for usage past your quota * Slack, Linear, and [MCP](/work-with-devin/mcp) integrations Pro is a single-user plan. Pro subscribers cannot invite additional members to their organization. To work with teammates on a shared subscription, use the [Teams](#teams) plan. ## Max Max is for individual users who consistently exceed the Pro quota. It includes everything in Pro, plus a significantly larger weekly usage quota (with no daily cap), also shared between Devin sessions, [Devin CLI](/cli), and Devin Desktop. Like Pro, Max is a single-user plan and does not support multiple members. ## Teams The Teams plan is Devin's self-serve plan for teams of any size. Key properties: * **Unlimited members**: invite as many teammates as you want. * **\$80/month minimum**: every Teams account pays at least \$80/month. * Each member gets either a **full seat** or a **flex seat**. * **On-demand credits** are shared across the whole team. ### Full seats vs. flex seats Every member of a Teams account holds one of two seat types: **\$40/month per seat**, billed as a fixed recurring line item. Best for members who use Devin regularly. Each full seat includes: * A daily and weekly usage quota equivalent to the Pro plan * Access to Devin Desktop **Free**. Teams can have unlimited flex seats. Best for occasional users. Flex seats: * Draw entirely from the team's shared pool of on-demand credits * Do **not** include Devin Desktop access * Have no fixed monthly charge per seat Admins choose the seat type when [inviting a member](/product-guides/invite-team), and can convert a member between seat types later from **Settings > Members**. ### The \$80 Teams minimum Every Teams subscription costs **at least \$80/month**. You can hit this minimum in any combination of full seats (\$40 each) and on-demand credits: | Full seats | On-demand credits included | Monthly total | | ---------: | -------------------------: | ------------: | | 0 | \$80 | \$80 | | 1 | \$40 | \$80 | | 2 | \$0 | \$80 | | 3 | \$0 | \$120 | | *N* ≥ 2 | \$0 | *N* × \$40 | When you have fewer than two full seats, the remainder of the \$80 minimum is automatically charged as prepaid on-demand credits that the whole team can draw from. Once you have two or more full seats, you've cleared the minimum and no additional on-demand credits are included, but you can still [top up on-demand credits](#on-demand-credits) at any time. Give a full seat to anyone who uses Devin regularly. Full seats include their own Pro-equivalent quota and Devin Desktop access at a predictable fixed cost, making them the best fit for power users. Reserve flex seats for occasional or trial users who only need ad-hoc access through shared on-demand credits. ## How quotas work Each paid plan and full seat includes a usage allowance that refreshes automatically on a calendar basis: * **Pro** and **Teams full seats** have a **daily and weekly** allowance. The daily allowance is more than 1/7 of the weekly, so you can keep working through weekends without giving up overall capacity for the week. * **Max** has a **weekly** allowance only, with no daily cap. When you've used up your allowance, [on-demand credits](#on-demand-credits) keep you working without interruption. ## On-demand credits On-demand credits are prepaid usage credit that fund any work past your plan's included quota: * **Roll over** month-to-month. Purchased credits never expire. * Can be topped up at any time from [Settings > Plans](https://app.devin.ai/settings/plans), and optionally refilled automatically via auto-reload. * Admins can set auto-reload thresholds and default session spending limits from **Settings > Usage**. * On the **Teams** plan, credits are **shared across all members**, with no per-member balance. Any teammate can draw from the shared pool. * On the **Teams** plan, credits fund all usage on **flex seats** and any **full seat** usage past its included quota, and cover any portion of the [\$80/month minimum](#the-80-teams-minimum) not already covered by full seats.
## Devin Review and Automations Pricing
[Automations](/product-guides/automations) and [Devin Review](/work-with-devin/devin-review) are available on self-serve plans. * **Teams use shared on-demand credits.** On the Teams plan, Automations and Devin Review draw directly from the team's shared [on-demand credit](#on-demand-credits) pool and do not consume full-seat quota. * **What happens when you run out of credits.** If you run out of credits, Automations stop running and Devin Review switches to its smart diff viewer. Top up [on-demand credits](#on-demand-credits) to start Automations again and re-enable AI-powered review. * **Public PRs are free.** Anyone can review a public GitHub PR at [devinreview.com](https://devinreview.com) — or by replacing `github.com` with `devinreview.com` in any PR URL — without a Devin account, and no on-demand credits are consumed. Admins can keep usage predictable by tuning how often auto-review runs. Configure the trigger mode (every commit, only when a PR is first opened, or manual only) per repository or per user from [Settings > Review](https://app.devin.ai/settings/review). See [Trigger Modes](/work-with-devin/devin-review#trigger-modes) in the Devin Review docs for details. ## Migrating from legacy ACU-based plans If you were previously on a legacy ACU-based plan, here's what you need to know: * On-demand credits are the same dollar value as the ACUs you're used to. * **Legacy Core plan users** have been migrated to the Free plan and can continue using any remaining on-demand credits. To purchase additional credits, upgrade to the [Teams](#teams) plan. ## Managing your plan Admins can view and change the account's plan from [Settings > Plans](https://app.devin.ai/settings/plans). From there you can: * Upgrade or downgrade between Free, Pro, Max, and Teams * Add or cancel Teams full seats * Purchase on-demand credits or configure auto-reload to replenish them automatically * Download past invoices For tips on keeping consumption under control across all plans, see [Usage](/admin/billing/usage). # Usage Source: https://docs.devin.ai/admin/billing/usage How Devin meters work, what counts toward consumption, and how to keep usage under control This page explains how Devin's work is metered. The mechanics are the same regardless of pricing model. The only difference is the unit: * **Enterprise** customers consume **Agent Compute Units (ACUs)** against the volume in their order form. * **Self-serve** customers consume their plan's included quota first, then draw from prepaid **on-demand credits**. Throughout this page, "usage" refers to whichever unit applies to your account. ## What counts toward usage Usage accrues based on the work Devin actually performs in a session, including: * Number and complexity of actions Devin takes (planning, context gathering, task execution, browser actions, code execution, and so on) * Virtual machine time and networking bandwidth (typically a small fraction of total usage) ### Windows sessions Windows sessions consume approximately **9% more** usage than equivalent Linux (Ubuntu) sessions. Aside from the few units required to keep the Devin VM running, Devin will not consume usage when: * Waiting for your response * Waiting for a test suite to run * Setting up and cloning repositories ## Sleep and idle behavior When a session is idle, Devin goes to sleep. While sleeping, Devin does not consume usage. You can wake the session up at any time by sending another message. Devin typically sleeps automatically after roughly 0.1 ACUs (or the equivalent quota / on-demand credit) of inactivity. ## Managing usage effectively A number of variables affect how much Devin consumes: * Task complexity * Prompt quality (or specificity) * Size of context or codebase * Number of files being touched or modified * Session runtime * Length of conversation * Frequency of back-and-forth messaging A few tips to keep usage under control: * Delegate clearly scoped tasks with a well-defined end goal * Keep prompts and sessions short * Avoid asking Devin to do a lot of different tasks in the same session * Split big projects into sub-tasks across sessions; there are no concurrent session limits, so take advantage of it These tips also tend to improve the quality of Devin's work, so it's a win-win. ## Frequently asked questions No, Devin does not consume any usage while sleeping. Devin typically sleeps automatically after roughly 0.1 ACUs (or the equivalent quota / on-demand credit) of inactivity, so awake-but-idle time generally adds up to very little. Any user can see per-session usage from [Session Insights](/product-guides/session-insights), regardless of pricing model. * **Self-serve**: Current month's usage, quota remaining, and on-demand credit balance live at [Settings > Plans](https://app.devin.ai/settings/plans). * **Enterprise**: Enterprise and per-Organization ACU consumption are available from the [Consumption](https://app.devin.ai/settings/consumption) and [Consumption Analytics](https://app.devin.ai/settings/analytics?tab=consumption) pages in Enterprise and Organization Settings respectively. Yes. If your enterprise enables [Personal Analytics](/enterprise/security-access/personal-analytics), users with the **View Personal Analytics** permission can see their own ACU consumption across every organization from the **My analytics** page in their settings. # Common Issues Source: https://docs.devin.ai/admin/common-issues ## I'm unable to connect my GitHub.com organization If you're unable to set up your integration or seeing "Configure" next to the organization you want to connect, you or one of your teammates has likely already connected your GitHub organization to another Devin account. **You will need to disconnect the existing integration before you can connect to your Devin account.** GitHub error You can disconnect the existing integration by following these steps: 1. Navigate to the Devin Enterprise or Organization with the active integration 2. Navigate to the Integrations page * If you are on an Enterprise account, navigate to [https://app.devin.ai/settings/connected-accounts](https://app.devin.ai/settings/connected-accounts) in Enterprise Settings * If you are on a Teams account, navigate to [https://app.devin.ai/settings/integrations](https://app.devin.ai/settings/integrations) in Organization Settings 3. Click through on the GitHub integration card 4. Click "Disconnect" under the GitHub integration Alternatively, you can disconnect the integration via GitHub: 1. Go to the [GitHub Integration settings](https://github.com/settings/installations) 2. Navigate to Devin.ai Integration and click "Configure" 3. Scroll to the "Danger zone" section to uninstall the integration Devin ## I'm unable to connect my Slack organization If you're seeing an "Unable to proceed with request" error, it means that you or one of your teammates has already connected your Slack organization to another Devin organization. **You will need to disconnect the existing integration before you can connect your new organization.** Slack error You can disconnect the existing integration by following these steps: 1. Navigate to the Devin Enterprise or Organization with the active integration 2. Navigate to the Integrations page * If you are on an Enterprise account, navigate to [https://app.devin.ai/settings/connected-accounts](https://app.devin.ai/settings/connected-accounts) in Enterprise Settings * If you are on a Teams account, navigate to [https://app.devin.ai/settings/integrations](https://app.devin.ai/settings/integrations) in Organization Settings 3. Click through on the Slack integration card 4. Click "Disconnect" under the Slack integration If you're unable to disconnect or find the existing organization, please reach out to [support@cognition.ai](mailto:support@cognition.ai) ## IP Allowlisting If you need to allowlist Devin's services, please add the following IP addresses: * 100.20.50.251 * 44.238.19.62 * 52.10.84.81 * 52.183.72.253 * 20.172.46.235 * 52.159.232.99 * 4.204.199.103 * 54.201.200.193 * 54.69.238.189 * 100.23.34.160 (Please note: While we intend to keep this list static, it is possible these IPs may change in future updates.) ## Session Expiration Devin sessions can't be continued after 30 days. If you need to resume work after that window, start a new session and re-share any relevant context (for example: goals, requirements, key decisions, and any important files or links) so Devin can continue effectively. # Security at Cognition Source: https://docs.devin.ai/admin/security We want Devin to be a core contributor in your organization, and have prioritized security, data privacy and compliance to make it possible ## Security All data transmission is encrypted in transit and at rest. Production software is also routinely monitored via logging, error handling and monitoring dashboards of live metrics. Unusual application states (i.e. unusually high error rates, slowness, failures) trigger alerts which are quickly investigated by our team. Access to our cloud environment in AWS is granted on an as-required basis based on business roles and only a small number of employees or contractors are granted direct access to production systems. All employees and contractors are required to use multi-factor authentication on all main work applications. All employees and contractors also receive annual training about security best practices, including good password management and how to identify social engineering and phishing scams. Cognition obtained SOC 2 Type II certification and conducted Security Training in March 2024 for all employees at Cognition. As part of the SOC 2 audit, Cognition's auditors reviewed all of Cognition's security policies, procedures, internal and third party controls related to data security, privacy, processing integrity, confidentiality and availability. For more details about our security please visit our [Trust Center](https://trust.cognition.ai/). If you have identified a potential security issue, we encourage you to share your findings with us. Please send your vulnerability reports to our security team at [security@cognition.ai](mailto:security@cognition.ai). ## Privacy & Intellectual Property Cognition processes data based on the application Customers use to interact with Devin. Devin can be accessed via web application, integration with GitHub, or integration with Slack. For the web application, Cognition only processes data actively provided by the authorized user prompting Devin; for the GitHub and Slack integrations, the administrator installing the integration can review and manage all permissions granted to Devin. Cognition uses Customer data to: * Deliver, maintain and update services provided to the Customer per their configuration and type of Devin access (e.g. web application, integration with GitHub, or integration with Slack) to make sure the software is up-to-date and operational. * Troubleshoot, prevent and resolve issues such as product-related issues, software bugs or security incidents to maintain service functionality and reliability. Cognition only retains data processed through Devin for the duration of the relationship with a given Customer, unless otherwise specified by the Customers. Any Feedback Data and User Interaction Data are retained as long as needed and as determined by Cognition. By default, we may use your data for model training purposes to improve and enhance the Services. If you're on a paid plan, you can opt out at any time on the Data Controls settings page. After you opt out, your data will not be used for training and Zero Data Retention will be enabled with our model providers. On the Teams plan, only an administrator can exercise the opt-out. Devin can still learn to fit into your unique workflow via the [Knowledge](/product-guides/knowledge) feature. When you share Knowledge, Devin can become more reliable at working on your specific projects over time. If you are an Enterprise customer, we will never train on your data without your express prior written consent. Please refer to the terms in your agreement with Cognition for details. The output — code, work product, or other — produced by Devin is considered the user’s intellectual property and can be used for the Customer’s commercial purposes, with the exception of using the output to train models that would attempt to reverse engineer and/or build a competing product to Devin. When setting up the GitHub integration, users can select which repositories Devin can access, with permissions adjustable through GitHub's App Settings during and post-installation. For more details on the requested permissions and security considerations go to [GitHub Integration Guide](/integrations/gh). In Slack, Devin doesn’t read, process or store any data in your Slack instance other than the information provided when @Devin is tagged, initially prompted and when any additional information is provided within the Slack thread while the session is ongoing. For more details on the requested permissions and security considerations go to [Integration with Slack Guide](/integrations/slack). ## User Best Practices While Devin’s performance is improving daily, it can still experience hallucinations, introduce bugs into code, or suggest insecure code or procedures. Like with any coding best practices, we recommend taking the appropriate precautions with the code written by Devin such as code reviews, enabling branch protections to ensure checks are enforced before Devin can merge any changes, and any practices currently adopted in your organization to review engineers’ work. You may need to provide Devin with credentials and keys such as passwords, API keys, cookies or other for authentication. In all cases we advise users to leverage our Secrets feature under the Settings page to share and store those credentials securely. We’re still learning and developing Devin to be a great AI software engineer, and our customers’ feedback is crucial for Devin’s development. We strongly encourage sharing feedback and feature requests directly with your Cognition account team or by emailing [support@cognition.ai](mailto:support@cognition.ai), and reporting incidents by emailing [security@cognition.ai](mailto:security@cognition.ai). # JetBrains Source: https://docs.devin.ai/cli/acp/jetbrains Run Devin inside JetBrains IDEs from AI Chat using the Agent Client Protocol (ACP), including JetBrains Remote Development. JetBrains IDEs can run Devin as an agent inside **AI Chat** using the [Agent Client Protocol (ACP)](https://agentclientprotocol.com/). The quickest way to add Devin is to install it from the **ACP Registry**; you can also configure it manually as a custom agent. Either way, you can drive Devin from the AI Chat panel in IntelliJ IDEA, PyCharm, GoLand, and other JetBrains IDEs — including over [JetBrains Remote Development](https://www.jetbrains.com/remote-development/). This integration uses JetBrains' built-in ACP support in AI Assistant. For the upstream reference, see the JetBrains docs on [adding a custom agent](https://www.jetbrains.com/help/ai-assistant/acp.html#add-custom-agent). ## Prerequisites * A JetBrains IDE with the **AI Assistant** plugin and AI Chat available. ## Setup Install Devin directly from the **ACP Registry** — no CLI installation or manual configuration required. Click the **AI Chat** icon in the right-hand tool window bar. AI Chat icon in the JetBrains tool window bar Click the agent selector in the AI Chat footer to see the list of available agents. Choose **Install From ACP Registry...**, search for **Devin**, and click **Install**. Devin is added to the list of available agents. Agent selector menu showing the Install From ACP Registry option The first time you connect, you may be prompted to authenticate. Follow the prompt to log in to your Devin account. Logging in to Devin from JetBrains AI Chat Select **Devin** in the agent selector and send a message to start a session. Devin selected as the agent in the AI Chat footer ## Manual setup (custom ACP) If you'd rather run Devin from your own installation of the Devin CLI, you can add it as a custom ACP agent instead of installing from the registry. ### Prerequisites * Devin CLI installed and authenticated. If you haven't installed it yet, follow the [Quickstart](/cli/index), then run `devin auth login`. * The absolute path to the `devin` binary. You can find it with: ```bash theme={null} which devin ``` This typically resolves to something like `~/.local/bin/devin`. For **JetBrains Remote Development**, Devin CLI must be installed on the **remote host** (where the backend runs), not on your local client. Run `which devin` in a terminal on the remote host and use that path in the configuration below. Click the **AI Chat** icon in the right-hand tool window bar. AI Chat icon in the JetBrains tool window bar Click the three-dots menu in the top-right of the AI Chat panel, then choose **Add Custom Agent**. This opens the `acp.json` configuration file. Add Custom Agent option in the AI Chat menu Add Devin to the `agent_servers` block in `acp.json`. Set `command` to the absolute path of your `devin` binary (from `which devin`) and pass `acp` as the only argument: ```json acp.json theme={null} { "default_mcp_settings": {}, "agent_servers": { "devin": { "command": "/home/you/.local/bin/devin", "args": ["acp"] } } } ``` Save the file. Devin now appears as a selectable agent in AI Chat. Select **devin** as the agent in AI Chat and send a message to start a session. The first time you connect, you may be prompted to authenticate; Devin uses the credentials from `devin auth login` (or `WINDSURF_API_KEY` if set). ## Managing the integration The three-dots menu in the AI Chat panel includes a few helpful actions for the Devin agent: * **Reset ACP Authentication** — clear stored ACP credentials and re-authenticate. * **Get ACP Logs** — open the ACP logs, useful for debugging connection issues or inspecting what the agent is doing under the hood. ## Notes and limitations * Devin's slash commands are advertised over ACP, so they appear in JetBrains AI Chat's own command palette — see [Slash commands in ACP hosts](/cli/reference/commands#slash-commands-in-acp-hosts). * Devin CLI's terminal/shell output is surfaced through JetBrains AI Chat's ACP rendering, which differs from the native Devin CLI terminal UI. Some richer interactions are only available in the standalone CLI. * The `devin acp` subcommand is intended to be launched by an ACP-aware client (like JetBrains AI Chat) as a subprocess — it speaks JSON-RPC over stdio and is not meant to be run interactively. See [`devin acp`](/cli/reference/commands#devin-acp) in the command reference. # Xcode Source: https://docs.devin.ai/cli/acp/xcode Run Devin inside Xcode's coding assistant via the Agent Client Protocol (ACP), or give the Devin CLI access to your Xcode project through Xcode's MCP bridge. Xcode 26.6's [coding intelligence](https://developer.apple.com/documentation/xcode/setting-up-coding-intelligence) can run Devin as an agent inside the **coding assistant** using the [Agent Client Protocol (ACP)](https://agentclientprotocol.com/). Devin isn't one of the agents listed in Xcode's Intelligence settings, so you add it manually as a custom ACP agent that runs from your local Devin CLI installation. This integration uses Xcode's built-in ACP support in the coding assistant. For the upstream reference, see Apple's docs on [setting up coding intelligence](https://developer.apple.com/documentation/xcode/setting-up-coding-intelligence). ## Prerequisites * **Xcode 26.6 or later** with the coding assistant available. * Devin CLI installed and authenticated. If you haven't installed it yet, follow the [Quickstart](/cli/index), then run `devin auth login`. * The **absolute** path to the `devin` binary. You can find it with: ```bash theme={null} which devin ``` This typically resolves to something like `/Users/you/.local/bin/devin`. Xcode requires an **absolute** path for the agent command — it does not expand `~` or use your shell's `PATH`. If `which devin` prints a `~`-prefixed path, expand it first (for example, run `echo "$(cd ~ && pwd)/.local/bin/devin"`) and use the full `/Users/...` result. ## Setup Add Devin as a custom agent from the Intelligence settings. Choose **Xcode > Settings**, then select **Intelligence** in the sidebar. Under **Agents**, click **Add an Agent**. Xcode's built-in ACP support lets you register any agent that speaks the Agent Client Protocol. In the sheet that appears, enter the agent's details: * **Name** — `Devin` (or any label you prefer). * **Command** — the **absolute** path to your `devin` binary (from `which devin`), for example `/Users/you/.local/bin/devin`. A relative path or a `~`-prefixed path won't work. * **Arguments** — `acp`. Add `--model ` (for example `acp --model opus`) to pick the model Devin uses; see [`devin acp`](/cli/reference/commands#devin-acp). Click **Add**. Devin now appears as a selectable agent under **Agents**. Select **Devin** in the coding assistant and send a message to start a session. The first time you connect, you may be prompted to authenticate; Devin uses the credentials from `devin auth login` (or `WINDSURF_API_KEY` if set). ## Give Devin CLI access to your Xcode project (MCP) Separately from running Devin *inside* Xcode, you can point the standalone Devin CLI at your Xcode project so it can build, run tests, read and edit files, render SwiftUI previews, and search Apple's documentation. Xcode ships an [MCP](/cli/extensibility/mcp/overview) server, `xcrun mcpbridge`, that exposes these Xcode tools to any external agent (the same mechanism [Cursor uses](https://cursor.com/docs/integrations/xcode)). Add it to Devin like any other MCP server. The Xcode MCP bridge requires **Xcode 26.3 or later**. Confirm the binary is available with `xcrun --find mcpbridge` (see [Troubleshooting](#troubleshooting) if it isn't). See Apple's docs on [giving external agents access to Xcode](https://developer.apple.com/documentation/xcode/giving-external-agents-access-to-xcode). Choose **Xcode > Settings**, select **Intelligence**, and under **Model Context Protocol** turn on **Allow external agents to use Xcode tools**. Register `xcrun mcpbridge` as a stdio MCP server: ```bash theme={null} devin mcp add xcode -- xcrun mcpbridge ``` Verify it was added with `devin mcp list`. See [`devin mcp`](/cli/reference/commands#devin-mcp) for scope and configuration options. Open your project or workspace in Xcode (the bridge needs a running Xcode session with a project open), then prompt Devin from the CLI. Xcode alerts you when the external agent connects and while it's active. ## Troubleshooting * **`xcrun: error: unable to find utility "mcpbridge"`** — your system is pointed at the Command Line Tools instead of the full Xcode install. Fix it with: ```bash theme={null} sudo xcode-select -s /Applications/Xcode.app/Contents/Developer sudo xcodebuild -runFirstLaunch ``` Then confirm with `xcrun --find mcpbridge`, which should print a path. * **Devin can't reach the Xcode tools** — make sure Xcode is running with a project (not an empty window) open, and that **Allow external agents to use Xcode tools** is enabled in Intelligence settings. ## Notes and limitations * The model can't be switched from Xcode's UI. To use something other than your team's default model, pass `--model ` in the agent's **Arguments** field (see [`devin acp`](/cli/reference/commands#devin-acp)), which sets the model for every session Xcode starts. * When you select an agent in Xcode's coding assistant, it automatically gets access to Xcode capabilities such as building and testing your app. You can review and restrict which commands and tools agents may use under **Agents > Permissions** in Intelligence settings — see Apple's docs on [extending and customizing agents](https://developer.apple.com/documentation/xcode/extending-and-customizing-agents). * Xcode's coding assistant does not surface Devin's slash commands. * Devin CLI's terminal/shell output is surfaced through Xcode's ACP rendering, which differs from the native Devin CLI terminal UI. Some richer interactions are only available in the standalone CLI. * The `devin acp` subcommand is intended to be launched by an ACP-aware client (like Xcode's coding assistant) as a subprocess — it speaks JSON-RPC over stdio and is not meant to be run interactively. See [`devin acp`](/cli/reference/commands#devin-acp) in the command reference. # Zed Source: https://docs.devin.ai/cli/acp/zed Run Devin CLI inside the Zed editor as a custom ACP agent in the Agent Panel. [Zed](https://zed.dev/) has native support for the [Agent Client Protocol (ACP)](https://agentclientprotocol.com/), so you can run Devin CLI as a custom external agent directly inside Zed's **Agent Panel** — with real-time editing, syntax highlighting, and agent following. This integration uses Zed's built-in support for external ACP agents. For the upstream reference, see the Zed docs on [external agents](https://zed.dev/docs/ai/external-agents). ## Setup Open the ACP registry with `zed: acp registry` from the command palette (Cmd+Shift+P on macOS and Ctrl+Shift+P on Windows). Search for "Devin" and install it. On the top left corner of the Threads Sidebar, click on the agent dropdown menu and select "Devin". In the new Devin thread, open the agent menu in the top right corner and select "Authenticate" (or "Reauthenticate"). Then on the bottom of the thread panel, click on "API Key". A browser window will open, where you can log into your Devin Cloud account and authenticate. If you don't have an account you can sign up for free! You can now start a conversation with Devin! By default, Devin will use Adaptive model selection, automatically choosing the best model for your task. You can also pick a specific model from the menu at the bottom of the thread panel. Devin in Zed ## Notes and limitations * Devin's slash commands are advertised over ACP, so they appear in Zed's own command palette — see [Slash commands in ACP hosts](/cli/reference/commands#slash-commands-in-acp-hosts). * Devin CLI's terminal/shell output is surfaced through Zed's ACP rendering, which differs from the native Devin CLI terminal UI. Some richer interactions are only available in the standalone CLI. * The `devin acp` subcommand is intended to be launched by an ACP-aware client (like Zed) as a subprocess — it speaks JSON-RPC over stdio and is not meant to be run interactively. See [`devin acp`](/cli/reference/commands#devin-acp) in the command reference. # Adaptive Source: https://docs.devin.ai/cli/adaptive Adaptive is Cognition's intelligent model router that automatically selects the best AI model for each task. ## Selecting Adaptive To select Adaptive, run `/model adaptive` during a session, pass `--model adaptive` when launching, or set it as your default in `~/.config/devin/config.json` (on Windows, `%APPDATA%\devin\config.json`): ```json theme={null} { "agent": { "model": "adaptive" } } ``` You can switch away from Adaptive to a specific model at any time with `/model`. Adaptive is an intelligent model router that automatically selects the best AI model for each task. Instead of manually choosing between dozens of models, Adaptive analyzes your prompt and routes it to the model that will deliver the best result. ## How it works When you select **Adaptive**, Devin evaluates each request and dynamically chooses the right underlying model. Simple tasks get routed to fast, efficient models. Complex tasks get routed to more capable ones. This means you get the right level of intelligence for every prompt without overspending on premium models for routine work. Adaptive helps your usage allowance last longer by avoiding unnecessary use of expensive models. Adaptive is the best default for most users. ## Enterprise availability For enterprise organizations, Adaptive is disabled by default. An admin must enable the **Adaptive model router** setting from the enterprise settings page before team members can select Adaptive in the model picker. * **Devin Desktop**: Go to **Settings > Devin Desktop > Models** and toggle **Adaptive model router** on. * **Windsurf**: Go to **Team Settings > Models** and toggle **Adaptive model router** on. ## Pricing Adaptive pricing depends on your billing plan. Adaptive draws down your quota at a **fixed per-token rate**, regardless of which underlying model is selected for a given request. Currently, the Adaptive model consumes quota and overage at an introductory promotional rate (through July 7, 2026). | Token type | Cost per 1M tokens | | :---------------- | :----------------- | | Input tokens | \$0.50 | | Output tokens | \$2.00 | | Cache read tokens | \$0.10 | These rates also apply to extra usage beyond your included quota. Because Adaptive routes simpler tasks to lighter models, it typically consumes fewer tokens overall than manually selecting a frontier model for every request. This makes it the most cost-effective option for most users. For customers on the Cognition platform, Adaptive usage is metered in **ACUs** (Agent Compute Units). ACU consumption scales with the tokens used and the model selected by the router for each request. For enterprise customers on credit-based billing, Adaptive uses **variable-token credit pricing**. Each request consumes credits based on the actual tokens used and the model that Adaptive selects for that request according to your credit rate. This means cheaper models cost fewer credits per request, and Adaptive's routing naturally favors cost-efficient choices — so your credit pool lasts longer compared to always selecting a premium model. ## Tips for getting the most out of Adaptive * **Be specific with your prompts.** Clear, focused instructions help Adaptive route to the right model and reduce unnecessary token usage. * **Leverage prompt caching.** Staying on the same model across turns in a conversation enables caching, which significantly reduces input token costs. Adaptive takes this into account when routing. * **Use Adaptive as your default.** For most workflows, Adaptive is the best starting point. Switch to a specific model only when you have a particular reason to — for example, if you need a specific model's reasoning capabilities for a complex task. # Devin Auth Source: https://docs.devin.ai/cli/enterprise/devin-auth Authenticate to Devin CLI using your existing Devin account ## Overview You can authenticate to Devin CLI using your existing Devin account. This provides a seamless experience for organizations already using Devin, with billing handled through the standard **Devin billing model**. User management, team organization, SSO, RBAC, billing, and consumption are all inherited natively through the Devin dashboard. For most of your organizational needs, you should rely on the [Devin dashboard](https://app.devin.ai). Devin authentication for Devin CLI is available to **Devin Enterprise** customers. Contact your account executive if you have questions about authentication, billing, or access. ## Getting Started ### Prerequisites Before using Devin authentication, ensure that: 1. Your organization has a Devin enterprise account 2. Your administrator has configured Devin CLI access permissions (see [Configuring Access](#configuring-access) below) 3. You have been assigned a role with the **Use Devin CLI** permission ### Authenticating To authenticate with your Devin enterprise account: ```bash theme={null} devin auth login ``` Follow the prompts and be sure to select the **Log in with Devin for Enterprise** button to authenticate through your organization's identity provider. ### Credentials file location After `devin auth login`, Devin CLI stores your API token in `credentials.toml`. By default, this token is persistent and does not expire. You can copy the credentials file between your own machines to reuse the same authentication, but treat it as sensitive: anyone with this file can authenticate as you. Do not share it or commit it to source control. | Platform | Location | | ------------- | ---------------------------------------------------------------------------------------------------------------------- | | macOS / Linux | `$XDG_DATA_HOME/devin/credentials.toml` when `XDG_DATA_HOME` is set; otherwise `~/.local/share/devin/credentials.toml` | | Windows | `%APPDATA%\devin\credentials.toml` (typically `C:\Users\\AppData\Roaming\devin\credentials.toml`) | Run `devin auth logout` to remove stored credentials. On MDM-managed devices, administrators can pin login to a specific enterprise host or account — skipping the login prompts entirely and rejecting out-of-policy accounts — with the [system configuration file](/cli/enterprise/system-config). ## Configuring Access Devin CLI access is controlled through Devin's [custom roles and RBAC system](/enterprise/security-access/custom-roles). Administrators must create a custom role with the **Use Devin CLI** role permission and assign it to users who need access. ### Creating an Access Role 1. Navigate to **Enterprise Settings > Roles** 2. Click **Create a custom role** 3. Provide a descriptive name (e.g., "Devin CLI User") 4. Select the **Use Devin CLI** permission 5. Save the role ### Assigning the Role * **Enterprise admins** or users with the **Manage Account Membership** permission can assign account-level roles via the "Enterprise members" page * **Organization admins** or users with the **Manage Organization Membership** permission can assign organization-level roles via the "Organization members" page You can automatically assign roles based on SSO IdP groups. See the [custom roles documentation](/enterprise/security-access/custom-roles) for details. ## Billing Usage through Devin CLI is billed using the standard **Devin ACU (Agent Compute Unit) model**. All Devin CLI usage counts toward your organization's existing Devin enterprise allocation. Enterprise admins can view their users' Devin CLI usage by accessing the **Cost** dashboard under the **Enterprise Analytics** tab in the Devin web app. This dashboard contains helpful visualizations of ACU consumption across all of the Cognition products, including Devin CLI. For details about ACU billing and usage tracking, refer to your enterprise agreement or contact your account executive. ## Further Reading For more information about Devin enterprise features, see the [Devin Enterprise documentation](/enterprise/getting-started/get-started): * [Enterprise Setup](/enterprise/getting-started/get-started) — Initial configuration and onboarding * [SSO Configuration](/enterprise/security-access/sso/guide) — Single sign-on setup * [Custom Roles & RBAC](/enterprise/security-access/custom-roles) — Fine-grained access control * [Enterprise Security](/enterprise/security-access/security/enterprise-security) — Security policies and controls # Team Settings Source: https://docs.devin.ai/cli/enterprise/team-settings Configure team-wide settings to control your users' Devin CLI usage ## Overview Team-wide settings allow enterprise admins to control Devin CLI usage across their organization. * **Devin Enterprise admins** can manage these settings in the customer-facing Devin dashboard under **Settings → Enterprise → Windsurf** (`app.devin.ai/org/{orgName}/settings/windsurf`). This is self-service for admins with access to enterprise settings. * **Windsurf Enterprise admins** can manage these settings in the Windsurf dashboard at [https://windsurf.com/team/cli-settings](https://windsurf.com/team/cli-settings). Only the Devin CLI-specific settings on these pages apply to Devin CLI. General [Windsurf Team Settings](https://windsurf.com/team/settings) apply to Windsurf and do not necessarily apply to Devin CLI unless also listed on the Devin CLI settings page. ## Available Settings ### Models Control which models your users can access through Devin CLI. You can: * **Allowlist specific models** — Restrict users to a curated list of approved models * **Allow all models** — Give users access to all available models Click **Configure** to manage model access for each category. #### Default model You can also pin a **team-wide default model** that Devin CLI will use for new sessions. This is the same setting Windsurf uses for its default model, so configuring it once applies to both surfaces. * If no team default is set, Devin CLI uses its built-in default model. * If the pinned default is not present in the **allowed models** list above, Devin CLI falls back to the built-in default — the allowlist always takes precedence. * Individual users can still switch models during a session; this setting only controls the starting model for new sessions. Enterprise admins can configure the default model from the [Windsurf Team Settings](https://windsurf.com/team/settings) page, the [Devin CLI Settings](https://windsurf.com/team/cli-settings) page, or the customer-facing Devin Enterprise settings page at `app.devin.ai/org/{orgName}/settings/windsurf`. ### Enable Web Search Allow the Devin CLI agent to perform web searches on the open Internet. This does not affect the agent's ability to read specific URLs, which is performed locally on the user's machine. This tool is **disabled by default** for enterprise teams. ### MCP Servers Control whether your users can use MCP (Model Context Protocol) tools. * **Toggle on/off** — Enable or disable MCP server usage entirely * **Allowlisted MCP Servers** — Specify which MCP servers users are allowed to connect to. If no servers are added, all servers are allowlisted by default. Click **Add Server** to restrict access to specific servers. The recommended way to manage approved servers is through an [MCP registry](#mcp-registry) rather than the explicit allowlist. ### MCP Registry You can use the [official MCP registry](https://modelcontextprotocol.io/registry/about), a downstream registry built on it, or your own registry. Configure registries in team settings: * **MCP registry URLs** — Add one or more registry URLs. With multiple registries, a server is allowed if it appears in any of them (the union of all registries). * **MCP registry enforcement** (toggle) — Choose whether to strictly enforce your registries. When on, users can only connect to servers from your registries; when off, they can also connect to other servers, including custom ones. ### Terminal Permissions Configure team-enforced permission rules for Devin CLI usage. These rules have the **highest precedence** and cannot be overridden by individual users' local or project configurations. Click **Configure** to open the permissions editor. The configuration requires a JSON object with three fields: ```json theme={null} { "deny": [ "exec" ], "ask": [], "allow": [ "Read(~/my-repository/**)" ] } ``` * **`deny`** — Actions that are blocked entirely (takes highest priority) * **`ask`** — Actions that always prompt the user for approval * **`allow`** — Actions that are automatically approved without prompting Permissions can be **scope-based** or **tool-based**: | Type | Format | Example | | ----------------- | -------------- | ------------------------------- | | File read | `Read(/path)` | `Read(~/sensitive/**)` | | File write | `Write(/path)` | `Write(.env*)` | | Command execution | `Exec(cmd)` | `Exec(rm)`, `Exec(sudo)` | | HTTP fetch | `Fetch(url)` | `Fetch(https://internal.api/*)` | | Tool-based | Tool name | `read`, `edit`, `exec` | Use team-enforced deny rules to prevent actions across your entire organization, such as blocking access to sensitive directories or dangerous commands like `rm -rf` or `sudo`. For detailed information on permission syntax, glob patterns, and configuration examples, see the [Permissions documentation](/cli/reference/permissions). ### Sandbox Enforcement Control sandbox behavior for your organization: **Enforcement mode** (whether `--sandbox` is **Optional** or **Required** for all CLI sessions), **Domain allowlist** and **Domain denylist** (organization-wide network filtering), and **Excluded allow** / **Excluded ask** / **Excluded deny** (rules for commands that may — or must never — run outside the sandbox). See the [Sandbox documentation](/cli/sandbox) for how the sandbox works, how these settings interact with user-level configuration, and examples. Enforcement mode is re-read at the start of every prompt, not just at startup. If you switch it to **Required** while a user is in a session that was started without the sandbox, that session refuses further prompts and tells the user to restart — the sandbox is then enabled automatically at startup. Sessions already running with the sandbox are unaffected. ### Attribution Filtering When attribution filtering is enabled for your team, code generated by Devin CLI is checked against a corpus of publicly available code: file edits that match public code are automatically reverted, and matching code blocks in chat responses are flagged while the agent is instructed to rewrite them. The setting applies to all Devin CLI users on the team. This setting is available on **Enterprise plans** and has no self-serve toggle; to enable it, reach out to [support@cognition.ai](mailto:support@cognition.ai) or your Cognition account team. Attribution filtering is also available for Devin cloud sessions — see [Attribution Filtering](/enterprise/features/attribution-filtering). ### Show "Install Devin CLI" in the Devin Desktop Command Palette Devin CLI is bundled with Devin Desktop but requires explicit activation by an admin. Toggle this setting **on** to allow your users to install Devin CLI directly from the Devin Desktop Command Palette. Once enabled, users can open the Command Palette (Cmd+Shift+P on macOS or Ctrl+Shift+P on Windows/Linux) and run **Install Devin CLI** to add the `devin` binary to their PATH. This setting is available on **Legacy Windsurf Enterprise** and **Devin Enterprise** plans and is **off by default**. ## Further Reading To understand how to configure Devin CLI further, see the [Configuration documentation](/cli/reference/configuration/config-file). Settings on this page are applied server-side once a user signs in. To enforce device-level policy that applies before or during login — pinning the enterprise host or account, or forcing an outbound proxy — see the [system configuration file](/cli/enterprise/system-config). # Legacy Windsurf Auth Source: https://docs.devin.ai/cli/enterprise/windsurf-auth Authenticate to Devin CLI using your existing legacy Windsurf enterprise account ## Overview Enterprise users can authenticate to Devin CLI using their existing legacy Windsurf enterprise accounts. This provides a seamless experience for organizations already using Windsurf, with billing handled through the standard **Windsurf legacy credit model**. User management, team organization, SSO, RBAC, billing, and consumption are all inherited natively through the Windsurf dashboard. For most of your organizational needs, you should rely on the [Windsurf dashboard](https://windsurf.com). Legacy Windsurf authentication for Devin CLI is available to **legacy Windsurf Enterprise** customers. Contact your account executive if you have questions about authentication, billing, or access. ## Getting Started ### Prerequisites Before using legacy Windsurf authentication, ensure that: 1. Your organization has a legacy Windsurf enterprise account 2. You have an active legacy Windsurf user account that can use the agentic tools No additional permissions are required to access Devin CLI. If your legacy Windsurf enterprise users can use Windsurf, they can use Devin CLI. ### Installation via Devin Desktop Devin CLI is bundled with Devin Desktop. An admin must first enable the option in [Devin CLI Team Settings](https://windsurf.com/team/cli-settings) — see [Team Settings](/cli/enterprise/team-settings#show-install-devin-cli-in-the-devin-desktop-command-palette) for details. Once enabled, open the Command Palette (Cmd+Shift+P / Ctrl+Shift+P) and run **Install Devin CLI**. Alternatively, you can install using the standalone installer — see the [Quickstart](/cli/) for instructions. ### Authenticating To authenticate with your legacy Windsurf enterprise account: ```bash theme={null} devin auth login ``` Follow the prompts and be sure to select the **Log in with Windsurf for Enterprise** option to authenticate through your organization's identity provider. ### Credentials file location After `devin auth login`, Devin CLI stores your API token in `credentials.toml`. By default, this token is persistent and does not expire. You can copy the credentials file between your own machines to reuse the same authentication, but treat it as sensitive: anyone with this file can authenticate as you. Do not share it or commit it to source control. | Platform | Location | | ------------- | ---------------------------------------------------------------------------------------------------------------------- | | macOS / Linux | `$XDG_DATA_HOME/devin/credentials.toml` when `XDG_DATA_HOME` is set; otherwise `~/.local/share/devin/credentials.toml` | | Windows | `%APPDATA%\devin\credentials.toml` (typically `C:\Users\\AppData\Roaming\devin\credentials.toml`) | Run `devin auth logout` to remove stored credentials. ## Billing & Analytics Usage through Devin CLI is billed using the standard **Windsurf legacy credit model**. All Devin CLI usage counts toward your organization's existing legacy Windsurf enterprise allocation. The analytics and billing systems are shared between Windsurf and Devin CLI. Use the [Team Members dashboard](https://windsurf.com/team/members) to manage team organization or view consumption metrics across both products. On prompt-based plans, each subagent consumes additional credits, just like a user message does. The number of credits depends on the model the subagent uses, so tasks that spawn multiple subagents (or [nest](/cli/subagents#nesting-depth) them) consume more credits. Enterprise admins can also access usage analytics programmatically through the [Analytics API](/desktop/accounts/api-reference/api-introduction) to monitor consumption across their organization. For details about credit billing and usage tracking, refer to your enterprise agreement or contact your account executive. ## Further Reading For more information about legacy Windsurf enterprise features, see the [Devin Desktop documentation](/desktop/getting-started): * [Guide for Admins](/desktop/guide-for-admins) — Administration and team management * [SSO & SCIM](/desktop/accounts/sso-scim) — Single sign-on and user provisioning * [API Reference](/desktop/accounts/api-reference/api-introduction) — Access analytics and usage data # Essential Commands Source: https://docs.devin.ai/cli/essential-commands If you remember nothing else... ## Starting Devin CLI By default, sessions happen in a REPL, a graphical terminal interface where you can chat back and forth and observe Devin's actions. ```bash theme={null} devin # Start interactive REPL (no prompt) devin -- your prompt here # Start REPL with initial prompt devin -p "prompt" # Single-turn, no REPL: print response to stdout and exit devin -p -- prompt words here # Same, using -- separator (still works) ``` Use `--` before your prompt so it is interpreted as a prompt and not a subcommand. Single-turn mode (`-p`) is great for scripts and automations. Type `@` in the prompt input to open autocomplete for local files/directories. Selecting one adds it as context for your message. You can paste images from your clipboard with **Ctrl+V**. Attached images appear in the input area and can be managed with **Left/Right** to navigate and **Backspace** to remove. ## Running shell commands Devin may run shell commands while working. If a command is still running after the default wait period, Devin moves it to the background and shows how long it waited along with the background shell ID. Devin can then continue working and check the command's output later. *** ## Modes Devin CLI has 5 built-in permission modes: **Normal**, **Accept Edits**, **Smart**, **Bypass**, and **Autonomous**, and 3 agent-modes: **Normal**, **Plan**, and **Ask**. For plan and ask, use `/plan` and `/ask`. Auto-approves read-only tools within the current directory, and asks for permission for write/execute operations. ```bash theme={null} /normal # or /mode normal ``` This is the default mode. Auto-approves file edits within the workspace while still prompting for shell commands and other actions. We expect people to spend most of their time here. ```bash theme={null} /accept-edits # or /mode accept-edits ``` Auto-approves file edits within the workspace like Accept Edits, and for every other action — shell commands, web fetches, MCP tools — a fast model decides whether it is safe to run without asking. Anything it does not judge clearly safe still prompts, and high-risk categories (package installs, mutating `git`, `rm`, `sudo`, destructive cloud CLI operations, sensitive files) always prompt. ```bash theme={null} /smart # or /mode smart ``` You can also start in smart mode: ```bash theme={null} devin --permission-mode smart ``` Smart mode is rolling out gradually, so it may not be available on your account yet. See [Smart Mode](/cli/reference/permissions#smart-mode) for the full behavior. Auto-approves **all** tool calls, including writes and shell commands. ```bash theme={null} /bypass # or /mode bypass ``` You can also start in bypass mode: ```bash theme={null} devin --permission-mode bypass ``` Aliases: `/yolo`, `/dangerous` Bypass mode **never** overrides organization-level permissions configured by your admin via [Team Settings](/cli/enterprise/team-settings). Admin-enforced deny and ask rules **always** take priority. Roughly equivalent to Accept Edits in the current workspace, with the additional ability to run any shell command within an [OS-level sandbox](/cli/reference/configuration/config-file#sandbox) (to contain what those commands can actually touch). ```bash theme={null} devin --sandbox --permission-mode autonomous ``` Autonomous is the **only** permission mode available when running with `--sandbox`, and it is selected automatically — Normal, Accept Edits, Smart, and Bypass are hidden in sandbox sessions. In Autonomous mode... * You are prompted for **capabilities rather than commands**. * Commands respect `Write` scopes and `Read(...)` deny rules via a filesystem sandbox. * Commands prompt you when they try to connect to network resources. * Read-only operations within the current directory auto-approve. Autonomous relies on the sandbox for safety. Without `--sandbox`, the mode is unavailable — use Bypass if you want unattended execution without OS-level isolation. See [Bypass vs Autonomous](#bypass-vs-autonomous) below for a direct comparison. ### Bypass vs Autonomous Bypass and Autonomous both reduce approval prompts, but they rely on different safety mechanisms: | | Bypass | Autonomous | | ------------------------------------------------------------- | --------------------------- | ----------------------------------------------------------------------------------------------------- | | Requires `--sandbox` | No | Yes (only available in sandbox sessions) | | Shell commands | Auto-approved, unrestricted | Auto-approved, contained by the sandbox | | File writes via `edit`/`write` tools | Auto-approved anywhere | Still prompt (granting a scope expands the sandbox) | | Network access | Unrestricted | Filtered by the sandbox's [domain allow/deny lists](/cli/reference/configuration/config-file#sandbox) | | Respects admin [Team Settings](/cli/enterprise/team-settings) | Yes | Yes | Pick Bypass when you trust the agent with your whole machine. Pick `--sandbox` (which selects Autonomous) when you want unattended execution with OS-enforced limits on what files and domains the agent can touch. If you like the feel of bypass but want the agent to have its own computer, try cloud Devin! ## Session History Your conversation history is saved so you can resume a session later. ```bash theme={null} devin -c # Continue the most recent session in the current directory devin --continue devin -r # Pick from recent sessions devin --resume devin -r brisk-otter # Resume a specific session by ID ``` *** ## Slash Commands You can use these commands while in an active session. ### Navigation & Control | Command | Description | | ------------------ | ---------------------------------------- | | `/help` | See all available commands | | `/exit` or `/quit` | Exit the application | | `/clear` or `/new` | Clear conversation history (start fresh) | You can also type `exit` or `quit` as plain text (without the `/` prefix) to exit. ### Mode Switching | Command | Description | | ----------------- | --------------------------------------------------------------------------------------------------- | | `/mode` | Show current mode | | `/mode ` | Switch mode (`normal`, `accept-edits`, `smart`, `plan`, `bypass`; `autonomous` in sandbox sessions) | | `/normal` | Switch to Normal mode (default) | | `/accept-edits` | Switch to Accept Edits mode | | `/smart` | Switch to Smart mode | | `/plan` | Switch to Plan mode | | `/ask ` | Ask a question without making code changes (oneshot) | | `/bypass` | Switch to Bypass mode (aliases: `/yolo`, `/dangerous`) | ### Model Switching | Command | Description | | -------- | ------------------- | | `/model` | Show model selector | ### Session Management | Command | Description | | ------------------ | ------------------------------------------------------------------- | | `/resume` | Open the interactive session picker | | `/resume ` | Resume session by ID | | `/ls` | List recent sessions in current directory (alias: `/list-sessions`) | | `/ls --all` | List all sessions across all directories | | `/continue` | Resume most recent session | | `/continue ` | Resume session by ID | | `/rm-session ` | Irreversibly delete a session by ID | ### Workspace | Command | Description | | ---------------------- | ------------------------------------------------- | | `/workspace` | List workspace directories (alias: `/workspaces`) | | `/add-dir ` | Add additional workspace directory | | `/undo-add-dir ` | Remove a workspace directory | ### Automation | Command | Description | | ---------------- | ------------------------------------------------------------------------------------ | | `/loop ` | Run a prompt then auto-review the diff in a loop (requires clean git state to start) | ### Extensibility | Command | Description | | -------- | ------------------------------------------------------------------- | | `/hooks` | List all loaded hooks with their IDs, event types, and source paths | ### Account & System | Command | Description | | ---------- | ---------------------------------------- | | `/login` | Authenticate with Devin | | `/logout` | Clear stored credentials and exit | | `/update` | Check for and install updates | | `/upgrade` | Upgrade your subscription plan | | `/bug` | Report a bug to the Devin CLI developers | | `/compact` | Force conversation compaction | If you installed Devin for Terminal via Homebrew, `/update` will direct you to use `brew upgrade devin` instead of performing a self-update. *** ## Keyboard Shortcuts Here are the most important keyboard shortcuts. See [Keyboard Shortcuts](/cli/reference/keyboard-shortcuts) for more shortcuts. | Shortcut | Description | | -------------------------- | --------------------------------------------------------------------- | | `Shift+Tab` | Cycle between modes (Normal, Accept Edits, Smart, Bypass, Autonomous) | | `Ctrl+C` | Clear input text, or cancel the running agent | | `Esc` | Cancel the running agent | | `Shift+Enter` | Insert a newline (multi-line input) | | `Ctrl+V` or `Shift+Insert` | Paste from clipboard | | `Ctrl+G` | Open external editor | | `Ctrl+O` | Open full-screen thinking trace viewer | | `@` | Mention files to add as context | # Configuration Source: https://docs.devin.ai/cli/extensibility/configuration How to configure Devin CLI behavior with config files Devin CLI is configured through JSON files (with comment support) at the user and project level. These config files control the agent's model, permissions, MCP servers, and more. *** ## Config File Locations **Path:** `~/.config/devin/config.json` Your personal defaults that apply across all projects. This is where you set your preferred model, theme, and global permissions. You can also place an `AGENTS.md` file in this directory (`~/.config/devin/AGENTS.md`) to define [global rules](/cli/extensibility/rules#global-rules) that apply to every project. On Windows, this path is `%APPDATA%\devin\config.json` (typically `C:\Users\\AppData\Roaming\devin\config.json`). ```json theme={null} { "agent": { "model": "claude-sonnet-4.5" }, "permissions": { "allow": ["Read(**)", "Exec(git)"] } } ``` **Path:** `.devin/config.json` (at your project root) Shared team configuration committed to version control. Use this for permission policies and import settings. Project-specific MCP servers go in `.devin/mcp_config.json` alongside it. ```json theme={null} // .devin/config.json { "permissions": { "allow": ["Exec(npm run)", "Read(src/**)"], "deny": ["Exec(sudo)"] } } ``` ```json theme={null} // .devin/mcp_config.json { "mcpServers": { "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"] } } } ``` **Path:** `.devin/config.local.json` Personal overrides for this project that aren't committed to git (automatically gitignored). Use this for secrets, API keys, and personal preference overrides. Personal MCP servers go in `.devin/mcp_config.local.json`. ```json theme={null} // .devin/mcp_config.local.json { "mcpServers": { "github": { "env": { "GITHUB_TOKEN": "ghp_your_token" } } } } ``` *** ## What You Can Configure Choose which AI model powers the agent — from Claude Opus to GPT 5.2 to Gemini 3. Pre-approve safe actions, block dangerous ones, and control what the agent can do without asking. Connect external tool servers for GitHub, Linear, databases, and any custom APIs. Import rules, skills, and configuration from Cursor, Windsurf, and Claude Code. *** ## Quick Start The fastest way to get started is to create a `.devin/config.json` in your project root: ```json theme={null} { "permissions": { "allow": [ "Read(**)", "Exec(git)", "Exec(npm run)" ] } } ``` This pre-approves file reads and common commands so the agent doesn't prompt you for every action. You can also configure Devin CLI interactively: when the agent asks for permission, choose to save the decision to your project or user config for next time. *** ## Project vs User Settings Not all settings are available at every level. Project configs (`.devin/config.json` and `.devin/config.local.json`) support: * **`permissions`** — allow, deny, and ask rules * **`mcpServers`** — MCP server definitions (in the dedicated `.devin/mcp_config.json` / `.devin/mcp_config.local.json` files since v3000.3, the Local 3.6 release; in `config.json` in older versions) * **`read_config_from`** — import settings from Cursor, Windsurf, and Claude * **`hooks`** — lifecycle hooks ([see Hooks](/cli/extensibility/hooks/overview)) All other settings — including `agent` (model), `theme_mode`, `unicode_mode`, `show_path`, `sandbox`, and other display/behavior options — are **user-config only** and can only be set in the user config (`~/.config/devin/config.json`; `%APPDATA%\devin\config.json` on Windows). *** ## Configuration Precedence For settings that support multiple levels, higher-priority sources win: | Priority | Source | Shared? | | ----------- | ------------------------------------------------------------------------------ | ---------------- | | 1 (highest) | Organization / Team settings | Yes (enterprise) | | 2 | Session grants (interactive approvals) | No (in-memory) | | 3 | Project local (`.devin/config.local.json`) | No (gitignored) | | 4 | Project (`.devin/config.json`) | Yes (committed) | | 5 (lowest) | User (`~/.config/devin/config.json`; `%APPDATA%\devin\config.json` on Windows) | No (personal) | Permissions are merged across levels, while MCP servers are merged by name (higher-priority source wins for same-named servers). Organization-level (enterprise) settings can **never** be overridden by project or user config. See [Configuration Precedence](/cli/reference/configuration/global-vs-local) for full details on how merging works. *** ## Limitations When run standalone, Devin CLI only respects `.gitignore` by default — it does not enforce `.devinignore`, `.codeiumignore`, or `.windsurfignore` files. When Devin CLI runs inside Devin Desktop, all four ignore files are enforced. *** ## Learn More Complete list of every configuration option and its format. How global, project, and local settings interact and merge. # Lifecycle Hooks Source: https://docs.devin.ai/cli/extensibility/hooks/lifecycle-hooks Understanding hook events and the data available at each stage Each hook event fires at a specific point in the agent's lifecycle. Use the **matcher** field (a regex matched against the hook event's `tool_name`) to filter which tool invocations trigger your hook. In addition to the event-specific fields below, every stdin payload includes a stable per-session `session_id` and a per-turn `prompt_id` (rotated on every user prompt; absent for events that fire before the first user prompt, e.g. `SessionStart`) — see [Command Hooks](/cli/extensibility/hooks/overview#command-hooks). *** ## PreToolUse Fires **before** a tool executes. Use this to block, modify, or add context to tool calls. **Stdin data:** | Field | Description | Example | | ------------ | ----------------------------- | ----------------------------------------------- | | `tool_name` | Name of the tool being called | `exec`, `edit`, `mcp__github__create_issue` | | `tool_input` | Arguments passed to the tool | `{ "command": "rm -rf /", "shell_id": "main" }` | **Example — Block destructive commands:** ```json theme={null} { "PreToolUse": [ { "matcher": "exec", "hooks": [ { "type": "command", "command": "python3 -c \"import sys, json; data = json.load(sys.stdin); cmd = data.get('tool_input', {}).get('command', ''); sys.exit(2 if 'rm -rf' in cmd else 0)\"" } ] } ] } ``` **Example — Require confirmation for writes outside src/:** Use a script that inspects the tool input and returns a decision: ```json theme={null} { "PreToolUse": [ { "matcher": "edit", "hooks": [ { "type": "command", "command": "./scripts/check-edit-path.sh", "timeout": 5 } ] } ] } ``` **Example — Rewrite commands before execution:** A hook can transparently rewrite the tool's input by printing `hookSpecificOutput.updatedInput` to stdout (see [Output format](/cli/extensibility/hooks/overview#output-format)). For example, a hook script that routes shell commands through a wrapper: ```json theme={null} { "hookSpecificOutput": { "hookEventName": "PreToolUse", "updatedInput": { "command": "rtk git status" } } } ``` The rewritten arguments are merged into the tool call before it runs — the agent executes the updated command instead of the original. *** ## PostToolUse Fires **after** a tool finishes executing. Use this for logging, validation, or triggering follow-up actions. **Stdin data:** | Field | Description | | --------------- | -------------------------------------------------------------------------------- | | `tool_name` | Name of the tool that ran | | `tool_input` | Arguments that were passed | | `tool_response` | Object with `success` (boolean), `output` (string), and `error` (string or null) | **Example — Log all shell commands:** ```json theme={null} { "PostToolUse": [ { "matcher": "exec", "hooks": [ { "type": "command", "command": "sh -c 'cat >> ~/.devin-command-log'" } ] } ] } ``` *** ## PermissionRequest Fires when the agent needs a permission decision. Use this to implement custom approval logic. **Stdin data:** | Field | Description | | ------------ | --------------------------- | | `tool_name` | Tool requesting permission | | `tool_input` | Arguments for the tool call | **Example — Auto-approve git commands:** ```json theme={null} { "PermissionRequest": [ { "matcher": "exec", "hooks": [ { "type": "command", "command": "python3 -c \"import sys, json; data = json.load(sys.stdin); cmd = data.get('tool_input', {}).get('command', ''); print(json.dumps({'decision': 'approve'})) if cmd.startswith('git ') else sys.exit(0)\"" } ] } ] } ``` *** ## UserPromptSubmit Fires when the user submits a message. Use this to add context or trigger workflows. **Stdin data:** | Field | Description | | -------- | ----------------------- | | `prompt` | The user's message text | **Example — Inject context on every prompt:** ```json theme={null} { "UserPromptSubmit": [ { "matcher": "", "hooks": [ { "type": "command", "command": "echo '{\"hookSpecificOutput\": {\"hookEventName\": \"UserPromptSubmit\", \"additionalContext\": \"Deploys require an approved change ticket.\"}}'" } ] } ] } ``` The command prints `additionalContext` inside a `hookSpecificOutput` object on stdout, tagged with the event name. That text is injected into the agent's context: ```json theme={null} { "hookSpecificOutput": { "hookEventName": "UserPromptSubmit", "additionalContext": "Deploys require an approved change ticket." } } ``` *** ## Stop Fires when the agent decides to stop (finish its turn). Use this to add follow-up instructions or prevent premature stopping. **Stdin data:** | Field | Description | | ------------------ | ------------------------------------- | | `stop_hook_active` | Whether a stop hook is already active | **Example — Remind agent to run tests:** ```json theme={null} { "Stop": [ { "matcher": "", "hooks": [ { "type": "command", "command": "echo '{\"decision\": \"block\", \"reason\": \"Please run the test suite before stopping.\"}'" } ] } ] } ``` Be careful with stop hooks that block — they can cause the agent to loop if the condition isn't eventually satisfied. *** ## PostCompaction Fires **after** context compaction completes successfully. Use this for logging, triggering follow-up actions, or re-injecting context that may have been lost during compaction. **Stdin data:** | Field | Description | | --------- | -------------------------------------------------------------------------------- | | `summary` | Summary text produced by the compactor (may be null if no summary was generated) | **Example — Log compaction events:** ```json theme={null} { "PostCompaction": [ { "matcher": "", "hooks": [ { "type": "command", "command": "sh -c 'cat >> ~/.devin-compaction-log'" } ] } ] } ``` *** ## SessionStart Fires when a new session begins. Use this for initialization, logging, or environment setup. **Stdin data:** | Field | Description | | -------- | --------------------------- | | `source` | How the session was started | **Example — Run setup script:** ```json theme={null} { "SessionStart": [ { "matcher": "", "hooks": [ { "type": "command", "command": "./scripts/dev-setup.sh", "timeout": 10 } ] } ] } ``` A SessionStart command can also inject context by printing `additionalContext` inside a `hookSpecificOutput` object on stdout: ```json theme={null} { "hookSpecificOutput": { "hookEventName": "SessionStart", "additionalContext": "Session started. Project uses ESM imports only." } } ``` *** ## SessionEnd Fires when a session ends. Use this for cleanup or final logging. **Stdin data:** | Field | Description | | -------- | --------------------- | | `reason` | Why the session ended | *** ## Matching Multiple Events A single hooks file can define hooks for multiple events: ```json theme={null} { "PreToolUse": [ { "matcher": "", "hooks": [ { "type": "command", "command": "./scripts/audit.sh" } ] } ], "PostToolUse": [ { "matcher": "", "hooks": [ { "type": "command", "command": "./scripts/audit.sh" } ] } ] } ``` ## Using the Matcher The `matcher` field is a **regex** matched against the hook event's `tool_name`. It is available for tool-related events: `PreToolUse`, `PostToolUse`, and `PermissionRequest`. For non-tool events (`UserPromptSubmit`, `Stop`, `PostCompaction`, `SessionStart`, and `SessionEnd`), there is no `tool_name`; use `""` or omit the matcher to run the hook for every event of that type. The matcher is not a permission glob. Patterns like `mcp__github__*` are useful in permissions, but hook matchers are regexes. Use `mcp__github__.*` in a hook matcher. | Matcher | Matches | | ------------------------------- | ---------------------------------------------------- | | `""` (empty) or omitted | All tool names for tool events | | `"exec"` | Tool names containing `exec` | | `"^exec$"` | Only the `exec` tool | | `"^(exec\|edit)$"` | Only `exec` or `edit` | | `"^mcp__.*"` | All MCP tools | | `"^mcp__github__.*"` | All tools from the `github` MCP server | | `"^mcp__github__create_issue$"` | The `create_issue` tool from the `github` MCP server | ### Tool names you can match Hook matchers run against the same externally-visible tool names that hook scripts receive in stdin as `tool_name`. The exact tool names available can vary by CLI mode, model, and enabled integrations. The core tool names, by category: | Category | Tool names | | ------------------ | -------------------------------------------------------------------------- | | File operations | `read`, `write`, `edit`, `apply_patch`, `notebook_read`, `notebook_edit` | | Search | `grep`, `glob` | | Shell | `exec`, `get_output`, `write_to_process`, `kill_shell` | | Web | `webfetch` | | Planning and tasks | `todo_write`, `exit_plan_mode` | | Skills | `skill` | | Subagents | `run_subagent`, `read_subagent` | | Permissions | `request_scope` | | MCP management | `mcp_list_servers`, `mcp_list_tools`, `mcp_call_tool`, `mcp_read_resource` | MCP server tools appear as `mcp____`. For example, a `github` MCP server tool named `create_issue` appears as `mcp__github__create_issue`. For other tools, match the exact `tool_name` shown in hook stdin. To confirm the complete set available in your current session, add a temporary `PostToolUse` hook with `matcher: ""` and log the stdin payload. # Hooks Source: https://docs.devin.ai/cli/extensibility/hooks/overview Run custom logic when specific events occur during a session Hooks let you run custom logic in response to events in the agent's lifecycle. You can use hooks to enforce policies, add context, log actions, modify permissions, or integrate with external systems. Hooks are configured with a JSON format. Place them in your project's `.devin/` directory (or a user-level config) and Devin CLI runs them at the matching lifecycle events. Existing hooks in `.claude/` directories are also picked up automatically — see [Where Hooks Live](#where-hooks-live). *** ## What Can Hooks Do? Block dangerous commands, require confirmation for specific actions, or restrict file access. Inject additional instructions or information when specific tools are called. Execute scripts, send notifications, or log events when things happen. Dynamically grant or restrict permissions based on the situation. *** ## Quick Example Create `.devin/hooks.v1.json` in your project: ```json theme={null} { "PreToolUse": [ { "matcher": "exec", "hooks": [ { "type": "command", "command": "./scripts/check-command.sh" } ] } ] } ``` This runs `./scripts/check-command.sh` before every shell command execution. The script receives event data on stdin and can block the action by returning a non-zero exit code. *** ## Hook Events Hooks can respond to these lifecycle events: | Event | When it fires | | ------------------- | ----------------------------------------------- | | `PreToolUse` | Before a tool executes | | `PostToolUse` | After a tool finishes | | `PermissionRequest` | When a permission decision is needed | | `UserPromptSubmit` | When the user submits a message | | `Stop` | When the agent wants to stop | | `PostCompaction` | After context compaction completes successfully | | `SessionStart` | When a session begins | | `SessionEnd` | When a session ends | See [Lifecycle Hooks](/cli/extensibility/hooks/lifecycle-hooks) for details on each event and its available data. *** ## Hook Format Each hook has a **type** (`command` or `prompt`), an optional **matcher** (regex on the hook event's `tool_name`), and configuration: ```json theme={null} { "PreToolUse": [ { "matcher": "exec", "hooks": [ { "type": "command", "command": "./scripts/validate.sh", "timeout": 10 } ] } ] } ``` | Field | Description | | --------- | -------------------------------------------------------------------------------------------------------------- | | `matcher` | Regex matched against the hook event's `tool_name`. Empty string or an omitted matcher matches all tool names. | | `type` | `"command"` to run a shell command, or `"prompt"` to evaluate an LLM prompt. | | `command` | Shell command to run (for `command` type). | | `prompt` | LLM prompt to evaluate (for `prompt` type). | | `timeout` | Timeout in seconds (optional). | ### Command Hooks Command hooks run a shell command. Event data is passed as JSON on **stdin**, and the command can return JSON on **stdout** to control the outcome (see [Output format](#output-format) below). **Input** (stdin): ```json theme={null} { "hook_event_name": "PreToolUse", "tool_name": "exec", "tool_input": { "command": "rm -rf /" }, "session_id": "3f8d1c2a-...", "prompt_id": "b71e9d40-..." } ``` Every event payload also carries two correlation ids alongside the event fields: | Field | Description | | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `session_id` | Stable id for the agent session. Use it to correlate hook invocations across a whole session. | | `prompt_id` | Per-turn id, rotated on every user prompt. All hooks fired during the same turn share one `prompt_id`. Absent for events that fire before the first user prompt (e.g. `SessionStart`). | The `DEVIN_PROJECT_DIR` environment variable is automatically set to the project root directory. See [Using the Matcher](/cli/extensibility/hooks/lifecycle-hooks#using-the-matcher) for the built-in tool names and MCP tool name format you can match. ### Output format A command hook can print a JSON object to **stdout** to control the outcome. To approve or block an action, return a top-level `decision` (with an optional `reason`): ```json theme={null} { "decision": "block", "reason": "Destructive command blocked by policy" } ``` To inject text into the agent's context, return `additionalContext` inside a `hookSpecificOutput` object tagged with the event name: ```json theme={null} { "hookSpecificOutput": { "hookEventName": "UserPromptSubmit", "additionalContext": "Remember: deploys require an approved change ticket." } } ``` To transparently rewrite a tool's input before it executes, return `updatedInput` inside a `PreToolUse` `hookSpecificOutput`. Fields in `updatedInput` are merged into the tool's arguments, so you can update a subset (e.g. just `command`): ```json theme={null} { "hookSpecificOutput": { "hookEventName": "PreToolUse", "updatedInput": { "command": "rtk git status" } } } ``` | Output field | Description | | -------------------------------------- | -------------------------------------------------------------------------------------------------- | | `decision` | `"approve"` to allow the action, or `"block"` to deny it | | `reason` | Explanation shown to the agent | | `hookSpecificOutput.hookEventName` | Event the output applies to (e.g. `UserPromptSubmit`, `SessionStart`, `PreToolUse`, `PostToolUse`) | | `hookSpecificOutput.additionalContext` | Text injected into the agent's context (for `UserPromptSubmit`, `SessionStart`, `PostToolUse`) | | `hookSpecificOutput.updatedInput` | Object merged into the tool's arguments before execution (for `PreToolUse`) | ### Exit Codes | Code | Meaning | | ----- | --------------------------------- | | 0 | Success — hook continues normally | | 2 | Block — action is denied | | Other | Error — logged but doesn't block | *** ## Where Hooks Live Devin CLI reads hooks from the following locations. All use the same JSON format. Project-level hook files are discovered in the working directory and its ancestor directories up to the repository root, matching how skills and rules are loaded. ### Project-Level | Location | Description | | ----------------------------- | ------------------------------------------ | | `.devin/hooks.v1.json` | Standalone hooks file (recommended) | | `.devin/config.json` | `"hooks"` key in the config file | | `.devin/config.local.json` | `"hooks"` key (local override, gitignored) | | `.claude/settings.json` | `"hooks"` key (Claude Code format) | | `.claude/settings.local.json` | `"hooks"` key (Claude Code format) | ### User-Level (Global) | Location | Description | | ------------------------------------------------------------------------ | ---------------------------------- | | `~/.config/devin/config.json` (`%APPDATA%\devin\config.json` on Windows) | `"hooks"` key in user config | | `~/.claude.json` | `"hooks"` key (Claude Code format) | | `~/.claude/settings.json` | `"hooks"` key (Claude Code format) | | `~/.claude/settings.local.json` | `"hooks"` key (Claude Code format) | In `.devin/hooks.v1.json`, the hooks object is the **entire file** (no wrapper key needed). In all other locations, hooks are nested under the `"hooks"` key in a settings file. Hooks from `.claude/` paths are loaded when `read_config_from.claude` is enabled (the default). You can disable this in your [user config](/cli/reference/configuration/read-config-from) if needed. *** ## Verifying Hooks Use the `/hooks` slash command to see all currently loaded hooks and their source files: ``` /hooks ``` *** ## Next Steps Deep dive into each event type and what data is available. Control which config locations Devin CLI reads hooks from. # Extensibility Overview Source: https://docs.devin.ai/cli/extensibility/index Customize and extend Devin CLI with rules, skills, and MCP servers Devin CLI is designed to be deeply customizable. You can shape how the agent behaves, what tools it has access to, and how it responds to events — all through configuration files in your project or home directory. Provide always-on context and instructions that guide the agent's behavior across every session. Create reusable prompts and workflows the agent can invoke as slash commands or use autonomously. Install and share bundles of skills across projects. Define specialized subagent profiles with their own system prompts, tools, and models. Connect external tool servers to give the agent access to APIs, databases, and more. Run shell commands or LLM prompts at key points in the agent's lifecycle to enforce policies and automate workflows. *** ## How It All Fits Together These features work at different layers: * **Rules** shape the agent's personality and constraints — they're always active. * **Skills** give the agent new capabilities it can invoke on demand. * **Custom Subagents** define specialized worker profiles the agent can delegate tasks to. * **MCP Servers** provide entirely new tools the agent can call. * **Hooks** run shell commands or LLM prompts at lifecycle events (e.g., before a tool runs) to enforce policies or trigger workflows. You can combine all of these in a single project. For example, you might have an `AGENTS.md` file with coding standards, a `review` skill for code review, an MCP server for your issue tracker, and hooks to block destructive commands. *** ## Where Configuration Lives All project-level extensibility configuration lives in the `.devin/` directory at your project root: ``` my-project/ ├── .devin/ │ ├── config.json # Project config (MCP, permissions) │ ├── config.local.json # Personal overrides (gitignored) │ ├── hooks.v1.json # Lifecycle hooks (Claude Code compatible) │ ├── skills/ │ │ └── review/ │ │ └── SKILL.md # A custom skill │ └── agents/ │ └── reviewer.md # A custom subagent profile (reviewer/AGENT.md also works) ├── AGENTS.md # Project rules └── src/ ``` User-level configuration lives in `~/.config/devin/` and applies to all projects. On Windows, this path is `%APPDATA%\devin\` instead. Files with `.local.` in the name are automatically excluded from git, so you can have personal overrides without affecting your team. *** ## Importing From Other Tools Devin CLI can read configuration from other AI coding tools you may already use: | Source | What's Imported | | -------------------------------------------- | --------------------------------------------------------------------------------------------------------- | | `AGENTS.md` / `AGENT.md` / `CLAUDE.md` | Rules (always-on context) | | `.cursor/rules/*.md` / `.cursor/rules/*.mdc` | Rules | | `.windsurf/rules/*.md` | Rules | | `.claude/` directory | Commands, [custom subagents](/cli/subagents#custom-subagents), [hooks](/cli/extensibility/hooks/overview) | This means you can start using Devin CLI without rewriting your existing configuration. Import is enabled by default and can be controlled in your config file: ```json theme={null} { "read_config_from": { "cursor": true, "windsurf": true, "claude": true } } ``` Set any provider to `false` to disable importing from it. # MCP Configuration Source: https://docs.devin.ai/cli/extensibility/mcp/configuration How to add, configure, and manage MCP servers ## Adding MCP Servers ### Via Command Line The quickest way to add an MCP server: ```bash theme={null} # stdio server — just pass the command after -- devin mcp add -- [args...] # HTTP server — pass the URL as a positional argument devin mcp add # HTTP server — or use the --url flag devin mcp add --url ``` The transport type is inferred automatically: a URL implies HTTP (Streamable HTTP), and trailing args (or `--command`) imply stdio. Remote MCP servers use Streamable HTTP by default. If the server responds with an HTTP 4xx error, the CLI falls back to SSE on the same URL. Set `"transport": "sse"` explicitly if needed — see [Legacy SSE fallback](#legacy-sse-fallback) below. By default, servers are saved to **local** scope (`.devin/mcp_config.local.json`, gitignored). Use `-s`/`--scope` to change: ```bash theme={null} devin mcp add -s project # shared via .devin/mcp_config.json devin mcp add -s user # global (~/.config/devin/mcp_config.json; %APPDATA%\devin\mcp_config.json on Windows) ``` You can also manage servers from the command line: ```bash theme={null} devin mcp list # List all configured servers devin mcp get # Show details for a specific server devin mcp remove # Remove a configured server devin mcp login # Authenticate with a server via OAuth devin mcp logout # Remove stored OAuth credentials devin mcp enable # Enable a disabled server devin mcp disable # Disable a server without removing it ``` ### Via Config File Add servers directly to your MCP config file's `mcpServers` section: **The MCP config file location changed in v3000.3 (the Local 3.6 release).** Older versions (before v3000.3) store MCP servers in the `mcpServers` key of the main config files (`~/.config/devin/config.json`, `.devin/config.json`, `.devin/config.local.json`). Newer versions store them in dedicated files at the same locations: `~/.config/devin/mcp_config.json` (`%APPDATA%\devin\mcp_config.json` on Windows), `.devin/mcp_config.json`, and `.devin/mcp_config.local.json`. Any `mcpServers` entries found in the main config files are migrated to the dedicated files automatically on startup. ```json theme={null} // .devin/mcp_config.json { "mcpServers": { "server-name": { "command": "npx", "args": ["-y", "@company/mcp-server"], "env": { "API_KEY": "your-key" } } } } ``` Project-level servers are shared with your team via version control. ```json theme={null} // ~/.config/devin/mcp_config.json { "mcpServers": { "my-server": { "command": "node", "args": ["/path/to/my-server.js"], "env": {} } } } ``` User-level servers apply to all your projects. ```json theme={null} // .devin/mcp_config.local.json { "mcpServers": { "server-name": { "command": "npx", "args": ["-y", "@company/mcp-server"], "env": { "API_KEY": "my-personal-key" } } } } ``` Local configs are gitignored — use these for personal API keys. *** ## Server Configuration Options MCP servers can be configured in two ways: as a **local command** (stdio transport) or as a **remote server** (HTTP transport). ### Local Command (stdio) | Field | Type | Required | Description | | ---------- | --------- | -------- | --------------------------------------------------------------------------------------------------------- | | `command` | string | Yes | The executable to run | | `args` | string\[] | No | Command-line arguments | | `env` | object | No | Environment variables to set | | `disabled` | boolean | No | Set to `true` to skip this server (see [Enabling and disabling servers](#enabling-and-disabling-servers)) | ### Remote Server (Streamable HTTP) | Field | Type | Required | Description | | ------------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `url` | string | Yes | The URL of the MCP server endpoint | | `transport` | string | No | `"http"` (Streamable HTTP, default for URL-based servers) or `"sse"` (legacy SSE). When set to `"http"` or omitted, the CLI tries Streamable HTTP first and falls back to SSE on 4xx errors ([per spec](https://spec.modelcontextprotocol.io/specification/2025-03-26/basic/transports/#backwards-compatibility)). Set `"sse"` explicitly if the server's SSE endpoint is at a different path. | | `headers` | object | No | Custom HTTP headers to include in requests | | `oauthClientId` | string | No | Pre-registered OAuth client ID, for servers that don't support dynamic client registration (DCR), e.g. GitHub. See the "Pre-registered OAuth clients" section below. | | `oauthClientSecret` | string | No | OAuth client secret, for confidential clients. Pair with `oauthClientId`. | | `oauthResource` | string | No | Override the RFC 8707 `resource` parameter sent in OAuth requests (default: the MCP server URL). Set to an empty string (`""`) to omit the parameter entirely, for providers that reject it. See [OAuth resource override](#oauth-resource-override). | | `disabled` | boolean | No | Set to `true` to skip this server (see [Enabling and disabling servers](#enabling-and-disabling-servers)) | ### Examples ```json theme={null} { "mcpServers": { "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": { "GITHUB_TOKEN": "ghp_..." } } } } ``` ```json theme={null} { "mcpServers": { "notion": { "url": "https://mcp.notion.com/mcp", "transport": "http" } } } ``` After adding an OAuth-based server, run `devin mcp login notion` to authenticate. See [Authentication](#authentication) below. ```json theme={null} { "mcpServers": { "linear": { "url": "https://mcp.linear.app/mcp", "transport": "http" } } } ``` ```json theme={null} { "mcpServers": { "atlassian": { "url": "https://mcp.atlassian.com/v1/mcp", "transport": "http" } } } ``` After adding, run `devin mcp login atlassian` to authenticate. Each MCP client (Windsurf, Claude Code, Devin CLI) maintains its own OAuth session, so you must log in separately even if you've already authenticated in another tool. ```json theme={null} { "mcpServers": { "my-tools": { "command": "python", "args": ["./scripts/mcp-server.py"], "env": { "DB_URL": "postgres://localhost/mydb" } } } } ``` *** ## Authentication Some remote MCP servers require OAuth authentication. After adding an OAuth-based server to your config, authenticate using the `login` command: ```bash theme={null} devin mcp login ``` For example: ```bash theme={null} devin mcp login notion # Authenticate with Notion devin mcp login linear # Authenticate with Linear ``` This opens a browser window where you can authorize access. The OAuth tokens are stored locally and refreshed automatically. You can optionally request specific OAuth scopes: ```bash theme={null} devin mcp login notion --scopes read,write ``` To remove stored OAuth credentials for a server: ```bash theme={null} devin mcp logout ``` If the server supports OAuth, you will also be prompted to authenticate automatically when the server is first used. ### Re-authenticating Stored OAuth credentials don't last forever — they expire, and an administrator can revoke them on the provider side. When that happens the server reports an **auth-required** state instead of connecting, and its tools (and [prompts](/cli/extensibility/mcp/overview#prompts-as-slash-commands)) stop being available until you sign in again. To re-authenticate, clear the stored credentials and run the browser flow again: ```bash theme={null} devin mcp logout devin mcp login ``` `logout` deletes the persisted tokens for that server; `login` re-runs the OAuth flow and stores fresh ones. Do the same after changing `oauthClientId`, `oauthClientSecret`, or `oauthResource` — credentials issued under the old settings are not reused. Editor integrations that drive Devin CLI over ACP surface the same auth-required state, with a re-authenticate action that clears the stored credentials and reopens the browser flow — equivalent to the `logout` + `login` pair above. ### Pre-registered OAuth clients Most OAuth-based MCP servers support [dynamic client registration](https://datatracker.ietf.org/doc/html/rfc7591) (DCR), so Devin CLI registers itself automatically and you don't need to provide any client credentials. Some providers (e.g. GitHub) don't support DCR and instead require a **pre-registered** OAuth client. For those, supply the client ID — and a client secret if it's a confidential client — via `oauthClientId` / `oauthClientSecret`: ```json theme={null} { "mcpServers": { "my-server": { "url": "https://mcp.example.com/mcp", "transport": "http", "oauthClientId": "Iv1.abc123def456", "oauthClientSecret": "${env:MY_MCP_CLIENT_SECRET}" } } } ``` When `oauthClientId` is set, Devin CLI skips dynamic client registration and uses your pre-registered client during the OAuth flow. Run `devin mcp login ` (or trigger first use) to authenticate as usual. You can also set these from the command line when adding or logging into a server: ```bash theme={null} devin mcp add my-server --oauth-client-id --oauth-client-secret devin mcp login my-server --oauth-client-id --oauth-client-secret ``` `oauthClientId` / `oauthClientSecret` are OAuth client credentials used during the authorization flow. They are **not** generic per-request credentials — if a server expects a static token, use `headers` (HTTP) or `env` (stdio) instead. Don't commit a client secret to a shared config. Reference it from an environment variable (`${env:VAR}`), read it from a file (`${file:/path}`), or put it in `.devin/mcp_config.local.json` (gitignored). See the "Managing Secrets" section below. ### OAuth resource override During OAuth authorization and token exchange, Devin CLI sends an [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) `resource` parameter so the authorization server can issue audience-restricted tokens. By default the value is the MCP server's URL. Override it with `oauthResource`: ```json theme={null} { "mcpServers": { "my-server": { "url": "https://my-server.example.com/mcp", "transport": "http", "oauthResource": "" } } } ``` The field has three behaviors: * **Unset** (default): sends `resource` set to the MCP server URL. * **Non-empty value**: replaces the default with your value (e.g. a specific application ID URI). * **Empty string (`""`)**: omits the `resource` parameter entirely from both the authorization URL and the token exchange. You can also set it from the command line when adding or logging into a server: ```bash theme={null} devin mcp add my-server --oauth-resource "" devin mcp login my-server --oauth-resource "" ``` Like other OAuth fields, `oauthResource` supports `${env:VAR}` and `${file:/path}` expansion. *** ## Enabling and Disabling Servers You can temporarily disable an MCP server without removing its configuration. A disabled server is skipped during tool discovery — its tools won't appear and the server process won't be started. ```bash theme={null} devin mcp disable # Disable a server devin mcp enable # Re-enable it ``` This sets the `"disabled": true` flag on the server entry in the config file. Use `-s`/`--scope` to target a specific scope: ```bash theme={null} devin mcp disable -s project my-server devin mcp enable -s user my-server ``` You can also set the flag directly in your config file: ```json theme={null} { "mcpServers": { "my-server": { "command": "npx", "args": ["-y", "@company/mcp-server"], "disabled": true } } } ``` Disabling is useful when you want to keep a server's configuration (including environment variables and OAuth credentials) but temporarily stop using it — for example, to reduce startup time or isolate an issue. *** ## Managing Secrets Never commit API keys or secrets to version control. Use `.devin/mcp_config.local.json` for sensitive values. For team projects, the recommended pattern is: 1. Define the server in `.devin/mcp_config.json` with placeholder or no env vars 2. Each team member adds their personal keys in `.devin/mcp_config.local.json` The local config file is automatically excluded from git. *** ## MCP Permissions You can pre-approve, deny, or force-ask for specific MCP tools in your permissions config: ```json theme={null} { "permissions": { "allow": [ "mcp__github__list_issues", "mcp__github__create_issue" ], "deny": [ "mcp__github__delete_repo" ], "ask": [ "mcp__linear__*" ] } } ``` **Permission matcher patterns:** | Pattern | Matches | | ------------------- | ------------------------------------ | | `mcp__server__tool` | A specific tool on a specific server | | `mcp__server__*` | All tools on a specific server | | `mcp__*` | All MCP tools on all servers | *** ## Prompts Prompts need no configuration of their own: any connected server that declares the MCP `prompts` capability automatically contributes `/mcp____` slash commands. Because the command name embeds the server name, renaming a server in `mcpServers` renames its prompt commands too. See [MCP Overview — Prompts as slash commands](/cli/extensibility/mcp/overview#prompts-as-slash-commands). *** ## Organization restrictions If you're on an enterprise team, your admin may restrict which MCP servers you can connect to. A server you've configured can be blocked if MCP is disabled for your team, or if it isn't on your team's allowlist or in an enforced **MCP registry** — in which case it won't connect and its tools won't be available. See [Team Settings — MCP Registry](/cli/enterprise/team-settings#mcp-registry) for details. *** ## Troubleshooting If you see errors like `Auth required` or `AuthRequired` when connecting to a remote MCP server, the server requires OAuth authentication. Run: ```bash theme={null} devin mcp login ``` Each MCP client authenticates independently. Even if you've already authenticated in Windsurf or Claude Code, you need to run `devin mcp login` separately for Devin CLI. To verify your auth status, try removing and re-adding credentials: ```bash theme={null} devin mcp logout devin mcp login ``` Verify the command works outside Devin CLI: ```bash theme={null} npx -y @modelcontextprotocol/server-github ``` Check that all required environment variables are set. Ask the agent to list MCP servers and tools. The server may need a moment to initialize. Check your permissions config. MCP tools default to prompting for approval. Add them to `permissions.allow` to auto-approve. Some authorization servers reject OAuth requests that include the RFC 8707 `resource` parameter. Set `oauthResource` to an empty string to omit the parameter: ```json theme={null} { "mcpServers": { "my-server": { "url": "https://my-server.example.com/mcp", "oauthResource": "" } } } ``` Then re-authenticate: ```bash theme={null} devin mcp logout my-server devin mcp login my-server ``` See [OAuth resource override](#oauth-resource-override) for the full set of `oauthResource` behaviors. When connecting to an HTTP server, Devin CLI tries **Streamable HTTP** first. If the server responds with an HTTP 4xx error (e.g. 404 or 405), it automatically falls back to **legacy SSE** on the **same configured URL**. This follows the [MCP spec's backwards-compatibility guidance](https://spec.modelcontextprotocol.io/specification/2025-03-26/basic/transports/#backwards-compatibility). The fallback only triggers on 4xx responses — connection errors, timeouts, and 5xx responses are reported directly without attempting SSE. If your server's SSE endpoint is at a different path (e.g. `/sse` instead of `/mcp`), set `"transport": "sse"` with the SSE URL to connect directly without the Streamable HTTP attempt. If both transports fail, the error message includes details from both attempts to help with troubleshooting. # MCP Overview Source: https://docs.devin.ai/cli/extensibility/mcp/overview Extend Devin CLI with external tool servers using the Model Context Protocol MCP (Model Context Protocol) lets you connect external tool servers to Devin CLI, giving the agent access to APIs, databases, issue trackers, and any other service you can wrap in an MCP server. When you configure an MCP server, its tools become available to the agent just like built-in tools. The agent can discover what tools are available and call them as needed. *** ## How It Works You define an MCP server in your config file with a command, arguments, and optional environment variables. Devin CLI starts the server process when needed. The server connects to the external API (GitHub, Linear, etc.). The agent discovers what tools the server provides (e.g., `create_issue`, `list_repos`). When the agent calls an MCP tool, the request flows through the server to the external service and the result is returned. *** ## Quick Example Add a GitHub MCP server to your project: ```json theme={null} // .devin/mcp_config.local.json (gitignored — keep tokens out of committed config) { "mcpServers": { "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": { "GITHUB_TOKEN": "ghp_your_token_here" } } } } ``` Now the agent can create issues, read PRs, search repos, and more — all through natural language. *** ## Permission Control Once configured, MCP tools appear with a namespaced format: `mcp____`. For example, a "github" server with a "create\_issue" tool becomes `mcp__github__create_issue`. MCP tools are subject to the same permission system as built-in tools. You can control access at multiple levels: ```json theme={null} { "permissions": { "allow": [ "mcp__github__*" ], "deny": [ "mcp__github__delete_repo" ] } } ``` See [Permissions](/cli/reference/permissions) for the full permission syntax. *** ## Prompts as Slash Commands Beyond tools, an MCP server can publish **prompts** — reusable, parameterized instructions declared through the MCP `prompts` capability. Devin CLI exposes each one as a slash command: ``` /mcp____ [arguments] ``` For example, a `linear` server that publishes a `bug_report` prompt becomes `/mcp__linear__bug_report`. Prompt commands are listed in the command palette under their own **MCP** category, described with the title or description the server publishes, and annotated with an argument hint built from the prompt's declared parameters — `` for required arguments and `[name]` for optional ones. When you send the command, Devin CLI fetches the prompt from the server and substitutes the messages it returns as your message for that turn. ### How arguments map Whatever you type after the command name is mapped **positionally** onto the prompt's declared arguments — first word to the first argument, second word to the second, and so on. The last declared argument receives all of the remaining text, so free-form trailing input survives intact: ``` /mcp__linear__bug_report ENG-1234 login page hangs after the SSO redirect ``` Here `ENG-1234` fills the first declared argument and the rest of the line fills the last one. If the prompt declares no arguments at all, anything you type is appended to the expanded prompt rather than dropped. Only servers that have already connected contribute advertised commands (connections are warmed in the background at startup), but invocation resolves lazily — typing `/mcp____` works even when the command was never advertised, connecting to the server on demand. Prompt expansion happens in the agent rather than in the terminal UI, so the same commands are advertised over ACP — editor integrations such as [Zed](/cli/acp/zed) and [JetBrains](/cli/acp/jetbrains) list them alongside built-in commands. *** ## Authentication Some remote MCP servers (such as Atlassian, Notion, and Linear) require OAuth authentication. Each MCP client authenticates independently — tokens from Windsurf or Claude Code are **not** shared with Devin CLI. After adding a remote server, authenticate with: ```bash theme={null} devin mcp login ``` This opens a browser window for the OAuth flow. If stored credentials later expire or are revoked, the server reports an auth-required state and you re-authenticate with `devin mcp logout` followed by `devin mcp login` — see [MCP Configuration — Authentication](/cli/extensibility/mcp/configuration#authentication) and [Re-authenticating](/cli/extensibility/mcp/configuration#re-authenticating) for details. *** ## Disabling Servers You can temporarily disable an MCP server without removing its configuration or credentials: ```bash theme={null} devin mcp disable devin mcp enable ``` See [MCP Configuration — Enabling and disabling servers](/cli/extensibility/mcp/configuration#enabling-and-disabling-servers) for details. *** ## Next Steps Learn how to configure MCP servers in detail Control which MCP tools the agent can use # Plugins Source: https://docs.devin.ai/cli/extensibility/plugins/overview Reference for installing, authoring, and governing plugins across Devin cloud sessions, the CLI, and Devin Desktop. Plugins are in **closed beta**. To request access, contact [support@cognition.ai](mailto:support@cognition.ai). Behavior and configuration may change in future releases. A **plugin** is a bundle of [skills](/cli/extensibility/skills/overview) and optional rules, hooks, MCP servers, or custom subagents that you can install from a GitHub repo, a git URL, a subfolder of a repo, or a local folder. Plugins work across Devin cloud sessions, the [Devin CLI](/cli/index), and Devin Desktop, subject to the surface-specific limitations described below. Installing a plugin makes its skills available as `/:` slash commands. The **plugin is the unit of installation**. Installing a plugin installs all of its skills and its `requiredPlugins`; you can't install individual skills from a plugin. To offer skills separately, split them into separate plugins. A plugin is just a source that contains: ``` my-plugin/ ├── .devin-plugin/ │ └── plugin.json # The plugin manifest ├── AGENTS.md # Optional always-on rule ├── rules/ # Optional triggered rules ├── agents/ │ └── reviewer.md # Optional custom subagent (reviewer/AGENT.md also works) ├── hooks.json # Optional lifecycle hooks ├── mcp_config.json # Optional MCP servers └── skills/ └── review/ └── SKILL.md # An ordinary skill ``` The `skills/` directory holds ordinary skills — plugins introduce no new skill format. See [Creating Skills](/cli/extensibility/skills/creating-skills) for the `SKILL.md` format. One repo (or one `git-subdir` subfolder) is one plugin. A single repo can host many plugins as subfolders, each referenced with its own `git-subdir` source. Beyond skills, a plugin can ship: * **Rules** — an `AGENTS.md` at the plugin root is injected as an always-on rule in every session, alongside your project's own rules. Markdown files in a `rules/` folder are loaded too, with the same `trigger` frontmatter and [activation types](/cli/extensibility/rules#rule-activation-types) as [Windsurf rules](/cli/extensibility/rules#rules-from-other-tools). * **Custom subagents** — `agents/.md` or `agents//AGENT.md` profiles (the same [custom subagent format](/cli/subagents#custom-subagents) as project subagents), available as `:`. Plugin subagents currently load in local Devin agents only — the CLI and Devin Desktop — not in cloud Devin sessions. * **Hooks** — a `hooks.json` at the plugin root registers [lifecycle hooks](/cli/extensibility/hooks/lifecycle-hooks) that run in every session where the plugin is installed. In cloud sessions, `command` hooks run on the session's machine and only fire while that machine is up. They support every event except `SessionStart` and `SessionEnd` — including `PreToolUse`, `PostToolUse`, `PermissionRequest`, `UserPromptSubmit`, `Stop`, and `PostCompaction`; `prompt`-type hooks are CLI/local-only. * **MCP servers** — an `mcp_config.json` at the plugin root declares [MCP servers](/cli/extensibility/mcp/overview) (`"mcpServers": { "": { … } }`) that start with the session. Plugin MCP servers don't yet appear in the MCP settings UI, but their tools are available to Devin. A plugin MCP config may set an OAuth client ID and scopes, but never a client secret — a server config carrying one is rejected at activation. Claude plugins' root `.mcp.json` and manifest `mcpServers` field are also honored. Claude plugins work as plugins too: if there's no `.devin-plugin/plugin.json`, Devin falls back to `.claude-plugin/plugin.json`. When both manifests are present, the Devin one wins. *** ## Installing a plugin A plugin source can be a GitHub `owner/repo`, a git URL, or a local path: ```bash theme={null} # From GitHub devin plugins install acme/review-tools # From any git host devin plugins install https://gitlab.com/acme/review-tools.git # From a local folder (great for authoring) devin plugins install ./my-plugin ``` Before installing, Devin shows what the plugin adds — the skills it provides, any required plugins that will be auto-installed, and any policy it introduces (for example, if it forbids other plugins). Pass `-y` / `--yes` to skip the prompt. Plugins are installed at the **user** level and are available across all your projects. *** ## Managing plugins ```bash theme={null} # List installed plugins, their versions, and whether any are blocked by policy devin plugins list # Show a plugin's skills and its required/optional/forbidden lists devin plugins info review-tools # Re-fetch a plugin (or all plugins) at the latest version devin plugins update review-tools devin plugins update # Remove a plugin (auto-installed required plugins are left in place) devin plugins remove review-tools ``` Local plugins are linked directly to their source folder, so edits are live: `devin plugins install ./my-plugin` → edit `skills//SKILL.md` → changes apply on the next session, no `update` needed. *** ## The manifest `.devin-plugin/plugin.json` describes the plugin. Only `name` is required, and it must be unique among installed plugins (it is the `/:…` namespace). ```jsonc theme={null} { "name": "review-tools", "version": "1.0.0", "description": "Code-review skills for our team", "requiredPlugins": [ "acme/secure-base", { "source": "github", "repo": "acme/audit-logging" } ], "optionalPlugins": [ "acme/deploy-tools", { "source": "url", "url": "https://gitlab.com/acme/extra.git" } ], "forbiddenPlugins": ["sketchy-org/bad-plugin", "acme/*", "*"] } ``` Supported metadata fields: `name`, `version`, `description`, `author` (`{ name, email }`), `homepage`, `repository`, `license`, and `keywords`. Two more optional fields control where assets load from: `skills` — a path or array of paths to skill directories, replacing the default `skills/` — and `mcpServers` — MCP declaration file paths or an inline server map, read in addition to the root conventions. A dependency entry is a **source** — either a string shorthand or an object: | Form | Meaning | | ------------------------------------------------------------------ | ----------------------------------------------- | | `"owner/repo"` | GitHub repository | | `"https://…"`, `"git@…"`, `"ssh://…"` | any git URL | | `{ "source": "github", "repo": "owner/repo" }` | GitHub, object form | | `{ "source": "url", "url": "https://gitlab.com/team/plugin.git" }` | git URL, object form | | `{ "source": "git-subdir", "url": "…", "path": "sub/dir" }` | a plugin living in a subfolder of a shared repo | All GitHub forms for the same repo (`owner/repo`, the HTTPS URL, the `.git` URL, the SSH form) refer to the same plugin identity. *** ## Dependencies and governance A plugin can declare three lists, which let a single plugin act as a curated, governed collection of other plugins. ### `requiredPlugins` Auto-installed (recursively) when the plugin is installed. If a required plugin is blocked by policy, the whole install fails — there is no partial install. ### `optionalPlugins` An **allow-list** of plugins this plugin endorses. They are **not** auto-installed; the list only matters as a carve-out against a forbidden entry (see below). ### `forbiddenPlugins` A **deny-list** of plugin identities and glob patterns. `forbiddenPlugins` entries are matched against plugin identities: * An **exact identity**, written as `owner/repo` or a git URL. All GitHub forms of the same repo (`owner/repo`, the HTTPS URL, the `.git` URL, the SSH form) refer to the same identity. * A **glob pattern** — any entry containing `*`. The `*` matches any sequence of characters, including `/`: `acme/*` matches all of `acme`'s GitHub repos, `*/secrets` matches a repo named `secrets` under any owner, and `https://gitlab.com/acme/*` matches any repo under that path. * The lone `"*"`, which matches everything else (a full lockdown). The lists combine deny-wins: * **Deny wins.** A plugin is blocked if any active manifest or installed plugin forbids it. If nothing forbids anything, nothing is blocked. * **Self-override.** A manifest's (or plugin's) own `requiredPlugins` and `optionalPlugins` — and, for a plugin, the plugin itself — are exempt from its **own** forbidden list, so `"forbiddenPlugins": ["*"]` plus `"optionalPlugins": ["acme/approved"]` means "allow only what this manifest lists; forbid everything else." The carve-out covers only those direct entries, not a required plugin's transitive dependencies — list those explicitly under a lockdown. * **No cross-scope re-permitting.** One manifest's or plugin's allow-list cannot re-permit what **another** forbids. A `"forbiddenPlugins": ["*"]` lockdown can't be defeated from a lower scope. Enforcement happens at two points: * **Install time** — installing a blocked plugin (or one whose required plugins can't be satisfied, or whose name collides with an installed plugin) is refused. * **Load time** — a plugin blocked after it's already installed stays on disk, but its skills are skipped at session start with a warning naming the forbidder. A forbidden identity can also be a **local path** (for plugins installed from a local folder), in addition to the `owner/repo` and git-URL forms above. *** ## Inheritance and levels Plugins aren't declared in one place. Beyond your own installs, plugins can be required, endorsed, or forbidden by your repo and by your organization's admin. Each source is a **level**, and the levels are ranked by **authority**, highest first: 1. **Enterprise** — the account-wide managed manifest, configured by an admin. 2. **Org** — an org-level managed manifest, layered below its account (an org can add to what its account declares, but can't overrule it). This applies only to **cloud Devin sessions**: the CLI authenticates at the account level and has no org context, so org-level requires and forbids don't reach CLI users. Put anything you need enforced in the CLI in the enterprise/account manifest. 3. **Repo** — the `requiredPlugins` / `optionalPlugins` / `forbiddenPlugins` in a checkout's `.devin/config.json`, discovered by walking up from your working directory. 4. **User** — plugins you install yourself with `devin plugins install`. Every level declares the same three lists, and within a level they combine with the same [deny-wins, self-override rules](#dependencies-and-governance) as a single manifest. What the levels add on top is one rule: **higher authority wins**. ### Higher authority wins * A lower level can never **re-permit** what a higher level forbids. * A lower level can never **forbid** what a higher level requires — the forbid is ignored and the plugin still loads. So an admin can mandate a plugin no repo or user can opt out of, and forbid a plugin no lower level can bring back. ### A denylist is only overridden at its own level Because allow-lists don't cross levels, the **only** way to carve an exception out of a denylist is at the same level that declared it. A level's `forbiddenPlugins` is overridden only by that same manifest's own `optionalPlugins` (or `requiredPlugins`) — never by a list at a lower level. For example, an enterprise-level managed manifest can lock the account down to a single approved plugin: ```jsonc theme={null} // Enterprise-level managed manifest { "forbiddenPlugins": ["*"], "optionalPlugins": ["acme/approved"] } ``` This means "across the whole account, allow only `acme/approved` and forbid every other plugin." No org, repo, or user can widen that allow-list — not by installing a plugin, and not by adding it to a lower level's `optionalPlugins`. The carve-out also covers only the entries this manifest lists directly; a required plugin's own transitive dependencies aren't exempt, so list those explicitly under a lockdown. ### Conflicts and dependencies * A require and a forbid for the same plugin at the **same level** but from **different manifests** (for example two separately installed user-level plugins) resolve to the forbid — an allow-list only exempts entries in its *own* manifest, so it can't rescue a plugin another manifest forbids. (Within a single manifest, its own required/optional stay exempt from its own forbids, as [above](#a-denylist-is-only-overridden-at-its-own-level).) * A plugin blocked by governance **soft-fails**: at session start its skills are skipped with a warning naming the forbidder, rather than aborting the session. * Being depended upon grants no exemption. A plugin pulled in only as a transitive dependency is still subject to every forbid that applies to it, and it inherits the highest authority level of any plugin that requires it. # Quickstart: team marketplace Source: https://docs.devin.ai/cli/extensibility/plugins/quickstart Stand up a shared plugin marketplace for your team in five steps Plugins are in **closed beta**. To request access, contact [support@cognition.ai](mailto:support@cognition.ai). Behavior and configuration may change in future releases. This quickstart takes you from zero to a **team plugin marketplace**: one repo your org owns that bundles your skills, rules, hooks, and MCP servers, installed automatically for every Devin session and CLI user. For the full background, see [Set up your plugin ecosystem](/product-guides/plugin-ecosystem). ## 1. Fork the template Fork [CognitionAI/team-marketplace-template](https://github.com/CognitionAI/team-marketplace-template). Its layout: ``` your-marketplace/ ├── .devin-plugin/ │ └── plugin.json # the meta-plugin: your baseline + policy ├── AGENTS.md # always-on rule shipped with the baseline ├── plugins/ │ ├── engineering-baseline/ # each subfolder is its own plugin │ ├── security-guardrails/ │ ├── frontend-standards/ │ └── docs-and-release/ └── scripts/validate-template.mjs # CI validation ``` The repo root is itself a plugin — the **meta-plugin**. Installing the repo installs your whole baseline: its manifest's `requiredPlugins` pulls in the plugins every teammate should have, `optionalPlugins` endorses extras, and `forbiddenPlugins` blocks what you don't want. ## 2. Make it yours * In the root `.devin-plugin/plugin.json`, change every `git-subdir` URL to point at **your fork**, and edit the required/optional/forbidden lists. * Add a plugin per team or concern under `plugins//` — each needs its own `.devin-plugin/plugin.json` and typically a `skills//SKILL.md`. Starting a plugin from scratch? Use [CognitionAI/plugin-template](https://github.com/CognitionAI/plugin-template). * Have an existing repo of skills? Drop each skill folder into a plugin's `skills/` directory — skills inside plugins are ordinary [skills](/cli/extensibility/skills/creating-skills), no format change. ## 3. Test locally with the CLI ```bash theme={null} node scripts/validate-template.mjs # structural validation (also runs in CI) devin plugins install . # install the meta-plugin from your checkout devin plugins list # see everything it pulled in ``` Local installs are linked, so edits apply on your next session — iterate on a skill, then start a session and invoke it as `/:`. ## 4. Distribute it to everyone An org or enterprise admin adds one required plugin to the managed manifest at [Settings → Resources → Plugins](https://app.devin.ai/settings/marketplace): ```json theme={null} { "requiredPlugins": ["your-org/your-marketplace"] } ``` Everyone in scope gets the baseline automatically — cloud sessions and, for the enterprise/account manifest, CLI and Devin Desktop users logged into the account too (org-level manifests reach cloud sessions only). A private repo works as-is: cloud fetches through your Git integration; CLI users fetch with their own git credentials. ## 5. Evolve and govern * Merging to your marketplace repo's default branch **is** the release — new sessions pick it up automatically. See [how updates roll out](/product-guides/plugins#how-updates-roll-out). * Teams add plugins by PR to the marketplace repo; CI validates the layout. * To lock the account down to your approved set only, add `"forbiddenPlugins": ["*"]` to the managed manifest and list every approved plugin (including the meta-plugin's dependencies — transitive deps aren't exempt) in `requiredPlugins`/`optionalPlugins`. Full semantics: [dependencies and governance](/cli/extensibility/plugins/overview#dependencies-and-governance). ## Next steps * [Set up your plugin ecosystem](/product-guides/plugin-ecosystem) — the full org playbook * [Plugins reference](/cli/extensibility/plugins/overview) — manifest format, install flows, governance levels * [Plugin marketplace](/product-guides/plugins) — the web app side: manifests, scopes, uploads # Rules & AGENTS.md Source: https://docs.devin.ai/cli/extensibility/rules Provide always-on instructions and context that guide the agent in every session Rules are persistent instructions that shape how Devin CLI behaves in your project. They're injected into the agent's context at the start of every session, ensuring consistent behavior across your team. Common uses for rules include coding standards, architectural guidelines, preferred libraries, testing conventions, and project-specific constraints. **To improve coding ability, speed of completion, and lower cost**, we highly recommend **using Skills instead whenever possible**. Skills are only injected into the context when relevant. **Rules and AGENTS should be kept as small as possible.** **Our recommended pattern** is to use a rule to reference skills that the model should use in particular scenarios. *** ## AGENTS.md The simplest way to add rules is with an `AGENTS.md` file at your project root: ```markdown theme={null} # Project Rules - Use TypeScript for all new files - Follow the existing patterns in src/components/ - Always run `npm run lint` before committing - Use pnpm, not npm or yarn - Write tests for all new utility functions ``` Devin CLI reads this file automatically. `AGENTS.md` is the recommended approach for project rules. It's easy to read, version-controlled, and works across multiple AI tools. *** ## Global Rules You can also create rules that apply to **every project** by placing an `AGENTS.md` file in your user config directory: ``` ~/.config/devin/AGENTS.md ``` ``` %APPDATA%\devin\AGENTS.md ``` Global rules are loaded at the start of every session, regardless of which project you're working in. Use them for personal preferences that apply everywhere: ```markdown theme={null} # My Global Rules - Always write commit messages in conventional commit format - Prefer functional patterns over imperative code - Run tests before suggesting a task is complete ``` Global rules work alongside project rules — both are loaded and active at the same time. `AGENT.md` is also supported at this location. If you use Claude Code, Devin CLI also reads `~/.claude/CLAUDE.md` as a global rule. *** ## Personal Rules with AGENTS.local.md If you have personal instructions that shouldn't be shared with collaborators — such as preferred working style, testing habits, or review preferences — create an `AGENTS.local.md` file next to your `AGENTS.md`: ```markdown theme={null} # My Personal Rules - Always start by writing failing tests before implementing a fix - Prefer functional patterns over imperative code - Run the full test suite before marking a task as complete ``` This file is loaded alongside `AGENTS.md` with the same always-on behavior. Add it to your `.gitignore` so it stays local: ```gitignore theme={null} AGENTS.local.md ``` This follows the same convention as `.devin/config.local.json` — the `.local.` suffix signals a personal override that shouldn't be committed. *** ## Supported File Names Devin CLI reads rules from any of these files: | File | Notes | | ----------------- | ------------------------------- | | `AGENTS.md` | Recommended | | `AGENTS.local.md` | Personal rules (gitignored) | | `AGENT.md` | Singular alternative | | `.windsurfrules` | Legacy Windsurf workspace rules | | `CLAUDE.md` | Compatible with Claude Code | All of these are treated identically — their contents are loaded as always-on rules. These files can exist at multiple levels in your project (not just the root). Files at the workspace root are loaded at session start. Files in subdirectories are discovered lazily when the agent accesses files in that directory, keeping the context focused on the relevant part of the codebase. They can also be placed in the [global config directory](#global-rules) to apply across all projects, except `CLAUDE.md` which is read globally from `~/.claude/CLAUDE.md`. Installed [plugins](/cli/extensibility/plugins/overview) can ship rules too: an always-on `AGENTS.md` at the plugin root plus `rules/*.md` files with `trigger` frontmatter. *** ## Rules in the .devin Directory Devin CLI also reads rules from the `.devin/` directory, one rule per file: | Path | Notes | | ------------------------ | ------------------------------------------------- | | `.devin/rules/*.md` | One rule per file. Supports `trigger` frontmatter | | `.devin/global_rules.md` | Single always-on file | These files use the same frontmatter as `.windsurf/rules/*.md`, so the `trigger` values `always_on`, `manual`, `model_decision`, `agent`, and `glob` all apply. `.devin/` is the preferred location and takes precedence over `.windsurf/`. If both `.devin/global_rules.md` and `.windsurf/global_rules.md` exist, Devin CLI loads only `.devin/global_rules.md`. Rule files in `.devin/rules/` and `.windsurf/rules/` are both loaded. Like other project rules, these directories are read at the workspace root and in each directory between the workspace root and your current directory. You can also place them in your home directory (`~/.devin/rules/*.md`, `~/.devin/global_rules.md`) to apply them to every project. *** ## Rules From Other Tools If you're coming from another AI coding tool, Devin CLI can read your existing rules: Devin CLI reads from `.cursor/rules/*.md` and `.cursor/rules/*.mdc`. Cursor rules support frontmatter to control activation: ```markdown theme={null} --- description: "React component guidelines" globs: "src/components/**/*.tsx" alwaysApply: false --- Use functional components with hooks. Never use class components. ``` **Activation behavior:** * `alwaysApply: true` — Always active * `globs` specified — Active when working with matching files * `description` only — Agent decides when to apply * None of the above — User must invoke manually Devin CLI reads from `.windsurf/rules/*.md` and `.windsurf/global_rules.md`. The Devin-native [`.devin/` equivalents](#rules-in-the-devin-directory) take precedence. **Subdirectory support:** `.windsurf/rules/` directories can exist at multiple levels in your project, not just the root. Rules at the workspace root are loaded at session start. Rules in subdirectories are discovered lazily — when the agent accesses files in that directory, any `.windsurf/rules/` found there (and in parent directories up to the workspace root) are automatically loaded. This avoids polluting the agent's context with rules from unrelated parts of the project. Windsurf rules support frontmatter: ```markdown theme={null} --- description: "API design rules" trigger: always_on --- All API endpoints must return JSON with a consistent envelope format. ``` **Trigger values:** `always_on`, `manual`, `model_decision`, `agent`, `glob` Devin CLI reads from the `.claude/` directory. Devin CLI does not support `.codeiumignore` files. If you use Codeium's autocomplete and have configured ignore patterns, those patterns will not apply to Devin CLI. *** ## Controlling Imports You can enable or disable reading from specific tool formats in your config file (`~/.config/devin/config.json` — or `%APPDATA%\devin\config.json` on Windows — or `.devin/config.json`): ```json theme={null} { "read_config_from": { "agents_standard": true, "cursor": true, "windsurf": true, "claude": true } } ``` Standard project rules from `AGENTS.md`, `AGENTS.local.md`, `AGENT.md`, and `.windsurfrules` are read by default. Set `"agents_standard": false` to disable importing them. *** ## Rule Activation Types Rules loaded from external formats may have different activation behaviors: | Type | Behavior | | ------------------ | ----------------------------------------------------------------- | | **Always-on** | Active in every session, no user action needed | | **Glob-activated** | Active when the agent works with files matching specific patterns | | **Agent-decided** | The agent chooses when to apply based on the rule's description | | **User-invocable** | Only active when explicitly triggered by the user | Rules from `AGENTS.md` are always "always-on". *** ## Best Practices Long, verbose rules dilute the agent's attention. Focus on what matters most. "Use pnpm" is better than "use the right package manager". Concrete instructions are easier to follow. Show the pattern you want, not just a description of it. Keep rules in your repo so the whole team benefits from the same guidelines. For most common types of rules, consider using skills instead. Skills give you more control over when and how they're applied. # Creating Skills Source: https://docs.devin.ai/cli/extensibility/skills/creating-skills Full reference for the SKILL.md format and frontmatter options Skills are defined as `SKILL.md` files inside a named directory. This page covers everything you need to know to write effective skills. *** ## File Structure Place skills in the appropriate directory depending on scope: ``` # Project-specific (committed to git) .devin/skills/ └── my-skill/ └── SKILL.md # Global — available in all projects (not committed) # Linux/macOS: ~/.config/devin/skills/ └── my-skill/ └── SKILL.md # Windows: %APPDATA%\devin\skills\ └── my-skill\ └── SKILL.md ``` The directory name is the skill's identifier (used for `/my-skill` invocation). The `SKILL.md` file contains optional YAML frontmatter and the skill's prompt content. On Windows, `%APPDATA%` typically resolves to `C:\Users\\AppData\Roaming`. *** ## Frontmatter Reference ```yaml theme={null} --- name: my-skill description: What this skill does (shown in completions) argument-hint: "[file] [options]" model: sonnet subagent: true allowed-tools: - read - grep - glob - exec permissions: allow: - Read(src/**) deny: - exec ask: - Write(**) triggers: - user - model --- Your prompt content goes here... ``` ### All Frontmatter Fields | Field | Type | Default | Description | | --------------- | ------- | --------------- | ------------------------------------------------------------------------------------------------------- | | `name` | string | directory name | Display name of the skill | | `description` | string | none | Shown in slash command completions | | `argument-hint` | string | none | Hint shown after the command name (e.g., `[filename]`) | | `model` | string | current model | Override the model used when running this skill | | `subagent` | boolean | `false` | Run the skill as a [subagent](/cli/subagents) instead of inline | | `agent` | string | none | Run the skill as a subagent using a specific [custom subagent](/cli/subagents#custom-subagents) profile | | `allowed-tools` | list | all tools | Restrict which tools the skill can use | | `permissions` | object | inherit | Permission overrides for this skill | | `triggers` | list | `[user, model]` | How the skill can be invoked | *** ## Model Override Use the `model` field to run a skill with a different model than the one active in the current session. This is useful for using a faster model for simple tasks or a more capable model for complex ones: ```yaml theme={null} --- name: quick-fix description: Fast lint fix using a lightweight model model: swe --- Fix the lint errors in the current file. ``` The model name uses the same values as the `--model` CLI flag (e.g., `opus`, `sonnet`, `swe`, `codex`). See [Models](/cli/models) for the full list. *** ## Running Skills as Subagents Running skills as subagents is **experimental**. The `subagent` and `agent` frontmatter fields may change in future releases. By default, a skill's prompt is injected into the current conversation — the agent processes it inline. You can instead run a skill as a **subagent**, which spawns an independent worker with its own context window. This is useful for skills that perform focused, self-contained tasks where you don't want the output to clutter the main conversation. There are two ways to run a skill as a subagent: ### `subagent: true` Set `subagent: true` to run the skill as a subagent using the default `subagent_general` profile: ```yaml theme={null} --- name: deep-research description: Thorough codebase research on a topic subagent: true model: sonnet allowed-tools: - read - grep - glob --- Research the topic the user asked about thoroughly. Search broadly, follow references, and trace call chains. Report all findings with specific file paths and line numbers. ``` When invoked, this skill spawns a foreground subagent that runs the skill's prompt as its task. The parent agent waits for the subagent to complete, then reads and summarizes the results. ### `agent: ` Use the `agent` field to run the skill as a subagent with a specific [custom subagent profile](/cli/subagents#custom-subagents): ```yaml theme={null} --- name: review-pr description: Review the current PR using the reviewer subagent agent: reviewer --- Review the staged changes for correctness, security, and style issues. ``` The `agent` value must match the name of a registered subagent profile (either built-in like `subagent_explore` / `subagent_general`, or a custom profile you've defined). The subagent inherits the profile's system prompt, tool restrictions, and model — while the skill's content becomes the task. If both `agent` and `subagent` are set, `agent` takes precedence. The `model` field on the skill overrides the subagent profile's model when both are specified. Skills running as subagents do not spawn nested subagents — if the skill is already executing inside a subagent, it runs inline instead to prevent infinite recursion. ### Orchestrating Subagents Using Skills Because skills can run as subagents, you can use them to orchestrate multi-step work. Define a set of subagent skills that each handle a focused task, then write a regular skill that invokes them. The outer skill becomes the orchestrator — it calls each subagent, collects the results, and decides what to do next. For example, here are two subagent skills and an orchestrator that coordinates them: ```markdown theme={null} --- name: research-changes description: Research recent code changes and their impact subagent: true allowed-tools: - read - grep - glob - exec --- Analyze the recent changes in this repository: 1. Run `git log --oneline -20` to see recent commits 2. For each significant commit, examine what changed and why 3. Identify any patterns, risks, or areas that need attention Report your findings with specific file paths and commit references. ``` ```markdown theme={null} --- name: validate-tests description: Run tests and validate coverage for recent changes subagent: true allowed-tools: - read - grep - glob - exec --- Validate the test suite for the project: 1. Identify the test framework and run command 2. Run the full test suite 3. Check for any failing tests 4. Review test coverage for recently changed files Report which tests pass, which fail, and any coverage gaps. ``` ```markdown theme={null} --- name: health-check description: Full project health check — research changes then validate tests --- Perform a full health check on this project: 1. First, use the /research-changes skill to understand recent changes 2. Then, use the /validate-tests skill to verify the test suite 3. Finally, synthesize the findings from both into a summary: - What changed recently and why - Whether tests are passing - Any risks or recommended actions ``` Invoking `/health-check` runs the orchestrator in the main agent. It calls `/research-changes`, which spawns a subagent to explore the repo. Once that finishes, it calls `/validate-tests`, which spawns another subagent to run the tests. The orchestrator then synthesizes both results into a final summary. A subagent skill will **never** use a subagent when calling other skills, even if those skills have `subagent: true` — they run inline instead. This means you don't need to worry about unbounded nesting. The orchestration pattern is always one level deep: the orchestrator spawns subagents, and those subagents execute everything else inline. *** ## Prompt Content The body of the SKILL.md file (after the frontmatter) is the prompt that gets injected when the skill is invoked. *** ## Permissions Skills can define their own permission scope using the same syntax as the main permissions config: ```yaml theme={null} permissions: allow: - Read(src/**) - Exec(npm run test) deny: - Write(/etc/**) - exec ask: - Write(src/**) ``` **How skill permissions work:** * `allow` — These scopes are auto-approved during skill execution * `deny` — These scopes are blocked during skill execution * `ask` — These scopes always prompt the user Skill permissions are additive to (not replacing) the session's base permissions. A skill cannot grant permissions that are denied at a higher level (project or organization config). *** ## Allowed Tools Restrict which tools the skill can use: ```yaml theme={null} allowed-tools: - read - grep - glob ``` Available tool names: `read`, `edit`, `grep`, `glob`, `exec` You can also allow MCP tools: ```yaml theme={null} allowed-tools: - read - mcp__github__list_issues - mcp__github__create_issue ``` If `allowed-tools` is not specified, the skill has access to all tools. For safety-critical skills, always restrict to the minimum needed. *** ## Examples ### Code Review Skill ```markdown theme={null} --- name: review description: Review staged changes for issues allowed-tools: - read - grep - glob - exec permissions: allow: - Exec(git diff) - Exec(git log) --- Run `git diff --staged` and review the changes for quality issues. Evaluate: 1. **Correctness** — Any logic errors or edge cases? 2. **Security** — Any vulnerabilities introduced? 3. **Performance** — Any obvious inefficiencies? 4. **Style** — Consistent with the codebase? Provide a summary with specific line references. ``` ### Component Generator ```markdown theme={null} --- name: component description: Generate a React component from a description argument-hint: "" allowed-tools: - read - edit - grep - glob model: sonnet permissions: allow: - Write(src/components/**) --- Create a new React component using the name the user provides: 1. Check existing components in src/components/ for style conventions 2. Create the component file at src/components//.tsx 3. Create a barrel export at src/components//index.ts 4. Add basic tests at src/components//.test.tsx 5. Follow the patterns you find in existing components ``` ### Deployment Checklist ```markdown theme={null} --- name: deploy description: Run through the deployment checklist triggers: - user allowed-tools: - read - exec - grep permissions: allow: - Exec(npm run) - Exec(git) --- Run through the deployment checklist: 1. Run the test suite: `npm run test` 2. Run the linter: `npm run lint` 3. Check for uncommitted changes: `git status` 4. Verify the build: `npm run build` 5. Show the current branch and last commit Report the status of each step. If anything fails, stop and explain the issue. ``` ### Search Expert ```markdown theme={null} --- name: find description: Find relevant code across the project argument-hint: "" allowed-tools: - read - grep - glob triggers: - user - model --- Search the codebase thoroughly for what the user asked about. Use grep for content search and glob for file discovery. Provide relevant file paths and code snippets. Explain how the pieces connect. ``` *** ## Tips A skill should do one thing well. Create multiple skills rather than one mega-skill. Show the agent what good output looks like in your prompt. Restricting tools makes skills safer and more predictable. Invoke your skill and iterate on the prompt until the output is what you want. # Skills Overview Source: https://docs.devin.ai/cli/extensibility/skills/overview Create reusable prompts and workflows that extend the agent's capabilities Skills are self-contained units of functionality that you can teach to Devin CLI. They bundle prompts, tool access, permissions, and workflows into a reusable package that can be invoked by either the agent or the human operator. *** ## What Are Skills? Think of skills as expert knowledge you give the agent. A skill might teach it how to: * Review code according to your team's standards * Generate a specific type of component * Run a deployment workflow * Perform a security audit * Set up a new service from a template Users can invoke skills with `/skill-name` in the chat. The agent can invoke skills on its own when relevant. Skills can have their own permission grants and restrictions. Restrict which tools a skill can use for safety. Run skills as independent [subagents](/cli/subagents) with their own context window. Use a different [model](/cli/models) for specific skills. *** ## Quick Example Create a code review skill at `.devin/skills/review/SKILL.md` (or `.windsurf/skills/review/SKILL.md`): ```markdown theme={null} --- name: review description: Review code changes before committing allowed-tools: - read - grep - glob - exec --- Review the current git diff and provide feedback: 1. Run `git diff --staged` (or `git diff` if nothing is staged) 2. Check for: - Logic errors or bugs - Missing error handling - Security issues - Style inconsistencies 3. Summarize findings and suggest improvements ``` Now you can invoke it with `/review` in any session. *** ## How Skills Work When a skill is invoked: 1. The skill's prompt is injected into the conversation 2. Tool access is restricted to the skill's `allowed-tools` (if specified) 3. Additional permissions from the skill's config are applied 4. The specified model is used (if different from the current one) *** ## Skill Triggers Skills can be invoked in two ways: | Trigger | Description | Default | | ------- | ------------------------------------------- | ------- | | `user` | User can invoke with `/skill-name` | Enabled | | `model` | Agent can invoke autonomously when relevant | Enabled | ```yaml theme={null} --- name: security-check triggers: - user - model --- ``` Set `triggers: [user]` to prevent the agent from invoking a skill on its own. *** ## Third-party Skills We support the `.agents` skills standards, so third-party skill installation tools work with Devin CLI. Third-party skills can execute arbitrary code, so install them at your own risk. *** ## Where Skills Live Skills can be scoped to a single project or shared across all projects: | Location | Scope | Committed to git? | | --------------------------------------------- | ---------------------------------------- | ----------------- | | `.agents/skills//SKILL.md` | Project-specific | Yes | | `.devin/skills//SKILL.md` | Project-specific | Yes | | `.windsurf/skills//SKILL.md` | Project-specific | Yes | | `~/.agents/skills//SKILL.md` | Global (all projects) | No | | `~/.config/devin/skills//SKILL.md` | Global (all projects) | No | | `~/.codeium//skills//SKILL.md` | Global (all projects, channel-dependent) | No | **Project skills** live in the `.devin/skills/` or `.windsurf/skills/` directory at your project root and are committed to version control, making them shareable with your team. Both locations use the same `SKILL.md` format. **Global skills** live in `~/.config/devin/skills/` (following [XDG conventions](https://specifications.freedesktop.org/basedir-spec/latest/)) or `~/.codeium//skills/` (where `` is `windsurf`, `windsurf-next`, or `windsurf-insiders` depending on your CLI channel) and are available in every project on your machine. **Windows:** The global skills path follows your system's application data directory. On Windows, use `%APPDATA%\devin\skills\\SKILL.md` (typically `C:\Users\\AppData\Roaming\devin\skills\\SKILL.md`) instead of `~/.config/devin/skills/`. *** ## Next Steps Learn the full skill format including frontmatter options, dynamic content, and examples. Bundle skills into a plugin you can install and share across projects. # Hand off to cloud Devins Source: https://docs.devin.ai/cli/handoff Hand off a task from the Devin CLI to a cloud Devin session with /handoff. When a task outgrows your local machine — or you want Devin to keep working while you step away — use the built-in `/handoff` command to transfer the current session to a cloud [Devin session](/get-started/first-run). The cloud session gets its own VM with a shell, browser, and full repo access, so it can keep going after you close your laptop. ``` /handoff fix the flaky integration tests in CI ``` The Devin CLI packages up the conversation context and your current git branch, then creates a cloud session that picks up where you left off. Track its progress from your terminal or in the [Devin web app](https://app.devin.ai). Run `/handoff` without a task description and the cloud session continues from where you left off automatically. ## When to hand off Hand a task off when it needs more than your local terminal, or when you want it to run in the background: * **VM or server** — running a dev server, hitting endpoints, Docker builds * **Browser** — screenshots, OAuth flows, end-to-end tests, scraping * **CI/CD** — pipeline debugging, deployments, infrastructure changes * **Long-running work** — migrations, batch jobs, large refactors * **Parallel execution** — offload work to the cloud while you keep coding locally ## What carries over The cloud session starts in a fresh VM, so the CLI includes everything it needs to pick up the thread: * **Repo and branch** — so the cloud session clones the right repo and checks out the branch you're on. * **Conversation context** — what you and Devin have been working on in the current session. * **Uncommitted changes** — your work-in-progress diff carries over. Commit or stash anything you don't want sent. Not using the Devin CLI? You can hand off from Claude Code, Codex, Cursor, or any coding agent — and from plain shell scripts — with the open-source [Devin Handoff](https://github.com/club-cog/devin-handoff) plugin. See [Hand off to Devin](/work-with-devin/devin-handoff) for setup and usage across every agent. ## Related resources Hand off from any coding agent, not just the Devin CLI Source, install guides, and the full script reference # Quickstart Source: https://docs.devin.ai/cli/index Get up and running in 2 minutes with Devin CLI, a local command-line coding agent with deep Devin Cloud integration. ```bash theme={null} curl -fsSL https://cli.devin.ai/install.sh | bash ``` On macOS, install Devin CLI with [Homebrew](https://brew.sh): ```bash theme={null} brew install --cask devin-cli ``` To upgrade to the latest version later, run: ```bash theme={null} brew upgrade --cask devin-cli ``` Download and run the installer: * [x86\_64 (most Windows PCs)](https://static.devin.ai/cli/devin-updater-x86_64-pc-windows.exe) * [ARM64 (Windows on ARM)](https://static.devin.ai/cli/devin-updater-aarch64-pc-windows.exe) Alternatively, open **PowerShell** and run: ```powershell theme={null} irm https://static.devin.ai/cli/setup.ps1 | iex ``` `irm` and `iex` are PowerShell commands. Do not run this in Git Bash or CMD — it will fail with "command not found". Use PowerShell for installation only. After installing, you can use Devin CLI from **PowerShell**, **Windows Terminal**, or **Git Bash**. Devin CLI is bundled with **Devin Desktop**. This installation method is available for **Legacy Windsurf Enterprise** and **Devin Enterprise** plans. **Admin setup:** For the Devin Desktop-bundled install, an admin must first enable the install option in Devin CLI team settings by toggling on **Show "Install Devin CLI" in the Devin Desktop Command Palette**. **User installation:** 1. Open Devin Desktop 2. Open the Command Palette with Cmd+Shift+P (macOS) or Ctrl+Shift+P (Windows/Linux) 3. Search for and run **Install Devin CLI** This adds the `devin` binary to your PATH so you can use it from any terminal. That's it! After you restart your terminal, enter a project directory and type `devin` to activate Devin CLI. Also try preloading the session with a prompt for automation: ```bash theme={null} devin -- check out this code and suggest a feasible, helpful feature ``` You're ready to go. For must-know tips, see [Essential Commands](/cli/essential-commands). ## What's next? Devin CLI can implement new features, fix bugs, review code, answer questions, automate tasks, and more. Must-know commands and slash commands Choose the right model for your task Connect MCP servers and skills Explore all commands and flags *** ## Devin CLI vs. Devin Devin CLI and [Devin](/get-started/devin-intro) are separate tools designed for different workflows. **Devin CLI** is a local coding agent that runs directly in your terminal. It works with your local files and environment, giving you fast, interactive assistance right where you code. **Devin** is our cloud-based AI software engineer that runs in a virtual machine. It includes features like Playbooks, Secrets, Knowledge, and other capabilities that are not available in Devin CLI. Devin CLI does not yet support Knowledge, Playbooks, or Secrets from your Devin account. We're actively working on adding support for each of these and plan to roll them out soon. Devin CLI overview # Models Source: https://docs.devin.ai/cli/models Available models and how to configure them Devin CLI supports multiple AI models. You can choose the best model for your task to optimize for maximum capability, speed, or cost efficiency. For most users, we recommend **Adaptive** — our intelligent model router that automatically selects the best model for each task, delivering the right level of intelligence for every prompt. *** ## Available Models Models release frequently. We typically support the latest and greatest models from **Anthropic**, **OpenAI**, **Google**, and **Cognition** within minutes of their launch. We also support a number of **leading open source models** like **DeepSeek**, **Kimi**, and **GLM**. To stay up-to-date on model releases, consider following the [**Cognition** X account](http://x.com/cognition). Short names like `opus`, `sonnet`, `swe`, `codex`, and `gemini` always resolve to the latest version in that model family. ### Reasoning / Thinking Levels Some models support configurable reasoning levels, which control how much compute the model spends "thinking" before responding. You can cycle the thinking level with `Alt+T` (macOS: `Opt+T`) during a session. *** ## Setting the Model ```bash theme={null} devin --model opus -- refactor this module devin --model sonnet -- explain this code ``` Switch models during a session: ```text theme={null} /model opus /model sonnet /model codex ``` Run `/model` with no argument to open the model selector. Set a default in `~/.config/devin/config.json` (on Windows, `%APPDATA%\devin\config.json`): ```json theme={null} { "agent": { "model": "swe-1-6-fast" } } ``` *** ## Model Selection Tips The correct choice of language model varies wildly from person-to-person and task-to-task. Many engineers working on the same project are convinced that their model is the best for the task, despite using different models. The fact of the matter is, AI can perform differently depending on your personal usage and writing style! **As such, we strongly recommend trying multiple models to see which one you prefer.** At minimum we recommend trying `swe`, `gpt`, and `opus`. We find that the vast majority of use-cases can be covered by these three. Use `opus` or `gpt` for multi-file refactors, architecture changes, and tasks requiring deep reasoning. Use `swe` (fast) for straightforward edits, bug fixes, and questions. It's both fast and cheap at a reasonable level of intelligence. Enterprise teams can restrict which models are available through [Team Settings](/cli/enterprise/team-settings). # Sandbox Source: https://docs.devin.ai/cli/sandbox OS-level isolation for Devin CLI sessions: how the sandbox works, network filtering, and enterprise enforcement. The `--sandbox` flag runs the CLI with OS-level isolation, enforcing writable paths and `deny` rules at the operating-system level and optionally restricting network traffic. ## How the sandbox works When the sandbox is active: * **Writable paths** are derived from granted `Write(...)` permission scopes plus the workspace directory; everything else is read-only * **Readable paths** are everything except paths covered by `Read(...)` rules in the `deny` list, which are hidden from sandboxed commands entirely * `Write(...)` scopes granted mid-session dynamically expand the sandbox for subsequent commands. Mid-session `Read(...)` approvals affect only the agent's own tools — they cannot reveal a path hidden by a `Read(...)` deny rule, which stays hidden for the whole session If sandbox resolution fails (e.g., the sandboxing tools are unavailable on the user's platform), the CLI will **refuse to start** rather than running unsandboxed. This fail-closed behavior applies whether sandbox was enabled by a [team setting](/cli/enterprise/team-settings#sandbox-enforcement) or by the user passing `--sandbox` directly, ensuring the security intent is never silently bypassed. Common causes of sandbox resolution failure: * **Windows**: OS-level sandboxing is not currently supported on Windows. Sessions on Windows will hard-fail when `--sandbox` is passed or when sandbox enforcement is **Required**, including when the CLI runs as an ACP server inside an IDE (e.g., Devin Desktop). * **Linux**: Sandboxing requires `bubblewrap` (`bwrap`) and `socat` to be installed. Sessions hard-fail with installation instructions when these are missing. * **Permission scope errors**: Invalid paths in permission scopes that can't be resolved. ## Network filtering Sandbox network filtering is currently unstable. If you need this feature, please reach out to your account representative for stability timelines. Configure domain-level network filtering for the sandbox in the [`sandbox` section of your config file](/cli/reference/configuration/config-file#sandbox) (user config only). When `--sandbox` is active and domain filtering is configured, a managed network proxy starts on loopback and the sandbox restricts all child traffic to route through it. | Option | Type | Default | Description | | ----------------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------- | | `allowed_domains` | string\[] | `[]` | Domain patterns allowed through the proxy. When non-empty, only matching domains are allowed (allowlist mode) | | `denied_domains` | string\[] | `[]` | Domain patterns always blocked. Deny rules take precedence over allow rules | | `network_mode` | string | `"full"` | `"full"` allows all HTTP methods; `"limited"` allows only GET/HEAD/OPTIONS | **Domain pattern syntax:** | Pattern | Matches | | ---------------- | ----------------------------- | | `example.com` | Exact match only | | `*.example.com` | Any subdomain (not the apex) | | `**.example.com` | Apex domain and any subdomain | **Example:** ```json theme={null} { "sandbox": { "allowed_domains": [ "github.com", "**.npmjs.org", "**.crates.io", "**.pypi.org" ], "denied_domains": ["evil.example.com"], "network_mode": "full" } } ``` Domain filtering applies when the sandbox is active (`--sandbox`). Without `--sandbox`, the sandbox section is ignored. ## Excluded commands Sometimes a specific command needs to run *outside* the sandbox — for example `git` commands that must access credentials or hooks the sandbox blocks. The `sandbox.excluded` config section lets you exclude matching commands from sandbox isolation using the same `Exec(...)` rule syntax as [permissions](/cli/reference/permissions): | Option | Type | Description | | ---------------- | --------- | -------------------------------------------------------------------------- | | `excluded.allow` | string\[] | Matching commands run outside the sandbox automatically | | `excluded.ask` | string\[] | Matching commands run outside the sandbox after the user approves a prompt | | `excluded.deny` | string\[] | Matching commands are never excluded — they always stay inside the sandbox | **Example:** ```json theme={null} { "sandbox": { "excluded": { "allow": ["Exec(git status *)"], "ask": ["Exec(git push *)"], "deny": ["Exec(git tag *)"] } } } ``` **Rule resolution:** for each command, the most specific matching rule wins within a source (e.g., `Exec(git push *)` beats `Exec(git *)`), and when both user config and [team settings](#enterprise-excluded-commands) match, the more restrictive verdict wins (`deny` > `ask` > `allow`). Commands with no matching rule — including when `sandbox.excluded` is not configured at all — always run inside the sandbox. * Only `Exec(...)` rules are supported in `sandbox.excluded`; any other rule type (e.g., `Read(...)`, `Write(...)`) is ignored with a warning. * Exclusion is fail-closed: if a command can't be safely resolved (e.g., it can't be parsed), it stays inside the sandbox. * Exclusions apply to the default per-command exec path. Commands run through a persistent PTY shell (interactive sessions, or when `pty_for_noninteractive_exec` is enabled) always stay inside the sandbox. ## Enterprise enforcement Enterprise admins can control sandbox behavior for their entire organization via [Team Settings](/cli/enterprise/team-settings#sandbox-enforcement). ### Sandbox enforcement mode Set the enforcement level for the `--sandbox` flag across your organization: * **Optional** (default) — Users choose whether to pass `--sandbox`. No enforcement. * **Required** — The `--sandbox` flag is forced on for all users, even if they don't pass it on the command line. All CLI sessions run with OS-level file system sandboxing that enforces writable paths and `Read(...)` deny rules. A future **Strict** mode may lock down sandbox configuration entirely, preventing users from modifying sandbox settings. Ensure all target machines are provisioned before setting sandbox enforcement mode to **Required** across your organization. If any users are on Windows, they will be unable to run the CLI until OS-level sandboxing is supported on Windows or the policy is relaxed to **Optional**. ### Enterprise domain filtering Admins can also configure organization-wide domain allowlists and denylists: * **Domain allowlist** — When set, **only** the domains in this list are reachable through the sandbox network proxy. This list is **authoritative**: it completely replaces any user-configured `allowed_domains`. Users cannot add additional domains to bypass admin restrictions. * **Domain denylist** — Domains that are always blocked. Enterprise denied domains are **additive**: they are merged with the user's local `denied_domains`, making the combined list more restrictive. **How enterprise and user domain lists interact:** | Scenario | Enterprise config | User config | Effective result | | -------------------- | --------------------------------- | --------------------------------- | ------------------------------------------------------------ | | Admin sets allowlist | `allowed_domains: ["github.com"]` | `allowed_domains: ["npmjs.org"]` | Only `github.com` is allowed (enterprise replaces user list) | | Admin sets denylist | `denied_domains: ["evil.com"]` | `denied_domains: ["risky.io"]` | Both `evil.com` and `risky.io` are blocked (merged) | | No admin allowlist | `allowed_domains: []` | `allowed_domains: ["github.com"]` | User's allowlist is used | Because the user's local `denied_domains` are preserved and merged additively, a user could deny a domain that appears in the enterprise allowlist. This is intentional: the combined effect is always more restrictive, never less. If this causes access issues, the user should remove the conflicting entry from their local config. ### Enterprise excluded commands Admins can also set organization-wide [excluded command](#excluded-commands) rules in team settings: * **Excluded allow / ask** — `Exec(...)` rules for commands that may run outside the sandbox across the organization, automatically or after a prompt. * **Excluded deny** — `Exec(...)` rules for commands that must never run outside the sandbox. A team `deny` overrides any user-level `allow` or `ask` for matching commands, so users cannot exclude commands their admins have locked down. Team and user rules are resolved together: the most specific matching rule wins within each source, and the more restrictive verdict wins across sources (`deny` > `ask` > `allow`). **Example: lock down all exclusions except `gh`.** A wildcard `deny` with an `allow` carve-out keeps every command inside the sandbox except `gh`, regardless of what users configure locally. These values go into the team-settings excluded-commands configuration (not the user config file, so there is no enclosing `sandbox` key): ```json theme={null} { "excluded": { "deny": ["Exec(**)"], "allow": ["Exec(gh *)"] } } ``` Because the more specific `Exec(gh *)` rule beats the wildcard `Exec(**)`, `gh` commands run outside the sandbox while everything else stays inside — and the team-level wildcard `deny` overrides any user-level `allow` or `ask` rules for other commands. ## Further reading * [Team Settings](/cli/enterprise/team-settings#sandbox-enforcement) — enterprise sandbox enforcement and domain filtering * [Config file reference](/cli/reference/configuration/config-file#sandbox) — the user-level `sandbox` config section * [Permissions](/cli/reference/permissions) — permission scopes that drive sandbox writable paths and deny rules # Shell Integration [Feature Preview] Source: https://docs.devin.ai/cli/shell-integration Wrap your shell with Devin to invoke it instantly and give Devin visibility into your recent commands. Shell integration is a **Feature Preview**. It is available on macOS, Linux, and WSL with Bash, Zsh, and Fish. Shell integration is not yet supported on Windows (PowerShell or CMD). You can still run Devin CLI on Windows — this feature just isn't available there yet. It is feature complete but may interact poorly with other shell functionality. If you run into something incompatible please let us know! Shell integration wraps your existing shell session so that Devin runs alongside it. Once set up, you can: * Hit **Ctrl+G** (configurable) anywhere in your shell to invoke Devin with your current command line as context * Type `# ` and press Enter to pass it straight to Devin (Zsh only) * Give Devin automatic visibility into your recent shell commands and their output We strongly recommend using `zsh` over `bash` or `fish` for best support. *** ## Setup Run the setup command to install shell integration into your shell config file: ```bash theme={null} devin shell setup ``` This adds managed blocks to your shell rc file (`~/.bashrc`, `~/.zshrc`, or `~/.config/fish/config.fish`). Then restart your terminal or source the config: ```bash theme={null} source ~/.bashrc ``` ```bash theme={null} source ~/.zshrc ``` ```fish theme={null} source ~/.config/fish/config.fish ``` You can also target a specific shell explicitly: ```bash theme={null} devin shell setup bash devin shell setup zsh devin shell setup fish ``` Shell integration is separate from the `devin setup` wizard. Running `devin setup` does **not** install shell integration — you must run `devin shell setup` separately. *** ## Features