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
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
@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
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
@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
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
@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
865
866
867
868
869
870
871
872
873
874
@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
    )