Skip to content
Scalekit Docs
Talk to an Engineer Dashboard

Connect AI agents to the Grain MCP server

Vendor MCP
Open markdown

The Grain MCP connector routes your AI agent's tool calls to Grain's own MCP server through Scalekit. Each user signs in to Grain once, and Scalekit stores and refreshes their tokens, so your agent never handles credentials. It comes with 41 tools.

Tools
41
What they doRead · write · destructive
29 · 9 · 329 read9 write3 destructive
Users sign in with
OAuth app
Scalekit's or your own

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 Grain MCP connection

    In AgentKit > Connections, create a Grain MCP connection. The name you give it is the connection_name your code passes. See Configure connections.

    Scalekit credentials are available for Grain, so you don't need to register an OAuth app. To show your own app on the consent screen, use your own credentials instead.

    Use your own OAuth app

    Grain MCP uses Dynamic Client Registration (DCR) — no client ID or secret is required. The only step is creating a connection in Scalekit and authorizing your Grain account.

    1. Create a connection in Scalekit

      • In the Scalekit dashboard, go to AgentKit → Connections → Create Connection.
      • Search for Grain MCP and click Create.
      • Note the Connection name — use this as connection_name in your code (e.g., grainmcp).
    2. Authorize your Grain account

      Generate an authorization link and open it in a browser to complete the Grain OAuth flow.

      The user is redirected to Grain to sign in and grant access. Scalekit stores the token and injects it automatically into every tool call — no further configuration is needed.

  4. 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 = 'grainmcp'
    const identifier = 'user_123'
    // Generate an authorization link for the user
    const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
    console.log('Authorize Grain 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: 'grainmcp_myself',
    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
  • grainmcp_fetch_collectionFetches detailed information about a single Grain collection (also known as a playlist) by ID, including the list of recordings it contains with their URLs.Read-only

    Fetch Collection

    Fetches detailed information about a single Grain collection (also known as a playlist) by ID, including the list of recordings it contains with their URLs.

    Inputs

    collection_idstringrequired
    ID of a collection.
  • grainmcp_fetch_dealFetches information about a single HubSpot deal by ID.Read-only

    Fetch Deal

    Fetches information about a single HubSpot deal by ID. In addition to returning the same data as returned by list_all_deals, this returns data about all the activity that has occurred on the deal.

    Inputs

    deal_idstringrequired
    ID of a deal.
  • grainmcp_fetch_meetingFetches information about a single Grain meeting by ID.Read-only

    Fetch Meeting

    Fetches information about a single Grain meeting by ID. The response format is the same as is returned by list_meetings.

    Inputs

    meeting_idstringrequired
    ID of a meeting.
  • grainmcp_fetch_meeting_action_itemsFetches the action items extracted from a single Grain meeting by ID.Read-only

    Fetch Meeting Action Items

    Fetches the action items extracted from a single Grain meeting by ID. Each action item includes the task description, timestamp, status (pending or completed), the assignee (person_id and name, or null when unassigned), and the due date (or null when not set). `end_timestamp_ms` is null when the action item has no end time. In some cases, older meetings may not have had action items generated for them.

    Inputs

    meeting_idstringrequired
    ID of a meeting.
  • grainmcp_fetch_meeting_coaching_feedbackFetches AI-generated sales coaching feedback and scorecard for a single Grain meeting by ID.Read-only

    Fetch Meeting Coaching Feedback

    Fetches AI-generated sales coaching feedback and scorecard for a single Grain meeting by ID. The response format is the same as is returned by list_coaching_feedback.

    Inputs

    meeting_idstringrequired
    ID of a meeting.
  • grainmcp_fetch_meeting_notesFetches the AI notes payload from a single Grain meeting by ID.Read-only

    Fetch Meeting Notes

    Fetches the AI notes payload from a single Grain meeting by ID. In some cases, older meetings may not have had notes generated for them. In these cases you can use `fetch_meeting_transcript` instead to determine the content of the meeting.

    Inputs

    meeting_idstringrequired
    ID of a meeting.
  • grainmcp_fetch_meeting_transcriptFetches the full transcript of a single Grain meeting by ID.Read-only

    Fetch Meeting Transcript

    Fetches the full transcript of a single Grain meeting by ID. Returns the entire conversation as markdown, which can be large for long meetings.

    Inputs

    meeting_idstringrequired
    ID of a meeting.
  • grainmcp_fetch_projectFetches detailed information about a single Grain project by ID, including the list of recordings it contains with their URLs.Read-only

    Fetch Project

    Fetches detailed information about a single Grain project by ID, including the list of recordings it contains with their URLs.

    Inputs

    project_idstringrequired
    ID of a project.

Workflows

Search meeting transcripts

Use grainmcp_search_in_transcripts to find relevant segments across all meeting recordings using hybrid semantic and keyword search.

const segments = await actions.executeTool({
connector: 'grainmcp',
identifier: 'user_123',
toolName: 'grainmcp_search_in_transcripts',
toolInput: {
search_queries: ['pricing objection', 'competitor mention'],
limit: 10,
},
});
console.log(segments);

Fetch meeting notes and action items

Use grainmcp_fetch_meeting_notes and grainmcp_fetch_meeting_action_items to retrieve AI-generated notes and extracted action items for a specific meeting.

// Fetch AI notes
const notes = await actions.executeTool({
connector: 'grainmcp',
identifier: 'user_123',
toolName: 'grainmcp_fetch_meeting_notes',
toolInput: { meeting_id: 'meeting_abc123' },
});
// Fetch action items
const actions_result = await actions.executeTool({
connector: 'grainmcp',
identifier: 'user_123',
toolName: 'grainmcp_fetch_meeting_action_items',
toolInput: { meeting_id: 'meeting_abc123' },
});
console.log(notes, actions_result);

Create a clip and add it to a story

Use grainmcp_create_clip to extract a video segment from a recording, then grainmcp_add_clips_to_story to curate it into a shareable story.

// Step 1 — create a clip
const clip = await actions.executeTool({
connector: 'grainmcp',
identifier: 'user_123',
toolName: 'grainmcp_create_clip',
toolInput: {
meeting_id: 'meeting_abc123',
clip_title: 'Customer feedback on pricing',
start_ms: 300000,
end_ms: 360000,
},
});
const clipId = clip.data?.id;
// Step 2 — add to an existing story
await actions.executeTool({
connector: 'grainmcp',
identifier: 'user_123',
toolName: 'grainmcp_add_clips_to_story',
toolInput: {
story_id: 'story_xyz789',
clip_ids: [clipId],
},
});