> **Building with AI coding agents?** Install the authstack plugin with one command. This equips your agent with accurate Scalekit implementation patterns.
>
> **Recommended** (the `-y` flags skip prompts, so the command runs without an interactive terminal):
> ```bash
> npx -y @scalekit-inc/cli setup -y
> ```
>
> Global:
> ```bash
> npm install -g @scalekit-inc/cli
> scalekit setup -y
> ```
>
> Supports Claude Code, Cursor, GitHub Copilot, Codex + skills for other Agent Skills-compatible agents in `~/.agents/skills`.
> Skills: integrate-agentkit, implement-saaskit, add-mcp-oauth, implement-sso, implement-scim.
> [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Connect AI agents to the Devin MCP server

The Devin MCP connector routes your AI agent's tool calls to Devin's own MCP server through Scalekit. Each user connects their own Devin access token once, and Scalekit sends it with every call, so your agent never handles credentials. It comes with 19 tools.

**Authentication:** Bearer Token
**Categories:** Developer Tools, AI, Automation
**Tools:** 19: 0 read, 19 write, 0 destructive
**Users sign in with:** Access token
**Built by:** Vendor MCP
**Try it:** [Playground in the Scalekit dashboard](https://app.scalekit.com/ws/signup?sk_intent=playground&provider=DEVINMCP)

## Setup

1. ### Install the SDK

   **Node.js**

   ```bash
   npm install @scalekit-sdk/node dotenv
   ```

   **Python**

   ```bash
   pip install scalekit-sdk-python python-dotenv
   ```

2. ### Set your credentials

   Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**.

   ```sh title=".env"
   SCALEKIT_ENVIRONMENT_URL=<your-environment-url>
   SCALEKIT_CLIENT_ID=<your-client-id>
   SCALEKIT_CLIENT_SECRET=<your-client-secret>
   ```

3. ### Create the Devin MCP connection

   In **AgentKit > Connections**, create a Devin MCP connection. The name you give it is the `connection_name` your code passes. See [Configure connections](/agentkit/connections/).

   **Console steps with screenshots:**

   Register your Devin API key with Scalekit so it stores it securely and injects it into every request. Devin uses API key authentication.

   1. ### Get your Devin API key

      - Sign in to [Devin](https://app.devin.ai) and go to **Settings** → **Devin API**.
      - Click the **API keys (legacy)** tab.
      - Under **Personal API key**, click **View key** to reveal your key, or expand the dropdown to regenerate it.

      > Image: Devin Settings → Devin API page showing the Personal API key with a View key button

      > caution: Keep your key private
      >
      > Devin API keys are tied to your account and have full access. Store the key in a secrets manager and never hard-code it in your source code. Use [Devin Secrets](https://app.devin.ai/settings/secrets) to give Devin access to third-party credentials instead.

   2. ### Create a connection in Scalekit

      - In [Scalekit dashboard](https://app.scalekit.com), go to **AgentKit** → **Connections** → **Create Connection**. Find **Devin MCP** and click **Create**.
      - Note the **Connection name** — you will use this as `connection_name` in your code (e.g., `devinmcp`).
      - Click **Save**.

   3. ### Add a connected account

      Connected accounts link a specific user identifier in your system to their Devin API key. Add one in the dashboard to test. In production, each user adds their own through the authorization link: they enter their credentials on the page it opens.

      **In the dashboard, to test**

      - Open the connection you created and click the **Connected Accounts** tab → **Add account**.
      - Fill in:
        - **Your User's ID** — a unique identifier for this user in your system (e.g., `user_123`)
        - **API Key** — the Devin API key from step 1
      - Click **Create Account**.

      **From your backend, if your app already has the credentials**

      For example, when users enter them on a settings page in your app:

        **Node.js**

        ```typescript
        import { Scalekit, ConnectorStatus } from '@scalekit-sdk/node';

        const scalekit = new Scalekit(
          process.env.SCALEKIT_ENVIRONMENT_URL,
          process.env.SCALEKIT_CLIENT_ID,
          process.env.SCALEKIT_CLIENT_SECRET,
        );

        // Never hard-code credentials — read from secure storage or user input
        const devinApiKey = getUserDevinApiKey(); // retrieve from your secure store

        const authorizationDetails = {
          details: {
            case: 'staticAuth',
            value: {
              details: {
                token: devinApiKey,
              },
            },
          },
        };

        let { connectedAccount } = await scalekit.actions.upsertConnectedAccount({
          connectionName: 'devinmcp',
          identifier: 'user_123',
          authorizationDetails,
        });

        // Make sure the account is ACTIVE before the first tool call.
        if (connectedAccount?.status !== ConnectorStatus.ACTIVE) {
          ({ connectedAccount } = await scalekit.actions.upsertConnectedAccount({
            connectionName: 'devinmcp',
            identifier: 'user_123',
            authorizationDetails,
          }));
        }
        ```

        **Python**

        ```python
        import os
        from scalekit import ScalekitClient

        scalekit_client = ScalekitClient(
            env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"],
            client_id=os.environ["SCALEKIT_CLIENT_ID"],
            client_secret=os.environ["SCALEKIT_CLIENT_SECRET"],
        )

        # Never hard-code credentials — read from secure storage or user input
        devin_api_key = get_user_devin_api_key()  # retrieve from your secure store

        authorization_details = {"static_auth": {"token": devin_api_key}}

        response = scalekit_client.actions.upsert_connected_account(
            connection_name="devinmcp",
            identifier="user_123",
            authorization_details=authorization_details,
        )

        # Make sure the account is ACTIVE before the first tool call.
        if response.connected_account.status != "ACTIVE":
            response = scalekit_client.actions.upsert_connected_account(
                connection_name="devinmcp",
                identifier="user_123",
                authorization_details=authorization_details,
            )
        ```

4. ### Authorize a user and make your first call

   **Node.js** (`quickstart.mts`)

   ```typescript
   import { ScalekitClient } from '@scalekit-sdk/node'
   import 'dotenv/config'
   import { createInterface } from 'node:readline/promises'

   const scalekit = new ScalekitClient(
     process.env.SCALEKIT_ENVIRONMENT_URL,
     process.env.SCALEKIT_CLIENT_ID,
     process.env.SCALEKIT_CLIENT_SECRET,
   )
   const actions = scalekit.actions

   const connector = 'devinmcp'
   const identifier = 'user_123'

   // Generate an authorization link for the user
   const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
   console.log('Authorize Devin MCP:', link)
   const rl = createInterface({ input: process.stdin, output: process.stdout })
   await rl.question('Press Enter after authorizing...')
   rl.close()

   // Make your first call
   const result = await actions.executeTool({
     connector,
     identifier,
     toolName: 'devinmcp_devin_session_search',
     toolInput: {},
   })
   console.log(result)
   ```

   ```bash
   npx tsx quickstart.mts
   ```

   **Python** (`quickstart.py`)

   ```python
   import os
   from scalekit import ScalekitClient
   from dotenv import load_dotenv
   load_dotenv()

   scalekit_client = ScalekitClient(
       env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"),
       client_id=os.getenv("SCALEKIT_CLIENT_ID"),
       client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
   )
   actions = scalekit_client.actions

   connection_name = "devinmcp"
   identifier = "user_123"

   # Generate an authorization link for the user
   link_response = actions.get_authorization_link(
       connection_name=connection_name,
       identifier=identifier,
   )
   print("Authorize Devin MCP:", link_response.link)
   input("Press Enter after authorizing...")

   # Make your first call
   result = actions.execute_tool(
       tool_input={},
       tool_name="devinmcp_devin_session_search",
       connection_name=connection_name,
       identifier=identifier,
   )
   print(result)
   ```

   ```bash
   python quickstart.py
   ```

   Each user opens the link once and enters their Devin MCP server credentials there. If your app already has a user's credentials, add the account from your backend instead, as the console steps above show. See [Authorize a user](/agentkit/tools/authorize/) for the full flow and statuses.

## Tools

Pass the exact name to `execute_tool`, with an input like each tool's example. To ask for a tool that's missing, use the [request form](https://scalekitsupport.portal.usepylon.com/forms/request-a-connector-tool).

**Node.js**

```typescript
const result = await actions.executeTool({
  toolName: 'devinmcp_ask_question',
  toolInput: {
    question: '<question>',
    repoName: '<repoName>',
  },
  connector: 'devinmcp',
  identifier: 'user_123',
})
```

**Python**

```python
result = actions.execute_tool(
    tool_name="devinmcp_ask_question",
    tool_input={
        "question": "<question>",
        "repoName": "<repoName>",
    },
    connection_name="devinmcp",
    identifier="user_123",
)
```

`result.data` is the app's response as JSON, and `result.execution_id` (`executionId` in Node.js) is the ID of the call.

### `devinmcp_ask_question`

Ask Question · Write

Ask any question about a GitHub repository and get an AI-powered, context-grounded response.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `question` (`string`, required): No description.
- `repoName` (`string`, required): No description.

Example input: `{"question":"<question>","repoName":"<repoName>"}`

### `devinmcp_devin_automation_manage`

Devin Automation Manage · Write

Manage Devin automations that run Devin in response to events (GitHub, Slack, Linear, schedules, webhooks) — list, get, create, update, delete, or run them.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `action` (`string`, required): No description. One of: `list`, `get`, `schemas`, `templates`, `create`, `validate_create`, `update`, `validate_update`, `delete`, `run`.
- `actions` (`string`, optional): No description.
- `after` (`string`, optional): No description.
- `agent_types` (`string`, optional): No description.
- `automation_id` (`string`, optional): No description.
- `concurrency` (`string`, optional): No description.
- `creator_id` (`string`, optional): No description.
- `enabled` (`string`, optional): No description.
- `event_data` (`string`, optional): No description.
- `event_type` (`string`, optional): No description.
- `first` (`string`, optional): No description.
- `limits` (`string`, optional): No description.
- `metadata` (`string`, optional): No description.
- `name` (`string`, optional): No description.
- `notifications` (`string`, optional): No description.
- `prompt` (`string`, optional): No description.
- `run_as` (`string`, optional): No description.
- `search` (`string`, optional): No description.
- `security_profile` (`string`, optional): No description.
- `session_settings` (`string`, optional): No description.
- `template_id` (`string`, optional): No description.
- `tools` (`string`, optional): No description.
- `triggers` (`string`, optional): No description.

Example input: `{"action":"list"}`

### `devinmcp_devin_code_scan_manage`

Devin Code Scan Manage · Write

Manage Devin code scans and scan profiles — list scans and findings, manage profiles, create scans, or remediate findings.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `action` (`string`, required): No description. One of: `list_scans`, `list_findings`, `list_profiles`, `get_profile`, `create_profile`, `update_profile`, `create_scan`, `remediate_finding`.
- `after` (`string`, optional): No description.
- `communication_guidance` (`string`, optional): No description.
- `description` (`string`, optional): No description.
- `exclude_globs` (`string`, optional): No description.
- `finding_id` (`string`, optional): No description.
- `first` (`string`, optional): No description.
- `host` (`string`, optional): No description.
- `include_globs` (`string`, optional): No description.
- `ingestion_source_guidance` (`string`, optional): No description.
- `investigation_guidance` (`string`, optional): No description.
- `mode` (`string`, optional): No description.
- `post_ingestion_guidance` (`string`, optional): No description.
- `profile_id` (`string`, optional): No description.
- `profile_name` (`string`, optional): No description.
- `remediation_guidance` (`string`, optional): No description.
- `repo_name` (`string`, optional): No description.
- `report_guidance` (`string`, optional): No description.
- `scan_id` (`string`, optional): No description.
- `scan_type` (`string`, optional): No description.
- `severity` (`string`, optional): No description.
- `status` (`string`, optional): No description.
- `threat_model_guidance` (`string`, optional): No description.
- `time_after` (`string`, optional): No description.
- `time_before` (`string`, optional): No description.
- `triage_guidance` (`string`, optional): No description.
- `validation_guidance` (`string`, optional): No description.

Example input: `{"action":"list_scans"}`

### `devinmcp_devin_knowledge_manage`

Devin Knowledge Manage · Write

Manage Devin knowledge notes and suggestions — list, get, create, or update entries.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `action` (`string`, required): No description. One of: `list`, `get`, `create`, `update`, `delete`, `folders`, `list_suggestions`, `view_suggestion`, `dismiss_suggestions`.
- `after` (`string`, optional): No description.
- `body` (`string`, optional): No description.
- `content` (`string`, optional): No description.
- `event_id` (`string`, optional): No description.
- `event_ids` (`string`, optional): No description.
- `first` (`string`, optional): No description.
- `folder_path` (`string`, optional): No description.
- `limit` (`string`, optional): No description.
- `name` (`string`, optional): No description.
- `note_id` (`string`, optional): No description.
- `offset` (`string`, optional): No description.
- `pinned_repo` (`string`, optional): No description.
- `query` (`string`, optional): No description.
- `search` (`string`, optional): No description.
- `since_days` (`string`, optional): No description.
- `status` (`string`, optional): No description.
- `trigger` (`string`, optional): No description.

Example input: `{"action":"list"}`

### `devinmcp_devin_oncall_manage`

Devin Oncall Manage · Write

View a Devin Oncall report's current responder membership, or a responder's open issues.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `action` (`string`, required): No description. One of: `report_context`, `responder_issues`.
- `after` (`string`, optional): No description.
- `first` (`string`, optional): No description.
- `order_by` (`string`, optional): No description.
- `report_id` (`string`, optional): No description.
- `responder_id` (`string`, optional): No description.

Example input: `{"action":"report_context"}`

### `devinmcp_devin_playbook_manage`

Devin Playbook Manage · Write

Manage Devin playbooks — list, get, create, or update playbook entries.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `action` (`string`, required): No description. One of: `list`, `get`, `create`, `update`, `delete`.
- `after` (`string`, optional): No description.
- `body` (`string`, optional): No description.
- `content` (`string`, optional): No description.
- `first` (`string`, optional): No description.
- `macro` (`string`, optional): No description.
- `playbook_id` (`string`, optional): No description.
- `structured_output_schema` (`string`, optional): No description.
- `title` (`string`, optional): No description.

Example input: `{"action":"list"}`

### `devinmcp_devin_review_manage`

Devin Review Manage · Write

Trigger a Devin Review for a pull/merge request, or fetch its latest review status.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `action` (`string`, required): No description. One of: `trigger`, `get_status`.
- `pr_url` (`string`, required): No description.
- `commit_sha` (`string`, optional): No description.

Example input: `{"action":"trigger","pr_url":"<pr_url>"}`

### `devinmcp_devin_schedule_manage`

Devin Schedule Manage · Write

Manage scheduled Devin sessions — list, get, create, update, or delete schedules.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `action` (`string`, required): No description. One of: `list`, `get`, `create`, `update`, `delete`.
- `agent` (`string`, optional): No description.
- `bypass_approval` (`string`, optional): No description.
- `enabled` (`string`, optional): No description.
- `frequency` (`string`, optional): No description.
- `limit` (`string`, optional): No description.
- `name` (`string`, optional): No description.
- `notify_on` (`string`, optional): No description.
- `offset` (`string`, optional): No description.
- `platform` (`string`, optional): No description.
- `playbook_id` (`string`, optional): No description.
- `prompt` (`string`, optional): No description.
- `schedule_id` (`string`, optional): No description.
- `schedule_type` (`string`, optional): No description.
- `scheduled_at` (`string`, optional): No description.
- `target_devin_id` (`string`, optional): No description.

Example input: `{"action":"list"}`

### `devinmcp_devin_session_create`

Devin Session Create · Write

Create one or more child Devin sessions via the REST API.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `sessions` (`array`, required): No description.
- `devin_mode` (`string`, optional): No description.
- `platform` (`string`, optional): No description.
- `repos` (`string`, optional): No description.
- `structured_output_schema` (`string`, optional): No description.

Example input: `{"sessions":[]}`

### `devinmcp_devin_session_events`

Devin Session Events · Write

Inspect events within a Devin session — list summaries, fetch full details, or search.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `action` (`string`, required): No description. One of: `list`, `details`, `search`.
- `session_id` (`string`, required): No description.
- `after` (`string`, optional): No description.
- `categories` (`string`, optional): No description.
- `created_after` (`string`, optional): No description.
- `created_before` (`string`, optional): No description.
- `direction` (`string`, optional): No description.
- `event_ids` (`string`, optional): No description.
- `event_types` (`string`, optional): No description.
- `first` (`string`, optional): No description.
- `limit` (`string`, optional): No description.
- `max_content_length` (`string`, optional): No description.
- `offset` (`string`, optional): No description.
- `query` (`string`, optional): No description.

Example input: `{"action":"list","session_id":"<session_id>"}`

### `devinmcp_devin_session_gather`

Devin Session Gather · Write

Wait for multiple Devin sessions to reach a settled state before returning.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `session_ids` (`array`, required): No description.
- `poll_interval_seconds` (`integer`, optional): No description. Default: `30`.
- `timeout_seconds` (`integer`, optional): No description. Default: `300`.

Example input: `{"session_ids":[]}`

### `devinmcp_devin_session_interact`

Devin Session Interact · Write

Interact with a Devin session — get status, send a message, sleep, or terminate.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `action` (`string`, required): No description. One of: `get`, `message`, `sleep`, `terminate`, `archive`, `unarchive`, `get_messages`, `get_attachments`, `set_tags`.
- `session_id` (`string`, required): No description.
- `after` (`string`, optional): No description.
- `archive_on_terminate` (`boolean`, optional): No description. Default: `false`.
- `attachment_urls` (`string`, optional): No description.
- `first` (`string`, optional): No description.
- `message` (`string`, optional): No description.
- `tags` (`string`, optional): No description.

Example input: `{"action":"get","session_id":"<session_id>"}`

### `devinmcp_devin_session_search`

Devin Session Search · Write

Search and filter Devin sessions by date, tags, playbook, schedule, or user.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `after` (`string`, optional): No description.
- `created_after` (`string`, optional): No description.
- `created_before` (`string`, optional): No description.
- `first` (`string`, optional): No description.
- `origins` (`string`, optional): No description.
- `parent_session_id` (`string`, optional): No description.
- `playbook_id` (`string`, optional): No description.
- `schedule_id` (`string`, optional): No description.
- `session_ids` (`string`, optional): No description.
- `tags` (`string`, optional): No description.
- `updated_after` (`string`, optional): No description.
- `updated_before` (`string`, optional): No description.
- `user_ids` (`string`, optional): No description.

Example input: `{}`

### `devinmcp_find_setting`

Find Setting · Write

Find a Devin webapp setting and get a deep-link URL to it.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `query` (`string`, optional): No description.

Example input: `{}`

### `devinmcp_generate_wiki`

Generate Wiki · Write

Generate a codebase wiki for a repository and wait for it to complete.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `repoName` (`string`, required): No description.

Example input: `{"repoName":"<repoName>"}`

### `devinmcp_list_available_repos`

List Available Repos · Write

List all repositories available to query with your Devin account.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs: none.

Example input: `{}`

### `devinmcp_list_integrations`

List Integrations · Write

List all native integrations and MCP servers for the organization with status and settings.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `filter` (`string`, optional): No description. One of: `all`, `installed`, `not_installed`. Default: `all`.

Example input: `{}`

### `devinmcp_read_wiki_contents`

Read Wiki Contents · Write

View documentation content for a GitHub repository.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `repoName` (`string`, required): No description.

Example input: `{"repoName":"<repoName>"}`

### `devinmcp_read_wiki_structure`

Read Wiki Structure · Write

Get a list of documentation topics for a GitHub repository.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `repoName` (`string`, required): No description.

Example input: `{"repoName":"<repoName>"}`

## Related

Other Developer Tools connectors ([all 94](/agentkit/connectors/?category=developer-tools)):

- [GitHub](/agentkit/connectors/github/): Scalekit connector, OAuth, 217 tools
- [Datadog](/agentkit/connectors/datadog/): Scalekit connector, API key, 105 tools
- [Linear](/agentkit/connectors/linear/): Scalekit connector, OAuth, 62 tools


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
