Veil
Veil
AI 에이전트는 자격 증명 값을 절대 수신하지 않으면서 자격 증명 배치를 조정할 수 있으며, 신뢰할 수 있는 인간 제어 인터페이스는 해당 자격 증명이 허용되는 대상을 독립적으로 승인합니다.
이 문장이 바로 전체 약속입니다. Veil은 MCP 서버와 안전한 입력 브로커입니다. 에이전트가 *"Google Secret Manager에 Stripe 프로덕션 키를 넣어줘"*라고 말하면, 사용자는 정확히 어떤 프로젝트와 시크릿이 기록될지 확인하고 Veil 자체 창에 값을 입력하며, 값은 대상으로 직접 전달됩니다. 모델은 절대 값을 보유하지 않습니다.
SPEC.md에서 구현되었습니다.
설치
Veil은 stdio MCP 서버이므로 직접 실행하지 않습니다. MCP 클라이언트가 시작합니다. 일반적인 Python-MCP 패턴이 적용됩니다. uvx가 일회용 환경에서 가져와 실행하며, 이는 TypeScript 서버에서 npx -y가 작동하는 방식과 정확히 같습니다. uv와 Python 3.11+가 필요합니다.
Claude Code
claude mcp add veil -e VEIL_ENV_ALLOWED_ROOTS="$PWD" -- \
uvx --from git+https://github.com/rosostolato/veil-mcp veil-mcp serve자체 설정 대신 저장소의 .mcp.json에 기록하려면 -s project를 추가하세요.
기타 클라이언트 (Claude Desktop, Cursor, Windsurf, VS Code, Zed…)
클라이언트의 MCP 설정 파일에 다음을 추가하세요. mcpServers 블록은 모든 곳에서 동일한 형태입니다:
{
"mcpServers": {
"veil": {
"command": "uvx",
"args": [
"--from", "git+https://github.com/rosostolato/veil-mcp",
"veil-mcp", "serve"
],
"env": {
"VEIL_ENV_ALLOWED_ROOTS": "/absolute/path/to/your/project"
}
}
}
}Veil이 PyPI에 등록되면 --from git+… 쌍은 사라지고 호출은 uvx veil-mcp serve가 됩니다. 클라우드 대상에는 해당 확장 기능(veil-mcp[gcp], veil-mcp[firestore], 또는 둘 다)이 사용하는 사양에 추가되어야 합니다.
일회성 설치보다 영구 설치를 선호한다면:
uv tool install "veil-mcp[gcp] @ git+https://github.com/rosostolato/veil-mcp"
# then use `veil-mcp serve` as the command, with no uvxVEIL_ENV_ALLOWED_ROOTS를 설정하세요. .env 어댑터는 해당 디렉토리 외부에 쓰는 것을 거부하며, 기본값은 서버의 작업 디렉토리로만 설정됩니다. 그 외 모든 것은 선택 사항입니다. 설정을 참조하세요.
첫 실행
에이전트에게 *"내 Stripe 테스트 키를 .env에 저장해줘"*와 같은 요청을 해보세요. 다음과 같은 일이 발생합니다:
에이전트는 자격 증명이 어디로 가는지 설명하는
secret.store를 호출합니다. 값을 보내지 않습니다. 도구에는 값을 전달할 수 있는 필드가 없기 때문입니다.Veil이 사용자 머신에 자체 창을 열어 자격 증명 이름, 대상, 프로젝트, 환경, 작업 및 위험을 표시합니다. 에이전트는 해당 링크를 받지 않습니다.
사용자는 마스킹된 필드에 값을 입력합니다. 중간 및 높은 위험 작업은 입력 후, 쓰기 전에 두 번째 확인을 요청합니다.
Veil이 값을 기록하고 에이전트에게
STORED와 대상 참조를 알립니다. 값은 절대 전달되지 않습니다.
Veil의 자체 stderr에는 구조화된 감사 JSON이 포함됩니다. 터미널에서 사용자가 해야 할 일은 더 이상 없습니다.
Related MCP server: Janee
Veil이 해결하는 문제
에이전트가 시크릿을 알고 있음으로 인해 발생하는 전체 오류 클래스를 제거합니다. Veil이 중간에 있으면 자격 증명은 다음을 통과하지 않습니다:
LLM 프롬프트 또는 대화 기록
MCP 도구 인수 또는 도구 결과
에이전트 메모리 또는 생성된 코드
셸 명령 인수 또는 프로세스 argv
로그, 디버그 추적 또는 원격 측정
URL
모델이 볼 수 있는 명령 출력
Veil이 해결하지 않는 문제
Veil은 AI 에이전트를 신뢰할 수 있게 만들지 않으며, "안전한 AI"가 아닙니다. 에이전트가 올바른 대상을 선택했는지, 사용자를 이해했는지, 프롬프트 인젝션이 없는지, 대상 자체가 안전한지, 사용자 머신이 손상되지 않았는지, 또는 자격 증명이 나중에 합법적으로 수신하는 소프트웨어에 의해 오용되지 않을 것임을 보장하지 않습니다.
여기에는 두 가지 별개의 문제가 있습니다:
질문 | Veil의 답변 |
에이전트가 시크릿을 알아야 하는가? | 아니요. |
에이전트가 시크릿이 갈 곳을 혼자 결정해야 하는가? | 인간의 승인 없이는 안 됩니다. |
Veil은 이 두 가지에 답합니다. 나머지에 답한다고 주장하지 않습니다.
신뢰 모델
Trusted with the credential value:
The human at the keyboard
Veil's secure input UI (loopback only, in your control)
Veil's secure input broker (this process)
The selected destination adapter
The destination provider (e.g. Google Secret Manager)
NOT trusted with the credential value:
The LLM
The agent / MCP client
The conversation
The prompt and any repository content it read
Generated code
Logs, telemetry, crash reports이 다이어그램은 신뢰할 수 있는 구성 요소가 무적이라고 주장하지 않습니다. 자격 증명이 존재할 수 있는 위치를 나타냅니다. Veil은 보안에 민감한 소프트웨어입니다. Veil 자체가 악의적이거나 손상된 경우 경계는 사라집니다. 그 소스, 종속성 및 릴리스는 자격 증명을 처리하는 도구에 기대하는 수준의 검토가 필요합니다.
두 가지 흐름
시크릿 흐름 — 모델이 관찰할 수 없는 인간의 경로:
Human ─▶ Veil secure UI (127.0.0.1) ─▶ Broker ─▶ Adapter ─▶ Destination에이전트 흐름 — 모델이 보는 모든 것:
LLM ─▶ MCP client ─▶ Veil MCP server ─▶ non-sensitive result metadataMCP 도구 스키마에는 자격 증명을 전달할 수 있는 속성이 없습니다. 이는 프롬프트 명령이 아닌 구조적인 것입니다. 남용할 수 있는 value, secret_value, password, token, content 또는 raw_secret 필드가 없으며, 폐쇄된 스키마는 알 수 없는 속성을 거부하고, 인수는 구문 분석 전에 자격 증명 형태의 값이 있는지 검사됩니다.
에이전트가 호출하는 것
{
"destination": "gcp-secret-manager",
"name": "STRIPE_SECRET_KEY",
"target": { "project": "my-production-project", "secret": "STRIPE_SECRET_KEY" },
"write_mode": "new-version",
"environment": "production",
"description": "Stripe production API key"
}Veil은 request_id, 위험 분류 및 정규화된 대상으로 응답하며, 사용자 머신에 자체 승인 창을 엽니다. 에이전트는 secret.status를 폴링합니다.
에이전트는 승인 링크를 받지 않습니다. 해당 링크는 기능입니다. 이를 보유한 모든 것이 인간 측 흐름을 완료할 수 있으며, 셸이나 HTTP 도구가 있는 에이전트가 바로 위협 모델입니다. Veil은 링크를 사용자의 브라우저에 전달하고 자체 콘솔에 출력합니다. 설정에서 에이전트가 링크를 중계해야 하는 경우(예: 원격 또는 헤드리스 세션) VEIL_DISCLOSE_AUTHORIZATION_URL=true를 설정하세요. 단, 이렇게 하면 손상된 에이전트가 자체 요청을 승인할 수 있음을 이해해야 합니다.
도구 | 목적 |
| 자격 증명 요청을 생성합니다. 민감하지 않은 메타데이터와 요청 ID를 반환합니다. |
| 요청을 폴링합니다. 자격 증명 자료를 절대 반환하지 않습니다. |
| 보류 중인 요청을 취소합니다. 입력된 모든 값은 삭제됩니다. |
| 승인을 무효화하고 새 승인을 시작합니다. 제자리에서 편집되지 않습니다. |
| 대상과 각 대상이 예상하는 대상 필드를 나열합니다. |
사용자가 보는 것
A 단계에서는 값이 입력되기 전에 자격 증명 이름, 대상 제공자, 프로젝트/계정, 리소스, 작업 및 위험을 표시합니다. 높은 위험 작업(프로덕션 덮어쓰기, 일반 텍스트 저장, 애플리케이션 데이터베이스, 자격 증명 교체)은 B 단계에서 입력 후, 쓰기 전에 두 번째 확인이 필요합니다. 값은 다시 표시되지 않습니다.
사용자가 읽는 페이지와 실행자가 수행하는 작업은 동일한 불변 객체입니다. 별도의 "표시 대상"은 없습니다. 대상, 프로젝트, 시크릿 이름, 작업, 쓰기 모드 또는 어댑터의 변경은 승인을 무효화하고 새 승인이 필요합니다.
지원되는 어댑터
어댑터 | 클래스 | 참고 |
|
| 권장. |
|
| 경로 제한, 심볼릭 링크 거부, 원자적 |
|
|
|
arbitrary-network 대상(일반 HTTP POST, 웹훅)은 구현되지 않았으며, 어댑터 레지스트리는 등록을 거부합니다.
보안 가정 및 제한 사항
보안 도구가 자신을 과대평가하는 것은 없는 것보다 나쁘기 때문에 명확히 설명합니다:
브로커 프로세스는 시크릿을 봅니다. 이것이 핵심입니다. 그렇지 않으면 저장이 불가능합니다. 보장은 최소한의 신뢰할 수 있는 전송 및 대상 구성 요소만 본다는 것입니다.
CPython은 메모리를 안정적으로 지울 수 없습니다.
SecretBuffer는 소유한 변경 가능한 버퍼를 지우지만, 퍼센트 디코딩,str/bytes변환 및 제공자 SDK는 인터프리터가 GC까지 유지할 수 있는 불변 복사본을 만듭니다. Veil은 이 보장을 최소화하고 조작하지 않습니다.UI는 루프백 HTTP입니다. 사용자 머신에서 사용자로 실행되는 모든 프로세스가 접근할 수 있으며, 그러한 프로세스는 이를 모방할 수도 있습니다. 각 Veil 프로세스는 페이지에 표시되는 무작위 식별 문구를 출력합니다(스푸핑 방지 지원, 암호화 제어 아님). 에이전트로부터 링크를 숨기는 것은 장벽을 높일 뿐, Veil의 콘솔 출력을 읽거나, 브라우저의 argv를 나열하거나, 루프백 포트를 스캔할 수 있는 프로세스를 막지는 않습니다.
Veil은 대상을 감사하지 않습니다. Firestore 문서에 자격 증명을 승인하면 Veil은 이를 기록하고 나쁜 생각이라고 알리지만, 막지는 않습니다.
타임아웃은 제공자 수준입니다. Veil은 외부에서 차단 SDK 호출을 취소할 수 없으므로, 각 어댑터는 제공자에게 명시적 타임아웃을 전달합니다. 자체 타임아웃을 무시하는 대상 SDK는 요청(및 해당 시크릿)을 계속 열어둘 수 있습니다.
사전 점검은 최선의 노력입니다. 사전 점검에서 연결할 수 없는 제공자는 추측보다는 사용 불가능으로 보고됩니다.
충돌 의미. 제공자 쓰기와 응답 사이의 충돌은 성공에 대한 로컬 기록 없이 자격 증명이 기록된 상태로 남을 수 있습니다. Veil은 요청을 실패로 보고합니다. 대상이 진실의 원천입니다.
로컬 개발
git clone https://github.com/rosostolato/veil-mcp && cd veil-mcp
uv venv
uv pip install -e ".[dev,gcp,firestore]"
# drive it the way a client would
uv run veil serve클라이언트를 체크아웃에 연결하려면 uvx 대신 명령어로 /path/to/veil-mcp/.venv/bin/veil-mcp를 사용하세요.
설정
설정은 Veil 자체 환경에서 읽습니다. 도구 인수에서 절대 읽지 않으므로 에이전트가 정책을 완화할 수 없습니다:
변수 | 기본값 | 의미 |
|
| 요청 만료 시간. |
|
| 한 대상 쓰기의 상한. |
|
| 중간 위험 작업에 확인 필요. |
|
| 보안 UI 바인드 주소. |
|
| 승인 창을 자동으로 엽니다. |
|
| 승인 링크를 에이전트에 반환합니다. |
| 현재 디렉토리 |
|
|
| Git 추적 env 파일에 쓰기 허용. |
| 모두 | 쉼표로 구분된 허용 목록. |
테스트
uv run pytest # everything
uv run pytest tests/security # the adversarial suite only
uv run ruff check .
uv run mypy보안 스위트는 제품 요구 사항이지 선택 사항이 아닙니다. 모든 관찰 가능한 채널에서의 카나리 누출 탐지, 악성 에이전트 테스트, 프롬프트 인젝션 픽스처, TOCTOU 및 재생 테스트, 100방향 동시성 스트레스, 경쟁 조건, 충돌 경로, 제공자 실패 시뮬레이션, UI 검사 및 퍼징이 포함됩니다. 카나리 누출, 승인 우회 성공, 승인 후 변이 성공, 완료된 요청 재생 가능, 시크릿이 요청 경계를 넘음, 원시 제공자 오류가 MCP에 도달, 또는 높은 위험 작업이 확인을 건너뛰는 경우 릴리스가 차단됩니다.
docs/SECURITY_MODEL.md를 참조하여 불변성-테스트 매핑을 확인하세요.
프로젝트 상태
버전 0.1.0은 SPEC.md를 기준으로 빌드되었으며, 이 파일은 저장소에 의도된 동작에 대한 권위 있는 설명으로 남아 있습니다. 모든 주요 모듈과 테스트는 구현하는 섹션을 인용하므로, 검토자는 요구 사항의 요약이 아닌 요구 사항 자체에 대해 코드를 확인할 수 있습니다.
MVP가 완료되었으며, 적대적 테스트를 포함한 전체 제품군이 통과합니다. 누군가가 이를 본격적으로 신뢰하기 전에 남은 작업: 독립적인 검토, 확인 UI(SPEC.md §35)의 사용자 경험 테스트, 서명된 릴리스 아티팩트(§43).
기여하기
여기서 보안이 핵심이므로, 변경 기준은 관료적이기보다 구체적입니다.
자격 증명 처리, 인증 또는 MCP 표면에 영향을 미치는 변경 사항은 작동을 보여주는 테스트뿐만 아니라 영향을 받는 불변성을 깨뜨리려는 테스트가 필요합니다.
테스트 스위트를 통과시키기 위해 보안 테스트를 약화시키지 마십시오. 테스트가 아키텍처 결함을 드러내면 아키텍처가 변경되어야 합니다.
코어에 새로운 런타임 종속성을 추가하는 것은 기본적으로 반대됩니다. 브로커는 자격 증명 자료의 신뢰할 수 있는 컴퓨팅 기반입니다. 제공자 SDK는 선택적 추가 기능 뒤에 있어야 합니다.
풀 리퀘스트를 열기 전에
ruff check .,ruff format --check .,mypy,pytest를 실행하세요.
취약점을 발견하셨나요? 공개 이슈를 열지 말고 GitHub 보안 권고를 통해 비공개로 신고해 주세요.
라이선스
Apache License 2.0 © 2026 Eduardo Rosostolato.
Available Tools
5 toolssecret.cancelCancel a credential requestA
Cancel a pending request. Any credential already entered is destroyed.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | No | ||
| request_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It explicitly discloses a critical side effect: 'Any credential already entered is destroyed.' This is valuable transparency for a destructive mutation. However, it doesn't mention other effects like whether cancellation is reversible or requires special permissions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences long, highly concise, and front-loaded with the core action ('Cancel a pending request') followed by a key consequence. There is no fluff or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description doesn't explain return values or error conditions. While it covers the key destructive behavior, it lacks guidance on when to use the reason parameter, potential side effects beyond credential destruction, and any prerequisites. For a security-related tool, more context would be helpful, but the essential purpose is clear.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, and the description does not explain the parameters at all. It doesn't mention that request_id is required or that reason is optional. The schema itself provides clear names, but the description adds no additional meaning, leaving the agent to infer that request_id identifies the request and reason is for audit context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Cancel a pending request' which is a specific verb (cancel) and resource (request). It distinguishes from siblings like secret.store and secret.revise, as it focuses on cancellation and the destruction of already-entered credentials.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for pending requests ('Cancel a pending request') but gives no explicit guidance on when to use it versus alternatives, nor exclusions. It lacks context like 'use secret.revise to modify instead' or 'do not use for completed requests'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
secret.destinationsList available destinationsARead-only
List the destinations this Veil instance can write to, with the target fields each one expects.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations include readOnlyHint: true, and the description does not contradict it. It adds context about the content (target fields) which is useful for the agent. Given the annotation already covers safety, the description provides adequate extra behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, front-loaded with the verb and resource, no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with no parameters and no output schema, the description fully explains what it does and includes the key detail about target fields, which is likely sufficient for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameterswing schema coverage is 100% (vacuously). Baseline for 0 params is 4, and the description clarifies that the output includes target fields per destination, which adds contextual meaning beyond the empty schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (List) and the specific resource (destinations this Veil instance can write to), and adds the detail about target fields. It distinguishes itself from sibling tools like store, cancel, revise, which involve mutations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use it (to discover available destinations and their required fields), but does not explicitly contrast with alternatives. Since it's a simple listing tool, the purpose clarity implicitly covers usage, though no exclusions are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
secret.reviseReplace a credential request with a corrected oneA
Cancel a pending request and create a new one. The original authorization is invalidated and the human must authorize the new operation from scratch; an authorized operation can never be edited in place.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Logical name of the credential, e.g. STRIPE_SECRET_KEY. This is a label, never the credential value. | |
| target | Yes | Where the credential goes. Fields depend on the destination; call secret.destinations for the exact contract. | |
| request_id | Yes | ||
| write_mode | No | create | |
| description | No | Short human-readable purpose, shown to the user. | |
| destination | Yes | Which destination adapter should receive the credential. | |
| environment | No | Environment you believe this destination belongs to. Advisory only: Veil classifies the destination itself and uses the stricter of the two. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so well. It discloses that the original authorization is invalidated, the human must reauthorize from scratch, and authorized operations cannot be edited in place. This covers the key side effects and workflow consequences of a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. The first sentence states the core action, and the second provides the key behavioral consequence and an important invariant. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter tool with nested objects and no output schema, the description explains the compound nature and authorization consequences sufficiently. It could additionally mention that all parameters must be resubmitted for the new request, but the schema and existing wording make the required inputs inferable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 71%, so most parameters have descriptions already. The tool description adds context around request_id by referring to 'pending request' and 'new operation from scratch,' but it does not explain parameter interactions or destination-specific requirements beyond what the schema provides. This is adequate but not enhanced.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a compound operation: 'Cancel a pending request and create a new one.' The title, 'Replace a credential request with a corrected one,' further specifies the resource and intent, distinguishing this from sibling tools like secret.cancel and secret.store.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear context for when to use the tool: when a pending request must be corrected, and specifically notes that 'an authorized operation can never be edited in place.' It doesn't explicitly contrast with secret.cancel or secret.store, but the described workflow makes the intended use case unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
secret.statusCheck a credential requestARead-only
Return the non-sensitive status of a credential request. Never returns credential material.
| Name | Required | Description | Default |
|---|---|---|---|
| request_id | Yes | ||
| wait_seconds | No | Optionally block until the request reaches a terminal state or this many seconds elapse. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds valuable behavioral context beyond the readOnlyHint annotation by guaranteeing that no credential material is ever returned. This safety guarantee is a key trait not covered by annotations, though it does not disclose blocking behavior or error handling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences that front-load the core purpose and add a critical safety note. There is no unnecessary detail or verbosity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with two parameters and a read-only annotation, but the description omits key behavioral details such as the optional blocking behavior via wait_seconds and what the response actually contains (e.g., status list, error scenarios). Without an output schema, the description should describe the return value format more fully.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description provides no explanation of the parameters. request_id is self-explanatory from its name, but wait_seconds is already described in the schema. With only 50% schema description coverage, the description fails to compensate for the missing request_id semantics or clarify how to obtain such an ID.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns the status of a credential request and explicitly mentions it never returns credential material. This distinguishes it from siblings like secret.cancel or secret.store, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for checking status but provides no explicit guidance on when to use it versus alternatives. There is no mention of 'use when you need to check status' or exclusions like 'do not use to cancel requests'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
secret.storeRequest that the user store a credentialADestructive
Ask the human to provide a credential and have Veil write it to the destination described here. The credential value is never passed through this tool, never returned by it, and never becomes visible to the model: the user enters it in Veil's own trusted window. Share the returned authorization_url with the user, then poll secret.status.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Logical name of the credential, e.g. STRIPE_SECRET_KEY. This is a label, never the credential value. | |
| target | Yes | Where the credential goes. Fields depend on the destination; call secret.destinations for the exact contract. | |
| write_mode | No | create | |
| description | No | Short human-readable purpose, shown to the user. | |
| destination | Yes | Which destination adapter should receive the credential. | |
| environment | No | Environment you believe this destination belongs to. Advisory only: Veil classifies the destination itself and uses the stricter of the two. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description explicitly discloses that the credential value never passes through the tool, is never returned, and never becomes visible to the model—a key behavioral trait. It also outlines the multi-step process involving an authorization_url and polling. Annotations already signal destructive and open-world behavior, and the description complements these without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the core action, and includes essential security and workflow context. Every sentence earns its place, and there is no redundant or extraneous text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (nested target, multiple destinations, write modes, environment), the description covers the critical workflow and security aspects, and points to secret.destinations for detailed contracts. It does not explain write_mode or environment semantics, but those are well-documented in the schema. Overall, it is reasonably complete for a tool of this intricacy.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description does not directly elaborate on any input parameters, but the schema provides extensive descriptions for 83% of fields. It directs users to secret.destinations for the target contract, which covers the remaining nuance. Since the schema already carries the semantic load, the description adds little beyond baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's action: asking the human for a credential and having Veil write it to a specified destination. It distinguishes itself from siblings like secret.status and secret.cancel by focusing on the store action and includes critical security context (credential not visible to model) and subsequent steps (share authorization_url, poll status).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear workflow guidance: ask the user, share the authorization_url, and poll secret.status. It implies this tool is for new credentials but does not explicitly contrast with secret.revise or specify when not to use it. The flow is described well, but alternative exclusions are missing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0- First observed
secret.cancel - First observed
secret.destinations - First observed
secret.revise - First observed
secret.status - First observed
secret.store
TDQS
Scored across 5 tools
Each tool has a clearly distinct role: status checks a pending request, store initiates a credential request, cancel aborts it, revise replaces it, and destinations lists available targets. No overlap in purpose, making agent selection unambiguous.
All tool names follow a consistent 'secret.<action>' pattern with clear, concise verbs (status, store, cancel, revise) and one noun (destinations). The pattern is uniform and predictable, though 'destinations' is a noun rather than a verb, it still fits the domain prefix style.
With 5 tools, the server is tightly scoped to credential request management. This is within the ideal range and each tool earns its place; no redundancy or bloat.
The tool surface covers the entire lifecycle of a credential request: create (store), read (status), update/replace (revise), delete (cancel), and context (destinations). There are no evident gaps—even revision gracefully handles invalidation of prior authorizations.
Maintenance
Related MCP Connectors
Give AI agents identity, scoped access, trusted context, and verifiable actions through MCP.
Zero-secret MCP gateway for AI agents: risk-scored, audited calls with human-in-the-loop approval.
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
- TAPOAuthtech.human
Credential isolation for AI agents: placeholder secrets, policy checks, optional human approval.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceMCP server that lets AI agents call APIs without ever seeing the credentials, using a local encrypted vault and per-secret allowlist policies for HTTP requests and subprocess environment variables.1AGPL 3.0
- AlicenseNot gradedqualityCmaintenanceSecrets management MCP server that injects credentials into API requests for AI agents, enforcing policies and logging all activity without exposing raw keys.112 npm30MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for AI-native credential management, enabling agents to securely store, retrieve, and manage API keys with encryption, spending budgets, and audit logging.MIT
- AlicenseNot gradedqualityCmaintenanceMCP server for DemiPass secrets management, enabling AI agents to securely store, rotate, and use credentials without exposing them in context windows.44 npmMIT