Skip to content

FastMCP Service Auth Tasks¤

task api names: bearer_token_store, bearer_token_list, bearer_token_delete, bearer_token_check

FastMCP service supports optional bearer token authentication for the MCP streamable HTTP endpoint. To manage token lifecycle, FastMCP provides tasks to store, delete, list, and check bearer tokens in the worker diskcache database.

These tasks are available through NorFab client jobs and the NFCLI shell. They are not exposed as MCP tools.

Task API Names¤

Task Description
bearer_token_store Store a bearer token for a username.
bearer_token_list List stored bearer tokens, optionally filtered by username.
bearer_token_delete Delete one token or all tokens for a username.
bearer_token_check Check whether a token exists and is still active.

Inputs¤

Parameter Required Description
username Required for create and username-scoped delete/list User name associated with one or more bearer tokens.
token Required for check and token-scoped delete Bearer token value. If omitted on create, the worker generates one.
expire No Token expiration time in seconds. If omitted, the token does not expire.
workers No FastMCP workers to target. Defaults to all workers.

Output¤

Create, delete, and check tasks return booleans per worker. List tasks return stored token records with username, token, age, creation time, and expiration time.

Examples¤

Example

Store an explicit token:

nf# fastmcp auth create-token username automation token secret-token expire 3600
{
    "fastmcp-worker-1": true
}
nf#

Generate and store a token automatically:

nf# fastmcp auth create-token username automation
{
    "fastmcp-worker-1": true
}
nf#

List tokens for a specific user:

nf# fastmcp auth list-tokens username automation
 worker              username    token         age             creation                    expires
 fastmcp-worker-1    automation  secret-token  0:01:29.688340  2026-05-31 12:08:51.914919  2026-05-31 13:08:51.914919
nf#

List all tokens:

nf# fastmcp auth list-tokens
 worker              username    token                             age             creation                    expires
 fastmcp-worker-1    automation  secret-token                      0:01:44.701374  2026-05-31 12:08:51.914919  2026-05-31 13:08:51.914919
 fastmcp-worker-1    vscode      888945f96b824bf1b4358de790c452b6  0:10:06.561696  2026-05-31 12:00:30.054597  None
nf#

Delete a specific token:

nf# fastmcp auth delete-token token secret-token
{
    "fastmcp-worker-1": true
}
nf#

Delete all tokens for a user:

nf# fastmcp auth delete-token username automation
{
    "fastmcp-worker-1": true
}
nf#

Check whether a token is valid:

nf# fastmcp auth check-token token secret-token
{
    "fastmcp-worker-1": true
}
nf#

Context manager - create and list tokens:

import pprint

from norfab.core.nfapi import NorFab

with NorFab(inventory="inventory.yaml") as nf:
    client = nf.make_client()

    client.run_job(
        service="fastmcp",
        task="bearer_token_store",
        kwargs={
            "username": "automation",
            "token": "secret-token",
            "expire": 3600,
        },
        workers="all",
    )

    result = client.run_job(
        service="fastmcp",
        task="bearer_token_list",
        kwargs={"username": "automation"},
        workers="all",
    )
    pprint.pprint(result)

Direct lifecycle - same task:

import pprint

from norfab.core.nfapi import NorFab

nf = NorFab(inventory="inventory.yaml")
try:
    nf.start()
    client = nf.make_client()

    client.run_job(
        service="fastmcp",
        task="bearer_token_store",
        kwargs={
            "username": "automation",
            "token": "secret-token",
            "expire": 3600,
        },
        workers="all",
    )

    result = client.run_job(
        service="fastmcp",
        task="bearer_token_list",
        kwargs={"username": "automation"},
        workers="all",
    )
    pprint.pprint(result)
finally:
    nf.destroy()

Using Tokens With MCP Clients¤

When authentication_enabled: true is configured in FastMCP inventory, MCP clients must send the stored token in the HTTP authorization header:

Authorization: Bearer secret-token

For example, VS Code MCP configuration can include the bearer header in the MCP server definition if the client supports custom headers.

NORFAB FastMCP Service Auth Tasks Command Shell Reference¤

NorFab shell supports these command options for FastMCP auth tasks:

