<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pow</title>
    <description>The latest articles on DEV Community by Pow (@powxenv).</description>
    <link>https://dev.to/powxenv</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F786208%2F9067487e-1b37-4d92-8725-e866132ad8df.jpg</url>
      <title>DEV Community: Pow</title>
      <link>https://dev.to/powxenv</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/powxenv"/>
    <language>en</language>
    <item>
      <title>I built Sotion, an AI social content workflow on top of Notion</title>
      <dc:creator>Pow</dc:creator>
      <pubDate>Sun, 29 Mar 2026 17:47:29 +0000</pubDate>
      <link>https://dev.to/powxenv/i-built-sotion-an-ai-social-content-workflow-on-top-of-notion-1nb6</link>
      <guid>https://dev.to/powxenv/i-built-sotion-an-ai-social-content-workflow-on-top-of-notion-1nb6</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/notion-2026-03-04"&gt;Notion MCP Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;&lt;a href="https://sotion.up.railway.app/" rel="noopener noreferrer"&gt;Sotion&lt;/a&gt;&lt;/strong&gt;, an AI-powered social content assistant that turns a Notion workspace into an operational content system.&lt;/p&gt;

&lt;p&gt;The idea came from a simple problem: a lot of people already keep their best raw material in Notion, whether they are creators, marketers, founders, indie hackers, or small teams. But the moment they want to turn those notes into social posts, the workflow breaks. They jump between docs, AI chat tabs, scheduling tools, and social apps. The content gets rewritten multiple times, context gets lost, and publishing becomes manual again.&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://sotion.noval.me/" rel="noopener noreferrer"&gt;Sotion&lt;/a&gt; to keep that loop in one place.&lt;/p&gt;

&lt;p&gt;I also wanted it to be useful not only for developers or highly technical users, but for anyone who already feels comfortable working in Notion. That is why the product is built around a guided onboarding flow, plain-language chat, and a workspace model that feels familiar instead of technical. Users do not need to understand MCP, APIs, or agent workflows to get value from it. They just connect their workspace, add an AI provider, and start asking for help naturally.&lt;/p&gt;

&lt;p&gt;Under the hood, I built a custom harness around &lt;strong&gt;&lt;a href="https://developers.notion.com/guides/mcp/mcp" rel="noopener noreferrer"&gt;Notion MCP&lt;/a&gt;&lt;/strong&gt; so Sotion can create an authenticated MCP client for each user, bring those tools into the assistant runtime, and use them as part of a real product workflow rather than as a standalone demo. That harness is what allows Sotion to connect Notion with chat, workspace setup, drafting, organization, and publishing actions in a way that feels seamless to the user.&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://sotion.noval.me/" rel="noopener noreferrer"&gt;Sotion&lt;/a&gt;, a user connects their workspace through Notion MCP, adds their preferred AI provider, and then starts chatting in plain language. From there, Sotion can help create a dedicated social media workspace in Notion, organize a content database, draft posts, rewrite existing ideas, check connected publishing accounts, and publish approved text posts to supported platforms.&lt;/p&gt;

&lt;p&gt;What makes it useful is that Notion is not treated as a passive note dump. It becomes the system of record for the content workflow.&lt;/p&gt;

