Other formats agents might prefer:
markdownjsonllms.txt

Agent? You probably want markdown or json, or Pod over MCP.

Reported issues for Distillery

Pod holds 24 of 87 problems reported by people outside the maintainer team. Issues filed by the project's own owners, members and collaborators are excluded entirely — a maintainer's release checklist is not a warning to a prospective user.

Back to Distillery.

Most discussed

Restrict MCP server access to GitHub org members

Problem

The Distillery MCP server currently uses GitHub OAuth for user authentication, but anyone with a GitHub account can authenticate. There is no way to restrict access to members of a specific organization.

Proposed Solution

Add an org membership check after the GitHub OAuth flow completes. When a user authenticates:

  1. OAuth flow completes, server receives the user's GitHub access token
  2. Server calls GET https://api.github.com/orgs/{org}/members/{username} (or `GET /user/

Read the thread · 2026-03-31 · closed · 10 comments

feat: session lifecycle hooks and session_id tracking for Claude Code integration

Context

We run an OpenMemory MCP server alongside Claude Code with three hooks that automate the memory lifecycle. The hooks work well enough that we're evaluating distillery as a replacement, but distillery currently has no equivalent to some of these patterns. This issue proposes adding the infrastructure to support them.

What the hooks do today

We have a single shell script registered on three Claude Code hook events:

1. SessionStart — context injection

When a session starts, t

Read the thread · 2026-04-08 · closed · 8 comments

fix(mcp): add summary/metadata-only mode to distillery_list to avoid token overflow

Problem

When Claude Code skills (e.g., /radar, /watch) call distillery_list to query feed entries, the full entry content is returned — including raw Reddit HTML, GitHub event bodies, and other verbose payloads. With 81 feed entries, a single distillery_list call produces ~151KB of JSON, which exceeds Claude Code's per-tool-result token cap.

