Using Mistral AI to write meta descriptions for my blog posts

Apr 17, 2025

python
ai

The title of this post may sound like clickbait. After all, it is about AI.

From time to time, I review my site in search of elements that can be improved. This time, I wanted to focus on one aspect related to SEO. I noticed that every sub-page had exactly the same content in the meta name="description" tag. I decided to change this and add unique content for each sub-page, which might at least slightly improve their positioning in search results.

I started from the most visited pages on my website - articles in the posts section. In my CMS panel (I use Decap CMS), I already had a place to write a description. However, I have been lazy so far and have never even written a short summary of a post. Writing a short 120–160 character summary for each post on my site felt too time-consuming. AI is great at creating text content, so I decided to hand over this task to AI. I chose Mistral AI, which I have been using privately quite often for several months. They offer several models, and for this task I chose a free one - mistral-small-latest.

To solve this task I’ve written a short python script. The procedure is very simple: for each file in a given folder, take its main content (omit the frontmatter metadata), send a request to Le Platforme API and execute the appropriate prompt on it: “Generate an SEO-friendly meta description (110-160 characters) for this blog post: /content of the blog post/“. After receiving the response from the API, place the obtained content as a new field in the file - “description”.

Here’s my script:

import frontmatter
import os
import requests
import time

apikey = {yourApiKey}
folder = "./../../geodev_site/src/lib/content/blog"

def generate_description(text, apikey):
    url = "https://api.mistral.ai/v1/chat/completions"
    headers = {
        "Authorization": f"Bearer {apikey}",
        "Content-Type": "application/json"
    }
    data = {
      "model": "mistral-small-latest",
        "messages": [
            {
                "role": "user",
                "content": f"Generate an SEO-friendly meta description (110-160 characters) for this blog post:\n\n{text}"
            }
        ]
    }
    response = requests.post(url, headers=headers, json=data)

    if response.status_code == 200:
        description = response.json().get("choices", [{}])[0].get("message", {}).get("content", "").strip()
        return description
    else:
        print(f"❌ Error: {response.status_code}, {response.text}")

def update_descriptions(folder, api_key):
    files = os.listdir(folder)
    for filename in files:
        try:
            if filename.endswith(".md"):
                path = os.path.join(folder, filename)
                post = frontmatter.load(path)

                content = post.content
                if "description" not in post.metadata:
                    description = generate_description(content[:1000], api_key)
                    if description:
                        post.metadata["description"] = description
                        with open(path, "w") as f:
                            f.write(frontmatter.dumps(post))
                        print(f"✅ Updated: {filename}")
                    else:
                        print(f"❌ Not Updated: {filename}")
                    time.sleep(3);
        except:
            print(f"❌ Error")

update_descriptions(folder, apikey)

You may notice that I use time.sleep(3) after each request is completed. This is because I got a lot of 429 http responses:

script execution errors

I added a 3 second break after each response, which may be too much, but thanks to this the entire process completed correctly for all 54 files.

script execution success

That’s it. Each article file now has a description metadata field with the appropriate content generated by Mistral AI. Example below.

category: React
date: 2021-01-24 17:18:31.121000+00:00
description: Learn how to create a reusable scroll indicator in React using hooks
  and Styled Components. Enhance user experience by highlighting scrollable content.
slug: Scroll indicator component in React
tag:
- react
- components
templateKey: blog-post
title: Scroll indicator component in React

Now after writing the next post I just need to execute this script.