jwt-decode — Claude Code skill: inspect JWTs without verifying
Splits a JWT into header, payload and signature, prints every claim and flags the expiry. Handy when you just need to see what is inside a token.
npx skills add jsonwebtoken/jwt-skills --skill jwt-decode -a claude-codeWhat jwt-decode does
The skill takes a JWT string, splits it on dots into three parts, and base64url-decodes the first two into JSON. You get the header, the payload with all claims, and the raw signature string. For exp, nbf and iat it prints both the Unix timestamp and a UTC date; if exp is in the past, the token is marked expired along with how long ago.
It also runs security checks. Signatures are never verified here — that is what the jwt-validate skill is for, so treat the contents as untrusted. What it will flag is alg: none: an unsigned token that anyone could have written or edited. It also calls out passwords, secrets and PII sitting in claims, a missing exp, and jku, jwk or x5u fields in the header.
A cty: JWT header means the payload is a nested token, and the skill decodes it recursively. On failure it reports the specific problem: malformed base64, invalid JSON, or the wrong segment count. Worth installing if you poke at tokens by hand often — just remember this one reveals contents and says nothing about authenticity.
What it helps with
- see which claims a token carries
- check whether
exphas already passed - spot passwords or API keys leaked into the payload
- catch an unsigned token with
alg: none - unwrap a nested JWT from the
ctyheader
Example prompts for the agent
- decode this JWT and show me the claims
- what's in this token?
- check if this JWT is expired
How to install jwt-decode
1Skills CLI (Vercel)
npx skills add jsonwebtoken/jwt-skills --skill jwt-decode -a claude-code2Manually: put the files in place
~/.claude/skills/jwt-decode/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/jwt-decode/
1Skills CLI (Vercel)
npx skills add jsonwebtoken/jwt-skills --skill jwt-decode -a codex2Manually: put the files in place
.agents/skills/jwt-decode/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add jsonwebtoken/jwt-skills --skill jwt-decode -a cursor2Manually: put the files in place
.cursor/skills/jwt-decode/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install jsonwebtoken/jwt-skills jwt-decode2Manually: put the files in place
.github/skills/jwt-decode/SKILL.md1Skills CLI (Vercel)
npx skills add jsonwebtoken/jwt-skills --skill jwt-decode -a gemini-cli2Platform CLI
gemini skills install https://github.com/jsonwebtoken/jwt-skills --path jwt-decodeManually: put the files in place
.devin/skills/jwt-decode/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add jsonwebtoken/jwt-skills --skill jwt-decode -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about jwt-decode
How do I install jwt-decode in Claude?
Run npx skills add jsonwebtoken/jwt-skills --skill jwt-decode -a claude-code. The skill lands in ~/.claude/skills/jwt-decode/SKILL.md.
What does jwt-decode do?
It base64url-decodes the header and payload of a JWT and prints all claims with the exp, nbf and iat dates. It does not verify the signature.
How is jwt-decode different from jwt-validate?
jwt-decode only reveals what is inside the token. Verifying the signature and authenticity is the job of jwt-validate.
Source text
SKILL.md · Apache-2.0
---
name: jwt-decode
description: Decode and inspect JSON Web Tokens (JWTs) without verification. Use when the user provides a JWT string and wants to see its header, payload, or claims — e.g. "decode this JWT", "what's in this token", "inspect this JWT", "show me the claims", "parse this token". Also triggers on raw JWT strings (three base64url segments separated by dots).
---
# JWT Decode
Decode a JWT by base64url-decoding its header and payload. Does NOT verify signatures — use `jwt-validate` for that.
## Steps
1. Split the token on `.` into three parts (header, payload, signature).
2. Base64url-decode and parse parts 1 and 2 as JSON.
3. Display header, payload (with all claims), and the raw signature string.
4. For `exp`, `nbf`, `iat` — show both the Unix timestamp and human-readable UTC. If `exp` is past, note **expired** and by how long.
5. Run security checks (see below).
## Output Format
```
## Header
{ "alg": "RS256", "typ": "JWT", "kid": "abc123" }
## Payload
{ "iss": "https://auth.example.com/", "sub": "user|12345", "exp": 1735689600 }
exp: 2025-01-01T00:00:00Z — EXPIRED (3 months ago)
iat: 2024-12-31T00:00:00Z
## Signature
Algorithm: RS256 | Signature: [base64url string]
(Not verified — use jwt-validate to verify)
```
## Security Checks
Flag these prominently when found:
- **`alg: none`** — Token is unsigned. Warn: "This token has no signature and cannot be trusted. Any party could have created or modified it." This is a known attack vector (CVE-2015-9235) where attackers strip signatures to bypass verification.
- **Sensitive data in payload** — JWTs are encoded, not encrypted. Warn if you spot passwords, secrets, API keys, or PII in claims.
- **Missing `exp`** — Token never expires. Flag as a security risk.
- **`jku`/`jwk`/`x5u` in header** — These can be used to trick verifiers into fetching attacker-controlled keys. Flag if present.
## Notes
- If `cty` header is "JWT", the payload is a nested JWT — decode recursively.
- On decode failure, report the specific error (malformed base64, invalid JSON, wrong segment count).
- This skill only reveals token contents — it says nothing about authenticity. Direct users to `jwt-validate` for verification.
---
© jsonwebtoken · Apache-2.0 · jsonwebtoken/jwt-skills