---
title: 'Entitlement walls: what a blocked tool returns and why'
description: 'Every wall the VarynForge MCP server can return, the entitlement payload field by field, and how your agent should handle one without retrying.'
slug: entitlement-walls
group: reference
order: 41
keywords: [entitlement wall, payment required, rate limited, upgrade rationale, mcp caps, alternative free actions]
related: [free-and-paid, mcp-tools, drafting-and-verification, from-your-own-ideas]
updated: '2026-10-26'
---

A wall is the answer when a call is not on your plan or has hit a cap. It is a normal tool result, not an error: the call returns `{ "entitlement": { ... } }` in place of the usual output. [Free and paid](/docs/free-and-paid) covers what each plan includes; this page covers the wall itself.

## When a wall appears

| Wall               | Code               | Tool                     | What lifts it                                               |
| ------------------ | ------------------ | ------------------------ | ----------------------------------------------------------- |
| Research on Free   | `PAYMENT_REQUIRED` | `start_research_run`     | A paid plan                                                 |
| Research pacing    | `RATE_LIMITED`     | `start_research_run`     | Waiting: one run per minute per user                        |
| Project cap        | `PAYMENT_REQUIRED` | `create_project`         | A paid plan, or reusing one of your 3 free projects         |
| Daily brief cap    | `RATE_LIMITED`     | `generate_article_brief` | The 24-hour window resetting, or a paid plan (no brief cap) |
| Lint cap           | `RATE_LIMITED`     | `lint_draft`             | The 24-hour window resetting; Free allows 10, paid plans 50 |
| Idea checks, day   | `RATE_LIMITED`     | `check_idea`             | Midnight UTC                                                |
| Idea checks, month | `RATE_LIMITED`     | `check_idea`             | The 1st of the month, or a plan with a larger allowance     |
| Idea check pacing  | `RATE_LIMITED`     | `check_idea`             | Waiting: two checks per minute                              |
| Idea expansions    | `RATE_LIMITED`     | `expand_idea`            | The 24-hour window resetting; 20 a day on every plan        |
| Feedback           | `RATE_LIMITED`     | `send_feedback`          | The daily reset; 10 a day on every plan                     |

`FEATURE_LOCKED` is part of the schema, but no tool returns it today. No feature is reserved for Pro or Master over Starter. A paid organization that has spent its research credits gets a plain error from `start_research_run`, not a wall.

## The payload, field by field

This is the free lint cap, as your agent would receive it:

```json
{
  "entitlement": {
    "error_code": "RATE_LIMITED",
    "tool": "lint_draft",
    "reason": "You have used today's 10 draft verifications. The cap resets at 2026-10-27T09:14:00.000Z.",
    "remaining": 0,
    "reset_at": "2026-10-27T09:14:00.000Z",
    "upgrade_url": "https://app.varynforge.com/pricing?ref=mcp&utm_source=mcp&utm_medium=tool_wall&utm_campaign=lint_draft",
    "upgrade_rationale": "You're out of free draft verifications for today. The free tier covers 10/day; Starter raises it to 50/day.",
    "what_unlocks": "Starter ($75/mo) raises the cap to 50/day.",
    "alternative_free_actions": [
      "get_lint_rubric (self-check the draft against the thresholds before resubmitting)",
      "update_article_status (move the article manually if you are confident)"
    ]
  }
}
```

- `error_code` (string): `PAYMENT_REQUIRED` when the plan does not include the call, `RATE_LIMITED` when a cap or pacing limit is spent.
- `tool` (string): the tool that was blocked.
- `reason` (string): what happened, in plain words, with the numbers.
- `remaining` (integer or null): `0` on a rate limit, `null` on a payment wall.
- `reset_at` (ISO timestamp or null): when the cap frees up. `null` on a payment wall.
- `upgrade_url` (string): the pricing page, tagged with the tool that walled.
- `upgrade_rationale` (string): a sentence usually written for you, the operator; the pacing and feedback walls address the agent instead.
- `what_unlocks` (string): what another plan changes, or that nothing does.
- `alternative_free_actions` (array of strings): tools that still work right now, each with a short note. It can be empty.

## What your agent does with a wall

1. It reads `upgrade_rationale` to you as written. That sentence is meant for you, so the agent does not paraphrase it.
2. It offers the `alternative_free_actions`, so the session keeps moving.
3. It asks before it hands you `upgrade_url`.
4. It does not retry or loop. The wall is the answer. On a pacing wall it waits until `reset_at` before it calls again.
5. It does not file the wall with `send_feedback`. A wall works as designed.

On the brief cap, an article brief that never existed is queued and forges on its own at the reset; a channel brief or a regeneration is not queued, so retry after `reset_at`. The `reason` says which. [Drafting and verification](/docs/drafting-and-verification) covers how the agent paces `lint_draft`.

## The same wall in the web app

The app enforces the same caps without the payload; the two per-minute pacing limits apply over MCP only. A queued brief shows when it forges, and the lint and idea caps say the daily limit is reached. Starting a research run without a plan opens a dialog that points to your plan settings. Compare plans on [the pricing page](/pricing).
