I stopped opening my own admin
I mostly wanted to try out MCP and see if it would up my workflow. It did, and by a lot more than I expected.
MCP (Model Context Protocol) is a standard way to give an AI agent tools. You run a small server next to your app, it lists what the agent is allowed to do ("list posts", "read a job", "mark as applied"), and the agent calls those tools when you ask it something. Two of my apps have one now: this site and Swipe2Job.
The push script lasted a day
On October 15 I shipped a push script for this site. It took an export folder with a post and its images, uploaded everything with an API token and created a draft. It worked. The next day the MCP server went in, and it turned out so much better and easier than the push script.
There's no export folder anymore. I just ask about whatever I need on the site: change this, change that. When I wanted to add PHP, WordPress, Supabase and Docker to the skills on my homepage and swap which projects are featured, that was one chat. I never opened /admin.
1list_posts get_post create_draft update_post2get_upload_url list_media discard_pending3preview_change publish_post unpublish_post4set_featured set_skills delete_media5get_analytics get_stats list_contacts
It also changed how posts get made. The companion skill I wrote about before now reads my newest posts through the MCP before it drafts, so it doesn't reuse the same headings. Then it uploads the images and creates the draft through the same tools. This post went the same way.
Nothing goes live until I've seen it
Drafts are free. The agent can create and update as many as it likes, because a visitor never sees them. Anything live is different: publishing, unpublishing, changing what's featured, the skills list, deleting an image. I want to see what changes before anything goes live.
So those tools don't work on their own. The agent first calls preview_change, which returns a summary and the list of what will change, plus a confirm code. It shows me the list, I say yes, and only then can it call publish_post with that code.
1const sign = (key: string, action: string, target: string, fingerprint: string, exp: number) =>2 createHmac('sha256', subKey(key)).update(`${action}\n${target}\n${fingerprint}\n${exp}`).digest('base64url');
The code is a signature over the action, the post, a fingerprint of the post as it is right now, and an expiry 10 minutes out. If the post changes after the preview, the fingerprint doesn't match and the code is useless. So the agent can't preview one version and publish another.
Which job should I apply for?
Swipe2Job is where I swipe through job ads on my phone. Applying happens at my PC, and that's where its MCP server comes in. It has four tools: list my saved jobs, read the whole ad, set a job's status, and add a note to the application.
I use all of them. I ask what's closing soon and work through that list. I read a saved job and get help writing the application. After I've sent it, the agent marks it applied and adds a note.
I also ask which job fits my profile best, which one makes the most sense for me to apply for. I keep my CV and profile in a folder on my PC, so the agent reads those next to the saved jobs and compares them. The jobs come from the app, the profile comes from the folder, and I get an answer in one place.
Swipe2Job runs on my homelab, so its MCP server only answers inside my Tailscale network, and it still needs its own token on top.
A third one, on the test bench
There's also a WordPress plugin that lets an agent build Elementor pages as drafts over MCP. Same rule as the site: it can write drafts, and putting a design live is a separate screen only a logged-in human can use. It's mostly a test of whether it could up my workflow too. It's not there yet. Whether I keep going with it depends on an upcoming project.
Next: the site from my phone
Right now the site's MCP only works from my PC, because it logs in with a token I set up there. I want to add OAuth so I can connect from my phone and update the site from anywhere.
After that, more MCP servers, but only when I see one fitting. Not every app needs an agent talking to it.