<?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: Aftab Alam</title>
    <description>The latest articles on DEV Community by Aftab Alam (@aftabbuddy).</description>
    <link>https://dev.to/aftabbuddy</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%2F194825%2F5f265236-cc82-48fd-b0ff-51225c0c69ae.png</url>
      <title>DEV Community: Aftab Alam</title>
      <link>https://dev.to/aftabbuddy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aftabbuddy"/>
    <language>en</language>
    <item>
      <title>MCP: Revolutionizing How AI Interacts with Your Tools and Data</title>
      <dc:creator>Aftab Alam</dc:creator>
      <pubDate>Fri, 07 Mar 2025 17:40:55 +0000</pubDate>
      <link>https://dev.to/aftabbuddy/mcp-revolutionizing-how-ai-interacts-with-your-tools-and-data-2poi</link>
      <guid>https://dev.to/aftabbuddy/mcp-revolutionizing-how-ai-interacts-with-your-tools-and-data-2poi</guid>
      <description>&lt;p&gt;Ever found yourself wishing your AI assistant could seamlessly connect to all your favorite tools without a mountain of custom code? That's exactly the problem that Model Context Protocol (MCP) solves! Today, we're diving into this game-changing protocol that's rapidly becoming the standard for AI-tool integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is MCP, and Why Should You Care?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://modelcontextprotocol.io/introduction" rel="noopener noreferrer"&gt;MCP (Model Context Protocol)&lt;/a&gt; is an open protocol that standardizes how AI applications interact with external systems. But what does that actually mean for you?&lt;/p&gt;

&lt;p&gt;Think about it this way: before MCP, if you wanted an AI to work with Slack, GitHub, or even your local files, you'd need custom code for each integration. Add ten more tools? That's ten more custom implementations. It's like needing a different type of charger for every single device you own!&lt;/p&gt;

&lt;p&gt;MCP changes this by creating a universal "language" that lets AI applications talk to any compatible tool or data source. It's the USB standard of the AI world.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pre-MCP World:
AI App 1 ⟷ Custom Code ⟷ GitHub
AI App 2 ⟷ Custom Code ⟷ Slack
AI App 3 ⟷ Custom Code ⟷ Gmail
...and so on for EACH combination

MCP World:
AI App 1 ⟷ MCP ⟷ GitHub MCP Server
AI App 2 ⟷ MCP ⟷ Slack MCP Server
AI App 3 ⟷ MCP ⟷ Gmail MCP Server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  MCP's Core Components
&lt;/h2&gt;

&lt;p&gt;MCP consists of three main parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Prompts&lt;/strong&gt;: User-controlled templates for common interactions (think of them as shortcuts for specific tasks)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools&lt;/strong&gt;: Model-controlled functions that the AI can choose to invoke at the right time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resources&lt;/strong&gt;: Application-controlled data that can be exchanged between the server and client&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's break these down with some real-world examples:&lt;/p&gt;

&lt;h3&gt;
  
  
  Tools in Action
&lt;/h3&gt;

&lt;p&gt;Imagine you're chatting with Claude and ask, "Can you help me manage my GitHub issues?" With MCP, Claude can access GitHub's tools like "list_issues," "create_issue," or "add_comment" without you or the AI needing to know the underlying API details.&lt;/p&gt;

&lt;p&gt;The magic here is that the model decides when to use these tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You: "Can you summarize the open issues on my repository and prioritize them?"

Claude: [Thinking: I should check what issues exist first]
[Invokes GitHub.list_issues tool]
[Receives data about open issues]
[Analyzes priorities based on content and labels]

"I've found 23 open issues in your repository. Based on their content and labels, here are the top 5 priorities..."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Resources as Shared Data
&lt;/h3&gt;

&lt;p&gt;Resources are data exposed by MCP servers that your application can use. These could be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Files (like a CSV of analytics data)&lt;/li&gt;
&lt;li&gt;JSON objects (like project metadata)&lt;/li&gt;
&lt;li&gt;Images or other media&lt;/li&gt;
&lt;li&gt;Dynamic content generated based on your request&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unlike tools, resources are controlled by the application, not the model. Think of them as attachments the server provides that you or the AI can choose to use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompts as User Shortcuts
&lt;/h3&gt;

