HarperFast / HarperFast/harper

MCP: let an agent discover unavailable operations and request access (human-approved)

Open
#1,627 0 comments 1 reaction 0 assignees View on GitHub
Dominant language
JavaScript
Stars
89
Forks
10
Avg merge
2d 6h
Merged PRs (30d)
200

Description

## Idea (from @dawsontoth, [harper#1554 review](https://github.com/HarperFast/harper/pull/1554#discussion_r3531035096))

Give an MCP client (LLM/agent) a way to see which operations it *doesn't* have access to, and a way to request access to them — with human approval (or by instructing the human to update a config).

## Why it doesn't work today

Two independent layers make an operation unavailable, and neither is introspectable by the client:

1. **Config filter** — `mcp.operations.allow` / `deny` globs plus the `DEFAULT_EXCLUDED` set (e.g. the secret ops). Applied at *tool-registration* time (`components/mcp/tools/operations.ts` — `if (!isOperationAllowed(operationName, config)) continue;`): a denied op is **never registered as a tool**, so it never appears in `tools/list`. The client has no signal it exists.
2. **RBAC** — the authenticated user's permissions, applied at *invocation* time (`chooseOperation` throws permission-denied even for a registered tool).

There is no discovery of what's filtered out, and no request/escalation path. Changing access is a manual human action (edit allow/deny, or adjust the caller's role).

## Proposed shape

- **`list_unavailable_operations`** — returns the operations filtered out for the current session, each tagged with the *reason* (config-denied vs RBAC-denied) so the agent can reason about what it needs. Must not leak anything sensitive beyond operation names/descriptions the operator is willing to expose.
- **`request_operation_access`** — stages an access change (a config edit to `mcp.operations.allow`, or a role grant) that a **human approves** before it takes effect. Given secret ops are default-deny + super_user-gated, human-in-the-loop is the right default; the plain fallback is to emit a clear instruction telling the human which config/role to change.

## Dependencies / sequencing

- Overlaps **#1545** (RBAC-filtered ops registry folded into the agent toolset) — that owns the RBAC dimension of "what's available."
- Ties into the agent-auth direction (scoped agent user + JWT, relaxing the hard super_user gate) — that's where "who requests / who approves" is decided.
- Should land **after** those rather than being bolted onto the secrets-store PR (#1554).

Not small, but coherent. Filing to track.

Contributor guide

Open the contributing guide

Research direction

Start with components/mcp/tools/operations.ts, especially registration filtering and chooseOperation, then read the dependency noted in #1545 and the agent-auth direction. Define how unavailable operations are reported by reason and how access requests remain human-approved without exposing sensitive details. Done should cover both config-filtered and RBAC-denied cases after those dependencies land.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
api, authorization, backend, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.