Skip to content
Scalekit Docs
Talk to an Engineer Dashboard

Connect AI agents to Miro

Scalekit connector
Open markdown

The Miro connector lets your AI agent act in each user's Miro account. Each user signs in to Miro once, and Scalekit stores and refreshes their tokens, so your agent never handles credentials. It comes with 115 tools.

Tools
115
What they doRead · write · destructive
48 · 45 · 2248 read45 write22 destructive
Users sign in with
OAuth app
Your own Miro app

What you can do

  • Manage boards: create, copy, update, and delete boards, and share them with members
  • Add board content: create and edit sticky notes, shapes, text, cards, frames, images, and connectors
  • Read board items: list and fetch everything on a board, including tags and grouped items
  • Build mind maps: add, read, and remove mind map nodes on a board
  • Organize teams and projects: create teams and projects, invite members, and update their settings
  • Export boards: start board export jobs and fetch the finished results

Setup

  1. Install the SDK

    Terminal window
    npm install @scalekit-sdk/node dotenv
  2. Set your credentials

    Add your Scalekit credentials to your .env file. Find values in app.scalekit.com > Developers > API Credentials.

    .env
    SCALEKIT_ENVIRONMENT_URL=<your-environment-url>
    SCALEKIT_CLIENT_ID=<your-client-id>
    SCALEKIT_CLIENT_SECRET=<your-client-secret>
  3. Create the Miro connection

    In AgentKit > Connections, create a Miro connection and copy its redirect URI. The name you give it is the connection_name your code passes. See Configure connections.

  4. Register an OAuth app

    Miro connections use your own OAuth app. Register one with Miro and add the redirect URI you copied.

    Then enter the app's Client ID and Client Secret on the Miro connection.

    Console steps with screenshots

    Register your Scalekit environment with the Miro connector so Scalekit handles the OAuth flow and token lifecycle for your users. Follow every step below from start to finish — by the end you will have a working connection.

    1. Create a Miro app

      You need a Miro OAuth app to get the Client ID and Client Secret that Scalekit will use to authorize your users.

      Go to the Miro Developer Portal:

      Create a new app:

      • Click Create New App (top right of the page).

      • Fill in the form:

        FieldWhat to enter
        App NameA recognizable name, e.g. My AI Collaboration Agent
        App DescriptionBrief description, e.g. AI agent for managing Miro boards
        Homepage URLYour app’s public URL. For testing you can use https://localhost
        Grant TypeSelect Authorization Code — this is required for OAuth 2.0
      • Leave Redirect URIs blank for now. You will add it in the next step.

      • Click Create App.

      After the app is created, Miro takes you to the app’s OAuth Settings page. Keep this tab open.

      Create a new OAuth app in Miro Developer Portal

    2. Copy the redirect URI from Scalekit

      Scalekit gives you a callback URL that Miro will redirect users back to after they authorize your app. You need to register this URL in your Miro app.

      In the Scalekit dashboard:

      • Go to app.scalekit.com and sign in.
      • In the left sidebar, click AgentKit.
      • Click Create Connection.
      • Search for Miro and click Create.
      • A connection details panel opens. Find the Redirect URI field — it looks like:
        https://<YOUR_ENV>.scalekit.cloud/sso/v1/oauth/conn_<ID>/callback
      • Click the copy icon next to the Redirect URI to copy it to your clipboard.

      Copy the redirect URI from Scalekit dashboard

    3. Register the redirect URI and copy credentials

      Switch back to the Miro Developer Portal tab.

      • Make sure you are on the OAuth Settings page of your app.
      • Scroll to the Redirect URIs section.
      • Paste the redirect URI you copied from Scalekit into the input box and click Add URI.
      • Click Save Changes at the bottom of the page.

      Copy your credentials:

      • Scroll to OAuth Credentials at the top of the page.
      • Client ID — shown in plain text. Click Copy ID to copy it.
      • Client Secret — click Reveal to show the secret, then copy it.

      Keep both values in a password manager or secrets vault. You will enter them into Scalekit in the next step.

      Miro OAuth credentials page showing Client ID, Client Secret, and Redirect URIs

    4. Configure permissions (scopes)

      Scopes control which Miro resources your app can access on behalf of each user. You select the scopes in Scalekit when saving your credentials.

      ScopeAccess grantedPlan required
      boards:readRead boards, members, and all board itemsAll plans
      boards:writeCreate, update, and delete boards, members, and itemsAll plans
      identity:readRead current user profile including emailAll plans
      team:readRead current team informationAll plans
      auditlogs:readRead audit logs for the organizationEnterprise only
      organizations:readRead organization informationEnterprise only
      organizations:teams:readRead teams within an organizationEnterprise only
      organizations:teams:writeCreate and manage teams within an organizationEnterprise only
      projects:readRead projects within teamsEnterprise only
      projects:writeCreate and manage projects within teamsEnterprise only

      For most integrations, boards:read and boards:write are sufficient.

    5. Add credentials in Scalekit

      Switch back to the Scalekit dashboard tab.

      • Go to AgentKit > Connections and open the Miro connection you created in step 2.

      • Fill in the credentials form:

        FieldValue
        Client IDPaste the Client ID from step 3
        Client SecretPaste the Client Secret from step 3
        PermissionsEnter the scopes your app needs, e.g. boards:read boards:write
      • Click Save.

      Add credentials in Scalekit dashboard

      Your Miro connection is now configured. Scalekit will use these credentials to run the OAuth flow whenever a user connects their Miro account.

  5. Authorize a user and make your first call

    quickstart.mts
    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 = 'miro'
    const identifier = 'user_123'
    // Generate an authorization link for the user
    const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
    console.log('Authorize Miro:', 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: 'miro_boards_list',
    toolInput: {},
    })
    console.log(result)
    Terminal window
    npx tsx quickstart.mts

    Each user signs in once. See Authorize a user for the full flow and statuses.

