WorkflowsMCP

Meeting notes → Linear tasks

Turn Notion meeting notes into Linear issues, then confirm them in Slack.

@workflowsmcpMar 19, 2026Verified Aug 2026meetingsaction-itemsai-extractionproject-managementautomation

Action items decided in a meeting evaporate unless someone files them the same day. This workflow watches a Notion "Meeting Notes" database for pages marked Ready, extracts the action items with owners and due dates, creates one Linear issue each, writes the issue links back into the note, and posts a confirmation in Slack so the room can catch a misread item within the hour.

How it flows

  1. 01

    Note marked "Ready to process"

    A human flips the Status select once the notes are actually finished.

  2. 02

    Poller picks it up within 10 minutes

    Filtered database query returns pages that are ready and recent.

  3. 03

    Action items extracted

    Owner, verb phrase and any stated due date. Items without a clear owner are flagged rather than assigned.

  4. 04

    One Linear issue per item

    issueCreate with team, assignee, label and the meeting-note backlink.

  5. 05

    Note updated with issue links

    Status → Processed. This write is the idempotency guard for the whole workflow.

  6. 06

    Slack confirmation posted

    One message listing the filed issues so the room can correct a misread item.

Set up each app

Work through these in order — later apps usually need a token or an id from an earlier one.

Notion

Source of the notes and the processed-state flag

  1. 01

    Set up the "Meeting Notes" database

    Properties: Name (Title), Date (Date), Attendees (Person), Status (Select: Draft / Ready to process / Processed), Linear Issues (Text), Team (Select). "Ready to process" is set by a human — never auto-process a Draft, or you will file half-written thoughts as tickets.

  2. 02

    Poll for ready notes every 10 minutes

    Retrieve the database once to get its data source id, then POST /v1/data_sources/{data_source_id}/query with the filter below and Notion-Version: 2026-03-11 — the version header is mandatory on every Notion request. The older /v1/databases/{database_id}/query is deprecated as of 2025-09-03 and now only answers if you pin a pre-split version and the database has exactly one data source. Polling is the simplest thing that works; if you want sub-poll latency, subscribe to the page.properties_updated webhook, which fires on the Status change itself (events are aggregated and usually land inside a minute).

    Data source query filter
    {
      "filter": {
        "and": [
          { "property": "Status", "select": { "equals": "Ready to process" } },
          { "property": "Date", "date": { "past_week": {} } }
        ]
      },
      "sorts": [{ "property": "Date", "direction": "descending" }],
      "page_size": 25
    }
  3. 03

    Write the results back

    After the issues exist, PATCH the page: set Status to "Processed" and put the issue identifiers in Linear Issues. That write is the idempotency guard — if it fails, the next poll re-processes the note, so do it last and check the response.

Linear

Receives one issue per action item

  1. 01

    Create a personal API key

    Linear → Settings → Security & access → Personal API keys → New API key (linear.app/settings/account/security). Send it as the raw Authorization header value (no "Bearer " prefix — that is the single most common 400 here; Bearer is for OAuth tokens).

  2. 02

    Look up team and state ids

    Everything in the Linear GraphQL API is addressed by id. Run this once and store the ids you need in config.

    Teams and workflow states
    query Bootstrap {
      teams {
        nodes {
          id
          key
          name
          states { nodes { id name type } }
        }
      }
    }
  3. 03

    Create the issue

    One mutation per action item. Put the meeting page URL in the description so the ticket carries its own context — use the url the Notion API returned for that page rather than hand-building a notion.so link, which now only survives as a redirect — and set dueDate only when the note actually stated one.

    issueCreate mutation + variables
    mutation CreateIssue($input: IssueCreateInput!) {
      issueCreate(input: $input) {
        success
        issue { id identifier url }
      }
    }
    
    # variables
    {
      "input": {
        "teamId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
        "title": "Cut the onboarding email from 5 steps to 3",
        "description": "From [Growth sync — 2026-01-28](https://app.notion.com/p/2f91c4a70b8d4e5f9a1c3b6d8e0f2a4b)",
        "assigneeId": "9f8e7d6c-5b4a-4392-8172-6f5e4d3c2b1a",
        "labelIds": ["c7d8e9f0-1a2b-4c3d-9e8f-7a6b5c4d3e2f"],
        "dueDate": "2026-02-04",
        "priority": 2
      }
    }

Slack

Confirmation so mistakes get caught fast

  1. 01

    Add an incoming webhook

    api.slack.com/apps → your app → Incoming Webhooks → Activate → Add New Webhook to Workspace → pick the team channel. Store the URL as a secret; anyone holding it can post as your app.

  2. 02

    Post the created issues as a list

    Keep it to one message per meeting, not one per issue, or the channel becomes unusable after a busy Monday. The owner names below are plain text labels, not pings — to actually notify someone you need their Slack member id and the <@U01ABCDEF> form, which means keeping a Linear-user-to-Slack-member map.

    Slack Block Kit payload
    {
      "text": "3 action items filed from Growth sync",
      "blocks": [
        { "type": "section",
          "text": { "type": "mrkdwn", "text": "*Growth sync — 28 Jan* → 3 issues in Linear" } },
        { "type": "section",
          "text": { "type": "mrkdwn",
            "text": "• <https://linear.app/acme/issue/GRW-412|GRW-412> Cut onboarding email to 3 steps — @dana\n• <https://linear.app/acme/issue/GRW-413|GRW-413> Pricing page A/B test — @sam\n• <https://linear.app/acme/issue/GRW-414|GRW-414> Churn survey copy — @rae" } },
        { "type": "context",
          "elements": [{ "type": "mrkdwn", "text": "Wrong owner or a hallucinated item? Edit in Linear — the note stays untouched." }] }
      ]
    }