<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/a-blog-mcp-server-with-fastmcp-and-pgvector-2orqqbrig" -->

---
title: A Blog MCP Server with FastMCP and pgvector | daily.dev
description: A detailed walkthrough of building an MCP server that powers a blog-writing AI assistant, combining FastAPI, FastMCP, SQLAlchemy/Postgres with pgvector, and...
canonical: https://daily.dev/posts/a-blog-mcp-server-with-fastmcp-and-pgvector-2orqqbrig
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: A Blog MCP Server with FastMCP and pgvector | daily.dev
og:description: A detailed walkthrough of building an MCP server that powers a blog-writing AI assistant, combining FastAPI, FastMCP, SQLAlchemy/Postgres with pgvector, and...
og:url: https://daily.dev/posts/a-blog-mcp-server-with-fastmcp-and-pgvector-2orqqbrig
og:image: https://api.daily.dev/og/posts/2ORqqbRIg.png
og:image:alt: A Blog MCP Server with FastMCP and pgvector
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# A Blog MCP Server with FastMCP and pgvector

**[RUBYLAND](https://daily.dev/sources/rubyla)** · 20 min read · 0 upvotes · 0 comments

## Summary

A detailed walkthrough of building an MCP server that powers a blog-writing AI assistant, combining FastAPI, FastMCP, SQLAlchemy/Postgres with pgvector, and Voyage embeddings. Covers the ingestion pipeline that syncs Jekyll markdown posts via GitHub commit diffs, embedding strategy using Voyage's document vs query input types, the design split between MCP tools and resources, docstring-as-interface practices for model-facing tool descriptions, testing with the MCP Inspector, and the accompanying Claude Code plugin built from skill markdown files that fetch style rules as resources rather than hardcoding them.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://www.ombulabs.ai/blog/blog-mcp-server-fastmcp-pgvector.html>

## Questions this post answers

### Why does an MCP server need stateless_http=True instead of the default session-based Streamable HTTP transport?

Session-based Streamable HTTP keeps session state on the server and hands the client a session ID, which breaks when the server restarts (for example on a daily dyno restart) because the client holds a session ID the server no longer recognizes, producing a spec-compliant 404 that only reconnecting fixes. Setting stateless_http=True in FastMCP avoids this by not relying on server-held session state.

_Anyone deploying MCP servers on ephemeral infrastructure can find deployment gotchas like this one on daily.dev._

### What changed in the MCP protocol's 2026-07-28 revision regarding session handling?

The 2026-07-28 Model Context Protocol revision retires sessions entirely, removing the Mcp-Session-Id header and the initialize handshake. What was previously a workaround (using stateless HTTP to dodge stale session IDs after server restarts) is now simply how the transport works by default, so stateless behavior is the only path going forward rather than an optional choice.

_Developers tracking MCP protocol changes before they hit production can follow updates like this on daily.dev._

### Why do you need two different embedding calls for search queries versus documents when using Voyage AI embeddings?

Voyage AI models take an input_type parameter of either 'document' or 'query', and passing the correct one matters because a short search phrase is embedded differently than a long document due to their asymmetric nature. This is why a semantic search system needs two separate functions: one that embeds a short natural-language query and another that embeds an entire draft as a document, producing meaningfully better similarity results.

_Teams building semantic search with embedding models can compare implementation trade-offs like these on daily.dev._

## Similar posts on daily.dev

- [How to Build MCP Servers for Your Internal Data](https://daily.dev/posts/how-to-build-mcp-servers-for-your-internal-data-mal9z290q) · freeCodeCamp · 3 upvotes · 0 comments
- [AI Assistant for Our Blog Writing Process](https://daily.dev/posts/ai-assistant-for-our-blog-writing-process-uduobqhmo) · RUBYLAND · 1 upvotes · 0 comments
- [5 Lines of Code Turned My FastAPI App Into Dozens of AI-Agent Tools](https://daily.dev/posts/5-lines-of-code-turned-my-fastapi-app-into-dozens-of-ai-agent-tools-qm2z1l1vm) · Medium · 0 upvotes · 0 comments
- [Build and Deploy an App Prototype with an AI Agent using MCP in an Afternoon](https://daily.dev/posts/build-and-deploy-an-app-prototype-with-an-ai-agent-using-mcp-in-an-afternoon-hdtdzu1ly) · SingleStore · 0 upvotes · 0 comments

---

Tags: [#python](https://daily.dev/tags/python), [#mcp](https://daily.dev/tags/mcp), [#claude-code](https://daily.dev/tags/claude-code), [#pgvector](https://daily.dev/tags/pgvector)

[View this post on daily.dev](https://daily.dev/posts/a-blog-mcp-server-with-fastmcp-and-pgvector-2orqqbrig)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"A Blog MCP Server with FastMCP and pgvector","url":"https://daily.dev/posts/a-blog-mcp-server-with-fastmcp-and-pgvector-2orqqbrig","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/a-blog-mcp-server-with-fastmcp-and-pgvector-2orqqbrig"},"datePublished":"2026-08-19T19:24:29.115Z","dateModified":"2026-09-14T08:07:06.026Z","description":"A detailed walkthrough of building an MCP server that powers a blog-writing AI assistant, combining FastAPI, FastMCP, SQLAlchemy/Postgres with pgvector, and...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/13b2e602aab7e3633709b145691d77ba?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/13b2e602aab7e3633709b145691d77ba?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"RUBYLAND","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"RUBYLAND","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/rubyla","url":"https://daily.dev/sources/rubyla"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/a-blog-mcp-server-with-fastmcp-and-pgvector-2orqqbrig","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"python,mcp,claude-code,pgvector","timeRequired":"PT20M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"RUBYLAND","item":"https://daily.dev/sources/rubyla"},{"@type":"ListItem","position":3,"name":"A Blog MCP Server with FastMCP and pgvector"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/a-blog-mcp-server-with-fastmcp-and-pgvector-2orqqbrig#faq","mainEntity":[{"@type":"Question","name":"Why does an MCP server need stateless_http=True instead of the default session-based Streamable HTTP transport?","acceptedAnswer":{"@type":"Answer","text":"Session-based Streamable HTTP keeps session state on the server and hands the client a session ID, which breaks when the server restarts (for example on a daily dyno restart) because the client holds a session ID the server no longer recognizes, producing a spec-compliant 404 that only reconnecting fixes. Setting stateless_http=True in FastMCP avoids this by not relying on server-held session state. Anyone deploying MCP servers on ephemeral infrastructure can find deployment gotchas like this one on daily.dev."}},{"@type":"Question","name":"What changed in the MCP protocol's 2026-07-28 revision regarding session handling?","acceptedAnswer":{"@type":"Answer","text":"The 2026-07-28 Model Context Protocol revision retires sessions entirely, removing the Mcp-Session-Id header and the initialize handshake. What was previously a workaround (using stateless HTTP to dodge stale session IDs after server restarts) is now simply how the transport works by default, so stateless behavior is the only path going forward rather than an optional choice. Developers tracking MCP protocol changes before they hit production can follow updates like this on daily.dev."}},{"@type":"Question","name":"Why do you need two different embedding calls for search queries versus documents when using Voyage AI embeddings?","acceptedAnswer":{"@type":"Answer","text":"Voyage AI models take an input_type parameter of either 'document' or 'query', and passing the correct one matters because a short search phrase is embedded differently than a long document due to their asymmetric nature. This is why a semantic search system needs two separate functions: one that embeds a short natural-language query and another that embeds an entire draft as a document, producing meaningfully better similarity results. Teams building semantic search with embedding models can compare implementation trade-offs like these on daily.dev."}}]}
```

