# Reported issues for qURL

Pod holds 17 of 17 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 [qURL](/mcp/qurl).

## Most discussed

### decide hosting boundary for public legal and video pages

## Context

PR #182 originally added public legal and video HTML routes to the MCP process. That expands an authenticated protocol server into a general public web host and needs an explicit product and architecture decision.

## Decision needed

- Should these pages live in qurl-mcp, a dedicated web service, or an existing LayerV site?
- Who owns content updates, localization, CSP, caching, accessibility, and uptime?
- Which routes must be public, and which deployment topology serves them?

## 

[Read the thread](https://github.com/layervai/qurl-mcp/issues/189) · 2026-07-10 · closed · 1 comment

### feat: design authenticated email delivery with recipient controls

## Context

PR #182 originally included SMTP-backed email delivery alongside the HTTP transport. Email is a security- and abuse-sensitive capability and should be reviewed as its own feature rather than riding with transport support.

## Scope

- Define who may send mail, which recipients are permitted, and how authorization is enforced per request.
- Add quotas and rate limits that cannot be bypassed by rotating MCP sessions or API keys.
- Prevent header injection, arbitrary sender identities, 

[Read the thread](https://github.com/layervai/qurl-mcp/issues/188) · 2026-07-10 · closed · 1 comment

### feat: add upload and text-to-PDF qURL tools in a focused change

## Context

PR #182 originally combined authenticated HTTP transport with file upload, data upload, and text-to-PDF tools. The transport work is being narrowed so it can be reviewed and shipped independently.

## Scope

- Add the file/data upload tool family and text-to-PDF generation as a separate, cohesive change.
- Define explicit size limits, MIME validation, temporary-file cleanup, and timeout behavior.
- Keep generated assets out of the repository unless their licensing and package-size im

[Read the thread](https://github.com/layervai/qurl-mcp/issues/187) · 2026-07-10 · closed · 1 comment

### Parameterize publish-mcp-registry composite action with publisher-version / publisher-sha256 inputs

## Background
PR #94 extracted the `mcp-publisher` install/validate/login/publish sequence into a composite action at `.github/actions/publish-mcp-registry/action.yml`, with the publisher version (`v1.7.2`) and sha256 hardcoded inline. CLAUDE.md §"MCP Registry" treats that file as the single source of truth.

## Problem
Bumping `mcp-publisher` (version + sha256) currently requires editing the action file directly on a branch and seeing it execute against the live registry on the next release-ple

[Read the thread](https://github.com/layervai/qurl-mcp/issues/95) · 2026-04-29 · open · 1 comment

### Audit MCP tools; ensure clean hide_url tool aligned with SDK/docs naming

## Problem
`qurl-mcp` is the direct AI integration point (MCP server → Claude / Cursor / other MCP clients). If its tool names and parameters diverge from the SDK helpers (`hideUrl`, `hide_url`) or the quickstart docs, AI consumers will get confused cross-referencing.

## Expected
Audit current tool set. Ensure:
- A primary `hide_url` (or equivalent) tool exists, named consistently with the SDK helpers
- Parameters mirror `hideUrl()` / `hide_url()` signature: `target_url`, `expires_in`, optional

[Read the thread](https://github.com/layervai/qurl-mcp/issues/64) · 2026-04-24 · closed · external user · 1 comment

### Type the heterogeneous ToolFactory registration seam

## Business relevance

The canonical tool registry intentionally erases per-tool handler argument variance with `(...args: any[])` so heterogeneous factories can share one array. Registration still validates each tool through its Zod input/output schemas, but removing the explicit `any` would preserve compiler guarantees at the final MCP SDK boundary and make future tool additions safer.

## Constraints

- Preserve one canonical tool-factory list for runtime registration and coverage tests.
- Ke

[Read the thread](https://github.com/layervai/qurl-mcp/issues/194) · 2026-07-10 · open · 0 comments

### refactor(http): split runtime into session and public-route modules

## Summary

After PR #182 merges, split the large HTTP runtime factory into focused internal modules for session registry/lifecycle and public legal/video routes while preserving the existing exported runtime contract and test seams.

## Business relevance

Smaller modules will make future transport changes easier to review, test, bisect, and selectively revert without changing the integrated release scope already accepted for #182.

## Acceptance criteria

- Extract session registry, expiry, di

[Read the thread](https://github.com/layervai/qurl-mcp/issues/193) · 2026-07-10 · open · 0 comments

### Track Nodemailer v9 declaration support

## Context

The runtime uses `nodemailer@^9`, while the current DefinitelyTyped line is `@types/nodemailer@^8`. The SMTP surface used by qurl-mcp is covered and CI type-checks it, but the major-version mismatch is a latent maintenance risk.

## Acceptance criteria

- Monitor Nodemailer/DefinitelyTyped for v9-compatible declarations or bundled types.
- Upgrade when an official compatible declaration package is available and passes dependency-age policy.
- Remove or update the compatibility commen

[Read the thread](https://github.com/layervai/qurl-mcp/issues/192) · 2026-07-10 · open · 0 comments

## Most recent

### Add connector cleanup for upload-to-mint partial failures

## Business relevance

An upload can succeed at the connector and then fail while minting its qURL. Today the MCP server logs the orphaned `resource_id`, but the connector exposes no delete endpoint, so operators must clean it up manually. A cleanup contract prevents storage leaks and makes upload workflows transactional from the user's perspective.

## Current behavior

- Connector upload succeeds and returns `resource_id`.
- `mintLink` fails.
- qurl-mcp logs the orphaned ID and returns the min

[Read the thread](https://github.com/layervai/qurl-mcp/issues/191) · 2026-07-10 · open · 0 comments

### ci: consider environment gate on manual publish-mcp-registry workflow_dispatch

## Context

Follow-up surfaced by the Claude review on #124 (which added `environment: npm-publish` to the auto-publish job in `release-please.yml`).

`.github/workflows/publish-mcp-registry.yml` is the `workflow_dispatch`-only escape hatch for republishing the current `main` to the MCP registry (recovery / registry outage retry). It is **not** gated by `npm-publish` or any other environment.

## Threat model (why this is low priority)

- The job does not touch npm — it only publishes to the MCP

[Read the thread](https://github.com/layervai/qurl-mcp/issues/125) · 2026-05-12 · open · outside contributor · 0 comments

### Pick up @layerv/qurl idempotency-safe retries; verify create/batch tools don't duplicate

## Summary

After the next qURL prod release, the API will support the [\`Idempotency-Key\` header](https://datatracker.ietf.org/doc/draft-ietf-httpapi-idempotency-key-header/) end-to-end on state-mutating endpoints, and \`@layerv/qurl\` will send it automatically (tracked at [layervai/qurl-typescript#77](https://github.com/layervai/qurl-typescript/issues/77)).

This MCP server wraps that SDK, so once the SDK ships idempotency-safe retries it inherits them transparently. We just need to bump the

[Read the thread](https://github.com/layervai/qurl-mcp/issues/113) · 2026-05-05 · open · 0 comments

### Audit tool description rendering against host UIs (Claude Desktop / Cursor / Glama)

## Background

Split out from #83 item 4 so the parent tracking issue can close cleanly. PR #82 expanded every tool description to the 800–1100 char range for TDQS scoring. Some hosts truncate at the first newline or ~200 chars.

## Acceptance

- Eyeball how Claude Desktop, Cursor, and Glama render `tools/list` and confirm the truncated view still conveys the tool's purpose.
- If truncation is ugly, move the deepest details (response shape sketches) into per-field `.describe()` calls on the inpu

[Read the thread](https://github.com/layervai/qurl-mcp/issues/106) · 2026-04-30 · open · 0 comments

### Smoke-test update_qurl extend_by duration syntax against staging

## Background

Split out from #83 item 2 so the parent tracking issue can close cleanly. The new round-trip test in `tdqs-metadata.test.ts` exercises `update_qurl` with `extend_by: "24h"` against a mock client. The tool description claims `update_qurl` accepts `extend_by`, but that hasn't been verified against the live API.

## Acceptance

- Run `update_qurl` against staging with `extend_by: "24h"` (and `extend_by: "7d"` for variety) and confirm the API accepts the duration string syntax.
- If o

[Read the thread](https://github.com/layervai/qurl-mcp/issues/105) · 2026-04-30 · open · 0 comments

### Verify list_qurls status filter accepts 'expired' (response can return it)

## Background

PR #100 promoted \`"expired"\` to a first-class value on \`qurlSchema.status\` because api-spec/qurls.yaml's \`Qurl.properties.status\` description documents that resources past their \`expires_at\` are reported as \`"expired"\` (even though the spec's \`enum:\` line lists only \`[active, revoked]\`).

cr round-7 on PR #100 noted the asymmetry: an agent reading the schema sees that \`status\` can be \`"expired"\` on response, but \`list_qurls\`'s \`status\` filter docs (\`src/tool

[Read the thread](https://github.com/layervai/qurl-mcp/issues/102) · 2026-04-30 · open · 0 comments

### Add operator-visible signal when qurlSchema.status .catch() coerces a drifted value

## Background

PR #100 added `.catch("unknown")` to `qurlSchema.status` and `accessTokenSchema.status` so an unanticipated API value (e.g. `"expired"`, `"pending"`) doesn't hard-fail `structuredContent` validation between weekly api-spec drift runs.

cr round 1 on PR #100 flagged that the coercion is silent: when `.catch()` fires, the original API value is dropped on the floor. There is no `console.warn` / telemetry hook. For a sentinel whose entire purpose is "something the snapshot does not kn

[Read the thread](https://github.com/layervai/qurl-mcp/issues/101) · 2026-04-29 · open · 0 comments

### Lock down list_qurls default-behavior claims (active-only, sort field) against spec or staging

## Background

PR #97 round-4 cr flagged two factual claims in `list_qurls`'s tool description that aren't pinned by the OpenAPI spec at `api-spec/qurls.yaml`:

1. **"By default only `active` qURLs are returned"** — `api-spec/qurls.yaml:265-270` documents the `status` filter as a comma-separated list with example `"active,revoked"` but no `default:` value. The current claim mirrors `delete_qurl`'s existing assertion ("By default the resource is excluded from `list_qurls`") and reflects current A

[Read the thread](https://github.com/layervai/qurl-mcp/issues/99) · 2026-04-29 · open · 0 comments

### Pin list_qurls 'filters AND together' claim against the API spec

## Background

PR #97 rewrote `list_qurls`'s tool description to assert that filters AND together (e.g. `status: 'active'` + `expires_before: '2026-05-01T00:00:00Z'` returns active qURLs about to expire). The cr review on PR #97 (round 3) flagged this as a strong factual claim that isn't test-pinned: if the API ever switches to OR semantics on multi-filter queries, the description would silently lie to agents.

The OpenAPI spec at `api-spec/qurls.yaml:266-294` lists each query parameter individu

[Read the thread](https://github.com/layervai/qurl-mcp/issues/98) · 2026-04-29 · open · 0 comments

The remaining reports are on [the project's issue tracker](https://github.com/layervai/qurl-mcp/issues).
