Files
mnemosyne/mnemosyne/mcp_server/management/commands/create_user_token.py
Robert Helewka 93639188d3
Some checks failed
CVE Scan & Docker Build / build-and-push (push) Has been cancelled
CVE Scan & Docker Build / security-scan (push) Has been cancelled
Build & Deploy Docs / build-and-deploy (push) Successful in 1m10s
feat: rework auth model with UserToken and Daedalus/Pallas integration
- Rename MCPToken to UserToken across models, views, and tests
- Update URL names from mcp-token-* to token-*
- Add Daedalus/Pallas integration design doc (v2)
- Switch docker-compose to build local mnemosyne:local image via shared
  build config instead of pulling from git.helu.ca
2026-05-23 19:50:29 -04:00

78 lines
2.7 KiB
Python

"""Create an MCP bearer token for a user. Token is printed once and not retrievable later."""
from datetime import timedelta
from django.contrib.auth import get_user_model
from django.core.management.base import BaseCommand, CommandError
from django.utils import timezone
from mcp_server.models import UserToken
class Command(BaseCommand):
help = "Create an API token for a user and print the full token (shown once)."
def add_arguments(self, parser):
parser.add_argument(
"--user",
required=True,
help="Username or email of the owner.",
)
parser.add_argument(
"--name",
required=True,
help="Friendly token name (e.g. 'Claude Desktop').",
)
parser.add_argument(
"--tools",
default="",
help="Comma-separated tool whitelist. Empty = all tools allowed.",
)
parser.add_argument(
"--expires-days",
type=int,
default=None,
help="Days until expiry. Omit for no expiry.",
)
def handle(self, *args, **options):
User = get_user_model()
identifier = options["user"]
try:
user = User.objects.get(email=identifier)
except User.DoesNotExist:
try:
user = User.objects.get(username=identifier)
except User.DoesNotExist:
raise CommandError(f'User "{identifier}" not found.')
if not user.is_active:
raise CommandError(f'User "{identifier}" is inactive.')
allowed_tools = [t.strip() for t in options["tools"].split(",") if t.strip()]
expires_at = None
if options["expires_days"] is not None:
if options["expires_days"] < 1:
raise CommandError("--expires-days must be at least 1.")
expires_at = timezone.now() + timedelta(days=options["expires_days"])
token, plaintext = UserToken.objects.create_token(
user=user,
name=options["name"],
allowed_tools=allowed_tools,
expires_at=expires_at,
)
self.stdout.write(self.style.SUCCESS("API token created"))
self.stdout.write(f" Name: {token.name}")
self.stdout.write(f" User: {user}")
if allowed_tools:
self.stdout.write(f" Tools: {', '.join(allowed_tools)}")
else:
self.stdout.write(" Tools: (all)")
if expires_at:
self.stdout.write(f" Expires: {expires_at.isoformat()}")
self.stdout.write(self.style.WARNING(" Token (shown once — store it now):"))
self.stdout.write(f" {plaintext}")