Tools

Pass the exact name to execute_tool
Try in PlaygroundRequest a tool
  • miro_app_card_getRetrieves an app card item from a Miro board.Read-only

    Get App Card

    Retrieves an app card item from a Miro board.

    Inputs

    board_idstringrequired
    Unique identifier of the board.
    item_idstringrequired
    Unique identifier of the item.
  • miro_audit_logs_getRetrieves audit logs for the organization (Enterprise only).Read-only

    Get Audit Logs

    Retrieves audit logs for the organization (Enterprise only). Returns events for the specified date range (max 90 days).

    Inputs

    created_afterstringrequired
    Start of date range in ISO 8601.
    created_beforestringrequired
    End of date range in ISO 8601.
    cursorstring
    Pagination cursor.
    limitinteger
    Max results per page (1-100).
    sortingstring
    Sort order: asc | desc.
  • miro_board_export_job_getGets the status of a board export job (Enterprise only).Read-only

    Get Board Export Job Status

    Gets the status of a board export job (Enterprise only).

    Inputs

    job_idstringrequired
    Export job ID.
    org_idstringrequired
    Organization ID.
  • miro_board_export_job_results_getRetrieves the results/download URLs of a completed board export job (Enterprise only).Read-only

    Get Board Export Job Results

    Retrieves the results/download URLs of a completed board export job (Enterprise only).

    Inputs

    job_idstringrequired
    Export job ID.
    org_idstringrequired
    Organization ID.
  • miro_board_export_jobs_listLists all board export jobs for an organization (Enterprise only).Read-only

    List Board Export Jobs

    Lists all board export jobs for an organization (Enterprise only).

    Inputs

    org_idstringrequired
    Organization ID.
    cursorstring
    Pagination cursor.
    limitinteger
    Max results.
  • miro_board_getRetrieves details of a specific Miro board by its ID.Read-only

    Get Board

    Retrieves details of a specific Miro board by its ID.

    Inputs

    board_idstringrequired
    Unique identifier of the Miro board.
  • miro_board_member_getRetrieves details of a specific member on a Miro board.Read-only

    Get Board Member

    Retrieves details of a specific member on a Miro board.

    Inputs

    board_idstringrequired
    Unique identifier of the board.
    member_idstringrequired
    Unique identifier of the board member.
  • miro_board_members_listReturns a list of members on a Miro board.Read-only

    List Board Members

    Returns a list of members on a Miro board.

    Inputs

    board_idstringrequired
    Unique identifier of the board.

Workflows

Proxy API call
// Example: list boards
const boards = await actions.request({
connectionName: 'miro',
identifier: 'user_123',
path: '/v2/boards',
method: 'GET',
});
console.log('Boards:', boards);
// Example: create a sticky note on a board
const stickyNote = await actions.request({
connectionName: 'miro',
identifier: 'user_123',
path: '/v2/boards/YOUR_BOARD_ID/sticky_notes',
method: 'POST',
body: {
data: { content: 'Hello from my AI agent!' },
style: { fillColor: 'yellow' },
},
});
console.log('Sticky note created:', stickyNote);
Execute a tool
const result = await actions.executeTool({
connector: 'miro',
identifier: 'user_123',
toolName: 'miro_app_card_create',
toolInput: {},
});
console.log(result);