reddit-mcp: read-only FastMCP-over-HTTP MCP wrapping the daily-social/daily-educational reddit reads #1

Closed
opened 2026-07-04 07:56:15 +00:00 by coilysiren · 3 comments
Owner

Goal

A small FastMCP streamable-HTTP MCP that republishes Kai's existing reddit reads as read-only tools, patterned off coilyco-flight-deck/node-stats-mcp (the reference for the FastMCP-over-HTTP server shape, the Dockerfile, and the Forgejo CI that builds and pushes the image to the in-cluster registry). Fulfils coilysiren/inbox#163 and is the first pure-read clone of the deploy#30 personal-MCP fleet.

Source of the reads (read this first)

The read logic already exists and is audited under cron. Read /substrate/agentic-os-kai/lib/my/routines/:

  • daily-social - pulls Kai's reddit inbox/unread.
  • daily-educational - pulls the reddit front page and upvoted items.

Both read private reddit JSON feed URLs from SSM under /prefs/feeds/. Take the exact routine logic, the SSM parameter names, and the feed-URL shapes from those routines - do not re-derive them. A private reddit feed URL is read-only by construction (a feed URL cannot write), which is the whole point: it deliberately sidesteps the 2026 Responsible Builder Policy API-app gate (no Reddit API app), per deploy#30.

Tools (all read-only)

Mirror what the routines pull, e.g. get_unread/get_inbox (daily-social) and get_frontpage/get_upvoted (daily-educational). Names your call - keep them faithful to the routine surface. Hard invariant from deploy#30: no write tool (no post, no vote, no comment) and no path that both ingests untrusted content and can act. This service reads, full stop.

Credential custody

