Atlassian
sanjay3290/ai-skills
Manage Jira issues and Confluence wiki pages in Atlassian Cloud.
Authentication, authorization, and multi-tenancy patterns for @cyanheads/mcp-ts-core.
$ npx skills add cyanheads/pubmed-mcp-server --skill api-auth -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install cyanheads/pubmed-mcp-server api-auth --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/cyanheads/pubmed-mcp-server.git skills-src && mkdir -p .claude/skills && cp -r skills-src/framework-skills/api-auth .claude/skills/api-auth && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "api-auth" agent skill from https://github.com/cyanheads/pubmed-mcp-server/tree/main/framework-skills/api-auth into .claude/skills/api-auth/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "api-auth", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/cyanheads/pubmed-mcp-server/tree/main/framework-skills/api-authType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add cyanheads/pubmed-mcp-server --skill api-auth -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install cyanheads/pubmed-mcp-server api-auth --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/cyanheads/pubmed-mcp-server.git skills-src && mkdir -p .agents/skills && cp -r skills-src/framework-skills/api-auth .agents/skills/api-auth && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "api-auth" agent skill from https://github.com/cyanheads/pubmed-mcp-server/tree/main/framework-skills/api-auth into .agents/skills/api-auth/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "api-auth", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add cyanheads/pubmed-mcp-server --skill api-auth -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install cyanheads/pubmed-mcp-server api-auth --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/cyanheads/pubmed-mcp-server.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/framework-skills/api-auth .cursor/skills/api-auth && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "api-auth" agent skill from https://github.com/cyanheads/pubmed-mcp-server/tree/main/framework-skills/api-auth into .cursor/skills/api-auth/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "api-auth", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/cyanheads/pubmed-mcp-server.git --path framework-skills/api-auth--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add cyanheads/pubmed-mcp-server --skill api-auth -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install cyanheads/pubmed-mcp-server api-auth --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/cyanheads/pubmed-mcp-server.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/framework-skills/api-auth .gemini/skills/api-auth && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "api-auth" agent skill from https://github.com/cyanheads/pubmed-mcp-server/tree/main/framework-skills/api-auth into .gemini/skills/api-auth/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "api-auth", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install cyanheads/pubmed-mcp-server api-authInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add cyanheads/pubmed-mcp-server --skill api-auth -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/cyanheads/pubmed-mcp-server.git skills-src && mkdir -p .github/skills && cp -r skills-src/framework-skills/api-auth .github/skills/api-auth && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "api-auth" agent skill from https://github.com/cyanheads/pubmed-mcp-server/tree/main/framework-skills/api-auth into .github/skills/api-auth/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "api-auth", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add cyanheads/pubmed-mcp-server --skill api-auth -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install cyanheads/pubmed-mcp-server api-auth --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/cyanheads/pubmed-mcp-server.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/framework-skills/api-auth .opencode/skills/api-auth && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "api-auth" agent skill from https://github.com/cyanheads/pubmed-mcp-server/tree/main/framework-skills/api-auth into .opencode/skills/api-auth/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "api-auth", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
api-authAuthentication, authorization, and multi-tenancy patterns for @cyanheads/mcp-ts-core.
API Auth is an agent skill from cyanheads/pubmed-mcp-server. Authentication, authorization, and multi-tenancy patterns for @cyanheads/mcp-ts-core. Use when implementing auth scopes on tools/resources, configuring auth modes (none/jwt/oauth), working with JWT/OAuth env vars, or understanding how tenantId flows through ctx.state.
Its SKILL.md is about 2.7k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Backend & APIs, covering Authentication, OAuth and OpenID Connect and MCP servers. It works with Model Context Protocol. The repository describes itself as: Search PubMed/Europe PMC, fetch articles and full text (PMC/EPMC/Unpaywall), citations, MeSH terms via MCP. STDIO or Streamable HTTP. The licence is Apache-2.0.
Read from SKILL.md and the folder at commit 5a417fb. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are typescript).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
MCP_AUTH_SECRET_KEYFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
API Auth loads about 2.7k tokens when it runs. Until then it costs about 70 tokens; SKILL.md has 1,024 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from cyanheads/pubmed-mcp-server at commit 5a417fb, republished under its Apache-2.0 licence (© cyanheads). 1,024 words, ~2,685 tokens.
.claude/skills/api-auth/SKILL.md (or your agent's skills folder).The framework handles auth at the handler factory level — tools and resources declare required scopes declaratively, and the framework enforces them before calling the handler. No try/catch or manual scope checking required for the common case.
Declare required scopes directly on the tool or resource definition via the auth property. The handler factory checks ctx.auth.scopes against these before calling handler.
import { tool } from '@cyanheads/mcp-ts-core';
const myTool = tool('my_tool', {
input: z.object({ query: z.string().describe('Search query') }),
output: z.object({ result: z.string().describe('Search result') }),
auth: ['tool:my_tool:read'],
async handler(input, ctx) {
// Only reached if caller has 'tool:my_tool:read' scope
},
});When MCP_AUTH_MODE=none, auth checks are skipped and defaults are allowed.
A failed check returns Forbidden (-32005, Insufficient permissions.) or, when auth is enabled but the request carries no auth context, Unauthorized (-32006). Neither carries data: the required, granted, and missing scope names stay in the server log, so a caller cannot enumerate scopes from the error.
For runtime-computed scopes (e.g., scopes that depend on input values like a team or resource ID), use checkScopes from @cyanheads/mcp-ts-core/auth inside the handler:
import { checkScopes } from '@cyanheads/mcp-ts-core/auth';
handler: async (input, ctx) => {
checkScopes(ctx, [`team:${input.teamId}:write`]);
// Continues only if scope is satisfied
},Signature: checkScopes(ctx: Context, requiredScopes: string[]): void
Throws:
McpError(Forbidden) — auth is active and one or more required scopes are missingMcpError(Unauthorized) — auth is enabled but no auth context exists on the requestMCP_AUTH_MODE=noneSet via MCP_AUTH_MODE environment variable.
| Mode | Value | Behavior |
|---|---|---|
| Disabled | none | No auth enforcement. All requests allowed. |
| JWT | jwt | Local secret verification via MCP_AUTH_SECRET_KEY. Requires explicit DEV_MCP_AUTH_BYPASS=true to bypass in development. |
| OAuth | oauth | JWKS verification against an external issuer. |
| Variable | Required | Purpose |
|---|---|---|
MCP_AUTH_SECRET_KEY | Yes (unless bypass) | Signing secret for HS256 JWT verification. Must be ≥ 32 characters. |
DEV_MCP_AUTH_BYPASS | No | Set to true to skip JWT verification in development. Blocked in NODE_ENV=production. |
DEV_MCP_CLIENT_ID | No | Client ID injected when bypass is active (default: 'dev-client-id'). |
DEV_MCP_SCOPES | No | Comma-separated scopes injected when bypass is active (default: ['dev-scope']). |
Important: With MCP_AUTH_MODE=jwt, a missing MCP_AUTH_SECRET_KEY is a fatal startup error unless DEV_MCP_AUTH_BYPASS=true is explicitly set. Setting DEV_MCP_AUTH_BYPASS in production (NODE_ENV=production) is rejected at config parse time.
| Variable | Required | Purpose |
|---|---|---|
OAUTH_ISSUER_URL | Yes | Token issuer URL (used for JWKS discovery) |
OAUTH_AUDIENCE | Yes | Expected aud claim value |
OAUTH_JWKS_URI | No | Override JWKS endpoint (defaults to {issuer}/.well-known/jwks.json) |
MCP_SERVER_RESOURCE_IDENTIFIER | No | RFC 8707 resource indicator URI. When set, the OAuth strategy validates that the token's resource or aud claim matches this value — throws Forbidden on mismatch. |
| Claim | JWT Field | Purpose |
|---|---|---|
clientId | cid / client_id | Identifies the calling client |
scopes | union of scp, scope, mcp_tool_scopes | Granted scope list (see below) |
sub | sub | Subject (user or service identity) |
tenantId | tid | Tenant identifier — drives ctx.state scoping |
scopes is the union of three claims, in this order:
| Claim | Form | Source |
|---|---|---|
scp | array of strings | Okta-style |
scope | space-delimited string | OAuth 2.1 / OIDC standard |
mcp_tool_scopes | array of strings or space-delimited string | Custom claim for OIDC providers that cannot inject scopes into scope during the authorization_code flow (Authentik, Keycloak < 26.5, Zitadel) |
Auth0/Okta-style providers that already populate scp or scope need no migration. Other deployments add a property mapping returning {"mcp_tool_scopes": "tool:foo:read tool:bar:write"} — the framework unions it into ctx.auth.scopes alongside the standard claims. Hardcoded claim name; deployments whose IdP cannot emit mcp_tool_scopes use the bypass flag below.
Standard OIDC providers compute the JWT scope claim from what the OAuth client requested at the authorization endpoint and ignore property mappings that try to override scope in the authorization_code flow. Property mappings that inject other claim names work fine. To grant per-tool scopes to a Claude.ai or ChatGPT custom connector that doesn't expose scope customization, configure your IdP to return the per-tool scopes under mcp_tool_scopes instead of overriding scope.
| Provider | Where to configure |
|---|---|
| Authentik | Customization → Property Mappings → new "Scope Mapping" returning {"mcp_tool_scopes": "tool:foo:read tool:bar:write"}; bind to the OAuth2/OpenID provider |
| Keycloak (< 26.5) | Client → Client Scopes → Mappers → new "Hardcoded claim" or "Script Mapper" emitting mcp_tool_scopes |
| Zitadel | Project → Roles + Action returning {"mcp_tool_scopes": "..."} from a pre-token script |
Keycloak ≥ 26.5 ships native MCP integration support; check its release notes before falling back to a custom claim.
For environments where no custom claim can be injected (managed services, restricted IdPs), set MCP_AUTH_DISABLE_SCOPE_CHECKS=true to bypass scope enforcement entirely.
| Variable | Default | Effect |
|---|---|---|
MCP_AUTH_DISABLE_SCOPE_CHECKS | false | When true, both withRequiredScopes (declared auth: [...]) and checkScopes (runtime-computed scopes inside handlers) early-return after the auth-context presence check. Token signature, audience, issuer, and expiry validation remain intact. |
The flag bypasses both declared auth: [...] enforcement and runtime checkScopes calls — including tenant isolation patterns like team:${input.teamId}:write. Naming is deliberate: this disables all scope checks, not just per-tool ones. Applies to MCP_AUTH_MODE=jwt and MCP_AUTH_MODE=oauth (no effect under none).
A WARNING-level log is emitted at startup whenever the flag is active so operators don't lose track of it. Combine with server-side ACLs (path filters, allowlists, tenant rules) — without an in-handler ACL, every authenticated user effectively has every scope.
| Endpoint | Protected |
|---|---|
GET /healthz | No |
GET /mcp | No |
POST /mcp | Yes (when auth enabled) |
DELETE /mcp | Yes (when auth enabled) — session termination |
OPTIONS /mcp | No (handled by CORS middleware before auth) |
CORS: Set MCP_ALLOWED_ORIGINS to a comma-separated list of allowed origins, or * for open access. Left unset, only loopback browser origins reach the endpoint. The preflight for an accepted origin allows every request header the server reads: Content-Type, Authorization, Mcp-Session-Id, MCP-Protocol-Version, the 2026-07-28 Mcp-Method and Mcp-Name, Last-Event-ID (SSE resume), and one Mcp-Param-<Name> per headerParam designation on a registered tool — derived from the tool definitions, nothing to configure. Any other origin gets the first four only, so it learns no designation names.
Stdio mode: No HTTP auth layer. Authorization is handled entirely by the host process.
ctx.state is automatically scoped to the current tenant — no manual key prefixing needed.
| Mode | Source | Value |
|---|---|---|
| Stdio (any auth mode) | Hardcoded default | 'default' |
HTTP + MCP_AUTH_MODE=none | Hardcoded default | 'default' (single-tenant by design) |
HTTP + MCP_AUTH_MODE=jwt/oauth | JWT tid claim | Auto-propagated from token; undefined if absent (fail-closed) |
../)..)ctx.statehandler: async (input, ctx) => {
// Automatically scoped to ctx.tenantId — no manual prefixing
await ctx.state.set('item/123', { name: 'Widget', count: 42 });
const item = await ctx.state.get<Item>('item/123');
await ctx.state.delete('item/123');
const page = await ctx.state.list('item/', { cursor, limit: 20 });
// page: { items: Array<{ key, value }>, cursor?: string }
},ctx.state throws McpError(InvalidRequest) if tenantId is missing. Stdio (any auth mode) and HTTP+MCP_AUTH_MODE=none default tenantId to 'default' so ctx.state works without forcing operators to mint tokens. HTTP+jwt/oauth deliberately fails closed when the token lacks a tid claim — distinct authenticated callers must not silently share state.
Available on ctx.auth inside handlers (when auth is enabled):
interface AuthContext {
clientId: string; // Required — 'cid' or 'client_id' JWT claim
scopes: string[]; // Required — union of 'scp', 'scope', and 'mcp_tool_scopes' claims
sub: string; // Required — 'sub' claim; falls back to clientId when absent
token?: string; // Optional — raw JWT or OAuth bearer token string (present when transport provides it)
tenantId?: string; // Optional — 'tid' claim; present only for multi-tenant tokens
}Access directly for conditional logic:
handler: async (input, ctx) => {
const isAdmin = ctx.auth?.scopes.includes('admin:write') ?? false;
// ...
},© cyanheads, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in framework-skills/api-auth of cyanheads/pubmed-mcp-server.
Open the folder on GitHubat commit 5a417fb
API Auth next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| API Auth this skillcyanheads/pubmed-mcp-server | 154 | — | ~2.7k | Automated safety check: Pass | Apache-2.0 | |
| Atlassiansanjay3290/ai-skills | 430 | — | ~1.6k | Automated safety check: Pass | Apache-2.0 | |
| Spring Security ConfigurationAmplicode/spring-skills | 126 | — | ~4.3k | Automated safety check: Pass | None | |
| Cao MCP Appsawslabs/cli-agent-orchestrator | 1.4k | — | ~1.9k | Automated safety check: Pass | Apache-2.0 | |
| Review Security ReportPrefectHQ/fastmcp | 28k | — | ~1.2k | Automated safety check: Pass | Apache-2.0 | |
| Supercheck Security Authsupercheck-io/supercheck | 215 | — | ~1.2k | Automated safety check: Pass | AGPL-3.0 |
sanjay3290/ai-skills
Manage Jira issues and Confluence wiki pages in Atlassian Cloud.
Amplicode/spring-skills
Creates a Spring Security configuration class with authentication, authorization, and HTTP protection setup.
awslabs/cli-agent-orchestrator
Enable, operate, and extend CAO's MCP Apps surface — the host-rendered fleet dashboard visible inside MCP App hosts (Claude Desktop, ChatGPT, VS Code Copilot, Goose, Postman).
PrefectHQ/fastmcp
Review FastMCP vulnerability reports before accepting, rejecting, patching, scoring, or publishing them.
supercheck-io/supercheck
Work on Supercheck authentication, RBAC, tenant isolation, sessions, API and trigger keys, invitations, project membership, project variables, OAuth, super-admin behavior, SSRF, or…
Xquik-dev/x-twitter-scraper
Connect, verify, and troubleshoot Xquik's remote MCP server.
cyanheads/pubmed-mcp-server
Scaffold an MCP App tool + UI resource pair. An agent skill from cyanheads/pubmed-mcp-server.
cyanheads/pubmed-mcp-server
Scaffold a new MCP prompt template. An agent skill from cyanheads/pubmed-mcp-server.
cyanheads/pubmed-mcp-server
Scaffold a new MCP resource definition. An agent skill from cyanheads/pubmed-mcp-server.
cyanheads/pubmed-mcp-server
Scaffold a new service integration. An agent skill from cyanheads/pubmed-mcp-server.
cyanheads/pubmed-mcp-server
Scaffold a test file for an existing tool, resource, or service.
cyanheads/pubmed-mcp-server
Stand up a persistent, self-refreshing local mirror of a bulk upstream dataset with the MirrorService (@cyanheads/mcp-ts-core/mirror).
Works with
Categories
Authentication, authorization, and multi-tenancy patterns for @cyanheads/mcp-ts-core. API Auth is an agent skill from cyanheads/pubmed-mcp-server. Authentication, authorization, and multi-tenancy patterns for @cyanheads/mcp-ts-core.
API Auth fits situations like: implementing auth scopes on tools/resources; configuring auth modes (none/jwt/oauth); working with JWT/OAuth env vars; understanding how tenantId flows through ctx.state.
Run `npx skills add cyanheads/pubmed-mcp-server --skill api-auth -a claude-code`. Or copy the skill folder (framework-skills/api-auth in cyanheads/pubmed-mcp-server) into .claude/skills/api-auth in your project. Claude Code loads it when a task matches its description.
Run `npx skills add cyanheads/pubmed-mcp-server --skill api-auth -a codex`. Or copy the skill folder (framework-skills/api-auth in cyanheads/pubmed-mcp-server) into .agents/skills/api-auth in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add cyanheads/pubmed-mcp-server --skill api-auth -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/api-auth, .gemini/skills/api-auth, .github/skills/api-auth and .opencode/skills/api-auth in your project.
Going by SKILL.md and its folder, API Auth needs credentials named MCP_AUTH_SECRET_KEY. Our summary lists: A credential in MCP_AUTH_SECRET_KEY.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
API Auth is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 2.7k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with API Auth: Atlassian (sanjay3290/ai-skills, 430 stars), Spring Security Configuration (Amplicode/spring-skills, 126 stars), Cao MCP Apps (awslabs/cli-agent-orchestrator, 1.4k stars) and Review Security Report (PrefectHQ/fastmcp, 28k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
cyanheads (a GitHub user) maintains it in cyanheads/pubmed-mcp-server, which has 154 GitHub stars. The repository holds 30 skills in this directory. The repository was last updated on October 4, 2026.
Source: cyanheads/pubmed-mcp-server on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.