passkey로 서명된 권한을 바탕으로 도구 호출을 검증하고, 교차 서명된 영수증을 생성하여 MCP tool server의 보안 가드 역할을 수행합니다.
다른 이름 provared/provared, mcp-executor, provared-mcp-executor
- 스타
- 0
- Tools
- —
- 다운로드, 30일
- —
- 최신 버전
- 0.4.1
- 마지막 커밋
- 2026년 11월 11일
- 라이선스
- Apache-2.0
Provared MCP Executor MCP란?
Provared MCP Executor은(는) MCP server입니다. passkey로 서명된 권한을 바탕으로 도구 호출을 검증하고, 교차 서명된 영수증을 생성하여 MCP tool server의 보안 가드 역할을 수행합니다.
프로젝트 README에서 생성된 요약
Provared MCP Executor MCP server 정보
Provared MCP executor는 AI 에이전트와 MCP tool server 사이에서 보안 중개자 역할을 합니다. 에이전트가 자격 증명에 직접 접근할 수 없도록 executor가 tool server의 credentials를 보유하는 방식으로 작동합니다. executor는 사람이 passkey를 사용하여 서명한 권한을 바탕으로 모든 도구 호출을 검증합니다. 호출이 content-rules.json 파일에 정의된 규칙과 일치하면, executor는 이를 server로 전달하고 교차 서명된 영수증을 생성합니다. 권한이 없는 호출의 경우, 작업을 거부하고 서명된 거부 메시지를 제공합니다.
개발자는 클라이언트가 executor를 subprocess로 시작하는 stdio transport 방식이나, 여러 에이전트를 위한 streamable HTTP MCP server 방식의 HTTP를 통해 이를 배포할 수 있습니다. 설정 과정에는 설정 파일 초기화, 키 생성, 그리고 사람이 passkey로 권한 허가서에 서명하는 단계가 포함됩니다. 보안을 보장하기 위해, 파일 접근 권한이 있는 에이전트가 executor의 private keys나 credentials를 읽지 못하도록 executor를 별도의 사용자 계정이나 별도의 Docker 컨테이너에서 실행해야 합니다.
활용 사례
- 1도구 권한 검증AI 클라이언트가 도구 사용을 시도하더라도, 사람이 passkey 권한에 서명한 경우에만 executor가 이를 허용합니다.
- 2서명된 감사 추적 생성시스템은 고유한 디지털 서명을 사용하여 모든 성공적인 도구 호출과 그 결과에 대한 검증 가능한 기록을 생성합니다.
- 3에이전트로부터 자격 증명 보호개발자는 executor가 보호된 환경에서 credentials를 관리하도록 하여 AI 에이전트가 server credentials를 탈취하는 것을 방지할 수 있습니다.
- 4도구 호출 이력 감사개발자는 executor의 내부 로그와 에이전트의 로그를 비교하여 누락되거나 변경된 기록이 있는지 확인할 수 있습니다.
프로젝트의 README를 바탕으로 작성되었습니다. 모든 활용 사례는 해당 내용의 인용문과 대조하여 확인합니다.
Provared MCP Executor MCP 설치 방법
형식 확인: 2026년 11월 10일Claude Code에 Provared MCP Executor MCP 설치
$ claude mcp add mcp-executor -- npx -y provared-mcp-executorCursor에 Provared MCP Executor MCP 설치
~/.cursor/mcp.json
{
"mcpServers": {
"mcp-executor": {
"command": "npx",
"args": [
"-y",
"provared-mcp-executor"
]
}
}
}VS Code에 Provared MCP Executor MCP 설치
.vscode/mcp.json
{
"servers": {
"mcp-executor": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"provared-mcp-executor"
]
}
}
}Claude Desktop에 Provared MCP Executor MCP 설치
claude_desktop_config.json
{
"mcpServers": {
"mcp-executor": {
"command": "npx",
"args": [
"-y",
"provared-mcp-executor"
]
}
}
}Codex에 Provared MCP Executor MCP 설치
~/.codex/config.toml
[mcp_servers.mcp-executor] command = "npx" args = ["-y", "provared-mcp-executor"]
Gemini CLI에 Provared MCP Executor MCP 설치
~/.gemini/settings.json
{
"mcpServers": {
"mcp-executor": {
"command": "npx",
"args": [
"-y",
"provared-mcp-executor"
]
}
}
}구성
FILES_API_TOKEN
| 이름 | 설명 | 유형 |
|---|---|---|
| FILES_API_TOKEN | — |
자동 검사
2026년 11월 14일에 실행됨전체 보고서 →자동 검사를 통과했습니다. 이는 보안 감사가 아닙니다. 코드를 직접 읽고 서버에 필요한 최소한의 권한만 부여하십시오. 검사 방식
- 소스 저장소 연결 및 접근 가능provared/provared is public and reachablegithub.com/provared/provared ↗통과
- 패키지가 이 저장소를 소스로 지정provared-mcp-executor names provared/provared as sourcenpmjs.com/package/provared-mcp-executor ↗통과
- 빌드 출처(Sigstore 증명)No build attestation published for this release검사되지 않음
- 오픈 소스 라이선스 (OSI)Apache-2.0spdx.org/licenses/Apache-2.0.html ↗통과
- 최근 1년 내 커밋 또는 릴리스Last commit or release 2026-11-11github.com/provared/provared ↗통과
- OpenSSF ScorecardOpenSSF Scorecard 4.9 / 10; weakest: Code-Review 0, Maintained 0, CII-Best-Practices 0scorecard.dev/viewer/?uri=github.com/provared/provared ↗부분 7/15
- 패키지 이름이 인기 패키지와 유사하지 않음No popular package one edit away from provared-mcp-executor통과
- 패키지와 의존성에 심각한 보안 권고 없음the package checked; no critical advisoryosv.dev ↗통과
- 모델에 대한 숨겨진 지침 없음0 tool descriptions and the README read; no override phrases, credential paths or hidden characters통과
- 파괴적인 도구에 라벨 표시됨검사되지 않음
- 원격 endpoint가 MCP 핸드셰이크에 응답검사되지 않음
README
GitHub에서 보기provared-mcp-executor
A guard, called the executor below, in front of an MCP tool server. It holds the server's credential in place of the agent, checks each tool call against a permission a person signed with a passkey, refuses calls outside it with a signed denial, and writes a receipt, countersigned with its own keys, for each call it lets through. The credential is kept from the agent only where the agent cannot read the guard's files or reach the server another way (What it is says when). Evidence, not a verdict.
Quick start
With Node.js 24.7 or later:
npm install -g provared-mcp-executor
provared-mcp-executor demo
demo needs no passkey and no settings. In a new temporary folder, which
it names and leaves in place, it puts the executor in front of a made-up
tool server, under a permission signed by a development stand-in for a
passkey, sends it one tool call that is let through and one that a rule
refuses, and checks the book with the Provared checker. The stand-in is not
a person: its name ends with "(development)", and nothing the
demonstration writes proves anything about anyone. It writes nothing
outside that folder.
provared-mcp-executor demo --stdio is for trying the executor from an MCP
client or a directory's inspector. Each start makes a new temporary
folder, as demo does, and leaves it in place; in it go the settings and
a stand-in permission valid for one hour, after which every call is
refused until it is started again. It then runs the executor over stdio
in front of the made-up server, with its two tools echo and add, until
its input closes. Its standard output carries MCP messages only; on its
standard error it says, in one line, that this is a demonstration whose
records prove nothing about anyone, when the permission ends, and where
the book is.
For real use, in a folder of your own:
provared-mcp-executor init
provared-mcp-executor keys --config executor.json
provared-mcp-executor check --config executor.json
init copies the example settings and rules into the folder, as
executor.json and content-rules.json. Put in each value written
<like this> but the passkey's thumbprint, then make the keys; a person
signs the permission with a passkey, and its thumbprint goes in last;
check lists every problem left. "Set it up" below gives each step.
The executor holds the tool server's credential in place of the agent,
and keeps it from the agent only if the agent cannot read the
executor's files: see "What it is".
What it is
This is the executor's record of what an agent asked for through it, and what the executor did with each call. It proves nothing about calls that do not go through it. It counts only if the agent has no other way to the tool server behind it: take the server's credential away from the agent, so that the executor alone holds it.
An executor, in the words of the Internet-Draft
draft-izmaylov-agent-permission-receipts,
is software other than the agent that takes actions for it or holds what
they need, and refuses an action the permission does not allow. This one
stands between an agent and a tool server that speaks the Model Context
Protocol (MCP). It runs in two ways: over the stdio transport, where the
agent's MCP client starts the executor as if it were the tool server and the
executor starts the real server, with its credential; or over HTTP, where
the executor is itself a Streamable HTTP MCP server in front of one upstream
HTTP MCP server, and several agents call it, each signing in with a secret
of its own (see "Over HTTP, for several agents"). Either way, for every
tools/call:
- works out which action the call is, and its amount, from a rules file the person writes, by the tool's name, not from anything the agent says;
- asks the agent's stub writer whether the person's signed permission (the slip) allows it: the check before acting of the Provared library;
- if it does, writes its own copy of the call to the disk, sends the call on, and writes a signed receipt (a stub) that names the executor and binds the arguments and the server's answer by their fingerprints, and countersigns it with keys of its own;
- if it does not, sends nothing, tells the model why in a tool error, and writes a signed denial.
Every other message (server/discover, initialize, ping, resources,
prompts, notifications, a legacy server's own requests to the client) passes
through unchanged. tools/list comes back without the tools that have no
rule.
The executor holds the agent's keys and the server's credential. The agent
holds neither, so it cannot write, change or skip a receipt, as long as it
cannot read the executor's files: an agent with a shell or file tools that
runs as the same computer user can read them, and then the copy, the keys
and the credential are all in its reach. Run the executor under a separate user account that the agent cannot use,
or give the agent no shell or file tools. Over HTTP it can also run apart from
the agent, where the agent cannot read the executor's files:
an example (in the repository, not
in the npm package) puts them in separate
Docker containers on one computer, and its seven checks passed with
Docker Desktop on Windows; on separate computers it has not been tried. The executor
also keeps its own copy of every call, apart from the agent's log, which can
be held against the log to find a receipt that was left out
(compare).
Evidence, not a verdict. The whole design, with every choice numbered for
review, is in DESIGN.md. The format is described in the Provared format
description (spec/provared-format.md in the repository); the library is
the npm package provared.
Install
npm install -g provared-mcp-executor
Or from a copy of the repository: in mcp-executor, npm pack, then
npm install -g ./provared-mcp-executor-0.4.1.tgz.
It needs Node.js 24.7 or later, and depends only on the provared library,
at version 0.7.0 or a later 0.7 version (^0.7.0): its receipts name
provared.tool-name and provared.tool-result, which the format reserved
in 0.7.0 and which a checker of 0.5.0 or 0.6.0 refuses (0.4.0 and
earlier read them as labels). provared-mcp-executor --version prints the
version installed.
The example files (executor.example.json, executor-http.example.json
and content-rules.example.json) are in the installed package's folder,
provared-mcp-executor inside the folder that npm root -g prints;
provared-mcp-executor init copies them into the current folder.
Node.js says that its ML-DSA-87 signing is experimental each time it is first used in a program. The executor signs every receipt with ML-DSA-87 beside Ed25519, so the notice is expected; the command does not print that one notice, and prints every other warning. A program of your own that uses the executor's or the library's code sees the notice: it is not an error.
Set it up
-
Write the settings.
provared-mcp-executor initcopies the example settings and rules into the current folder asexecutor.jsonandcontent-rules.json(init --httpcopies the HTTP executor's asexecutor-http.json), and overwrites nothing. Then put in each value written<like this>: the server to start, the folder it runs in and the file its credential is read from. Settoolsto the server's tools and the action each is, and changecontent-rules.jsonto rules of your own, or takecontentRulesout. The paths of the agent's keys, slip and book and of the executor's keys and copy can stay as they are. Paths are read from the settings file's folder. Leave the passkey's thumbprint (agent.issuerKeys) for step 3. -
Make the keys. This makes the two key files if there are none, and prints what goes into the permission:
provared-mcp-executor keys --config executor.jsonIt does not need the passkey's thumbprint yet. It reads and checks everything before it writes: the settings, the rules file, any key file already there, and that the folder of each file it would write can be made. With
--out <file>it writes what it prints to a new file instead (not one of the key files), making its folder where needed. The printedagent.keysgo into the permission as the agent's keys; the printedwithentry (the executor's id, name and keys) goes into the permission'swith; andrequiresshould hold{"need": "countersignature"}, so that a receipt without the executor's countersignature is a finding. -
The person signs the permission with their passkey (on the signing page at https://sign.prova.red, or from a web page of your own with the library's browser part,
provared/passkey-browser) and saves it where the settings say (agent.slip). The thumbprint of the passkey goes intoagent.issuerKeys. -
Check the settings. This reads every rule, the keys, the slip and the credentials, and says what is wrong. It prints no credential.
provared-mcp-executor check --config executor.jsonIt writes nothing: no line to the book, no copy key. It lists in one run every problem it can find on its own: each value still written
<like this>, the server's program and folder, each credential, the rules file, each key file and the slip. Once none is left, it holds the slip against the keys and the rules, as a start does, and stops at the first difference there. -
Point the agent's MCP client at the executor where it named the server. For a client whose settings are JSON:
{ "mcpServers": { "files": { "command": "provared-mcp-executor", "args": ["stdio", "--config", "/etc/provared-mcp/files/executor.json"] } } }The client starts the executor; the executor starts the server named in
server.commandwithserver.args, inserver.cwd, with the credentials inserver.env.
Over HTTP, for several agents
provared-mcp-executor http --config executor-http.json
The executor listens as a Streamable HTTP MCP server (one endpoint, /mcp
unless the settings say otherwise, on 127.0.0.1:8796 unless they say
otherwise) in front of one upstream HTTP MCP server named in
upstream.url. Each agent signs in with a secret of its own, in one header,
Authorization: Bearer <secret>, and has its own slip, keys, book and copy
under agents.<name>. provared-mcp-executor secret makes a secret and
prints its hash; the hash goes into the settings as the agent's
secretHash, the secret goes to the agent and is stored nowhere else.
init --http copies the example settings (executor-http.json) and rules
into the current folder. keys makes the executor's key file and one for
each agent, and prints the entries for each agent's permission (it needs
no secret hash and no passkey's thumbprint yet); check reads every
agent's slip;
compare --agent <name> holds one agent's copy against its book.
What the executor does with each request:
- A
tools/callgoes through the same rules, check, receipt, countersignature and copy as on stdio, under the slip and into the book of the agent that sent it. The check happens before anything reaches the upstream. One call at a time goes through each agent's writer; agents do not wait for each other.maxWaitingholds for each agent on its own. - The agent's
Authorizationheader is removed. The upstream is sent the executor's own credential, a bearer token read from the fileupstream.credential.file. Of the agent's headers onlyAccept,Accept-Language,Content-Type,Mcp-Session-IdandLast-Event-IDgo on, with theMCP-Protocol-Versionthe body states, and the mirrored headers of the 2026-07-28 revision where each agrees with the body:Mcp-Methodwith the body'smethod,Mcp-Namewith itsparams.urion aresources/reador itsparams.nameon atools/callorprompts/get, andMcp-Param-<name>with the call's argument at the property of the tool'sinputSchemathat the upstream'stools/listannotatedx-mcp-header: <name>(a value wrapped as=?base64?…?=is decoded before comparing, and a number in the body is compared as a number with a header in JSON's form of one, so42.0agrees with 42 and0x2Adoes not). Every other header is dropped, and the names of the dropped ones are logged. A mirrored header that does not agree with the body, or that the executor cannot check (notools/listseen yet, no such annotation, a GET or a response, anMcp-Nameon any other method), is refused with 400 and JSON-RPC error -32020 (the specification's HeaderMismatch), and nothing reaches the upstream; a request with none of these headers is not refused, and the executor never generatesMcp-Method,Mcp-NameorMcp-Param-*itself, though the protocol version the body states goes on as its header. Of the upstream's headers onlyContent-Type,Mcp-Session-Id,MCP-Protocol-VersionandCache-Controlcome back. - One message per POST, read as strictly as a line on stdio: a batch, a
repeated member name, an id that is not text or a whole number, a number
beyond 2^53 - 1, or a shape that is not a message is refused (400) and
goes no further. A
tools/callsent as a notification is dropped (202). - The upstream's answer comes back as it came: a JSON body, or a stream of events forwarded one by one as they arrive. The response under the call's id is the outcome and ends the call; a response under another id is never taken as the outcome. The stream to the upstream is closed once the outcome is in. An upstream that refuses a call with a 4xx status and a JSON-RPC error under the call's id (the specification's way: 400 for a header mismatch or an unsupported protocol version, 404 for a method it does not have) has that error recorded as the outcome and relayed, with its status, under the agent's id; a non-2xx with no such body is recorded as "outcome not known", and its body is not relayed.
- Legacy sessions pass through: the
Mcp-Session-Idthe upstream gives comes back as it is, the GET stream of server messages andinitializepass through, and a session belongs to the agent that opened it. Another agent's request under it, or an unknown id (after a restart, the executor knows none), is answered 404, and the client begins a new session. - Cancellation follows the era. On the 2026-07-28 revision, closing the
response stream is the cancellation: the executor then closes its stream
to the upstream, the outcome is recorded as not known, as on stdio, and
the agent's own
notifications/cancelledfor a call in progress does the same and is answered 202, with nothing sent on. On a legacy session (a session id, or a protocol version before 2026-07-28), where the specification says a disconnection is not a cancellation, the agent'snotifications/cancelledis sent on to the upstream under the upstream's id for the call, answered as the upstream answers it, and then the stream is closed; the agent merely disconnecting leaves the call running, bounded bytimeout, and its real outcome is recorded. - A request that names an
Originis refused (403) unlessallowedOriginslists it; a body overbodyLimit(10 MiB) is refused (413), and one that does not arrive whole withintimeoutis refused (408); an answer or an event of the upstream over 16 MiB is cut off; a call the upstream does not answer withintimeoutis cancelled and gets a receipt that says its outcome is not known; an agent whose connection does not take what the executor has waiting withintimeouthas that exchange cut, the upstream's stream having been paused meanwhile rather than buffered, and a very slow reader can be cut too, since the clock stops only when all that is waiting has gone; each agent may have 256 requests in flight and 1,000 sessions remembered, its own oldest forgotten first. A JSON answer the agent does not read is still held after its place among the 256 is freed, up to 16 MiB for each connection, until that connection closes; the executor does not limit the number of connections. - A stop on request (SIGINT, SIGTERM) with a call in flight settles the call as the executor's stop ("The executor stopped while this call was with the tool server, so its outcome is not known."), writes its receipt, answers the agent with that error, and then closes; a call still waiting its turn is not sent and is answered so. A stop without warning, followed by a start, writes the receipt from the agent's copy before the executor listens, as on stdio.
When the credential is kept from the agent, and when it is not. The
upstream's token never goes to an agent in a header, a body, an error or a
log: the executor forwards none of the upstream's headers but the four
named, and those with the token's text replaced too; relays nothing of an
upstream answer that refuses the token (401 or 403; the agent is told the
executor's credential was refused, and no more); never follows a
redirection; and replaces the token's text wherever it occurs in anything
it sends an agent (a tool result that echoes it, an error text, an event, a
header) with the words "[a credential was removed by the Provared
executor]". That holds for the token as it is in the file; a token the
upstream encodes or splits before echoing it is not seen, and JSON's own
escaping of a /, " or \ in the token counts as encoding. It holds only
for what passes through the executor: an agent that can reach the upstream
by another way, or read the executor's files, has the token. And the
agents' secrets are only as safe as the connection they travel on: the
executor listens on the local address by default and speaks plain HTTP, so
an agent on another computer should reach it through an encrypted
connection that something else provides.
The settings (executor-http.example.json is a start): name, service,
tools, contentRules, unlisted, hideUnlisted, timeout,
denialsPerHour, callIdInMeta and maxWaiting as below; and
listen:host(default127.0.0.1; another address is warned about) andport(default 8796).path: the endpoint (default/mcp).upstream:url(http or https; plain http off this computer is warned about) andcredential:{"file": <path>}, the file that holds the bearer token, readable by the executor alone. Withoutcredentialthe upstream is called with none, and the start says so.agents: one member for each agent, by name (1 to 64 lower-case letters, digits, full stops, hyphens or underscores):secretHash,slip,book,keys,issuerKeys, andcopyandcopyKey(defaultscopies/<name>.jsonlandcopies/<name>.jsonl.key). No two agents may share a secret or a file.executor:keys, the executor's own key file.bodyLimit: the most a POST body may be, in bytes (default 10,485,760).allowedOrigins: the origins (scheme, host and port) whose pages may call the executor. Default none.
Provared MCP Executor MCP 질문
Provared MCP Executor MCP를 Claude Code에 추가하려면 어떻게 하나요?
터미널에서 claude mcp add mcp-executor -- npx -y provared-mcp-executor를 실행합니다. 모든 프로젝트에서 사용할 수 있게 하려면 --scope user를 추가합니다.
Provared MCP Executor MCP를 Cursor에 추가하려면 어떻게 하나요?
~/.cursor/mcp.json를 열고 mcpServers 아래에 서버를 추가합니다. 위 설치 섹션에 표시된 Cursor 구성을 사용합니다.
에이전트가 영수증을 조작하는 것을 어떻게 방지할 수 있나요?
에이전트가 접근할 수 없는 별도의 사용자 계정에서 executor를 실행하거나, 에이전트에게 셸 또는 파일 도구가 없도록 설정해야 합니다.
executor가 HTTP transport를 지원하나요?
네, 상위 HTTP MCP server 앞단에서 streamable HTTP MCP server로 실행할 수 있으며, 이를 통해 여러 에이전트가 각자의 secret을 사용하여 연결할 수 있습니다.
executor 실행을 위한 시스템 요구 사항은 무엇인가요?
executor는 Node.js 24.7 이상의 버전이 필요합니다.