server.json
1 field changed
- version
-
2.28.12.29.1
io.github.chrischall/ofw-mcp
18 changes recorded. MCP Harbor re-reads this listing from the official registry every six hours and asks the live server what it exposes, and keeps what changed between one look and the next.
https://raw.githubusercontent.com/chrischall/ofw-mcp/HEAD/AGENTS.md
− # ofw-mcp− MCP server for OurFamilyWizard (OFW). Reads/writes messages, calendar, expenses, and journal; backs message tools with a local SQLite cache. stdio transport.− ## Commands− ```bash− npm run build # tsc → dist/, then esbuild bundle → dist/bundle.js− npm test # tsc typecheck + vitest run (all tests)− npm run test:watch # vitest in watch mode− npm run dev # node --env-file=.env dist/index.js (requires built dist)− ```− `dist/` is gitignored — it is produced at build/release time and shipped in the npm package (`package.json` `files`).− ## Session cache− `src/session-cache.ts` caches the bearer token at− `$MCP_DATA_DIR/.ofw-mcp/session.json` (0600, `OFW_SESSION_FILE` overrides) via− `createFileStatePersistence` + `resolveStateFile` (`@chrischall/mcp-utils/session`).− OFW has no refresh grant — renewing IS logging in — so `mint()` serves as both− `initial` and `refresh` on the `TokenManager`, and `isRefreshRevoked: () => false`− turns off the library's re-mint-after-a-failed-refresh recovery, which here would− just repeat the call that failed. The token lasts six hours, so on a scale-to-zero− host the cache turns most cold starts into zero-cost ones.− The cache is **disabled** in three cases, each deliberate: `OFW_SESSION_CACHE=false`;− an injected `resolveAuth` (the per-user hosted path — this registration declares no− `identity.perUserChild`, so one process can serve several people and a shared file− would hand one user's session to the next); and no env credentials (the fetchproxy− path authenticates from a browser tab, with nothing stable to bind a record to).− The record is `boundTo` a salted digest of username+password, so rotating either− discards it; neither value is written. A failed write is reported to stderr and is− NOT fatal — OFW tokens are re-mintable from the environment.− `tests/_setup.ts` forces the cache off and pins its path into a temp dir for the− whole suite, so no test can reach the developer's real `~/.ofw-mcp`.− ## Architecture− ```− src/− index.ts MCP server entry — SQLite-warning shim, then runMcp() from @chrischall/mcp-utils (builds McpServer, applies registrars with client as deps, prints banner, wires shutdown + stdio transport)− protocol.ts Wire-level constants (BASE_URL, OFW_PROTOCOL_HEADERS, token TTL) + assertOfwUrl() egress allowlist. Leaf module to break the client→auth→auth-password import cycle− client.ts OFWClient (Bearer token, 401/429 retry, JSON + binary). Delegates auth to ./auth.ts− auth.ts resolveAuth(): three-path priority (env vars → fetchproxy fallback → error). Template for sibling MCPs− auth-password.ts loginWithPassword(): legacy OFW Spring Security form login (kept as own module so auth.ts can mock it cleanly)− config.ts env-driven cache dir + sha256(OFW_CACHE_IDENTITY|OFW_USERNAME|"_default") DB path + attachments dir− cache.ts node:sqlite cache (messages, drafts, draft_lineage, attachments, sync_state, meta) with typed CRUD + findLatestReplyTip− sync.ts resolveFolderIds + syncMessageFolder/syncDrafts/syncAll + attachment-meta fetch+ CLAUDE.md
Showing the first 40 of each.
https://raw.githubusercontent.com/chrischall/ofw-mcp/HEAD/AGENTS.md
− - **No read reports an absence it cannot verify** (`guardedCacheRead` / `unverifiedEmptyResponse`). `ofw_list_messages`, `ofw_list_drafts` and `ofw_get_unread_sent` refuse an EMPTY result whenever the backing cache is not `fresh`, returning `result: "UNVERIFIED_EMPTY"` with a `remedy` instead of `[]`. An empty list carrying a 207-minute-old freshness warning is shaped identically to a verified "nothing there", and the natural next sentence off one is a false negative stated as fact. A false ne− - `src/index.ts` — the `version: '…'` literal on the line marked `// x-release-please-version`− 2. **The release PR sits open as your review gate.** Look at the proposed CHANGELOG. When you're ready to ship, either merge it via the GitHub UI, or add the `ready-to-merge` label and `auto-merge.yml` will arm `gh pr merge --auto`. CI gates the merge either way.+ - **No read reports an absence it cannot verify** (`guardedCacheRead` / `unverifiedEmptyResponse`). `ofw_list_messages`, `ofw_list_drafts` and `ofw_get_unread_sent` refuse an EMPTY result whenever the backing cache is not `fresh`, returning `result: "UNVERIFIED_EMPTY"` with a `remedy` instead of `[]`. An empty list carrying a 207-minute-old freshness warning is shaped identically to a verified "nothing there", and the natural next sentence off one is a false negative stated as fact. A false ne+ - `src/version.ts` — the `VERSION` literal on the line marked `// x-release-please-version` (imported by `index.ts` and `auth.ts`; never import `package.json` from `src/`, which inlines the whole manifest into `dist/bundle.js`)+ 2. **The release PR sits open as the owner's review gate** — the proposed CHANGELOG is reviewed there. Shipping it is the owner's call (fleet policy below); agents don't merge or label it. CI gates the merge either way.
We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect