
{"id":77,"date":"2026-09-07T18:59:37","date_gmt":"2026-09-07T18:59:37","guid":{"rendered":"https:\/\/shofutex.net\/?p=77"},"modified":"2026-09-07T19:03:54","modified_gmt":"2026-09-07T19:03:54","slug":"tinkering-with-ai-and-mastodon","status":"publish","type":"post","link":"https:\/\/shofutex.net\/index.php\/2026\/09\/07\/tinkering-with-ai-and-mastodon\/","title":{"rendered":"Tinkering with AI and Mastodon"},"content":{"rendered":"\n<p>Mastodon is really cool. The two the things I most like about it are its decentralized nature, allowing instances to pop up and automatically integrate with the overall &#8220;fediverse&#8221;; and the open API, so with the right user tokens, we can practically do anything with it.<\/p>\n\n\n\n<p>I&#8217;ve long wanted a tool that could review the posts on my timeline, summarize them, and highlight the ones that seem most interesting to me&#8211;essentially creating an algorithm, something that certainly violates one of the core tenets of folks in the fediverse. but this one would be constructed by me, to a point. With Claude code, I have worked on putting together a python script that summarizes the points on my timeline. I learned an interesting thing about mastodon during this process.<\/p>\n\n\n\n<p>Mastodon timelines that get pulled from the API aren&#8217;t fully complete. I had the script pull the last 24 hours worth of posts and it pulled roughly 800 posts, which seemed fair, but then it was obviously missing some posts I explicitly called out I wanted included. After some digging, I found a bug report about <a href=\"https:\/\/github.com\/mastodon\/mastodon\/issues\/37343\">posts missing from mastodon timelines<\/a>, but that bug report is from over nine months ago. If it was a true issue, I&#8217;d like to think it would have been addressed by now. I dug further, and apparently mastodon defaults to <a href=\"https:\/\/github.com\/mastodon\/mastodon\/blob\/main\/app\/lib\/feed_manager.rb\">800 maximum items in a single feed<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  # Maximum number of items stored in a single feed\n  MAX_ITEMS = 800<\/code><\/pre>\n\n\n\n<p>Turns out, I can&#8217;t have this script run daily, or it will miss posts I want it to sift through. In my case, running every 4-6 hours seems to do the trick.<\/p>\n\n\n\n<p>There are also some mastodon accounts I really love to view and I miss them all the time, since I&#8217;m not on Mastodon all day long. So I had the script pull their posts out explicitly&#8211;this is where I caught the bug. SwiftOnSecurity had a post that was omitted from the latest run. Due to how awesome Mastodon is with APIs, you can actually just pull the user&#8217;s feed directly! The script will only do that for a handful of accounts, since I don&#8217;t want to run into rate limits or issues with the server I&#8217;m connecting to.<\/p>\n\n\n\n<p>One of the other things I have been doing the past couple of weeks is tinkering with Ollama and local LLMs. For this project, the script pulls all of the posts and asks a local Ollama model to summarize them&#8211;with some attributions where possible. One of the things I learned tinkering with Ollama is that you can only really deal with a maximum prompt and input size before the model truncates it. As the prompt gets more complicated, the input needs to be shortened&#8211;or the context window needs to be increased. As such, the script breaks the posts into different batches, summarizes each batch, and then provides an overall summary based on this. It also has an heuristic to increase the context window if the batch and prompt ends up being a bit larger than anticipated.<\/p>\n\n\n\n<p>The script also reviews the summary and uses an heuristic to link @mentions to posts that make the most sense for that part of the summary: it collects the words in each sentence and compares them to the stored posts and a post with a reasonable score will get linked in the summary&#8211;especially if that summary references a specific account.<\/p>\n\n\n\n<p>To get what I was looking for, I also had to work on tweaking the prompt sent to Ollama. Sometimes it would reference individual batches and sometimes it would just write me a nice essay rather than structuring the summary. I&#8217;m still trying to get the hang of it. For example, I still can&#8217;t seem to get devstral2 and opencode to do anything I&#8217;m looking for when modifying my code&#8211;Claude is far superior in that regard. I&#8217;ll be honest, I&#8217;m using Claude a lot nowadays. I&#8217;ve learned a good deal about python tinkering with Claude and Ollama. For example, I never really had a reason to parse json files, deal with mistakes in command-line arguments, or some of the other myriad issues I&#8217;ve run into before. Claude is pretty good at helping me resolve those issues&#8211;I&#8217;m not sure i would have found out about difflib and how it can save me from hours of debugging because i misspelled a configuration input without Claude&#8230; <\/p>\n\n\n\n<p>Kind of tongue-in-cheek, but I think Alberta.tech summarized it perfectly: <a rel=\"noreferrer noopener\" href=\"https:\/\/youtube.com\/shorts\/9Z6BHj5flws\" target=\"_blank\">AI didn&#8217;t make you forget how to code<\/a>. Although, in my case, I never had the time to spend on Python as much as I would have liked. School was C++ and work is mostly Java with Bash scripting in the middle.<\/p>\n\n\n\n<p>Let&#8217;s see how well this script works out over the next week.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Mastodon is really cool. The two the things I most like about it are its decentralized nature, allowing instances to pop up and automatically integrate with the overall &#8220;fediverse&#8221;; and the open API, so with the right user tokens, we can practically do anything with it. I&#8217;ve long wanted a tool that could review the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":80,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":[],"categories":[11],"tags":[13,12],"_links":{"self":[{"href":"https:\/\/shofutex.net\/index.php\/wp-json\/wp\/v2\/posts\/77"}],"collection":[{"href":"https:\/\/shofutex.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/shofutex.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/shofutex.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/shofutex.net\/index.php\/wp-json\/wp\/v2\/comments?post=77"}],"version-history":[{"count":2,"href":"https:\/\/shofutex.net\/index.php\/wp-json\/wp\/v2\/posts\/77\/revisions"}],"predecessor-version":[{"id":79,"href":"https:\/\/shofutex.net\/index.php\/wp-json\/wp\/v2\/posts\/77\/revisions\/79"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/shofutex.net\/index.php\/wp-json\/wp\/v2\/media\/80"}],"wp:attachment":[{"href":"https:\/\/shofutex.net\/index.php\/wp-json\/wp\/v2\/media?parent=77"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/shofutex.net\/index.php\/wp-json\/wp\/v2\/categories?post=77"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/shofutex.net\/index.php\/wp-json\/wp\/v2\/tags?post=77"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}