Feedmon Docs
Feedmon Skills Reference
Human-facing view of the same MCP skills document published under .well-known.
/.well-known/skills.md
markdown
# Feedmon machine-readable skills
Feedmon exposes a small MCP-focused surface for two workflows:
1. Fetch recent posts from the user's configured feeds.
2. Train the matcher with swipe-style feedback.
**Base URL:** use the same origin as this document, for example `http://localhost:8080`.
---
## Recent posts
| Skill | Method | Path | Description |
|-------|--------|------|-------------|
| Get recent posts | `GET` | `/api/posts/recent` | Returns up to 100 recent posts from configured feeds as JSON. Uses the same filters as `/posts`: `status=all|new`, `days=<n>` (default `7`, use `0` for all time), `subreddit=<name>`, and `min_score=<n>`. Each row includes `id`, `reddit_id`, `subreddit`, `title`, `author`, `url`, `permalink`, `content`, `published_at`, `discovered_at`, `matched_keywords`, `relevance_score`, `status`, `feed_name`, `feed_city`, `feed_province`, and `comment_count`. |
Use this endpoint when an agent needs the newest posts already discovered from the user's monitored subreddits.
`content` is the best-effort body-like text used for downstream analysis. It comes from rfetcher's `thread.Content` stream field and is derived from the Reddit RSS item description, so it may be empty, HTML-stripped, whitespace-normalized, and truncated to 2000 characters. Analyze `content` when present; if it is empty, rely on `title`.
---
## Training
| Skill | Method | Path | Description |
|-------|--------|------|-------------|
| Get posts to rate | `GET` | `/api/train/posts` | Returns up to 100 unrated training candidates with stored match evidence, ordered so literal hits and stronger candidates surface first. Use `?for_agent=1` to omit `relevance_score`; the response still includes `id`, `title`, `content`, `subreddit`, `matched_keywords`, and related metadata. `content` is optional best-effort RSS-derived text, not guaranteed full Reddit self-post body text. |
| Record feedback | `POST` | `/api/train/feedback` | Body: `{"post_id": <id>, "rating": "Excellent" \| "Good" \| "Bad"}`. Ratings are case-insensitive. `Good` maps to the canonical `acceptable` rating stored by Feedmon. |
| Undo feedback | `POST` | `/api/train/undo` | Body: `{"post_id": <id>}`. Removes the latest feedback for that post and reverts the learned-weight updates. |
| Get training stats | `GET` | `/api/train/stats` | Returns training progress JSON including `rated_today`, `rated_total`, and `daily_goal`. |
**Training loop:** `GET /api/train/posts` → choose `Excellent`, `Good`, or `Bad` for each post → `POST /api/train/feedback` with `post_id` and `rating` → optionally `POST /api/train/undo`.
---
## Human docs
- MCP manifest: [`/.well-known/mcp.json`](/.well-known/mcp.json)
- Skills document: [`/.well-known/skills.md`](/.well-known/skills.md)
- Human-friendly MCP page: [`/docs/mcp`](/docs/mcp)
- Human-friendly skills page: [`/docs/skills`](/docs/skills)
- Training UI: [`/train`](/train)
- Posts UI: [`/posts`](/posts)
---
## Implementation references
| Concern | Location |
|---------|----------|
| Route registration | `feedmon/web/handler.go` |
| Shared post filtering for `/posts` and MCP recent posts | `feedmon/web/routes.go` |
| Training handlers | `feedmon/web/train.go` |
| Well-known file serving | `feedmon/web/wellknown.go` |
| skills.md / mcp.json content | `feedmon/web/wellknown/` |
---
*Update this file when adding or removing MCP-facing routes.*