# 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](/mcp/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](https://github.com/norrietaylor/distillery/issues/76) · 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](https://github.com/norrietaylor/distillery/issues/191) · 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](https://github.com/norrietaylor/distillery/issues/78) · 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](https://github.com/norrietaylor/distillery/issues/39) · 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](https://github.com/norrietaylor/distillery/issues/232) · 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](https://github.com/norrietaylor/distillery/issues/196) · 2026-04-09 · closed · 5 comments

### [bug] live demo can't connect to MCP

<img width="1512" height="982" alt="Image" src="https://github.com/user-attachments/assets/b60623a4-8a0d-4e61-b2bd-852626c27fec" />

Can an API key be provided?

[Read the thread](https://github.com/norrietaylor/distillery/issues/33) · 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](https://github.com/norrietaylor/distillery/issues/100) · 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](https://github.com/norrietaylor/distillery/issues/696) · 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](https://github.com/norrietaylor/distillery/issues/588) · 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`:

```python
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](https://github.com/norrietaylor/distillery/issues/480) · 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:

```python
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](https://github.com/norrietaylor/distillery/issues/469) · 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](https://github.com/norrietaylor/distillery/issues/468) · 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](https://github.com/norrietaylor/distillery/issues/466) · 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](https://github.com/norrietaylor/distillery/issues/461) · 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](https://github.com/norrietaylor/distillery/issues/452) · 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](https://github.com/norrietaylor/distillery/issues/416) · 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](../blob/main/.claude-plugin/plugin.json#L31-L36)). That demo is explicitly labelled **"evaluation only — do not store sensitive data"** ([docs/getting-started/plugin-install.md:25-26](../blob/main/docs/getting-started/plugin-install.md#L25-L26)), yet it is the path of least resistance for every new user. Docs urge a 

[Read the thread](https://github.com/norrietaylor/distillery/issues/381) · 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).
