Skip to content

FastMCP Service Auth Tasks¤

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.

FastMCP Auth Tasks Sample Usage¤

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#
import pprint

from norfab.core.nfapi import NorFab

if __name__ == "__main__":
    nf = NorFab(inventory="inventory.yaml")
    nf.start()
    nfclient = nf.make_client()

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

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

    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
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
@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
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
@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
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
@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
520
521
522
523
524
525
526
527
528
529
@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
    )