feat: added HTTP-Based MCP Server on Netlify

This commit is contained in:
Wayne Sutton
2025-12-27 22:18:03 -08:00
parent d6e76f6e39
commit 01ac2a01c7
21 changed files with 1850 additions and 24 deletions

View File

@@ -123,6 +123,7 @@ Content here...
| `blogFeatured` | No | Show as featured on blog page (first becomes hero, rest in 2-column row) |
| `newsletter` | No | Override newsletter signup display (`true` to show, `false` to hide) |
| `contactForm` | No | Enable contact form on this post |
| `showImageAtTop` | No | Set `true` to display the `image` field at the top of the post above the header (default: `false`) |
### Static pages
@@ -161,9 +162,12 @@ Content here...
| `aiChat` | No | Enable AI chat in right sidebar. Set `true` to enable (requires `rightSidebar: true` and `siteConfig.aiChat.enabledOnContent: true`). Set `false` to explicitly hide even if global config is enabled. |
| `newsletter` | No | Override newsletter signup display (`true` to show, `false` to hide) |
| `contactForm` | No | Enable contact form on this page |
| `showImageAtTop` | No | Set `true` to display the `image` field at the top of the page above the header (default: `false`) |
**Hide pages from navigation:** Set `showInNav: false` to keep a page published and accessible via direct URL, but hidden from the navigation menu. Pages with `showInNav: false` remain searchable and available via API endpoints. Useful for pages you want to link directly but not show in the main nav.
**Show image at top:** Add `showImageAtTop: true` to display the `image` field at the top of the post/page above the header. Default behavior: if `showImageAtTop` is not set or `false`, image only used for Open Graph previews and featured card thumbnails.
### Sidebar layout
Posts and pages can use a docs-style layout with a table of contents sidebar. Add `layout: "sidebar"` to the frontmatter:
@@ -752,6 +756,14 @@ The `npm run sync` command only syncs markdown text content. Images are deployed
- **Homepage logo:** Configured via `logo` in `siteConfig.ts`. Set to `null` to hide.
- **Inner page logo:** Configured via `innerPageLogo` in `siteConfig.ts`. Shows on blog page, posts, and static pages. Desktop: top left corner. Mobile: top right corner (smaller). Set `enabled: false` to hide on inner pages while keeping homepage logo.
## Tag Pages and Related Posts
Tag pages are available at `/tags/[tag]` for each tag used in your posts. They display all posts with that tag in a list or card view with localStorage persistence for view mode preference.
**Related posts:** Individual blog posts show up to 3 related posts in the footer based on shared tags. Posts are sorted by relevance (number of shared tags) then by date. Only appears on blog posts (not static pages).
**Tag links:** Tags in post footers link to their respective tag archive pages.
## Search
Press `Command+K` (Mac) or `Ctrl+K` (Windows/Linux) to open the search modal. Click the search icon in the nav or use the keyboard shortcut.
@@ -802,6 +814,68 @@ Each post and page includes a share dropdown with options:
**Download as SKILL.md:** Downloads the content formatted as an Anthropic Agent Skills file with metadata, triggers, and instructions sections.
## Homepage Post Limit
Limit the number of posts shown on the homepage:
```typescript
postsDisplay: {
showOnHome: true,
homePostsLimit: 5, // Limit to 5 most recent posts (undefined = show all)
homePostsReadMore: {
enabled: true,
text: "Read more blog posts",
link: "/blog",
},
},
```
When posts are limited, an optional "read more" link appears below the list. Only shows when there are more posts than the limit.
## Blog Page Featured Layout
Posts can be marked as featured on the blog page using the `blogFeatured` frontmatter field:
```yaml
---
title: "My Featured Post"
blogFeatured: true
---
```
The first `blogFeatured` post displays as a hero card with landscape image, tags, date, title, excerpt, author info, and read more link. Remaining `blogFeatured` posts display in a 2-column featured row with excerpts. Regular (non-featured) posts display in a 3-column grid without excerpts.
## Homepage Post Limit
Limit the number of posts shown on the homepage:
```typescript
postsDisplay: {
showOnHome: true,
homePostsLimit: 5, // Limit to 5 most recent posts (undefined = show all)
homePostsReadMore: {
enabled: true,
text: "Read more blog posts",
link: "/blog",
},
},
```
When posts are limited, an optional "read more" link appears below the list. Only shows when there are more posts than the limit.
## Blog Page Featured Layout
Posts can be marked as featured on the blog page using the `blogFeatured` frontmatter field:
```yaml
---
title: "My Featured Post"
blogFeatured: true
---
```
The first `blogFeatured` post displays as a hero card with landscape image, tags, date, title, excerpt, author info, and read more link. Remaining `blogFeatured` posts display in a 2-column featured row with excerpts. Regular (non-featured) posts display in a 3-column grid without excerpts.
## Real-time stats
The `/stats` page displays real-time analytics:

