> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devinenterprise.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create PRs After Every Call

export const UseCaseHero = ({title, description, prompt, category, features, devinUrl, agent, intent, playbookId, type}) => {
  const encodedPrompt = encodeURIComponent(prompt || '');
  const tag = 'docs-use-case-gallery';
  const utm = 'utm_source=docs&utm_medium=use-case-gallery&utm_campaign=hero-cta';
  const agentParams = (agent ? '&agent=' + agent : '') + (intent ? '&intent=' + intent : '') + (playbookId ? '&playbookId=' + playbookId : '');
  const devinHref = type === 'schedule' ? 'https://app.devin.ai/settings/schedules/create?' + utm + agentParams + (prompt ? '&prompt=' + encodedPrompt : '') : type === 'review' ? 'https://app.devin.ai/review?' + utm : agent === 'ada' ? 'https://app.devin.ai/search?' + utm + '&noSubmit=true' + (prompt ? '&prompt=' + encodedPrompt : '') : devinUrl ? devinUrl.includes('?') ? devinUrl + '&' + utm + agentParams : devinUrl + '?' + utm + agentParams : prompt ? 'https://app.devin.ai/?tags=' + tag + '&' + utm + agentParams + '&prompt=' + encodedPrompt : 'https://app.devin.ai/?' + utm + agentParams;
  const buttonLabel = type === 'schedule' ? 'Schedule in Devin ↗' : type === 'review' ? 'Set Up Devin Review ↗' : agent === 'advanced' ? 'Try in Devin ↗' : agent === 'dana' ? 'Try in Dana ↗' : agent === 'ada' ? 'Try in Ask Devin ↗' : 'Try in Devin ↗';
  const featureList = features ? features.split(',').map(f => f.trim()) : [];
  return <div className="uc-hero">
      <div className="uc-hero-inner">
        <div className="uc-hero-left">
          <h1 className="uc-hero-title">{title}</h1>
          <p className="uc-hero-desc">{description}</p>
          <div>
            <a href={devinHref} target="_blank" rel="noopener noreferrer" className="try-in-devin-btn">
              {buttonLabel}
            </a>
          </div>
        </div>
        <div className="uc-hero-meta">
          <div className="uc-meta-item">
            <span className="uc-meta-label">Author</span>
            <span className="uc-meta-value">Cognition</span>
          </div>
          <div className="uc-meta-item">
            <span className="uc-meta-label">Category</span>
            <span className="uc-meta-value">{category}</span>
          </div>
          {featureList.length > 0 && <div className="uc-meta-item">
              <span className="uc-meta-label">Features</span>
              <span className="uc-meta-value">{featureList.join(', ')}</span>
            </div>}
        </div>
      </div>
    </div>;
};

export const PromptBlock = ({children, type, agent, intent, playbookId}) => {
  var utm = 'utm_source=docs&utm_medium=use-case-gallery&utm_campaign=prompt-block';
  var tag = 'docs-use-case-gallery';
  var agentParams = (agent ? '&agent=' + agent : '') + (intent ? '&intent=' + intent : '') + (playbookId ? '&playbookId=' + playbookId : '');
  var label = type === 'schedule' ? 'Schedule in Devin' : type === 'playbook' ? 'Create Playbook' : type === 'knowledge' ? 'Add to Knowledge' : agent === 'advanced' ? 'Try in Devin' : agent === 'dana' ? 'Try in Dana' : agent === 'ada' ? 'Try in Ask Devin' : 'Try in Devin';
  var buildUrl = function (text) {
    var encoded = encodeURIComponent(text);
    if (type === 'schedule') return 'https://app.devin.ai/settings/schedules/create?' + utm + agentParams + '&prompt=' + encoded;
    if (type === 'playbook') return 'https://app.devin.ai/settings/playbooks/create?' + utm + '&body=' + encoded;
    if (type === 'knowledge') return 'https://app.devin.ai/knowledge?' + utm + '&body=' + encoded;
    if (agent === 'ada') return 'https://app.devin.ai/search?' + utm + '&noSubmit=true&prompt=' + encoded;
    return 'https://app.devin.ai/?tags=' + tag + '&' + utm + agentParams + '&prompt=' + encoded;
  };
  const ref = React.useRef(null);
  const [href, setHref] = React.useState('#');
  React.useEffect(() => {
    if (!ref.current) return;
    var codeEl = ref.current.querySelector('pre code');
    if (codeEl) {
      var text = codeEl.textContent.trim();
      if (text) setHref(buildUrl(text));
    }
    var header = ref.current.querySelector('[data-component-part="code-block-header"]');
    if (header && !header.querySelector('.prompt-block-devin-link')) {
      var link = document.createElement('a');
      link.href = href;
      link.target = '_blank';
      link.rel = 'noopener noreferrer';
      link.className = 'prompt-block-devin-link';
      link.style.cssText = 'display:inline-flex;align-items:center;gap:6px;text-decoration:none;color:#fff;font-size:11px;font-weight:500;padding:4px 10px;border-radius:6px;white-space:nowrap;background:#317CFF;transition:background 0.2s;margin-left:8px;';
      link.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg> ' + label;
      link.onmouseenter = function () {
        link.style.background = '#2968D9';
      };
      link.onmouseleave = function () {
        link.style.background = '#317CFF';
      };
      header.appendChild(link);
    }
    var existingLink = ref.current.querySelector('.prompt-block-devin-link');
    if (existingLink && href !== '#') existingLink.href = href;
  });
  return <div className="prompt-block" ref={ref}>{children}</div>;
};

