内容
# Markdown 博客
一个使用 FastAPI 构建的极简博客。`content/` 目录下的每个 `.md` 文件都成为一个页面。
- `content/home.md` → `/`(首页)
- `content/my-post.md` → `/posts/my-post`
该博客还在 `/mcp/` 处公开了一个 MCP 服务器,支持 OAuth DCR(RFC 8414/7591),用于 Claude.ai 兼容性。
## 本地开发
```bash
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
export PUBLIC_URL=http://localhost:8000
uvicorn app.main:app --reload
```
打开 http://localhost:8000
## 添加帖子
在 `content/` 目录下创建文件:
```markdown
---
title: 我的帖子标题
---
这里是你的 Markdown 内容。
```
如果省略 `title`,则使用文件名(例如 `my-cool-post.md` → "我的酷帖子")。
您还可以通过 MCP 的 `create_blog_post` 工具创建帖子(参见下文)。
## MCP 服务器
MCP 端点位于 `/mcp/`。它使用 OAuth 2.1 和动态客户端注册,以便 Claude.ai 可以自动连接。
### 环境变量
| 变量 | 是否必需 | 描述 |
| --- | --- | --- |
| `PUBLIC_URL` | 是(生产环境) | 公共基准 URL,例如 `https://your-app.railway.app`。本地默认为 `http://localhost:8000`。
### OAuth 发现端点
- `/.well-known/oauth-authorization-server/mcp` — RFC 8414 授权服务器元数据
- `/.well-known/oauth-protected-resource/mcp` — RFC 9728 受保护资源元数据
- `/mcp/register` — RFC 7591 动态客户端注册
- `/mcp/authorize` — OAuth 授权(显示一个简单的登录页面)
- `/mcp/token` —令牌交换
### 从 Claude.ai 连接
1. 使用 `PUBLIC_URL` 部署应用程序,并设置为您的公共域名
2. 在 Claude.ai → 设置 → 连接器 → 添加 MCP 服务器
3. 输入 `https://your-domain/mcp`(不带尾部斜杠)
4. Claude.ai 发现 OAuth 元数据,通过 DCR 注册,并打开登录页面
5. 点击 **登录** 以授权
6. 请求 Claude.ai 创建帖子,例如 "创建一个标题为 Hello MCP 的博客帖子,slug 为 hello-mcp"
### 可用工具
| 工具 | 描述 |
| --- | --- |
| `create_blog_post` | 创建一个新的 Markdown 帖子(`slug`、`title`、`content`) |
### 本地测试
验证 OAuth 元数据是否可达:
```bash
curl http://localhost:8000/.well-known/oauth-authorization-server/mcp
```
您应该看到一个 JSON 对象,其中 `registration_endpoint` 指向 `/mcp/register`。
## 部署到 Railway(免费层)
1. 将此仓库推送到 GitHub
2. 进入 [railway.app](https://railway.app) 并创建一个新项目
3. 选择 **从 GitHub 仓库部署** 并选择此仓库
4. Railway 通过 `requirements.txt` 自动检测 Python,并使用 `railway.toml` 作为启动命令
5. 您的应用程序在 **设置 → 网络 → 生成域名** 下获得一个公共 URL
6. 将环境变量 `PUBLIC_URL` 设置为您的 Railway 域名(例如 `https://your-app.up.railway.app`)
### 持久性说明
通过 MCP 创建的帖子写入 `content/` 目录下的容器文件系统。Railway 的文件系统是短暂的 — 在重新部署时帖子会丢失。为了实现持久存储,在 `content/` 目录下挂载 Railway 卷或将帖子提交到 git。