Skip to content
Development
Skill

/finding-secrets

Locating the right Keeper record without reading any of them: the metadata returned by `list_secrets`, `search_secrets` and `list_folders`, how record UIDs, titles and folders relate, what `search_secrets` actually matches on (and what it silently does not), the query strings

From plugin
msp-claude-plugins
52200 skills146 agents200 commands4 MCP

Claude Code

$ npx -y skills add wyre-ai/msp-claude-plugins --skill finding-secrets --agent claude-code

SKILL.md

finding-secrets.SKILL.md
name: "Keeper Secret Discovery"
description: >
  Locating the right Keeper record without reading any of them: the
  metadata returned by `list_secrets`, `search_secrets` and
  `list_folders`, how record UIDs, titles and folders relate, what
  `search_secrets` actually matches on (and what it silently does not),
  the query strings its validator rejects, and why an empty result set
  usually means scope rather than absence.
when_to_use: >-
  When turning a description of a credential into the record UID that
  retrieval needs, or when auditing what a Keeper connection can reach.
  Use when: find a keeper secret, search keeper, list_secrets,
  search_secrets, list_folders, keeper record uid, keeper folder, what
  secrets can you see, or "which record holds the".

Finding the Right Secret

Overview

Discovery is the half of Keeper work that involves no credential material at all. `list_secrets`, `search_secrets` and `list_folders` return metadata only — no passwords, no field values, nothing masked because there is nothing sensitive to mask. Do all the narrowing here, end up with one UID, and only then reach for a retrieval tool.

The three discovery tools

`list_secrets`

Every record in the application's scope, optionally filtered by folder.

{}                                            // everything in scope
{ "folder_uid": "kJ3v9PqR2mXwL7nBcD4sTg" }    // one folder
{ "folder_uids": ["uid1", "uid2"] }           // several — preferred

`folder_uids` is the multi-folder form and is pushed down to Keeper's folder filtering; `folder_uid` exists for backward compatibility. Passing both ignores the singular one.

Response — `count` plus one entry per record:

{ "count": 2, "secrets": [
  { "uid": "NJ_xXSkk3xYI1h9ql5lAiQ", "title": "Contoso DC01 Local Admin",
    "type": "serverCredentials", "folder": "kJ3v9PqR2mXwL7nBcD4sTg" },
  { "uid": "8fQ2wKmT5vXyL9pRnB3cAa", "title": "Contoso Firewall",
    "type": "login", "folder": "kJ3v9PqR2mXwL7nBcD4sTg" }
] }

Four fields, and that is the whole surface: `uid`, `title`, `type`, `folder`. `type` is the Keeper record type — it tells you which fields the record can carry, and so which field names KSM notation is likely to address. To see the actual names, read them off a masked `get_secret`.

`list_folders`

Every folder shared to the application, as a flat list of `uid` / `name` / `parent_uid`. Nesting is expressed by `parent_uid` pointers, not by structure, so build the tree yourself if you need one. A folder whose `parent_uid` names a folder that is not in the list is a subfolder of something outside the application's scope — normal, not an error.

This is also the fastest honest answer to "what can this connection see?".

`search_secrets`

One required `query` string. Returns the same four metadata fields under `results`, plus a `count`.

What it actually matches — verified against the upstream implementation, in this order, stopping at the first hit:

1. Record **title** 2. Record **notes** 3. Record **type** (so `query: "login"` matches every login record) 4. The values of four standard fields only: **`login`, `url`, `hostname`, `address`** 5. **Attachment** filenames and titles

All matching is case-insensitive substring. It is not a Keeper-side search: the tool pulls every record in scope and filters locally, so there is no pagination, no ranking and no result cap — a broad query returns the whole scope.

Workflow: description to UID

1. `list_folders` — orient, and confirm the scope is what you expect. 2. `search_secrets` with the most distinctive token you have (a hostname, a tenant name, a device name). Prefer one distinctive word over a long phrase; the match is a plain substring, so `"Contoso DC01"` fails against a record titled `"DC01 (Contoso) Local Admin"` while `"DC01"` succeeds. 3. If the result set is large, narrow with `list_secrets` on the folder the likely candidate sits in. 4. Confirm the choice by title and type, then hand the UID to `get_field` — not to `get_secret`, unless the whole record is genuinely needed.

When two candidates look equally plausible, ask the user which record they mean. Do not disambiguate by fetching both and comparing credentials.

Gotchas

**`search_secrets` does not search custom fields.** The upstream code carries an explicit TODO to that effect. A record whose only mention of "Azure" is a custom field labelled `Tenant ID` will not be found by searching `Azure`. Fall back to `list_secrets` over the likely folder and read titles.

**Some perfectly ordinary queries are rejected, and client names are the usual casualty.** The query validator refuses, case-insensitively, any query *containing* `union`, `select`, `insert`, `update`, `delete`, `drop`, `xp_`, `sp_`, `--`, `/*`, `*/`, `';` or `";` — plus shell metacharacters and queries over 256 characters. It is a SQL-injection filter applied to a search that never touches SQL, and it matches on substrings, so it catches real business names:

| Query | Rejected because it contains | |-------|------------------------------| | `Union Bank` | `union` | | `Updates Server` | `update` | | `Select Insurance` | `select` | | `Dropbox` | `drop` | | `Insertech` | `insert` |

All of them fail with `search query contains suspicious patterns`. That is input validation, not a permissions problem and not evidence the record is missing — never report it as either. Search a different token from the same record: a hostname, a login, part of a URL. Not a folder name — `search_secrets` never matches those (see the match list above); to narrow by folder use `list_secrets` with `folder_uids`.

**A hit does not mean the title matched.** Matching on notes and on `login` / `url` / `hostname` / `address` values means a result can look unrelated to the query. Read the returned `title` before acting, and say which record you chose.

**`type` matching makes generic queries useless.** Searching `login` ma

Read more
@wyre-technology
Ships withmsp-claude-plugins

One command to supercharge Claude Code for MSP workflows. Then restart Claude Code. That's it. Documentation: mcp.wyre.ai

52200 skills146 agents4 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
52
Star history of wyre-technology/msp-claude-plugins on GitHub, a chart by star-history.com

Other skills on msp-claude-plugins.

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc11d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about finding-secrets.

Which coding agents can use finding-secrets?
finding-secrets installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.