{"openapi":"3.1.0","info":{"title":"Keyforge API","version":"0.1.0","description":"A fully local password/passphrase generator and strength estimator: cryptographically random passwords and Diceware-style passphrases, entropy-based strength scoring, crack-time estimates, PIN generation, common-pattern detection, and NIST/strict policy checks. Zero upstream calls; nothing generated or checked is stored.\n\nEvery operation is read-only or compute-only. The same tools are available over MCP (streamable HTTP) at https://keyforge.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"hr@unifydynamics.com","url":"https://connectorbay.com/keyforge/docs"},"termsOfService":"https://connectorbay.com/keyforge/terms"},"servers":[{"url":"https://keyforge.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/keyforge/docs"},"security":[{},{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Optional. A Pro API key raises rate limits; no credentials are required."}},"schemas":{"Error":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object"}}}}},"paths":{"/v1/tools/generate_password":{"post":{"operationId":"generate_password","summary":"A cryptographically random password (Python's `secrets` module, never `random`), 8-128 characters,","description":"A cryptographically random password (Python's `secrets` module, never `random`), 8-128 characters,\n    with configurable character classes. At least one class must stay enabled. Use for \"generate a strong\n    password\", \"give me a 20-character password with no symbols\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"length":{"default":16,"description":"Password length.","maximum":128,"minimum":8,"title":"Length","type":"integer"},"use_upper":{"default":true,"description":"Include uppercase letters A-Z.","title":"Use Upper","type":"boolean"},"use_lower":{"default":true,"description":"Include lowercase letters a-z.","title":"Use Lower","type":"boolean"},"use_digits":{"default":true,"description":"Include digits 0-9.","title":"Use Digits","type":"boolean"},"use_symbols":{"default":true,"description":"Include symbols, e.g. !@#$%^&*()-_=+.","title":"Use Symbols","type":"boolean"},"exclude_ambiguous":{"default":false,"description":"Drop visually ambiguous characters (l, 1, I, O, 0, o, |, quotes).","title":"Exclude Ambiguous","type":"boolean"}},"title":"generate_passwordArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/generate_passphrase":{"post":{"operationId":"generate_passphrase","summary":"A Diceware-style passphrase: several words chosen uniformly at random (via `secrets`) from a bundled,","description":"A Diceware-style passphrase: several words chosen uniformly at random (via `secrets`) from a bundled,\n    hand-curated ~3,000-word list, joined by `separator`. Use for \"give me a passphrase\", \"make a 6-word\n    passphrase I can remember\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"word_count":{"default":5,"description":"Number of random words.","maximum":12,"minimum":3,"title":"Word Count","type":"integer"},"separator":{"default":"-","description":"Text placed between words.","maxLength":8,"title":"Separator","type":"string"},"capitalize":{"default":false,"description":"Capitalize the first letter of each word.","title":"Capitalize","type":"boolean"},"include_number":{"default":false,"description":"Insert one random digit at a random position for extra entropy.","title":"Include Number","type":"boolean"}},"title":"generate_passphraseArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/password_strength":{"post":{"operationId":"password_strength","summary":"Entropy-based strength estimate (bits, from character-class coverage and length), a plain-language","description":"Entropy-based strength estimate (bits, from character-class coverage and length), a plain-language\n    rating (very weak/weak/fair/strong/very strong), and specific improvement suggestions. Flags local\n    heuristic weaknesses -- all-lowercase, sequential runs, keyboard-walk patterns, repeated characters,\n    common passwords (with or without leet substitutions) -- never a live breached-password database\n    lookup. The password is never stored or logged. Use for \"how strong is this password\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"password":{"description":"The password to score.","maxLength":256,"minLength":1,"title":"Password","type":"string"}},"required":["password"],"title":"password_strengthArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/estimate_crack_time":{"post":{"operationId":"estimate_crack_time","summary":"Estimated time to crack a password (or a given entropy-bits value) under three standard guess-rate","description":"Estimated time to crack a password (or a given entropy-bits value) under three standard guess-rate\n    assumptions: online throttled (~100/hour), offline slow hash like bcrypt/Argon2 (~10,000/second), and\n    offline fast hash on GPUs (~10 billion/second). Use for \"how long would it take to crack this\n    password\", \"how long to brute-force 60 bits of entropy\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"password_or_entropy_bits":{"description":"Either a password to score, or a raw entropy value in bits (e.g. '60').","title":"Password Or Entropy Bits","type":"string"}},"required":["password_or_entropy_bits"],"title":"estimate_crack_timeArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/pin_generator":{"post":{"operationId":"pin_generator","summary":"A random numeric PIN (via `secrets`), optionally avoiding obviously weak patterns -- repeated digits","description":"A random numeric PIN (via `secrets`), optionally avoiding obviously weak patterns -- repeated digits\n    (1111), sequences (1234, 4321), and well-known common PINs (1234, 0000, 2580, ...). Use for \"give me a\n    6-digit PIN\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"length":{"default":6,"description":"Number of digits.","maximum":12,"minimum":3,"title":"Length","type":"integer"},"avoid_patterns":{"default":true,"description":"Reroll away from repeated digits, sequences, and common PINs like 1234/0000.","title":"Avoid Patterns","type":"boolean"}},"title":"pin_generatorArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/check_common_patterns":{"post":{"operationId":"check_common_patterns","summary":"Flags keyboard-walk patterns (qwerty, asdf), sequential runs (1234, abcd), repeated characters or","description":"Flags keyboard-walk patterns (qwerty, asdf), sequential runs (1234, abcd), repeated characters or\n    substrings, and common weak passwords (with or without leet-style substitutions like P@ssw0rd) -- all\n    from a bundled local list, with no breach-database lookup. Use for \"does this password have any obvious\n    weak patterns\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"password":{"description":"The password to check.","maxLength":256,"minLength":1,"title":"Password","type":"string"}},"required":["password"],"title":"check_common_patternsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/password_policy_check":{"post":{"operationId":"password_policy_check","summary":"Validates a password against the \"nist\" preset (SP 800-63B modern guidance: length over composition","description":"Validates a password against the \"nist\" preset (SP 800-63B modern guidance: length over composition\n    rules, screened against common passwords), the \"strict\" preset (longer minimum, all four character\n    classes required), or \"custom\" with explicit overrides. Use for \"does this password meet NIST rules\",\n    \"check this against a 14-character strict policy\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"password":{"description":"The password to validate.","maxLength":256,"minLength":1,"title":"Password","type":"string"},"policy":{"default":"nist","description":"nist | strict | custom. With custom, set requirements explicitly below.","title":"Policy","type":"string"},"min_length":{"anyOf":[{"maximum":256,"minimum":1,"type":"integer"},{"type":"null"}],"default":null,"description":"Override the preset's minimum length.","title":"Min Length"},"require_upper":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":null,"description":"Override whether an uppercase letter is required.","title":"Require Upper"},"require_lower":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":null,"description":"Override whether a lowercase letter is required.","title":"Require Lower"},"require_digit":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":null,"description":"Override whether a digit is required.","title":"Require Digit"},"require_symbol":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":null,"description":"Override whether a symbol is required.","title":"Require Symbol"}},"required":["password"],"title":"password_policy_checkArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/security_tips":{"post":{"operationId":"security_tips","summary":"A short, hand-curated reference: password managers (explained generically, no specific product","description":"A short, hand-curated reference: password managers (explained generically, no specific product\n    named or recommended), multi-factor authentication, passphrases vs. passwords, why length beats\n    complexity (per NIST guidance), password reuse, and safe storage. Use for \"tips on using a password\n    manager\", \"why does length matter more than complexity\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"topic":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"password_managers | mfa | passphrase_vs_password | length_vs_complexity | reuse | storage. Omit to list all topics.","title":"Topic"}},"title":"security_tipsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}}}}