View File

@@ -91,19 +91,19 @@ If you prefer to update files manually, follow the guide in `FORK_CONFIG.md`. It
The configuration script updates these files:
| File | What changes |
| ----------------------------------- | ----------------------------------------- |
| `src/config/siteConfig.ts` | Site name, bio, GitHub username, features |
| `src/pages/Home.tsx` | Intro paragraph, footer links |
| `src/pages/Post.tsx` | SITE_URL, SITE_NAME constants |
| `convex/http.ts` | SITE_URL, SITE_NAME constants |
| `convex/rss.ts` | SITE_URL, SITE_TITLE, SITE_DESCRIPTION |
| `index.html` | Meta tags, JSON-LD, page title |
| `public/llms.txt` | Site info, GitHub link |
| `public/robots.txt` | Sitemap URL |
| `public/openapi.yaml` | Server URL, site name |
| `public/.well-known/ai-plugin.json` | Plugin metadata |
| `src/context/ThemeContext.tsx` | Default theme |
| File | What changes |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `src/config/siteConfig.ts` | Site name, bio, GitHub username, features, footer, social footer, newsletter, contact form, AI chat, right sidebar |
| `src/pages/Home.tsx` | Intro paragraph, footer links |
| `src/pages/Post.tsx` | SITE_URL, SITE_NAME constants |
| `convex/http.ts` | SITE_URL, SITE_NAME constants |
| `convex/rss.ts` | SITE_URL, SITE_TITLE, SITE_DESCRIPTION |
| `index.html` | Meta tags, JSON-LD, page title |
| `public/llms.txt` | Site info, GitHub link |
| `public/robots.txt` | Sitemap URL |
| `public/openapi.yaml` | Server URL, site name |
| `public/.well-known/ai-plugin.json` | Plugin metadata |
| `src/context/ThemeContext.tsx` | Default theme |
## Optional settings
@@ -136,15 +136,65 @@ The JSON config file supports additional options:
},
"postsDisplay": {
"showOnHome": true,
"showOnBlogPage": true
"showOnBlogPage": true,
"homePostsLimit": 5,
"homePostsReadMore": {
"enabled": true,
"text": "Read more blog posts",
"link": "/blog"
}
},
"featuredViewMode": "cards",
"showViewToggle": true,
"theme": "tan"
"theme": "tan",
"fontFamily": "serif",
"rightSidebar": {
"enabled": true,
"minWidth": 1135
},
"footer": {
"enabled": true,
"showOnHomepage": true,
"showOnPosts": true,
"showOnPages": true,
"showOnBlogPage": true
},
"socialFooter": {
"enabled": true,
"showOnHomepage": true,
"showOnPosts": true,
"showOnPages": true,
"showOnBlogPage": true,
"socialLinks": [
{
"platform": "github",
"url": "https://github.com/yourusername/your-repo-name"
}
],
"copyright": {
"siteName": "Your Site Name",
"showYear": true
}
},
"aiChat": {
"enabledOnWritePage": false,
"enabledOnContent": false
},
"newsletter": {
"enabled": false,
"signup": {
"home": { "enabled": false },
"blogPage": { "enabled": false },
"posts": { "enabled": false }
}
},
"contactForm": {
"enabled": false
}
}
```
These are optional. If you omit them, the script uses sensible defaults.
These are optional. If you omit them, the script uses sensible defaults. See `fork-config.json.example` for the complete schema with all available options.
## After configuring

View File

@@ -4,7 +4,7 @@
---
Type: post
Date: 2025-12-20
Date: 2025-12-26
Reading time: 2 min read
Tags: tutorial, firecrawl, import
---

View File

@@ -6,16 +6,14 @@ This is the homepage index of all published content.
- **[How to use AgentMail with Markdown Sync](/raw/how-to-use-agentmail.md)** - Complete guide to setting up AgentMail for newsletters and contact forms in your markdown blog
- Date: 2025-12-27 | Reading time: 5 min read | Tags: agentmail, newsletter, email, setup
- **[How to use Firecrawl](/raw/how-to-use-firecrawl.md)** - Import external articles as markdown posts using Firecrawl. Get your API key and configure environment variables for local imports and AI chat.
- Date: 2025-12-26 | Reading time: 2 min read | Tags: tutorial, firecrawl, import
- **[Happy holidays and thank you](/raw/happy-holidays-2025.md)** - A quick note of thanks for stars, forks, and feedback. More AI-first publishing features coming in 2026.
- Date: 2025-12-25 | Reading time: 2 min read | Tags: updates, community, ai
- **[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: 5 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
- **[How to use Firecrawl](/raw/how-to-use-firecrawl.md)** - Import external articles as markdown posts using Firecrawl. Get your API key and configure environment variables for local imports and AI chat.
- Date: 2025-12-20 | Reading time: 2 min read | Tags: tutorial, firecrawl, import
- **[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.
@@ -26,6 +24,8 @@ This is the homepage index of all published content.
- 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
- **[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-14 | Reading time: 5 min read | Tags: netlify, edge-functions, ai, troubleshooting, help
- **[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.

View File

@@ -4,7 +4,7 @@
---
Type: post
Date: 2025-12-21
Date: 2025-12-14
Reading time: 5 min read
Tags: netlify, edge-functions, ai, troubleshooting, help
---

View File

@@ -877,6 +877,37 @@ Cards display post thumbnails (from `image` frontmatter field), titles, excerpts
**View preference:** User's view mode choice is saved to localStorage and persists across page visits.
**Blog page featured layout:**
Posts can be marked as featured on the blog page using the `blogFeatured` frontmatter field:
```yaml
---
title: "My Featured Post"
blogFeatured: true
---
```
The first `blogFeatured` post displays as a hero card with landscape image, tags, date, title, excerpt, author info, and read more link. Remaining `blogFeatured` posts display in a 2-column featured row with excerpts. Regular (non-featured) posts display in a 3-column grid without excerpts.
### Homepage Post Limit
Limit the number of posts shown on the homepage:
```typescript
postsDisplay: {
showOnHome: true,
homePostsLimit: 5, // Limit to 5 most recent posts (undefined = show all)
homePostsReadMore: {
enabled: true,
text: "Read more blog posts",
link: "/blog",
},
},
```
When posts are limited, an optional "read more" link appears below the list. Only shows when there are more posts than the limit.
### Hardcoded Navigation Items
Add React route pages (like `/stats`, `/write`) to the navigation menu via `siteConfig.ts`. These pages are React components, not markdown files.
@@ -1044,6 +1075,14 @@ Pages appear automatically in the navigation when published.
**Right sidebar:** When enabled in `siteConfig.rightSidebar.enabled`, posts and pages can display a right sidebar containing the CopyPageDropdown at 1135px+ viewport width. Add `rightSidebar: true` to frontmatter to enable. Without this field, pages render normally with CopyPageDropdown in the nav bar. When enabled, CopyPageDropdown moves from the navigation bar to the right sidebar on wide screens. The right sidebar is hidden below 1135px, and CopyPageDropdown returns to the nav bar automatically.
**Show image at top:** Add `showImageAtTop: true` to display the `image` field at the top of the post/page above the header. Default behavior: if `showImageAtTop` is not set or `false`, image only used for Open Graph previews and featured card thumbnails.
**Footer:** Footer content can be set in frontmatter (`footer` field) or use `siteConfig.footer.defaultContent`. Control visibility globally via `siteConfig.footer.enabled` and per-page via `showFooter: true/false` frontmatter.
**Social footer:** Display social icons and copyright below the main footer. Configure via `siteConfig.socialFooter`. Control visibility per-page via `showSocialFooter: true/false` frontmatter.
**Contact form:** Enable contact forms on any page or post via `contactForm: true` frontmatter. Requires `AGENTMAIL_API_KEY` and `AGENTMAIL_INBOX` environment variables in Convex. See the [Contact Form section](#contact-form-configuration) below.
**AI Agent chat:** The site includes an AI writing assistant (Agent) powered by Anthropic Claude API. Enable Agent on the Write page via `siteConfig.aiChat.enabledOnWritePage` or in the right sidebar on posts/pages using `aiChat: true` frontmatter (requires `rightSidebar: true`). Requires `ANTHROPIC_API_KEY` environment variable in Convex. See the [AI Agent chat section](#ai-agent-chat) below for setup instructions.
### Update SEO Meta Tags
@@ -1059,6 +1098,14 @@ Edit `index.html` to update:
Edit `public/llms.txt` and `public/robots.txt` with your site information.
## Tag Pages and Related Posts
Tag pages are available at `/tags/[tag]` for each tag used in your posts. They display all posts with that tag in a list or card view.
**Related posts:** Individual blog posts show up to 3 related posts in the footer based on shared tags. Posts are sorted by relevance (number of shared tags) then by date. Only appears on blog posts (not static pages).
**Tag links:** Tags in post footers link to their respective tag archive pages.
## Search
Your blog includes full text search with Command+K keyboard shortcut.
@@ -1101,6 +1148,137 @@ How it works:
- A cron job cleans up stale sessions every 5 minutes
- No personal data is stored (only anonymous UUIDs)
## Footer Configuration
The footer component displays markdown content and can be configured globally or per-page.
**Global configuration:**
In `src/config/siteConfig.ts`:
```typescript
footer: {
enabled: true, // Global toggle for footer
showOnHomepage: true, // Show footer on homepage
showOnPosts: true, // Default: show footer on blog posts
showOnPages: true, // Default: show footer on static pages
showOnBlogPage: true, // Show footer on /blog page
defaultContent: "...", // Default markdown content
},
```
**Frontmatter override:**
Set `showFooter: false` in post/page frontmatter to hide footer on specific pages. Set `footer: "..."` to provide custom markdown content.
**Footer images:** Footer markdown supports images with size control via HTML attributes (`width`, `height`, `style`, `class`).
## Social Footer Configuration
Display social icons and copyright information below the main footer.
**Configuration:**
In `src/config/siteConfig.ts`:
```typescript
socialFooter: {
enabled: true,
showOnHomepage: true,
showOnPosts: true,
showOnPages: true,
showOnBlogPage: true,
socialLinks: [
{ platform: "github", url: "https://github.com/username" },
{ platform: "twitter", url: "https://x.com/handle" },
{ platform: "linkedin", url: "https://linkedin.com/in/profile" },
],
copyright: {
siteName: "Your Site Name",
showYear: true, // Auto-updates to current year
},
},
```
**Supported platforms:** github, twitter, linkedin, instagram, youtube, tiktok, discord, website
**Frontmatter override:**
Set `showSocialFooter: false` in post/page frontmatter to hide social footer on specific pages.
## Right Sidebar Configuration
Enable a right sidebar on posts and pages that displays CopyPageDropdown at wide viewport widths.
**Configuration:**
In `src/config/siteConfig.ts`:
```typescript
rightSidebar: {
enabled: true, // Set to false to disable globally
minWidth: 1135, // Minimum viewport width to show sidebar
},
```
**Frontmatter usage:**
Enable right sidebar on specific posts/pages:
```yaml
---
title: My Post
rightSidebar: true
---
```
**Features:**
- Right sidebar appears at 1135px+ viewport width
- Contains CopyPageDropdown with sharing options
- Three-column layout: left sidebar (TOC), main content, right sidebar
- Hidden below 1135px, CopyPageDropdown returns to nav
## Contact Form Configuration
Enable contact forms on any page or post via frontmatter. Messages are sent via AgentMail.
**Environment Variables:**
Set these in the Convex dashboard:
| Variable | Description |
| ------------------------- | --------------------------------------------------------------------------- |
| `AGENTMAIL_API_KEY` | Your AgentMail API key |
| `AGENTMAIL_INBOX` | Your inbox address for sending |
| `AGENTMAIL_CONTACT_EMAIL` | Optional: recipient for contact form messages (defaults to AGENTMAIL_INBOX) |
**Site Config:**
In `src/config/siteConfig.ts`:
```typescript
contactForm: {
enabled: true, // Global toggle for contact form feature
title: "Get in Touch",
description: "Send us a message and we'll get back to you.",
},
```
**Frontmatter Usage:**
Enable contact form on any page or post:
```yaml
---
title: Contact Us
slug: contact
contactForm: true
---
```
The form includes name, email, and message fields. Submissions are stored in Convex and sent via AgentMail to the configured recipient.
## Newsletter Admin
A newsletter management interface is available at `/newsletter-admin`. Use it to view subscribers, send newsletters, and compose custom emails.