nf# man tree fastmcp.auth
root
└── fastmcp:    FastMCP service
    └── auth:    Manage auth tokens
        ├── create-token:    Create authentication token
           ├── timeout:    Job timeout
           ├── workers:    Filter worker to target, default 'all'
           ├── token:    Token string to store, autogenerate if not given
           ├── *username:    User name to store the token for
           └── expire:    Token expiration time in seconds
        ├── list-tokens:    Retrieve authentication tokens
           ├── timeout:    Job timeout
           ├── workers:    Filter worker to target, default 'all'
           └── username:    User name to list tokens for
        ├── delete-token:    Delete existing authentication token
           ├── timeout:    Job timeout
           ├── workers:    Filter worker to target, default 'all'
           ├── username:    User name whose tokens should be deleted
           └── token:    Bearer token string to delete
        └── check-token:    Check if given token valid
            ├── timeout:    Job timeout
            ├── workers:    Filter worker to target, default 'all'
            └── *token:    Bearer token string to check
nf#

Python API Reference¤

bearer_token_store¤

Store a bearer token in the FastMCP worker token database.

Source code in norfab\workers\fastmcp_worker\fastmcp_worker.py
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
@Task(input=BearerTokenStoreInput, output=BoolResult, fastapi=False, mcp=False)
def bearer_token_store(
    self, job: Job, username: str, token: str, expire: int = None
) -> Result:
    """
    Store a bearer token in the FastMCP worker token database.
    """
    expire = expire or self.fastmcp_inventory.get("auth_bearer", {}).get(
        "token_ttl", expire
    )
    self.cache.expire()
    cache_key = f"bearer_token::{token}"
    if cache_key in self.cache:
        user_token = self.cache.get(cache_key)
    else:
        user_token = {
            "token": token,
            "username": username,
            "created": str(datetime.now()),
        }
    self.cache.set(cache_key, user_token, expire=expire, tag=username)

    return Result(task=f"{self.name}:bearer_token_store", result=True)

bearer_token_delete¤

Delete bearer tokens by username or token value.

Source code in norfab\workers\fastmcp_worker\fastmcp_worker.py
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
@Task(input=BearerTokenDeleteInput, output=BoolResult, fastapi=False, mcp=False)
def bearer_token_delete(
    self, job: Job, username: str = None, token: str = None
) -> Result:
    """
    Delete bearer tokens by username or token value.
    """
    self.cache.expire()
    token_removed_count = 0
    if token:
        cache_key = f"bearer_token::{token}"
        if cache_key in self.cache:
            if self.cache.delete(cache_key, retry=True):
                token_removed_count = 1
            else:
                raise RuntimeError(f"Failed to remove {username} token from cache")
    elif username:
        token_removed_count = self.cache.evict(tag=username, retry=True)
    else:
        raise Exception("Cannot delete, either username or token must be provided")

    log.info(
        f"{self.name} removed {token_removed_count} token(s) for user {username}"
    )

    return Result(task=f"{self.name}:bearer_token_delete", result=True)

bearer_token_list¤

List bearer tokens stored in the FastMCP worker token database.

Source code in norfab\workers\fastmcp_worker\fastmcp_worker.py
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
@Task(
    input=BearerTokenListInput,
    output=BearerTokenListResult,
    fastapi=False,
    mcp=False,
)
def bearer_token_list(self, job: Job, username: str = None) -> Result:
    """
    List bearer tokens stored in the FastMCP worker token database.
    """
    self.cache.expire()
    ret = Result(task=f"{self.name}:bearer_token_list", result=[])

    for cache_key in self.cache:
        if not str(cache_key).startswith("bearer_token::"):
            continue
        token_data, expires, tag = self.cache.get(
            cache_key, expire_time=True, tag=True
        )
        if username and tag != username:
            continue
        if expires is not None:
            expires = datetime.fromtimestamp(expires)
        creation = datetime.fromisoformat(token_data["created"])
        age = datetime.now() - creation
        ret.result.append(
            {
                "username": token_data["username"],
                "token": token_data["token"],
                "age": str(age),
                "creation": str(creation),
                "expires": str(expires),
            }
        )

    if not ret.result:
        ret.result = [
            {
                "username": "",
                "token": "",
                "age": "",
                "creation": "",
                "expires": "",
            }
        ]

    return ret

bearer_token_check¤

Check if a bearer token is present and active in the FastMCP token database.

Source code in norfab\workers\fastmcp_worker\fastmcp_worker.py
731
732
733
734
735
736
737
738
739
740
@Task(input=BearerTokenCheckInput, output=BoolResult, fastapi=False, mcp=False)
def bearer_token_check(self, token: str, job: Job) -> Result:
    """
    Check if a bearer token is present and active in the FastMCP token database.
    """
    self.cache.expire()
    cache_key = f"bearer_token::{token}"
    return Result(
        task=f"{self.name}:bearer_token_check", result=cache_key in self.cache
    )