&lt;p&gt;Prompts are predefined templates for common tasks. For example, an IDE with MCP support might offer shortcuts like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/summarize-pr [PR-ID]&lt;/code&gt; - Generate a summary of the specified pull request&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/explain-code&lt;/code&gt; - Provide a detailed explanation of the selected code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/optimize&lt;/code&gt; - Suggest optimizations for the highlighted function&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Real Power: Composability and Discovery
&lt;/h2&gt;

&lt;p&gt;Where MCP truly shines is in creating networks of capabilities that your AI can tap into:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Composability&lt;/strong&gt;: MCP servers can also be clients, creating chains of tools. Your AI can talk to an "orchestrator" agent, which then communicates with specialized agents for research, coding, or analysis.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dynamic Discovery&lt;/strong&gt;: With the upcoming MCP registry, AIs can discover new capabilities on the fly. Imagine asking your agent to analyze Grafana logs, and even if it wasn't specifically programmed for that, it can search for and integrate with a Grafana MCP server.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Coding Time: A Simple MCP Server Example
&lt;/h2&gt;

&lt;p&gt;Let's look at how straightforward it is to create an MCP server for a weather service:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;McpServer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ResourceTemplate&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@modelcontextprotocol/sdk/server/mcp.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;StdioServerTransport&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@modelcontextprotocol/sdk/server/stdio.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;zod&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Create an MCP server&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;McpServer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Weather&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1.0.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Add the current weather tool&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;get_current_weather&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;City name or coordinates&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;units&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enum&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;metric&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;imperial&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;metric&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Unit system&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;units&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// In a real implementation, this would call a weather API&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;content&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;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;units&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;units&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;metric&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;F&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;conditions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Partly cloudy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Add the forecast tool&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;get_forecast&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;City name or coordinates&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Implementation would call forecast API&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;forecast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Monday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;high&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;low&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;conditions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sunny&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tuesday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;high&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;low&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;conditions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rain&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="c1"&gt;// More days...&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;content&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;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;forecast&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Add a weather resource&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;current-conditions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResourceTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;weather://current/{location}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
      &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Current conditions for &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: Temperature 22°C, Partly cloudy`&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="c1"&gt;// Start the server using stdio transport&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transport&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StdioServerTransport&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once created, any MCP-compatible client (like Claude, Cursor, Windsurf, or your own application) can instantly connect to this server and start using its tools without any additional integration work!&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World MCP Adoption
&lt;/h2&gt;

&lt;p&gt;MCP has seen incredible growth since its launch. Over 1,100 community-built servers have emerged in just a few months, and companies like Cloudflare, Stripe, and others have released official MCP servers.&lt;/p&gt;

&lt;p&gt;IDE integrations have been particularly successful, with applications like Perser, Windsurfer, and Zed embracing MCP to give developers context-aware AI assistance.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next for MCP?
&lt;/h2&gt;

&lt;p&gt;The MCP ecosystem is evolving rapidly, with several exciting developments on the horizon:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Remote Servers and OAuth&lt;/strong&gt;: Support for remotely hosted servers with authentication, removing the need for local installation. See &lt;a href="https://mcp.composio.dev" rel="noopener noreferrer"&gt;Composio.dev&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP Registry&lt;/strong&gt;: A &lt;a href="https://mcp-get.com" rel="noopener noreferrer"&gt;centralized&lt;/a&gt; way to discover and verify MCP servers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Well-Known URLs&lt;/strong&gt;: A standard way for websites to expose their MCP capabilities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Streaming&lt;/strong&gt;: Better support for streaming data between clients and servers&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why MCP Matters for Agent Systems
&lt;/h2&gt;

&lt;p&gt;If you're excited about AI agents, MCP is crucial infrastructure. It enables:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Self-evolving agents&lt;/strong&gt; that can discover and use new capabilities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Specialized sub-agents&lt;/strong&gt; that focus on specific tasks but work together&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standardized tool access&lt;/strong&gt; without duplicating integration code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Privacy and control&lt;/strong&gt; over your data and tool usage&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Getting Started with MCP
&lt;/h2&gt;

&lt;p&gt;Want to start exploring MCP? Here are some options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Try Claude in &lt;a href="https://claude.ai/download" rel="noopener noreferrer"&gt;Claude for desktop&lt;/a&gt;, which is already MCP-compatible&lt;/li&gt;
&lt;li&gt;Explore Goose by Block, which uses MCP "extensions"&lt;/li&gt;
&lt;li&gt;Check out the open-source &lt;a href="https://github.com/lastmile-ai/mcp-agent" rel="noopener noreferrer"&gt;MCP Agent framework&lt;/a&gt; by LastMile AI&lt;/li&gt;
&lt;li&gt;Build your own MCP server using the official SDKS, for &lt;a href="https://github.com/modelcontextprotocol/python-sdk" rel="noopener noreferrer"&gt;Python&lt;/a&gt;, &lt;a href="https://github.com/modelcontextprotocol/typescript-sdk" rel="noopener noreferrer"&gt;Typescript&lt;/a&gt;, etc. or explore the available &lt;a href="https://github.com/modelcontextprotocol/servers" rel="noopener noreferrer"&gt;servers&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;MCP is transforming how AI applications access context and tools, solving the N×M integration problem that has held back AI assistants from reaching their full potential. Rather than requiring custom code for every combination of AI app and external tool, MCP provides a standardized layer that connects them all.&lt;/p&gt;

&lt;p&gt;The result? More powerful and context-rich AI that can genuinely help you get things done.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Additional Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/introduction" rel="noopener noreferrer"&gt;Official MCP Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/examples" rel="noopener noreferrer"&gt;MCP Server Examples Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lastmile-ai/mcp-agent" rel="noopener noreferrer"&gt;MCP Agent Framework&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What has your experience with AI integrations been like? Would MCP solve problems you're facing? Share your thoughts in the comments!&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>genai</category>
    </item>
    <item>
      <title>Manage your Astro site's content with Git-based Netlify CMS</title>
      <dc:creator>Aftab Alam</dc:creator>
      <pubDate>Tue, 08 Feb 2022 15:18:43 +0000</pubDate>
      <link>https://dev.to/aftabbuddy/manage-your-astro-sites-content-with-git-based-netlify-cms-17a0</link>
      <guid>https://dev.to/aftabbuddy/manage-your-astro-sites-content-with-git-based-netlify-cms-17a0</guid>
      <description>&lt;p&gt;I have a series on my blog &lt;a href="https://aalam.in/blog/astro-get-up-and-running" rel="noopener noreferrer"&gt;Get Up &amp;amp; Running with Astro&lt;/a&gt; that teaches you all the things you need to get started with &lt;a href="https://astro.build/" rel="noopener noreferrer"&gt;Astro&lt;/a&gt;, one of the fastest SSG with a really amazing approach to partial hydration.&lt;/p&gt;

&lt;p&gt;If you'll follow the &lt;a href="https://aalam.in/blog/astro-get-up-and-running" rel="noopener noreferrer"&gt;series&lt;/a&gt;, you'll have an Astro site already up and running at &lt;a href="https://astro-ink.vercel.app/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt;. It concludes with a good, crisp, blog setup. However, there's one aspect that still feels a bit non-intuitive. We author our content by hand in editors that could support markdown, which could be a bit clumsy. Plus, missing any important front-matter tags could lead to unexpected results. There should be a better way to do this. In this article, we'll cover how we can manage the markdown content like a pro with open-source, headless, Git-based CMS - Netlify CMS.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's a Git-based CMS?
&lt;/h2&gt;

&lt;p&gt;A Git-based CMS is your day-to-day CMS with just a slight twist - Git as the data source and content manager. Unlike the traditional CMSs that persist your changes in a database, Git-based CMSs are headless and let you&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep the content management duties separate from the presentational responsibilities&lt;/li&gt;
&lt;li&gt;Work with markdown and associated media files directly in their UIs&lt;/li&gt;
&lt;li&gt;Update your changes through Git commits on Github (or systems following the same versioning model)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You get all the essential content management features you expect your CMS to ship with, without much hassles of a conventional CMS setup. Most of the CMS configuration is versioned in the same repository(Self-hosted) you use to maintain the data in markdown files.&lt;/p&gt;

&lt;p&gt;When it comes to Git-based or JAMStack CMSs in the market &lt;a href="https://www.netlifycms.org/" rel="noopener noreferrer"&gt;NetlifyCMS&lt;/a&gt; and Forestry(or TinaCMS) are two of the most popular CMS that can go with git-based content.&lt;/p&gt;

&lt;p&gt;NetlifyCMS, by Netlify - the JAMStack Stack provider, is fully open-source, has a good basic experience, and plays well with the overall Netlify suite of tools. The only requirement, I've found with Ink, is that the site must be hosted on Netlify.&lt;/p&gt;

&lt;p&gt;Forestry is also pretty good and has more superior content editing experience but you'd be able to work with only a limited amount of sites in the free plan. Config for your CMS is still stored in Github, but Forestry's experience is more controlled.&lt;/p&gt;

&lt;p&gt;For the current article, we'll use NetlifyCMS as the CMS of our choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy Ink to Netlify
&lt;/h2&gt;

&lt;p&gt;Although not necessary, NetlifyCMS uses certain features that are Netlify-native. Wouldn't it be good if the deployment pipeline is also Netlify-native? Let's go ahead and set up our site on Netlify. Head on over to the site, and use your Github account to signup with Netlify.&lt;/p&gt;

&lt;p&gt;Once Signed-up/Signed-in you should land on the Netlify dashboard&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foe0x3za8akelty8w4q0f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foe0x3za8akelty8w4q0f.png" alt="Netlify Dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the &lt;em&gt;New Site from Git&lt;/em&gt; to connect Github, and configure a site to work with Netlify&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuc18jtgnfbembge8pune.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuc18jtgnfbembge8pune.png" alt="Connect"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffsuwubdzdi5e98f7akx9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffsuwubdzdi5e98f7akx9.png" alt="Connected"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Press Github, and choose &lt;code&gt;[your-gh-username]/[repo-name]&lt;/code&gt; from the list of repository it presents. For us, it should be &lt;code&gt;[your-gh-username]/astro-ink&lt;/code&gt; if you're working with a cloned template or fork of &lt;code&gt;astro-ink&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs28wims987eb2i63ivf9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs28wims987eb2i63ivf9.png" alt="Select Repo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Netlify must have access to list your repositories for this to work. You can provide full access or configure it on a per-site basis.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once you've connected to github and picked the repository, configure the build settings as per your SSG. By default, Netlify picks the &lt;code&gt;public&lt;/code&gt; directory for SSG-generated content, but since Astro prefers a &lt;code&gt;dist&lt;/code&gt; directory for the same, you should change the publish directory to &lt;code&gt;/dist&lt;/code&gt;. The command to build must be &lt;code&gt;yarn build&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv9al55ug7fcko5e2h334.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv9al55ug7fcko5e2h334.png" alt="Configure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once done, click on the "Deploy" button.&lt;/p&gt;

&lt;p&gt;Netlify will take you to the project dashboard, where you can see your site deployment in progress. Once done, you should see a &lt;code&gt;random-app-name.netlify.com&lt;/code&gt; available.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7tfh127fcgrmgn60xyoq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7tfh127fcgrmgn60xyoq.png" alt="App Available"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your app's hosted now on Netlify. If you want you can change the random name to something more appropriate like &lt;code&gt;astro-ink&lt;/code&gt;.netlify.com.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlxdkuum01et4qopu36w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlxdkuum01et4qopu36w.png" alt="Change Site Name"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's configure the Netlify CMS
&lt;/h2&gt;

&lt;p&gt;NetlifyCMS is a React SPA fundamentally. To make it work, you need to link the CMS file from the CDN and make the &lt;code&gt;index.html&lt;/code&gt; that hosts it available in the &lt;code&gt;public&lt;/code&gt; directory of your SSG, alongside other public assets you serve.&lt;/p&gt;

&lt;p&gt;For us, &lt;code&gt;/public&lt;/code&gt; is the directory Astro uses to host static, non-generated, assets. We'll use the same to host the NetlifyCMS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup NetlifyCMS
&lt;/h3&gt;

&lt;p&gt;Let's consider that We eventually want the NetlifyCMS/CMS to be available at &lt;code&gt;astro-ink.netlify.com/admin&lt;/code&gt;. For this to work, we'll go into the public directory and create a folder called &lt;code&gt;admin&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Within the &lt;code&gt;admin&lt;/code&gt; directory we first need the index.html file that will render the NetlifyCMS when the author will visit &lt;code&gt;astro-ink.netlify.com/admin&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Create an &lt;code&gt;index.html&lt;/code&gt; file and place the following content&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="utf-8" /&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0" /&amp;gt;
    &amp;lt;title&amp;gt;Astro Ink - Content Manager&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;script src="https://unpkg.com/netlify-cms@2.10.161/dist/netlify-cms.js"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will include the &lt;code&gt;netlify-cms&lt;/code&gt; scripts that manage the rendering for NetlifyCMS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure NetlifyCMS
&lt;/h3&gt;

&lt;p&gt;With the script included, now we need to tell Netlify about our CMS configuration and where to find it.&lt;/p&gt;

&lt;p&gt;Create a &lt;code&gt;config.toml&lt;/code&gt;(a variant of .yml) and put the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;backend:
  name: git-gateway
  branch: main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells NetlifyCMS to use the &lt;code&gt;git&lt;/code&gt; gateway and the &lt;code&gt;main&lt;/code&gt; branch to push the commits.&lt;/p&gt;

&lt;p&gt;Netlify CI/CD is pre-configured to build your site with every commit and this behavior is at the center of content editing with a Git CMS. Every change you do in a Git-based CMS pushes a new commit to your repo, which triggers a rebuild of your site. Here we're configuring Netlify to use the &lt;code&gt;main&lt;/code&gt; branch for all the commits.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure the Content types
&lt;/h3&gt;

&lt;p&gt;With the CMS setup, the next thing to do is to configure the content types we'll allow our users to create and update. With NetlifyCMS we manage the configuration in the same Github repository's &lt;code&gt;config.toml&lt;/code&gt; file we just updated for Git in the previous step. Go ahead and add the following changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;collections: # A list of collections the CMS should be able to edit
  - name: 'post' # Used in routes, ie.: /admin/collections/:slug/edit
    label: 'Post' # Used in the UI, ie.: "New Post"
    folder: 'src/pages/blog' # The path to the folder where the documents are stored
    create: true # Allow users to create new documents in this collection
    fields: # The fields each document in this collection have
      - {label: "Layout", name: "layout", widget: "hidden", default: "$/layouts/post.astro"}
      - { label: 'Title', name: 'title', widget: 'string' }
      - { label: 'Description', name: 'description', widget: 'text' }
      - { label: 'Body', name: 'body', widget: 'markdown' }
      - { label: 'Tags', name: 'tags', widget: 'list' }
      - { label: 'Author', name: 'author', widget: 'string' }
      - { label: 'Author Twitter Handle', name: 'authorTwitter', widget: 'string' }
      - { label: 'Publish Date', name: 'date', widget: 'datetime' }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what all the above settings mean to NetlifyCMS&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;collections&lt;/code&gt; - Collections are all the content types your CMS is configured to edit. For us, all the posts inside the &lt;code&gt;/src/pages/blog&lt;/code&gt; followed the same front-matter structure being a blog with similar attribute requirements. Collections are the blueprints or classes for your content type. With new content types, you add new collections with all the config that makes them unique and that you'd like to edit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There's just one &lt;code&gt;post&lt;/code&gt; type we'd like to edit for our CMS, so we'll just add one entry named &lt;code&gt;post&lt;/code&gt; under &lt;code&gt;collections&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt; - The unique name the collection will be recognized by in the NetlifyCMS system&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;label&lt;/code&gt; - The label your collection will be recognized by in the UI&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;folder&lt;/code&gt; - The location in your Github repo where all your markdown files will be kept. Since &lt;code&gt;src/pages/blog&lt;/code&gt; is the folder, we've used to keep the hand-edited markdown file and our blogs are available at &lt;code&gt;site/blog/[slug]&lt;/code&gt;, we'll use &lt;code&gt;src/pages/blog&lt;/code&gt; as the folder.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;create&lt;/code&gt; - boolean value to inform NetlifyCMS if creation is allowed&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fields&lt;/code&gt; - fields configures all the fields that we'd prefer to be editable in the NetlifyCMS. They can be directly mapped to the front-matter details we're maintaining with &lt;code&gt;*.md&lt;/code&gt; file, and the UI controls that are more appropriate to edit it conveniently.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since we had the following front-matter structure&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$/layouts/post.astro&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Introducing&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Astro&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Ship&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Less&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;JavaScript"&lt;/span&gt;
&lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2021-06-08&lt;/span&gt;
&lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Fred K. Schott&lt;/span&gt;
&lt;span class="na"&gt;authorTwitter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;FredKSchott&lt;/span&gt;
&lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;design&lt;/span&gt;
&lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Astro&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;jam-stack&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;There's&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;simple&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;secret&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;building&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;faster&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;website&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;—&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;just&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ship&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;less."&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it could get translated to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Layout"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;layout"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;widget&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hidden"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;$/layouts/post.astro"&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Title'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;title'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;widget&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;string'&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Description'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;description'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;widget&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;text'&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Body'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;body'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;widget&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;markdown'&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Tags'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;tags'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;widget&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;list'&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Author'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;author'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;widget&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;string'&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Author&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Twitter&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Handle'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;authorTwitter'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;widget&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;string'&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Publish&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Date'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;date'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;widget&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;datetime'&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in &lt;code&gt;config.yml&lt;/code&gt;. As learned earlier, &lt;code&gt;name&lt;/code&gt; is for NetlifyCMS and &lt;code&gt;label&lt;/code&gt; is for you. &lt;code&gt;widget&lt;/code&gt; is what controls what UI element needs to be rendered in NetlifyCMS for each field you configure. NetlifyCMS supports a &lt;a href="https://www.netlifycms.org/docs/widgets/#common-widget-options" rel="noopener noreferrer"&gt;wide range of widgets&lt;/a&gt; you can use here to render a control as you prefer. You can even create your own &lt;a href="https://www.netlifycms.org/docs/custom-widgets/" rel="noopener noreferrer"&gt;custom widgets&lt;/a&gt; if you want.&lt;/p&gt;

&lt;p&gt;With the above changes, the &lt;code&gt;config.yml&lt;/code&gt;  file should look like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;backend:
  name: git-gateway
  branch: main

collections: # A list of collections the CMS should be able to edit
  - name: 'post' # Used in routes, ie.: /admin/collections/:slug/edit
    label: 'Post' # Used in the UI, ie.: "New Post"
    folder: 'src/pages/blog' # The path to the folder where the documents are stored
    create: true # Allow users to create new documents in this collection
    fields: # The fields each document in this collection have
      - {label: "Layout", name: "layout", widget: "hidden", default: "$/layouts/post.astro"}
      - { label: 'Title', name: 'title', widget: 'string' }
      - { label: 'Description', name: 'description', widget: 'text' }
      - { label: 'Body', name: 'body', widget: 'markdown' }
      - { label: 'Tags', name: 'tags', widget: 'list' }
      - { label: 'Author', name: 'author', widget: 'string' }
      - { label: 'Author Twitter Handle', name: 'authorTwitter', widget: 'string' }
      - { label: 'Publish Date', name: 'date', widget: 'datetime' }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pay attention to the layout field. It's necessary to register it as a &lt;code&gt;hidden&lt;/code&gt; field so that program-level concerns can be hidden from the author's eye, and accidental, unintended mistakes can be prevented.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure NetlifyCMS for media uploads
&lt;/h3&gt;

&lt;p&gt;textual content would not be the only format authors would use. We may add images to our posts. To support images, we'll have to tell NetlifyCMS where it can upload/find images with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;media_folder: 'public/images/uploads' # Folder where user uploaded files should go
public_folder: '/images/uploads'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;media_folder&lt;/code&gt; - Where should the user uploaded files go?&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;public_folder&lt;/code&gt; - The location to use to link the user uploaded files.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The resultant &lt;code&gt;config.yml&lt;/code&gt; should look like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;backend:
  name: git-gateway
  branch: main

media_folder: 'public/images/uploads' # Folder where user uploaded files should go
public_folder: '/images/uploads'

collections: # A list of collections the CMS should be able to edit
  - name: 'post' # Used in routes, ie.: /admin/collections/:slug/edit
    label: 'Post' # Used in the UI, ie.: "New Post"
    folder: 'src/pages/blog' # The path to the folder where the documents are stored
    create: true # Allow users to create new documents in this collection
    fields: # The fields each document in this collection have
      - {label: "Layout", name: "layout", widget: "hidden", default: "$/layouts/post.astro"}
      - { label: 'Title', name: 'title', widget: 'string' }
      - { label: 'Description', name: 'description', widget: 'text' }
      - { label: 'Body', name: 'body', widget: 'markdown' }
      - { label: 'Tags', name: 'tags', widget: 'list' }
      - { label: 'Author', name: 'author', widget: 'string' }
      - { label: 'Author Twitter Handle', name: 'authorTwitter', widget: 'string' }
      - { label: 'Publish Date', name: 'date', widget: 'datetime' }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With all the above changes done, let's push our changes to Github.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"feat: Add Netlify CMS Admin"&lt;/span&gt;
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configure Netlify for Authentication and Git Backend
&lt;/h2&gt;

&lt;p&gt;CMS configuration is just one part of the CMS story. For your users to log in to your site with their Git credentials you'll require a way to identify/authorize them. &lt;code&gt;Netlify Identity&lt;/code&gt; is Netlify's answer to browser-based user authentication, and configuring it with Netlify is utterly simple. Being Netlify's own, It's also just a click away in the Netlify dashboard.&lt;/p&gt;

&lt;p&gt;In your Netlify dashboard click your &lt;code&gt;site settings&lt;/code&gt; -&amp;gt; &lt;code&gt;https://app.netlify.com/sites/[your-ink-clone]/settings/general&lt;/code&gt; and then click on &lt;code&gt;Identity&lt;/code&gt; &lt;a href="https://app.netlify.com/sites/%5Byour-ink-clone%5D/settings/identity" rel="noopener noreferrer"&gt;https://app.netlify.com/sites/[your-ink-clone]/settings/identity&lt;/a&gt;. Under the &lt;code&gt;Identity&lt;/code&gt; section click on &lt;code&gt;Enable Identity&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For registration preferences &lt;a href="https://app.netlify.com/sites/astro-ink/settings/identity#registration" rel="noopener noreferrer"&gt;https://app.netlify.com/sites/astro-ink/settings/identity#registration&lt;/a&gt;&lt;br&gt;
 you can leave the &lt;em&gt;Open&lt;/em&gt; radio button selected and click on &lt;em&gt;Save&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Enable Git Gateway
&lt;/h3&gt;

&lt;p&gt;Under the identity section, scroll to Services &lt;code&gt;https://app.netlify.com/sites/[your-ink-clone]/settings/identity#services&lt;/code&gt; and enable Git Gateway. This will enable the NetlifyCMS to work with Git as a backend.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9qg2x1jnjz8qo7gsvusd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9qg2x1jnjz8qo7gsvusd.png" alt="Enable Git Gateway"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmpbhigaabd2dq8l6dkxo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmpbhigaabd2dq8l6dkxo.png" alt="Enabled Git Gateway"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Load/Initialise the Identity files
&lt;/h3&gt;

&lt;p&gt;For Netlify Identity to work with your NetlifyCMS rendering page &lt;code&gt;/admin/index.html&lt;/code&gt; we'll have to hook up the identity script&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;https://identity.netlify.com/v1/netlify-identity-widget.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;from the CDN in the &lt;code&gt;head&lt;/code&gt; tag of &lt;code&gt;public/admin/index.html&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="utf-8" /&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0" /&amp;gt;
    &amp;lt;title&amp;gt;Astro Ink - Content Manager&amp;lt;/title&amp;gt;
    &amp;lt;script src="https://identity.netlify.com/v1/netlify-identity-widget.js"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;script src="https://unpkg.com/netlify-cms@2.10.161/dist/netlify-cms.js"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This covers the &lt;code&gt;/admin&lt;/code&gt; relative URLs. To have Netlify Identity in action on all the site pages the same needs to be done on all the site pages. Open &lt;code&gt;src/components/BaseHead.astro&lt;/code&gt; and add the following on line 64&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;src&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://identity.netlify.com/v1/netlify-identity-widget.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One final change is redirecting the users to CMS Admin UI after successful login. For that, to work we'll be required a way to know Netlify Identity is available/initialized, as soon as the document is done loading, and redirect the users on successful login. Since we have an Astro site, and its hydration on JS behaviour is opt-in we'll create a component to register this behaviour that will get triggered on window &lt;code&gt;load&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script lang="ts"&amp;gt;
    import { onMount} from 'svelte'
    onMount(() =&amp;gt; {
        if (window.netlifyIdentity) {
            window.netlifyIdentity.on('init', (user) =&amp;gt; {
                if (!user) {
                    window.netlifyIdentity.on('login', () =&amp;gt; {
                        document.location.href = '/admin/';
                    });
                }
            });
        }
    })
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;src/components/Footer.astro&lt;/code&gt; and include the above component&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
    import { SITE } from '$/config'
    import ModeLabel from './ModeLabel.svelte'
    import NetlifyIdentity from './NetlifyIdentity.svelte'
---
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="footer"&amp;gt;
    &amp;lt;nav class="nav"&amp;gt;
        &amp;lt;div&amp;gt;2021  &amp;amp;copy; Copyright notice |  &amp;lt;a href={ SITE.githubUrl } title={`${ SITE.name }'s Github URL'`}&amp;gt;{ SITE.name }&amp;lt;/a&amp;gt;
        &amp;lt;ModeLabel client:load/&amp;gt; theme on &amp;lt;a href="https://astro.build/"&amp;gt;Astro&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;
        &amp;lt;NetlifyIdentity client:load/&amp;gt;
    &amp;lt;/nav&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's push our changes, and open the &lt;code&gt;[your-site].netlify.app/admin&lt;/code&gt; to see the CMS in action.&lt;br&gt;
Commit: &lt;a href="https://github.com/one-aalam/astro-ink/commit/2b39e1519906162ec05abcadd2d08f8849961de2" rel="noopener noreferrer"&gt;https://github.com/one-aalam/astro-ink/commit/2b39e1519906162ec05abcadd2d08f8849961de2&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Work with NelifyCMS
&lt;/h2&gt;

&lt;p&gt;Click on the "Login with Netlify Identity" button,&lt;br&gt;
&lt;a href="https://astro-ink.netlify.app/admin/#/" rel="noopener noreferrer"&gt;https://astro-ink.netlify.app/admin/#/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8iedl7n6pwozbpx2756b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8iedl7n6pwozbpx2756b.png" alt="CMS Signup"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and sign-up with your actual details(name, email, password, etc.) or &lt;code&gt;continue with Github&lt;/code&gt; credentials for the first time. Once signed up with basic credentials or Github, and the account is activated, use "Login" to visit the CMS dashboard in the subsequent visits.&lt;/p&gt;

&lt;p&gt;You'll be landed to the default collections view post a successful login like &lt;code&gt;https://astro-ink.netlify.app/admin/#/collections/post&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxr9ktkce0lmbngxfxh68.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxr9ktkce0lmbngxfxh68.png" alt="Netlify CMS Admin"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Where you can &lt;em&gt;Edit&lt;/em&gt; the pre-existing posts, or create new posts and publish them. Go ahead and create/update/delete posts. Once done, click on "Publish" and choose one of the following options&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Publish now&lt;/li&gt;
&lt;li&gt;Publish and Create new&lt;/li&gt;
&lt;li&gt;Publish and duplicate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and see the NetlifyCMS sync the changes with your Github repo. Since Netlify CI is watching your Github repo for commits, it will re-build your site as soon as it finds a new commit with your content changes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One important thing you must keep in mind is that the NetlifyCMS content-editing uses the same commit-based workflow you do to commit your code. Since the application code and content changes are inseparable, you'll have to keep your local changes always in sync with the remote repo to not have conflicts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, you got to learn about Git-based CMSs and Netlify. Git-based CMSs offer several benefits like -&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simplicity of setup, configuration, and management&lt;/li&gt;
&lt;li&gt;version controlled goodness, without a complex pipeline or infrastructural requirements, and thus rolling back is easy&lt;/li&gt;
&lt;li&gt;No vendor lock-in as all content is present as flat files. You can use any tools that can work natively with Markdown. If you want you can additionally set up Forestry.io also, or any other Git CMS.&lt;/li&gt;
&lt;li&gt;Natural and homogenous to how we code. Use a tool, or don't use it you can still get quite done. Less lock-in leads to less hassles when migrating or changing authoring tools.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;but there are certain features only pretty advanced CMS can capably do.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If markdown isn't your source of truth, you cannot use the approach to scale to other sites or repositories. Every markdown site will need exactly one CMS&lt;/li&gt;
&lt;li&gt;The CMS might not be very capable to handle a humongous amount of content, because they are pretty simplistic by nature.&lt;/li&gt;
&lt;li&gt;Content Modelling is one-one mapped to your front-matter structures, so they're pretty coupled in that sense. The models/collections are content-derived, and can only be extended to support what you can and must keep in markdown. Also with too many collections, it could get pretty involved&lt;/li&gt;
&lt;li&gt;Your media uploads are restricted by the max size Git allows for a certain repo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But even with the aforementioned limitations, having an option to co-locate content and code, in such a seamless manner makes the job of managing simple sites and blogs effortless.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>jamstack</category>
      <category>astro</category>
      <category>netlify</category>
    </item>
  </channel>
</rss>