<UseCaseHero title="Create PRs After Every Call" description="An hourly Devin schedule polls Granola for new meetings, extracts engineering tasks from transcripts, and kicks off child sessions to write PRs." prompt="Set up an hourly Devin schedule that polls Granola for new meetings via the Granola MCP server. For each meeting with a ready transcript, extract engineering tasks and start child Devin sessions to open PRs. Use a Knowledge note to log processed meetings." category="Automations" features="Schedules, MCP, Playbooks, Advanced" type="schedule" agent="devin" />

<div className="uc-detail-wrapper">
  <Tip>Don't want to set this up manually? Paste a link to this page into a Devin session and ask it to set everything up for you.</Tip>

  Granola records your meetings and turns them into notes, summaries, and transcripts. Once you connect the Granola MCP, Devin can use those meeting artifacts the same way a teammate would: read what was discussed, find concrete engineering follow-ups, and start work.

  Run this as an hourly schedule and tasks can start right when you get off a call. The whole loop runs inside your Devin instance, using a schedule, the Granola MCP, Knowledge, and child sessions.

  ```
  Devin scheduled session (hourly)
    → List recent Granola meetings via MCP
    → For each new meeting (oldest-to-newest):
        → Fetch metadata, notes, AI summary, transcript
        → Identify engineering tasks from the discussion
        → Start child Devin sessions for concrete tasks
        → Log the processed meeting in Knowledge
  ```

  <Steps>
    <Step title="Connect the Granola MCP">
      Devin needs access to your Granola meetings to read transcripts and notes.

      1. Go to **Settings > Connections > MCP servers** and search for **Granola**
      2. Click **Enable** and authenticate — this grants Devin read access to your meetings, transcripts, and notes
      3. Click **Test listing tools** to verify the connection is working

      Once connected, Devin can call `list_meetings`, `get_meetings`, and `get_meeting_transcript` to pull meeting data during a session. Learn more about [configuring MCP servers](/work-with-devin/mcp).
    </Step>

    <Step title="Create a processed-meetings Knowledge note">
      Devin uses a single [Knowledge](/product-guides/knowledge) note to log which meetings have already been processed. This prevents duplicate processing across hourly runs.

      Go to **Settings > Knowledge** and create a new note:

      * **Name**: `Granola Post-call Processor Meeting Log`
      * **Trigger**: `When running the Granola post-call processor scheduled session, use this note to track meetings that have already been processed.`
      * **Body**:

      ```json Granola Post-call Processor Meeting Log theme={null}
      {
        "last_processed_meeting_id": null,
        "last_processed_meeting_time": null,
        "last_processed_title": null,
        "updated_at": null
      }
      ```

      The scheduled session logs each successfully processed meeting in this note, so the next run picks up where the last one left off.
    </Step>

    <Step title="Write the Post-call Operator playbook">
      Create a [playbook](/product-guides/creating-playbooks) that tells Devin how to process each meeting. Go to [**Settings > Playbooks**](https://app.devin.ai/settings/playbooks/create?utm_source=docs\&utm_medium=use-case-gallery) and create a new playbook:

      <PromptBlock type="playbook">
        ```txt Post-call Operator theme={null}
        Turn a completed Granola meeting into concrete engineering work.
        Read the transcript, identify every actionable code task, and kick
        off Devin child sessions to write PRs. Bias heavily toward action —
        if something can become a PR, start it.

        For each meeting:
        1. Read the transcript, AI summary, and any private notes
        2. Identify every engineering task mentioned or implied:
           - Bug fixes discussed
           - Feature requests with enough detail to spec
           - Refactors or improvements agreed on
           - Research/investigation tasks
           - Documentation updates
           - Infrastructure or DevOps changes
        3. For each task, write a concrete spec:
           - What repo(s) to work in
           - What the change should do
           - Acceptance criteria
           - Key context from the meeting (quote sparingly)
        4. Start a child Devin session for each task concrete enough to
           produce a PR. Include the full spec as the prompt.
        5. For tasks too vague for a PR, list them as recommended actions
           with the missing context noted.
        6. Return a structured summary of sessions started and
           recommendations.

        Do not start sessions for vague ideas. If a task needs
        clarification, list it as a recommendation instead.
        ```
      </PromptBlock>

      Note the playbook ID after saving — you'll reference it in the schedule prompt.
    </Step>

    <Step title="Create the hourly schedule">
      Go to [**Settings > Schedules**](/product-guides/scheduled-sessions) and click **Create schedule**.

      * **Name**: `Granola post-call processor`
      * **Frequency**: Hourly (`0 * * * *`)
      * **Agent**: Devin — this lets Devin spawn child sessions for each task, so fixes run in parallel
      * **Slack channel** (optional): Select a channel so your team gets notified when meetings are processed and PRs are opened
      * **Prompt**:

      <PromptBlock type="schedule" agent="devin">
        ```txt Granola post-call processor theme={null}
        Run the Granola post-call processor.

        Use the Granola MCP server and the Knowledge note named
        "Granola Post-call Processor Meeting Log".

        1. Check the meeting log to find the last processed meeting ID/time.
        2. List Granola meetings from the last 24 hours.
        3. Select meetings newer than the latest meeting in the log. Sort oldest-to-newest.
        4. For each meeting:
           a. Fetch metadata, private notes, and AI summary via MCP
           b. Fetch the full transcript via MCP
           c. If transcript is not available, STOP processing the batch
              here — do not skip ahead. The next run will retry.
           d. Run the Post-call Operator playbook against this meeting
           e. Start child Devin sessions for concrete engineering tasks
           f. Log this processed meeting in the Knowledge note
        5. Post a summary to Slack: meetings processed, sessions started,
           and any meetings skipped due to missing transcripts.

        If there are no new meetings since the latest meeting in the log, exit quietly.
        ```
      </PromptBlock>

      Set **bypass approval** to `true` if you want fully autonomous operation — no manual approvals needed for MCP tools, Knowledge updates, or child session creation.
    </Step>

    <Step title="What a typical run produces">
      Each hour, Devin processes any new meetings and opens targeted PRs. Here's what a real session output looks like:

      ```
      Processed 1 new Granola meeting since the latest meeting log entry:

      Meeting: "Backend API planning" (2026-04-29 2:00 PM)

      Child sessions started (3):
      1. Fix N+1 query in /api/invoices endpoint
         Repo: acme/api-server
         PR: Eager-load invoice line items to fix timeout
         Session: https://app.devin.ai/sessions/abc123

      2. Add rate limiting to webhook endpoints
         Repo: acme/api-server
         PR: Per-key rate limits on /webhooks/*
         Session: https://app.devin.ai/sessions/def456

      3. Update API docs for new billing endpoints
         Repo: acme/docs
         PR: Add billing endpoint reference docs
         Session: https://app.devin.ai/sessions/ghi789

      Recommended actions (1):
      - Investigate auth token refresh flow — mentioned as "sometimes
        flaky" but no specific error or repo identified. Needs more
        context from the team.

      Knowledge meeting log updated to "Backend API planning" (2026-04-29).
      ```

      Each child session runs independently and opens its own PR with the meeting context baked into the description.
    </Step>

    <Step title="Tune and iterate">
      After a few days of runs, review what's working and adjust:

      **Handle transcript delays.** The schedule stops processing when it hits a meeting without a ready transcript — this prevents skipping meetings with delayed processing. If you find transcripts are consistently slow, increase the schedule interval or add a delay buffer to the prompt.

      **Scope by meeting type.** Not every meeting produces engineering work. Add filters to the prompt to skip certain meeting types:

      <PromptBlock agent="advanced">
        ```txt Filter meetings by type theme={null}
        Update the schedule prompt: skip meetings with titles containing
        "1:1", "standup", or "social". Only process meetings that are
        likely to contain engineering discussions — planning sessions,
        bug triage, design reviews, and customer calls.
        ```
      </PromptBlock>

      **Learn from results.** After a couple of weeks, ask Devin to analyze which child sessions produced merged PRs and which were closed without merging. Use that feedback to refine the playbook's task extraction criteria:

      <PromptBlock agent="advanced">
        ```txt Analyze post-call outcomes and update playbook theme={null}
        Look at all child sessions started by the Granola post-call
        processor in the last 2 weeks. For each session, check whether
        the PR was merged or closed.

        Identify patterns — which task types consistently produce
        mergeable PRs, which are too vague, and where the playbook
        needs more context. Then suggest updates to the Post-call
        Operator playbook based on these learnings.
        ```
      </PromptBlock>
    </Step>
  </Steps>
</div>