The result gets dumped to a temp file on disk, forcing the skill to dynamically generate Python/jq scripts to extract basic metadata (titles, s

Read the thread · 2026-03-31 · closed · 7 comments

Package Distillery as a Claude Code plugin (skills + MCP server)

Summary

Package Distillery as a self-contained Claude Code plugin that bundles both the MCP server and the skills, so users can install it with a single command rather than manually configuring MCP servers and copying skill files.

Motivation

Currently, using Distillery with Claude Code requires:

  1. Installing the Python package (pip install -e ".[dev]")
  2. Manually adding the MCP server to Claude Code settings
  3. Having the skills available in .claude/skills/ (only works inside this

Read the thread · 2026-03-28 · closed · 6 comments

distillery_store tool description enum omits github entry type (used by gh-sync)

Summary

The MCP tool description for distillery_store lists the allowed entry_type values as:

entry_type must be one of: session, bookmark, minutes, meeting, reference, idea, inbox.

But github is also accepted by the server and is the entry type that the gh-sync skill stores every synced issue and PR as (per its SKILL.md, Step 5b). The tool description is out of sync with what the server actually supports.

Minor severity — the server accepts github fine and the skill works

Read the thread · 2026-04-11 · closed · 5 comments

feat: reduce MCP tool surface from 20 to 12 via three-tier architecture

Core Principle

MCP tools are for agents and developers. Any tool that an agent calls during work, or a developer invokes through a skill in an active session, stays in MCP.

Webhooks and CLI are for operators and scheduled maintenance. Operations that run on a cron, don't require inference, and don't need an active agent session belong outside MCP.

Skills always call MCP tools. Skills never wrap CLI commands.

Problem

Distillery exposes 20 MCP tools (19 existing + correct from

Read the thread · 2026-04-09 · closed · 5 comments

[bug] live demo can't connect to MCP

Image

Can an API key be provided?

Read the thread · 2026-03-28 · closed · 5 comments

chore(plugin): audit gaps and improvement opportunities vs best practices

Summary

Comprehensive audit of the Distillery Claude Code plugin against plugin authoring best practices. Covers structure, skills, MCP implementation, testing, and missing capabilities.


1. Structural Gaps (Plugin Layout)

Skills directory nested incorrectly

Skills live at .claude-plugin/skills/<name>/SKILL.md. Best practice: skills/ at plugin root, not inside .claude-plugin/.

Missing plugin.json fields

  • userConfig — Jina API key, GitHub OAuth tokens should u

Read the thread · 2026-04-01 · closed · 4 comments

Most recent

feat(auth): GitLab (self-hosted or gitlab.com) as an identity provider

Summary

Add GitLab -- self-hosted instances and gitlab.com -- as an alternative identity provider for the MCP HTTP transport (server.auth.provider: gitlab), alongside the existing GitHub OAuth. Like GitHub, GitLab is an identity gate only: the server never accesses the user's GitLab resources.

Design was settled in a grilling session on 2026-07-06. Full spec: docs/specs/19-spec-gitlab-auth/19-spec-gitlab-auth.md; the load-bearing decision is recorded in `docs/adr/0001-gitlab-auth-claim-

Read the thread · 2026-07-06 · closed · 0 comments

gh_sync: background mode unusable over HTTP — synchronous path times out on cold backfill

Summary

distillery_gh_sync has no non-blocking path over HTTP. background=true is hard-rejected in stateless HTTP mode (src/distillery/mcp/server.py:1283), so every HTTP caller falls back to the synchronous path (src/distillery/mcp/tools/feeds.py:882, await adapter.sync_batched()), which blocks the MCP response until the full sync finishes. A cold backfill exceeds the MCP client request timeout and the call fails with -32001 — even though the sync completes server-side.

`skills/

Read the thread · 2026-06-03 · closed · 0 comments

store: probe_readiness uses cached COUNT(*); blind to data-page corruption

Root cause

DuckDBStore.probe_readiness and count_entries both rely on SELECT COUNT(*) FROM entries, which DuckDB serves from row-group metadata without reading any data page. When the table data pages are corrupted but the catalog/metadata is intact, both functions return success and the status handler reports status: "ok" — even when the table is completely unreadable.

src/distillery/store/duckdb.py:1034:

async def probe_readiness(self) -> tuple[bool, str | None]:
    

[Read the thread](https://github.com/norrietaylor/distillery/issues/582) · 2026-06-02 · closed · 0 comments

### store: schema-validation ValueError masked as 'INTERNAL: Failed to store entry'

## Root cause

`validate_metadata` (`src/distillery/models.py:228`) raises `ValueError` for schema-validated entry types (`person`, `project`, `digest`, `github`, `feed`) when required fields are missing or constrained values are wrong. The store path runs validation inline (`src/distillery/store/duckdb.py:1119, 1182, 1370`), and the MCP tool layer wraps the call in a catch-all:

`src/distillery/mcp/tools/crud.py:523`:

```python
except Exception:  # noqa: BLE001
    logger.exception("Error stor

[Read the thread](https://github.com/norrietaylor/distillery/issues/559) · 2026-05-21 · closed · 0 comments

### store: misclassify transient DB / provider errors as 'Failed to check embedding budget'

## Root cause

`distillery_store` / `distillery_store_batch` report `INTERNAL: Failed to check embedding budget` for any failure inside `record_and_check`, conflating:

1. **Actual budget exhaustion** (`EmbeddingBudgetError` — has its own `BUDGET_EXCEEDED` branch).
2. **Transient DB faults** — aborted transaction on the shared connection, connection lock contention, post-rollback retryable state.
3. **Provider unavailability** — embedding API timeouts surfacing inside the budget counter path.

`

[Read the thread](https://github.com/norrietaylor/distillery/issues/557) · 2026-05-21 · closed · 0 comments

### Make fastembed the plugin install default (supersedes #466)

## Summary

Once #538 (`fastembed-wiring`) merges, ship the Distillery plugin with fastembed as the install-time default embedding provider. This removes the \`userConfig\` prompt requirement entirely and unblocks \`claude plugin install distillery\` as a zero-secret single-command install. **Supersedes #466.**

## Why this works

The #466 blocker was a two-sided trade-off:
- Mark \`jina_api_key\` as \`required: true\` → forces every evaluator to provide a Jina key just to try the plugin
- Leave

[Read the thread](https://github.com/norrietaylor/distillery/issues/548) · 2026-05-20 · closed · 1 comment

### Fly autosuspend strands active_job_id, blocking all subsequent /api/poll with 409

## Symptom

Once a poll job starts but doesn't reach a terminal state before Fly autosuspends the machine, the persisted \`active_job_id\` metadata entry is never cleared. Every subsequent \`/api/poll\` returns 409 Conflict with the orphaned job_id, even after machine resume.

## Repro (prod, 2026-05-12)

\`distillery-mcp\` (Fly), v0.5.0 image:

\`\`\`
00:15:05  POST /api/poll → 202 Accepted; "Webhook poll: starting poll cycle"
00:15:05–00:15:45  poller fetches feeds, posts 2 Jina embeddings (20

[Read the thread](https://github.com/norrietaylor/distillery/issues/507) · 2026-05-12 · closed · 0 comments

### feeds: per-source threshold overrides — global `feeds.thresholds` forces one cutoff for vendor blogs and HN/Lobsters/Reddit alike

## Root cause

`feeds.thresholds.{alert,digest}` is global. The only per-source dampener is `FeedSourceConfig.trust_weight`, which the poller multiplies into the score before threshold comparison:

```python
# src/distillery/feeds/poller.py:869
adjusted_score = score * source.trust_weight

if adjusted_score < self._threshold:
    result.items_below_threshold += 1

trust_weight only attenuates downward and can't separate the alert vs. digest tiers — both share the same multiplier. Effect in

Read the thread · 2026-05-07 · closed · 0 comments

mcp: bearer token auth is case-sensitive on the scheme, rejects RFC-7235-compliant clients

Bug

_verify_bearer_token rejects valid Authorization headers whose scheme is not exactly the title-cased string Bearer.

Location

src/distillery/mcp/webhooks.py:404-406

What's wrong

The check is:

if not auth_header.startswith("Bearer "):
    return False

Requests with Authorization: bearer <token> or Authorization: BEARER <token> are rejected with 401 even when the token itself is correct.

Why it's a bug

[RFC 7235 §2.1](https://datatracker.ietf.org/d

Read the thread · 2026-05-06 · closed · 0 comments

store: get() returns archived entries instead of filtering them out

Bug

DuckDBStore._sync_get() does not filter out archived (soft-deleted) entries, violating the DistilleryStore.get() protocol contract.

Location

src/distillery/store/duckdb.py:1168

What's wrong

_sync_get() runs SELECT {self._ENTRY_COLUMNS} FROM entries WHERE id = ? without any check on the status column. Archived entries are returned to callers.

Why it's a bug

The protocol (src/distillery/store/protocol.py:109) explicitly states:

Returns: The matching Entry,

Read the thread · 2026-05-06 · closed · 0 comments

Plugin installer: revisit userConfig wiring once upstream fixes land

Tracker for upstream Claude Code plugin manifest gaps that block a better install UX for the Distillery plugin.

Upstream issues

  • anthropics/claude-code#39455 — userConfig values not prompted on enable. Workaround confirmed 2026-05-05: setting "required": true makes /plugin install (inside Claude Code) prompt for values. Does NOT work for claude plugin install from the terminal, and the prompt is silent in some Desktop/Cowork contexts per recent comments.
  • anthropics/claude-cod

Read the thread · 2026-05-06 · closed · 2 comments

/radar: issue all top-5 tag queries (not just top-3) and raise default candidate set from 20 to 35

Symptom

`/radar` documents "top 5 tags by combined count" but then issues only up to 3 queries against `distillery_search`, with each query capped at `ceil(--limit / N)` entries (default `--limit` 20, N=3 → 7 per query → 21 raw, ~19 unique after dedup).

Effects:

  1. Tags ranked 4 and 5 are computed but never used. The 5-tag interest profile becomes a 3-tag interest profile in practice.
  2. The 21-entry candidate set is small relative to the size of a healthy 75-source feed — a

Read the thread · 2026-05-06 · closed · 0 comments

Cut v0.4.1 release: radar (#444) + poller-UA (#443) fixes stranded on main; plugin marketplace still serves v0.4.0 SKILL.md

Symptom

The MCP server has the fixes from #443 and #444 (running build_sha 1bc7cda, downstream of both). But running `/radar` in Claude Code still surfaces 2024-2025 backfill items.

Reproduced: a `/radar 1 day` invocation just returned items with `published_at` of January 2025 (`Introducing Operator`, `Stargate Project`), an OpenAI `o1 Contributions` page, and other backfill — exactly the bug #444 was filed to fix.

Root cause

Three-layer version drift:

| Layer | Has the

Read the thread · 2026-05-05 · closed · 0 comments

fix(store): DuckDB connection accessed concurrently from multiple threads, causing heap corruption

Symptom

Local Distillery server intermittently goes unresponsive while the container is reported Up. HTTP requests time out, MCP tools time out, but docker logs shows the Python process emitting:

corrupted double-linked list

immediately followed by hung-but-not-crashed state — httpx log lines for in-flight embedding requests continue to print after the message but the main loop is dead. The container must be restarted to recover. Reproduced 2026-05-01 17:11:43 during a mainte

Read the thread · 2026-05-01 · closed · 0 comments

Flip plugin default from hosted demo to local stdio

Problem

claude plugin install distillery currently wires mcpServers.distillery to the hosted demo at https://distillery-mcp.fly.dev/mcp (.claude-plugin/plugin.json:31-36). That demo is explicitly labelled "evaluation only — do not store sensitive data" (docs/getting-started/plugin-install.md:25-26), yet it is the path of least resistance for every new user. Docs urge a

Read the thread · 2026-04-20 · closed · 0 comments

Validation order: ID is checked before entry_type/action, masking secondary invalid params

Summary

When a tool call has multiple invalid parameters, the server short-circuits on the ID lookup and never reports the other validation failures. Agents that self-correct based on error messages get one fix per retry instead of learning about all bad inputs at once.

Repro

1. distillery_classify with both a bad id and an invalid entry_type

distillery_classify(entry_id="00000000-0000-0000-0000-000000000000",
                    entry_type="invalid_type_xyz",
             

[Read the thread](https://github.com/norrietaylor/distillery/issues/372) · 2026-04-19 · closed · 1 comment

The remaining reports are on [the project's issue tracker](https://github.com/norrietaylor/distillery/issues).