&lt;p&gt;Live URL: &lt;a href="https://sotion.noval.me/" rel="noopener noreferrer"&gt;https://sotion.noval.me/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Core features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Connect Notion through &lt;a href="https://developers.notion.com/guides/mcp/mcp" rel="noopener noreferrer"&gt;Notion MCP&lt;/a&gt;&lt;/strong&gt; so &lt;a href="https://sotion.noval.me/" rel="noopener noreferrer"&gt;Sotion&lt;/a&gt; can work directly with the user’s workspace&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Guided onboarding&lt;/strong&gt; to connect Notion and add an AI provider before entering the app&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Natural-language chat&lt;/strong&gt; for turning notes, ideas, and drafts into social content&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dedicated social content workspace in Notion&lt;/strong&gt;, including a structured database for managing posts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-model AI support&lt;/strong&gt; through providers like OpenAI, Claude, OpenRouter, DeepSeek, Moonshot AI, and Z.AI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Social account connection and readiness checks&lt;/strong&gt; for publishing workflows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human-approved publishing&lt;/strong&gt; for posts to supported social platforms&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optional online research sources&lt;/strong&gt; via MCP integrations like &lt;a href="https://exa.ai/" rel="noopener noreferrer"&gt;Exa&lt;/a&gt; and &lt;a href="https://www.tavily.com/" rel="noopener noreferrer"&gt;Tavily&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Supported social workflow today
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://sotion.noval.me/" rel="noopener noreferrer"&gt;Sotion&lt;/a&gt; is designed for &lt;strong&gt;text-based social publishing&lt;/strong&gt;. Right now, the app supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Twitter (X)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LinkedIn&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Threads&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Video Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/YK8Xza1msIo"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Show us the code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/powxenv" rel="noopener noreferrer"&gt;
        powxenv
      &lt;/a&gt; / &lt;a href="https://github.com/powxenv/sotion" rel="noopener noreferrer"&gt;
        sotion
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      An AI-powered social content assistant that helps you turn your Notion workspace into a system for planning, drafting, organizing, and publishing social posts.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Sotion&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Sotion is an AI-assisted social content workspace built around Notion.&lt;/p&gt;
&lt;p&gt;It helps users connect Notion, draft social posts with AI, keep content organized in a dedicated Notion workspace, and publish approved text posts to connected platforms.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Demo&lt;/h2&gt;
&lt;/div&gt;

  
    

    &lt;span class="m-1"&gt;demo.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Key Features&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Connect Notion with &lt;strong&gt;Notion MCP&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Guided onboarding for Notion + AI provider setup&lt;/li&gt;
&lt;li&gt;Chat-based workflow for planning, drafting, and rewriting content&lt;/li&gt;
&lt;li&gt;Dedicated Notion workspace for social content management&lt;/li&gt;
&lt;li&gt;Multiple AI provider support:
&lt;ul&gt;
&lt;li&gt;OpenRouter&lt;/li&gt;
&lt;li&gt;OpenAI&lt;/li&gt;
&lt;li&gt;Claude&lt;/li&gt;
&lt;li&gt;DeepSeek&lt;/li&gt;
&lt;li&gt;Moonshot AI&lt;/li&gt;
&lt;li&gt;Z.AI&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Social account connection for &lt;strong&gt;X&lt;/strong&gt; and &lt;strong&gt;LinkedIn&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Approval-based publishing for text posts&lt;/li&gt;
&lt;li&gt;Optional MCP online research sources:
&lt;ul&gt;
&lt;li&gt;Exa&lt;/li&gt;
&lt;li&gt;Tavily&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Setup&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;1. Install dependencies&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;bun install&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;2. Create &lt;code&gt;.env.local&lt;/code&gt;
&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;SERVER_URL=http://localhost:7634
VITE_APP_TITLE=Sotion

DATABASE_URL=postgres://user:password@localhost:5432/sotion
DATABASE_POOL_URL=postgres://user:password@localhost:5432/sotion

NOTION_CLIENT_ID=
NOTION_CLIENT_SECRET=

X_CLIENT_ID=
X_CLIENT_SECRET=

LINKEDIN_CLIENT_ID=
LINKEDIN_CLIENT_SECRET=

THREADS_CLIENT_ID=
THREADS_CLIENT_SECRET=

MCP_ENCRYPTION_KEY=replace-with-a-random-secret-at-least-32-chars
AI_PROVIDER_ENCRYPTION_KEY=replace-with-a-different-random-secret-at-least-32-chars&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;DATABASE_URL&lt;/code&gt; is used by the app&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DATABASE_POOL_URL&lt;/code&gt; is used by Drizzle Kit&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;MCP_ENCRYPTION_KEY&lt;/code&gt; is used to encrypt MCP-related secrets&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AI_PROVIDER_ENCRYPTION_KEY&lt;/code&gt; is used to encrypt AI provider API…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/powxenv/sotion" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Tech stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TanStack Start&lt;/li&gt;
&lt;li&gt;AI SDK&lt;/li&gt;
&lt;li&gt;Drizzle ORM + Neon&lt;/li&gt;
&lt;li&gt;Better Auth&lt;/li&gt;
&lt;li&gt;Notion MCP&lt;/li&gt;
&lt;li&gt;Deploy on Railway&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the core parts of the project is the custom &lt;a href="https://developers.notion.com/guides/mcp/mcp" rel="noopener noreferrer"&gt;Notion MCP&lt;/a&gt; client flow. I built this layer so &lt;a href="https://sotion.noval.me/" rel="noopener noreferrer"&gt;Sotion&lt;/a&gt; can connect to &lt;a href="https://developers.notion.com/guides/mcp/mcp" rel="noopener noreferrer"&gt;Notion MCP&lt;/a&gt; using OAuth and create an authorized MCP client for each user session.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;NOTION_MCP_SERVER_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://mcp.notion.com/mcp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createAuthorizedNotionMcpClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;createMCPClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NOTION_MCP_SERVER_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;authProvider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;authorizationRequired&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How I Used Notion MCP
&lt;/h2&gt;

&lt;p&gt;I used &lt;a href="https://developers.notion.com/guides/mcp/mcp" rel="noopener noreferrer"&gt;Notion MCP&lt;/a&gt; to make &lt;a href="https://sotion.noval.me/" rel="noopener noreferrer"&gt;Sotion&lt;/a&gt; work with the same place where ideas already live.&lt;/p&gt;

&lt;p&gt;Most social content tools start after the thinking is already done. In my workflow, that thinking usually starts in Notion: rough notes, half-written drafts, launch ideas, product updates, and scattered content angles. I wanted the assistant to step into that environment instead of forcing users to move everything somewhere else first.&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://developers.notion.com/guides/mcp/mcp" rel="noopener noreferrer"&gt;Notion MCP&lt;/a&gt;, &lt;a href="https://sotion.noval.me/" rel="noopener noreferrer"&gt;Sotion&lt;/a&gt; can look into the workspace, understand what already exists, and help turn that raw material into something operational.&lt;/p&gt;

&lt;p&gt;In practice, this means &lt;a href="https://sotion.noval.me/" rel="noopener noreferrer"&gt;Sotion&lt;/a&gt; can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;find relevant notes and drafts inside Notion&lt;/li&gt;
&lt;li&gt;create and organize a content database for tracking ideas and posts&lt;/li&gt;
&lt;li&gt;store platform-specific drafts back into Notion&lt;/li&gt;
&lt;li&gt;update statuses and publishing metadata as work progresses&lt;/li&gt;
&lt;li&gt;use Notion as persistent context across sessions instead of starting from zero every time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That changes the product from “AI that writes posts” into “AI that works with your real content system.”&lt;/p&gt;

&lt;p&gt;A simple example:&lt;br&gt;
A user can connect Notion, ask &lt;a href="https://sotion.noval.me/" rel="noopener noreferrer"&gt;Sotion&lt;/a&gt; to create a social content workspace, and then continue with prompts like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Turn my product notes into a LinkedIn post”&lt;/li&gt;
&lt;li&gt;“Make an X version of this idea”&lt;/li&gt;
&lt;li&gt;“Plan posts for this week”&lt;/li&gt;
&lt;li&gt;“Save the drafts back to Notion”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because the assistant can operate directly on the workspace, the output does not disappear into chat history. It becomes part of a living system inside Notion that the user can review, edit, and keep building on.&lt;/p&gt;

&lt;p&gt;I also wanted the workflow to stay useful when the answer is not already inside Notion. Sometimes drafting a strong post needs fresh context from the web, whether that is industry news, supporting references, or additional research. For that, &lt;a href="https://sotion.noval.me/" rel="noopener noreferrer"&gt;Sotion&lt;/a&gt; supports additional MCP-powered online sources like &lt;strong&gt;&lt;a href="https://exa.ai/" rel="noopener noreferrer"&gt;Exa&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;a href="https://www.tavily.com/" rel="noopener noreferrer"&gt;Tavily&lt;/a&gt;&lt;/strong&gt;. When users enable them, &lt;a href="https://sotion.noval.me/" rel="noopener noreferrer"&gt;Sotion&lt;/a&gt; can search the web, open relevant pages, and bring that context into the drafting process, while still keeping Notion as the place where the work is organized and saved.&lt;/p&gt;

&lt;p&gt;That was the main thing I wanted to unlock: keeping ideation, drafting, organization, research, and follow-up in one continuous workflow instead of breaking it across disconnected tools.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>notionchallenge</category>
      <category>mcp</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
