diff --git a/prds/MCP Server for markdown-site.md b/prds/MCP Server for markdown-site.md new file mode 100644 index 0000000..ed5cb80 --- /dev/null +++ b/prds/MCP Server for markdown-site.md @@ -0,0 +1,115 @@ +# MCP Server for markdown-site + +Add MCP server capability so this blog can serve as a content source for AI tools like Cursor. When users fork the repo, they can run their own MCP server connected to their Convex deployment. + +## Architecture + +```mermaid +flowchart LR + subgraph local [Local Machine] + Cursor[Cursor/AI Client] + MCP[MCP Server] + end + + subgraph cloud [Convex Cloud] + Convex[(Convex DB)] + Queries[Existing Queries] + end + + Cursor -->|MCP Protocol| MCP + MCP -->|ConvexHttpClient| Queries + Queries --> Convex +``` + +## Files to create + +### 1. MCP Server Script + +Create `scripts/mcp-server.ts` + +- Connects to Convex using `ConvexHttpClient` (same pattern as `scripts/sync-posts.ts`) +- Implements MCP protocol via stdio transport +- Exposes tools that wrap existing Convex queries: + - `list_posts` calls `api.posts.getAllPosts` + - `get_post` calls `api.posts.getPostBySlug` + - `list_pages` calls `api.pages.getAllPages` + - `get_page` calls `api.pages.getPageBySlug` + - `search_content` calls `api.search.search` + - `export_all` returns all posts with full content + +### 2. Package updates + +Update `package.json` + +- Add dependency: `@modelcontextprotocol/sdk` +- Add script: `"mcp": "tsx scripts/mcp-server.ts"` + +## Files to update + +### 3. Documentation + +Update `README.md` with MCP Server section: +- How to start the MCP server +- Cursor configuration example +- Available tools list + +Update `content/pages/docs.md` with MCP documentation + +Update `files.md` with new script description + +Update `changelog.md` with new feature + +## MCP Tools specification + +| Tool | Description | Convex Query | +|------|-------------|--------------| +| `list_posts` | Get all published posts | `api.posts.getAllPosts` | +| `get_post` | Get post by slug | `api.posts.getPostBySlug` | +| `list_pages` | Get all published pages | `api.pages.getAllPages` | +| `get_page` | Get page by slug | `api.pages.getPageBySlug` | +| `search_content` | Full text search | `api.search.search` | +| `export_all` | Batch export all content | Multiple queries | + +## User workflow after fork + +```bash +# Install dependencies +npm install + +# Start MCP server (reads VITE_CONVEX_URL from .env.local) +npm run mcp +``` + +Cursor config (`~/.cursor/mcp.json`): +```json +{ + "mcpServers": { + "my-blog": { + "command": "npm", + "args": ["run", "mcp"], + "cwd": "/path/to/blog", + "env": { + "VITE_CONVEX_URL": "https://deployment.convex.cloud" + } + } + } +} +``` + +## Security + +- Read-only access only (no mutations exposed) +- Uses existing Convex queries (same access as public API) +- Each user runs their own MCP server locally +- No authentication needed (blog content is public) + +## Implementation todos + +1. Add `@modelcontextprotocol/sdk` dependency to package.json +2. Create `scripts/mcp-server.ts` with MCP protocol implementation +3. Add `mcp` script to package.json +4. Add MCP Server section to README.md +5. Add MCP documentation to content/pages/docs.md +6. Add mcp-server.ts to files.md +7. Add MCP feature to changelog.md + diff --git a/public/raw/index.md b/public/raw/index.md new file mode 100644 index 0000000..4411ce5 --- /dev/null +++ b/public/raw/index.md @@ -0,0 +1,42 @@ +# Homepage + +This is the homepage index of all published content. + +## Blog Posts (11) + +- **[Netlify edge functions blocking AI crawlers from static files](/raw/netlify-edge-excludedpath-ai-crawlers.md)** - Why excludedPath in netlify.toml isn't preventing edge functions from intercepting /raw/* requests, and how ChatGPT and Perplexity get blocked while Claude works. + - Date: 2025-12-21 | Reading time: 4 min read | Tags: netlify, edge-functions, ai, troubleshooting, help +- **[Visitor tracking and stats improvements](/raw/visitor-tracking-and-stats-improvements.md)** - Real-time visitor map, write conflict prevention, GitHub Stars integration, and better AI prompts. Updates from v1.18.1 to v1.20.2. + - Date: 2025-12-21 | Reading time: 5 min read | Tags: features, stats, convex, updates, analytics +- **[Configure your fork in one command](/raw/fork-configuration-guide.md)** - Two options to set up your forked markdown framework: automated JSON config with npm run configure, or step-by-step manual guide. + - Date: 2025-12-20 | Reading time: 4 min read | Tags: configuration, setup, fork, tutorial +- **[v1.18.0 release: 12 versions of shipping](/raw/raw-markdown-and-copy-improvements.md)** - Everything new from v1.7 to v1.18.0. Automated fork setup, GitHub contributions graph, write page, mobile menu, aggregates, and more. + - Date: 2025-12-20 | Reading time: 8 min read | Tags: release, features, updates, developer-tools +- **[New features: search, featured section, and logo gallery](/raw/new-features-search-featured-logos.md)** - Three updates that make your markdown framework more useful: Command+K search, frontmatter-controlled featured items, and a scrolling logo gallery. + - Date: 2025-12-17 | Reading time: 4 min read | Tags: features, search, convex, updates +- **[About This Markdown Framework](/raw/about-this-blog.md)** - How this open source framework works with Convex for real-time sync and Netlify for deployment. + - Date: 2025-12-14 | Reading time: 4 min read | Tags: convex, netlify, open-source, markdown, ai, llm +- **[How to Publish a Blog Post](/raw/how-to-publish.md)** - A quick guide to writing and publishing markdown posts using Cursor after your framework is set up. + - Date: 2025-12-14 | Reading time: 3 min read | Tags: tutorial, markdown, cursor, IDE, publishing +- **[Writing Markdown with Code Examples](/raw/markdown-with-code-examples.md)** - A complete reference for writing markdown with links, code blocks, images, tables, and formatting. Copy examples directly into your posts. + - Date: 2025-12-14 | Reading time: 5 min read | Tags: markdown, tutorial, code +- **[Setup Guide - Fork and Deploy Your Own Markdown Framework](/raw/setup-guide.md)** - Step-by-step guide to fork this markdown sync framework, set up Convex backend, and deploy to Netlify in under 10 minutes. + - Date: 2025-12-14 | Reading time: 8 min read | Tags: convex, netlify, tutorial, deployment +- **[Using Images in Blog Posts](/raw/using-images-in-posts.md)** - Learn how to add header images, inline images, and Open Graph images to your markdown posts. + - Date: 2025-12-14 | Reading time: 4 min read | Tags: images, tutorial, markdown, open-graph +- **[Git commit message best practices](/raw/git-commit-message-best-practices.md)** - A guide to writing clear, consistent commit messages that help your team understand changes and generate better changelogs. + - Date: 2025-01-17 | Reading time: 5 min read | Tags: git, development, best-practices, workflow + +## Pages (5) + +- **[Docs](/raw/docs.md)** +- **[About](/raw/about.md)** - An open-source publishing framework for AI agents and developers. +- **[Projects](/raw/projects.md)** +- **[Contact](/raw/contact.md)** +- **[Changelog](/raw/changelog.md)** + +--- + +**Total Content:** 11 posts, 5 pages + +All content is available as raw markdown files at `/raw/{slug}.md` diff --git a/scripts/sync-posts.ts b/scripts/sync-posts.ts index 3828786..49f7d6d 100644 --- a/scripts/sync-posts.ts +++ b/scripts/sync-posts.ts @@ -341,7 +341,7 @@ function generateRawMarkdownFile( date: string, tags: string[], readTime?: string, - type: "post" | "page" = "post" + type: "post" | "page" = "post", ): void { // Ensure raw output directory exists if (!fs.existsSync(RAW_OUTPUT_DIR)) { @@ -375,10 +375,7 @@ function generateRawMarkdownFile( } // Generate homepage index markdown file listing all posts -function generateHomepageIndex( - posts: ParsedPost[], - pages: ParsedPage[] -): void { +function generateHomepageIndex(posts: ParsedPost[], pages: ParsedPage[]): void { const publishedPosts = posts.filter((p) => p.published); const publishedPages = pages.filter((p) => p.published); @@ -448,7 +445,7 @@ function generateHomepageIndex( // Generate all raw markdown files during sync function generateRawMarkdownFiles( posts: ParsedPost[], - pages: ParsedPage[] + pages: ParsedPage[], ): void { console.log("\nGenerating static markdown files in public/raw/..."); @@ -473,7 +470,7 @@ function generateRawMarkdownFiles( post.date, post.tags, post.readTime, - "post" + "post", ); } @@ -488,7 +485,7 @@ function generateRawMarkdownFiles( new Date().toISOString().split("T")[0], // pages don't have date [], // pages don't have tags undefined, - "page" + "page", ); } @@ -496,7 +493,7 @@ function generateRawMarkdownFiles( generateHomepageIndex(posts, pages); console.log( - `Generated ${publishedPosts.length} post files, ${publishedPages.length} page files, and 1 index file` + `Generated ${publishedPosts.length} post files, ${publishedPages.length} page files, and 1 index file`, ); }