Read the /prefs/feeds/* URLs from SSM at runtime, server-side (mirror the mcporter stdio fleet ssm-load pattern and node-stats' env-based config). The keys never leave the box. Never bake a feed URL into the image, the repo, or a committed config - they are private. Config comes in via env/SSM at runtime only.

Serving

  • Streamable-HTTP on a PORT env, matching node-stats' HOST/PORT convention. node-stats holds 9110; pick the next free kai-server port (e.g. 9111) and document it in the README.
  • This is a plain outbound-HTTP reader: it does NOT need hostPID/hostNetwork/hostPath/ROOTFS/readable-roots (those are node-stats' node-local machinery). Keep the source a dumb backend.
  • Do not add auth here. The Authelia/Traefik overlay is layered on in the deploy repo, not in the source (deploy#28 principle: the MCP source stays unchanged by the overlay). This repo just serves the reads over HTTP.

CI

Mirror coilyco-flight-deck/node-stats-mcp's .forgejo workflow that builds the image and pushes it to the in-cluster registry 192.168.0.194:30500 under :<sha>. That publish is exactly what the deploy rollout consumes.

Repo and house style

  • The repo coilyco-flight-deck/reddit-mcp has been created empty (auto-init, private, mirroring node-stats-mcp). Note: private mirrors node-stats but means the credential-less CD runner falls back to the running-image sha (deploy#26); public would smooth CD since the code is public-safe (no secrets in-repo). Flag the public option in the WARD-OUTCOME but default to private.
  • Scaffold the README / AGENTS / docs/FEATURES trifecta and run pre-commit run --all-files before committing per house style.

Out of scope

  • The k8s deploy wiring (namespace/main.yml, Ingress, Authelia client, values.env) - that is the coilyco-bridge/deploy clean-clone issue, blocked on this repo publishing an image plus the RBAC and shared-rollout DRY substrate.

Refs

Provenance: director surface session, 2026-07-04.

## Goal A small **FastMCP streamable-HTTP** MCP that republishes Kai's existing reddit reads as **read-only** tools, patterned off `coilyco-flight-deck/node-stats-mcp` (the reference for the FastMCP-over-HTTP server shape, the Dockerfile, and the Forgejo CI that builds and pushes the image to the in-cluster registry). Fulfils `coilysiren/inbox#163` and is the first pure-read clone of the deploy#30 personal-MCP fleet. ## Source of the reads (read this first) The read logic already exists and is audited under cron. Read `/substrate/agentic-os-kai/lib/my/routines/`: - **daily-social** - pulls Kai's reddit inbox/unread. - **daily-educational** - pulls the reddit front page and upvoted items. Both read **private reddit JSON feed URLs from SSM** under `/prefs/feeds/`. Take the exact routine logic, the SSM parameter names, and the feed-URL shapes from those routines - do not re-derive them. A private reddit feed URL is **read-only by construction** (a feed URL cannot write), which is the whole point: it deliberately sidesteps the 2026 Responsible Builder Policy API-app gate (no Reddit API app), per deploy#30. ## Tools (all read-only) Mirror what the routines pull, e.g. `get_unread`/`get_inbox` (daily-social) and `get_frontpage`/`get_upvoted` (daily-educational). Names your call - keep them faithful to the routine surface. Hard invariant from deploy#30: **no write tool** (no post, no vote, no comment) and no path that both ingests untrusted content and can act. This service reads, full stop. ## Credential custody Read the `/prefs/feeds/*` URLs from **SSM at runtime, server-side** (mirror the mcporter stdio fleet `ssm-load` pattern and node-stats' env-based config). The keys never leave the box. **Never** bake a feed URL into the image, the repo, or a committed config - they are private. Config comes in via env/SSM at runtime only. ## Serving - Streamable-HTTP on a `PORT` env, matching node-stats' `HOST`/`PORT` convention. node-stats holds `9110`; pick the next free kai-server port (e.g. `9111`) and document it in the README. - This is a **plain outbound-HTTP reader**: it does NOT need `hostPID`/`hostNetwork`/`hostPath`/`ROOTFS`/readable-roots (those are node-stats' node-local machinery). Keep the source a dumb backend. - Do **not** add auth here. The Authelia/Traefik overlay is layered on in the deploy repo, not in the source (deploy#28 principle: the MCP source stays unchanged by the overlay). This repo just serves the reads over HTTP. ## CI Mirror `coilyco-flight-deck/node-stats-mcp`'s `.forgejo` workflow that builds the image and pushes it to the in-cluster registry `192.168.0.194:30500` under `:<sha>`. That publish is exactly what the deploy rollout consumes. ## Repo and house style - The repo `coilyco-flight-deck/reddit-mcp` has been created empty (auto-init, private, mirroring node-stats-mcp). Note: private mirrors node-stats but means the credential-less CD runner falls back to the running-image sha (deploy#26); public would smooth CD since the code is public-safe (no secrets in-repo). Flag the public option in the WARD-OUTCOME but default to private. - Scaffold the README / AGENTS / docs/FEATURES trifecta and run `pre-commit run --all-files` before committing per house style. ## Out of scope - The k8s deploy wiring (namespace/main.yml, Ingress, Authelia client, values.env) - that is the coilyco-bridge/deploy clean-clone issue, blocked on this repo publishing an image plus the RBAC and shared-rollout DRY substrate. ## Refs - Reads: `/substrate/agentic-os-kai` daily-social + daily-educational. - Source pattern: `coilyco-flight-deck/node-stats-mcp`. - Fleet + spec: coilyco-bridge/deploy#30, coilysiren/inbox#163. Provenance: director surface session, 2026-07-04.
Member

🔒 Reserved by ward agent --driver claude — container engineer-claude-reddit-mcp-1 on host KAI-DESKTOP-TOWER is carrying this issue (reserved 2026-07-04T07:56:21Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

Do not comment on or edit this issue to steer the run while it is reserved. The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a new issue, dispatched fresh — that is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494).

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `engineer-claude-reddit-mcp-1` on host `KAI-DESKTOP-TOWER` is carrying this issue (reserved 2026-07-04T07:56:21Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. **Do not comment on or edit this issue to steer the run while it is reserved.** The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a **new issue, dispatched fresh** — that is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494). <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Owner

⚠️ Reopened: this run's work did not land on main

An ephemeral ward container (claude mode) dispatched for this issue finished but its work was not merged to main, so the reaper preserved it on a branch before teardown and reopened the issue (its closes #1 never reached main). Recover from the salvage branch below.

  • Repo: coilyco-flight-deck/reddit-mcp
  • Salvage branch: ward-salvage/reddit-mcp-39cc8f04
  • Reason: push to main failed
  • Container uptime at reap: 6m (age of the baked Forgejo PAT snapshot; a long-lived container is likelier to carry a rotated token)

Reap diagnostics

--- reap diagnostics ---
ward version:      v0.385.0
version source:    pinned via WARD_VERSION/--ward-version (v0.385.0)
HEAD:              99b7d1bab59e
origin/main:       -
ancestry:          origin/main absent - cannot compute ancestry
decision gate:     no origin/main to integrate against
reason:            push to main failed
provenance:        not read (no origin/main)
run-owned landed:  no
working tree:      15 dirty path(s)
container uptime:  6m (baked Forgejo PAT age proxy)
--- end reap diagnostics ---

Recover

git fetch https://forgejo.coilysiren.me/coilyco-flight-deck/reddit-mcp.git ward-salvage/reddit-mcp-39cc8f04
git checkout -b ward-salvage/reddit-mcp-39cc8f04 FETCH_HEAD

Working tree at reap time

?? .dockerignore
?? .forgejo/
?? .gitignore
?? .pre-commit-config.yaml
?? .ward/
?? AGENTS.md
?? CLAUDE.md
?? Dockerfile
?? Makefile
?? README.md
?? docs/
?? pyproject.toml
?? src/
?? tests/
?? uv.lock

— Claude (she/her), via ward agent

## ⚠️ Reopened: this run's work did not land on `main` An ephemeral `ward container` (claude mode) dispatched for this issue finished but its work was **not merged to `main`**, so the reaper preserved it on a branch before teardown and reopened the issue (its `closes #1` never reached `main`). Recover from the salvage branch below. - **Repo:** `coilyco-flight-deck/reddit-mcp` - **Salvage branch:** `ward-salvage/reddit-mcp-39cc8f04` - **Reason:** push to main failed - **Container uptime at reap:** 6m (age of the baked Forgejo PAT snapshot; a long-lived container is likelier to carry a rotated token) ## Reap diagnostics ``` --- reap diagnostics --- ward version: v0.385.0 version source: pinned via WARD_VERSION/--ward-version (v0.385.0) HEAD: 99b7d1bab59e origin/main: - ancestry: origin/main absent - cannot compute ancestry decision gate: no origin/main to integrate against reason: push to main failed provenance: not read (no origin/main) run-owned landed: no working tree: 15 dirty path(s) container uptime: 6m (baked Forgejo PAT age proxy) --- end reap diagnostics --- ``` ## Recover ```bash git fetch https://forgejo.coilysiren.me/coilyco-flight-deck/reddit-mcp.git ward-salvage/reddit-mcp-39cc8f04 git checkout -b ward-salvage/reddit-mcp-39cc8f04 FETCH_HEAD ``` ## Working tree at reap time ``` ?? .dockerignore ?? .forgejo/ ?? .gitignore ?? .pre-commit-config.yaml ?? .ward/ ?? AGENTS.md ?? CLAUDE.md ?? Dockerfile ?? Makefile ?? README.md ?? docs/ ?? pyproject.toml ?? src/ ?? tests/ ?? uv.lock ``` <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Owner

Landed: source is on main @ 99b7d1ba and build-publish.yml published reddit-mcp:99b7d1ba to the in-cluster registry (CI run 1, publish job success). The work reached main via the salvage->main promotion, so the commit's closes #1 was never tied to the push - closing manually. Deploy wiring continues at coilyco-bridge/deploy#33.

Landed: source is on `main` @ 99b7d1ba and `build-publish.yml` published `reddit-mcp:99b7d1ba` to the in-cluster registry (CI run 1, publish job success). The work reached main via the salvage->main promotion, so the commit's `closes #1` was never tied to the push - closing manually. Deploy wiring continues at coilyco-bridge/deploy#33.
Sign in to join this conversation.
No description provided.