| name | tool-schema-plan |
|---|---|
| description | Canonical specification and phased roadmap for proton-pass-community-mcp tool contracts and naming conventions. |
This document defines the planned MCP tool surface for proton-pass-community-mcp with two goals:
- Expose the applicable
pass-clicommand surface (command parity), excluding authentication lifecycle commands that are intentionally user-managed out-of-band. - Add MCP-native tools/contracts where raw CLI output is not LLM-efficient.
Primary optimization target: item discovery (pass-cli item list) should return lightweight references, not full item payloads.
- Tool names use snake_case without provider prefix and prefer natural-language order (for example
list_vaults,view_item). - Current implementation requires explicit confirmation (
confirm: true) and write gate (ALLOW_WRITE=1); see policy proposal below for elicitation-first migration. - Read tools default to structured, token-efficient JSON in
structuredContent. - When
structuredContentis returned, also return aTextContentserialization of that same JSON object for backwards compatibility/interoperability. This is not a separate human-output mode from the CLI. - Listing/search tools return references, then callers use
view_itemfor full content. - Release branches may retain non-release code paths, but only release-scoped tools are registered/exposed by default.
- Authentication session lifecycle (
pass-cli login,pass-cli logout) remains out-of-band and is not exposed as MCP tools, even when login is PAT-backed. - PAT administration is evaluated separately from login/logout because it manages scoped credentials after bootstrap auth; see
docs/ADR/ADR-005-pat-auth-boundary-and-tooling.md. - CLI binary lifecycle commands (for example
pass-cli update/ track switching) remain out-of-band and are not exposed as MCP tools. - Host SSH agent integration/lifecycle commands (
pass-cli ssh-agent *) remain out-of-band and are not exposed as MCP tools.
This section defines the target mutation-safety model for this server, aligned with current MCP protocol semantics:
ALLOW_WRITE=1is the hard, server-side write gate and remains mandatory.- Tool annotations (for example
destructiveHint) are advisory UX metadata only and are not treated as a security boundary. - For destructive tools, the server should request runtime user confirmation via MCP elicitation (
elicitation/create) when the negotiated client capability supports it. - If elicitation is unavailable, interactive sessions should fail closed for destructive operations.
- CI/non-interactive automation may opt in with an explicit override environment variable (proposed:
ALLOW_NONINTERACTIVE_WRITE=1) for throwaway-account workflows. - The existing input-level
confirmparameter is an implementation fallback and should be phased out once elicitation coverage is in place for supported hosts.
- Elicitation is not a universal requirement across all protocol versions.
- Elicitation was introduced in spec version
2025-06-18; sessions negotiating older versions cannot use it. - Even on current spec versions, elicitation is capability-negotiated and optional at runtime; servers must branch behavior based on negotiated capabilities.
- For local
stdiodeployments, the same person usually controls both sides (client config and server process environment), so write-gate env vars are effectively user-chosen launch policy. This does not weaken enforcement: the server still applies its own gate checks at runtime.
| Context | Behavior |
|---|---|
| Read-only tool | Execute normally |
Mutating tool + ALLOW_WRITE!=1 |
Deny (WRITE_DISABLED) |
Mutating tool + ALLOW_WRITE=1 + client supports elicitation |
Prompt via elicitation; execute only on explicit accept |
Mutating tool + ALLOW_WRITE=1 + no elicitation + ALLOW_NONINTERACTIVE_WRITE!=1 |
Deny (WRITE_CONFIRMATION_UNAVAILABLE) |
Mutating tool + ALLOW_WRITE=1 + no elicitation + ALLOW_NONINTERACTIVE_WRITE=1 |
Execute (CI/non-interactive throwaway-account mode) |
- Keep current
confirm-based behavior while adding elicitation-backed flows. - Prefer elicitation path when available; retain
confirmonly as temporary compatibility shim. - Remove
confirmfrom mutating tool schemas after host compatibility validation and test coverage are complete.
{
"id": "string",
"share_id": "string",
"vault_id": "string",
"title": "string | null",
"display_title": "string",
"type": "string | null",
"state": "string | null",
"create_time": "string | null",
"modify_time": "string | null",
"uri": "pass://<share_id>/<id>"
}Title fallback policy:
- Use
content.titlewhen non-empty. - Otherwise set
title: nullanddisplay_title: "[untitled:<short-id>]".
Raw upstream shape reference (anonymized sample from pass-cli item list --output json):
{
"id": "itm_9f2a1c7e",
"share_id": "shr_7d4b2e11",
"vault_id": "vlt_4c6f8a90",
"content": {
"title": "Example Login Entry",
"note": "Autosaved from redacted origin",
"item_uuid": "uuid_3b5d7f91",
"content": {
"Login": {
"email": "user+sample@example.invalid",
"username": "example_user",
"password": "REDACTED_SECRET",
"urls": ["https://example.invalid/login"],
"totp_uri": "",
"passkeys": []
}
},
"extra_fields": []
},
"state": "Active",
"flags": [],
"create_time": "2026-01-10T12:34:56Z",
"modify_time": "2026-01-12T08:15:30Z"
}Notes:
content.content.<Type>(for exampleLogin) is used to deriveItemRef.type(normalized to filter token format, for examplelogin).- Nested secret-bearing fields (passwords, TOTP URIs, passkeys, notes) must not be surfaced in
ItemRef.
{
"items": "T[]",
"cursor": "string",
"pageSize": 100,
"returned": 100,
"total": 708,
"nextCursor": "string | null"
}Cursor is an offset string ("0", "100", ...).
{
"id": "string",
"type": "string | null",
"target_name": "string | null",
"inviter": "string | null",
"role": "string | null",
"state": "string | null",
"create_time": "string | null"
}Notes:
- Treat invitation tokens as sensitive capabilities and do not expose them in list payloads.
- Include only stable metadata needed for triage and follow-up selection.
{
"id": "string",
"username": "string | null",
"email": "string | null",
"role": "string | null",
"state": "string | null",
"create_time": "string | null"
}Input:
- Existing selectors:
vaultNameorshareId. - Existing filters:
filterType,filterState,sortBy. - Pagination:
pageSize,cursor. - Optional
output, defaultjson.
Output:
structuredContent: CursorPage<ItemRef>.- No full sensitive fields.
- Reference-only output is the default and current policy (no full-item compatibility fallback mode).
Input:
query(required).field(default and only supported value initially:"title").matchenum:contains | prefix | exact(defaultcontains).caseSensitiveboolean (defaultfalse).vaultNameorshareIdoptional selector.filterType,filterState,sortBypassthrough.pageSize,cursor.
Output:
structuredContent: CursorPage<ItemRef>.queryMetaobject withfield,match, andcaseSensitive.
Notes:
- Search is explicitly title-based for v1.
- If title is missing, item is still returned as a ref but cannot match title query except by empty/exact edge cases.
Input:
pageSize,cursor.
Output:
structuredContent: CursorPage<InviteRef>.- Reference-only invite metadata (no raw invite token material in list payloads).
- When structured parsing is unavailable, return best-effort normalized text in
content.
Input:
- Scope selector: exactly one of
shareIdorvaultName. pageSize,cursor.
Output:
structuredContent: CursorPage<VaultMemberRef>.scopeobject echoing the selector used (shareIdorvaultName).- When structured parsing is unavailable, return best-effort normalized text in
content.
Input:
- none.
Output:
structuredContentwith parsed settings when machine-readable shape is derivable.contentremains present for debugging/interoperability.
Status key:
Implemented: currently registered as MCP resources.Planned: not yet registered.
| Resource URI Prefix | Status | Source | Notes |
|---|---|---|---|
pass://templates/item-create |
Implemented | Snapshot artifact (docs/testing/item-create-templates.snapshot.json) |
Catalog/index resource |
pass://templates/item-create/<type> |
Implemented | Snapshot artifact (docs/testing/item-create-templates.snapshot.json) |
Per-type template resource (login, note, credit-card, wifi, custom, identity) |
pass://vaults |
Planned | MCP-native | High-read vault listing |
pass://share/<id>/items |
Planned | MCP-native | High-read item refs |
Status key:
Implemented: currently in server.Planned: targeted for schema/tool implementation.Planned (MCP-native): added for MCP ergonomics, not direct CLI command.Deferred (Secret-emitting): intentionally postponed because safe MCP handling of the returned secret material is unresolved.Out of Scope (Out-of-Band): intentionally not exposed as MCP tools.
Input summary convention:
required:fields required by MCP tool contract/runtime gate.optional:accepted but not required.selector:scope selector semantics (shareId | vaultNameetc.).xor:mutually exclusive groups (exactly one when provided).
| Tool | Source | Status | Input Summary | Output Summary |
|---|---|---|---|---|
login |
pass-cli login |
Out of Scope (Out-of-Band) | n/a | n/a |
logout |
pass-cli logout |
Out of Scope (Out-of-Band) | n/a | n/a |
check_status |
pass-cli test + pass-cli --version |
Implemented | none | Connectivity/auth preflight + CLI version compatibility |
view_session_info |
pass-cli info |
Implemented | output? |
Account/session info |
view_user_info |
pass-cli user info |
Implemented | output? |
User profile |
update |
pass-cli update |
Out of Scope (Out-of-Band) | n/a | n/a |
support |
pass-cli support |
Out of Scope (Out-of-Band) | n/a | n/a |
inject |
pass-cli inject |
Implemented | inFile, outFile?, fileMode?, force?, confirm |
Output path/status |
run |
pass-cli run |
Implemented | command[], envFile[]?, noMasking?, confirm |
Exit code/stdout/stderr summary |
| Tool | Source | Status | Input Summary | Output Summary |
|---|---|---|---|---|
create_personal_access_token |
pass-cli pat create |
Deferred (Secret-emitting) | name, expiration, confirm |
One-time bearer credential + metadata |
list_personal_access_tokens |
pass-cli pat list |
Planned | output? |
Token refs / expiration metadata |
delete_personal_access_token |
pass-cli pat delete |
Planned | personalAccessTokenId, confirm |
Delete status |
renew_personal_access_token |
pass-cli pat renew |
Deferred (Secret-emitting) | xor: personalAccessTokenId | personalAccessTokenName; required: expiration, confirm |
New bearer credential + metadata |
grant_personal_access_token_access |
pass-cli pat access grant |
Planned | token selector: personalAccessTokenId | personalAccessTokenName; scope selector: shareId | vaultName; item selector: itemId? | itemTitle?; role?, confirm |
Grant status |
revoke_personal_access_token_access |
pass-cli pat access revoke |
Planned | token selector: personalAccessTokenId | personalAccessTokenName; required: shareId, confirm |
Revoke status |
list_personal_access_token_access |
pass-cli pat access list-access |
Planned | token selector: personalAccessTokenId | personalAccessTokenName; output? |
Current grant list |
Notes:
- PAT-backed
pass-cli loginremains out of scope because it is still login lifecycle, not steady-state vault operation. pat createandpat reneware deferred because upstream docs say the full token value is shown only once; exposing that through normal MCP tool output would leak a fresh bearer credential into tool transcripts/model context.- Dynamic PAT state is not planned as an MCP resource surface because it is security-sensitive and mutable.
| Tool | Source | Status | Input Summary | Output Summary |
|---|---|---|---|---|
list_vaults |
pass-cli vault list |
Implemented | output? |
Vault list |
create_vault |
pass-cli vault create |
Implemented | name, confirm |
Created vault status |
update_vault |
pass-cli vault update |
Implemented | shareId | vaultName, newName, confirm |
Update status |
delete_vault |
pass-cli vault delete |
Implemented | shareId | vaultName, confirm |
Delete status |
share_vault |
pass-cli vault share |
Implemented | shareId | vaultName, email, role?, confirm |
Share result |
transfer_vault |
pass-cli vault transfer |
Implemented | shareId | vaultName, memberShareId, confirm |
Transfer result |
list_vault_members |
pass-cli vault member list |
Implemented | shareId | vaultName, pageSize?, cursor? |
CursorPage<VaultMemberRef> |
update_vault_member |
pass-cli vault member update |
Implemented | shareId | vaultName, memberShareId, role, confirm |
Update status |
remove_vault_member |
pass-cli vault member remove |
Implemented | shareId | vaultName, memberShareId, confirm |
Remove status |
| Tool | Source | Status | Input Summary | Output Summary |
|---|---|---|---|---|
list_items |
pass-cli item list |
Implemented | vaultName | shareId, filterType?, filterState?, sortBy?, pageSize?, cursor? |
CursorPage<ItemRef> |
search_items |
MCP-native | Implemented (MCP-native) | query, title-search params, selectors, filters, paging |
CursorPage<ItemRef> |
view_item |
pass-cli item view |
Implemented | uri or selector tuple, field?, output? |
Full item or selected field |
generate_item_totp |
pass-cli item totp |
Implemented | uri or selector tuple, field?, output? |
TOTP value(s) |
| Tool | Source | Status | Input Summary | Output Summary |
|---|---|---|---|---|
update_item |
pass-cli item update |
Implemented | required: fields[], confirm; selector: shareId | vaultName; xor: itemId | itemTitle |
Update status |
move_item |
pass-cli item move |
Implemented | required: confirm; source selector: fromShareId | fromVaultName; destination selector: toShareId | toVaultName; xor: itemId | itemTitle |
Move status |
delete_item |
pass-cli item delete |
Implemented | required: shareId, itemId, confirm |
Delete status |
share_item |
pass-cli item share |
Implemented | required: shareId, itemId, email, confirm; optional: role |
Share status |
trash_item |
pass-cli item trash |
Implemented | required: confirm; selector: shareId? | vaultName?; xor: itemId | itemTitle |
Trash status |
untrash_item |
pass-cli item untrash |
Implemented | required: confirm; selector: shareId? | vaultName?; xor: itemId | itemTitle |
Restore status |
| Tool | Source | Status | Input Summary | Output Summary |
|---|---|---|---|---|
create_login_item |
pass-cli item create login |
Implemented | required: title, confirm; optional: selector (shareId or vaultName), username, email, password, url, generatePassword, output |
Created item |
create_login_item_from_template |
pass-cli item create login --from-template |
Implemented | required: template.title, confirm; optional: selector (shareId or vaultName), template.username, template.email, template.password, template.urls[], output |
Created item |
create_note_item |
pass-cli item create note |
Implemented | required: title, confirm; optional: selector (shareId or vaultName), note |
Created item |
create_credit_card_item |
pass-cli item create credit-card |
Implemented | required: title, confirm; optional: selector (shareId or vaultName), cardholderName, number, cvv, expirationDate, pin, note |
Created item |
create_wifi_item |
pass-cli item create wifi |
Implemented | required: title, ssid, confirm; optional: selector (shareId or vaultName), password, security, note |
Created item |
create_custom_item |
pass-cli item create custom --from-template |
Implemented | required: template.title, confirm; optional: selector (shareId or vaultName), template.note, template.sections[] |
Created item |
create_identity_item |
pass-cli item create identity --from-template |
Implemented | required: template.title, confirm; optional: selector (shareId or vaultName), template identity fields |
Created item |
generate_ssh_key_item |
pass-cli item create ssh-key generate |
Out of Scope (Out-of-Band) | n/a | n/a |
import_ssh_key_item |
pass-cli item create ssh-key import |
Out of Scope (Out-of-Band) | n/a | n/a |
Notes:
- Docs verification (snapshot
v1.5.2andprotonpass.github.io, checked on March 6, 2026): explicit template schema examples are login-centric upstream. - Empirical validation against the throwaway account on March 6, 2026 (
scripts/pass-dev.sh) confirmed--get-templateand--from-templatesupport fornote,credit-card,custom,wifi, andidentity(in addition tologin). - Inferred per-type template contracts are documented in
docs/testing/ITEM_CREATE_TEMPLATE_SCHEMA_INFERENCE.mdand should be treated as tested working contracts, not authoritative upstream schema guarantees. item create <type> --get-templateoutputs should be treated as templates/examples, not strict schemas;wifitemplate defaults are a concrete case where baseline output is not directly create-ready.- Additional-properties probe (March 6, 2026): unknown template keys are accepted by parser/create flow across tested types, but spot-check persistence indicates they are ignored/dropped; MCP contracts should not assume unknown keys become stored fields.
- Template-backed creation tools (
create_login_item_from_template,create_custom_item,create_identity_item) use explicit strict schemas (additionalProperties: falsebehavior at MCP validation layer). item create login --get-templateis currently out-of-band (not exposed as an MCP tool).
| Tool | Source | Status | Input Summary | Output Summary |
|---|---|---|---|---|
create_item_alias |
pass-cli item alias create |
Implemented | shareId | vaultName, prefix, output?, confirm |
Alias item |
download_item_attachment |
pass-cli item attachment download |
Implemented | shareId, itemId, attachmentId, outputPath |
Download status/path |
list_item_members |
pass-cli item member list |
Implemented | shareId, itemId, output? |
Member list |
update_item_member |
pass-cli item member update |
Implemented | shareId, memberShareId, role, confirm |
Update status |
remove_item_member |
pass-cli item member remove |
Implemented | shareId, memberShareId, confirm |
Remove status |
| Tool | Source | Status | Input Summary | Output Summary |
|---|---|---|---|---|
list_shares |
pass-cli share list |
Implemented | onlyItems?, onlyVaults?, output? |
Shares list |
list_invites |
pass-cli invite list |
Implemented | pageSize?, cursor? |
CursorPage<InviteRef> |
accept_invite |
pass-cli invite accept |
Implemented | inviteToken, confirm |
Accept status |
reject_invite |
pass-cli invite reject |
Implemented | inviteToken, confirm |
Reject status |
generate_random_password |
pass-cli password generate random |
Implemented | generation flags | Password value/metadata |
generate_passphrase |
pass-cli password generate passphrase |
Implemented | generation flags | Passphrase value/metadata |
score_password |
pass-cli password score |
Implemented | password |
Strength report |
generate_totp |
pass-cli totp generate |
Implemented | secretOrUri, output? |
TOTP value |
view_settings |
pass-cli settings view |
Implemented | none | Settings object |
set_default_vault |
pass-cli settings set default-vault |
Implemented | vaultName | shareId, confirm |
Set status |
unset_default_vault |
pass-cli settings unset default-vault |
Implemented | confirm |
Unset status |
set_default_format |
pass-cli settings set default-format |
Out of Scope (Out-of-Band) | n/a | n/a |
unset_default_format |
pass-cli settings unset default-format |
Out of Scope (Out-of-Band) | n/a | n/a |
ssh_agent_start |
pass-cli ssh-agent start |
Out of Scope (Out-of-Band) | n/a | n/a |
ssh_agent_load |
pass-cli ssh-agent load |
Out of Scope (Out-of-Band) | n/a | n/a |
ssh_agent_debug |
pass-cli ssh-agent debug |
Out of Scope (Out-of-Band) | n/a | n/a |
Notes:
- Output format defaults are intentionally user/workflow configuration and are not exposed as MCP tools. MCP tools should return structured outputs independent of CLI human/json display preferences.
- Finalized
list_itemsreference contract with payload-shape normalization ({items:[...]}). - Added
filterType,filterState,sortBysupport inlist_items. - Added
search_items(title-only search).
- Add parity wrappers for remaining read-focused commands.
- Add parity wrappers for remaining write commands with confirmation gates.
- Add resources for high-read paths (
pass://vaults,pass://share/<id>/items). - Keep tools for actions and targeted retrieval.
list_itemsresponse strategy: use ref-only now (Option A). Future compatibility expansions are conditional on concrete downstream tool-flow needs, not preemptive.- MCP output format policy: JSON-only for tool-facing responses. When upstream CLI offers human/json output modes, MCP tool handlers should select/normalize JSON and minimize fields for agent consumption.