Skip to content

Feature Proposal: Secure Tool/Resource/Prompt Decorators with Auth + Encrypted I/O #1305

Description

@wenhuizhang

Description

🚀 Feature Request

I would like to propose adding a secure wrapper layer to @mcp.tool, @mcp.resource, and @mcp.prompt that supports:

  1. Authentication (Auth)

Ability to pass an auth function (e.g. verify_identity()) that can validate JWT, Certs, or TEE Attestation before executing the function.

Authentication should be bidirectional - we need to verify both:

  1. Client authentication - Is the client authorized to use the tool?
  2. Tool/Server authentication - Is the tool legitimate and trustworthy?

If authentication fails, return a proper MCP Error (e.g. 403 Forbidden).

  1. Key Negotiation Mechanism

Client provides a public key (PK) or session token.

Server performs Diffie-Hellman (ECDH) or TLS/mTLS handshake to derive a session key.

Session key is stored in context and used for symmetric encryption/decryption of I/O.

  1. Unified Secure Interface

Developers could write secure MCP functions like this:

@mcp.secure_tool(auth=verify_identity, encrypt=True)
async def trade(symbol: str, amount: float) -> str:
return f"Trade {amount} {symbol} executed"

And the same approach could apply to resource and prompt.

🔹 Example Implementation

import functools
from mcp.server.fastmcp import FastMCP, tool, resource, prompt
from mcp.server.models import Error
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os, base64
mcp = FastMCP("SecureApp")
# ========== Simple Key Management ==========
SESSION_KEY = AESGCM.generate_key(bit_length=128)
aesgcm = AESGCM(SESSION_KEY)
NONCE_SIZE = 12
def encrypt(data: str) -> str:
nonce = os.urandom(NONCE_SIZE)
ct = aesgcm.encrypt(nonce, data.encode(), None)
return base64.b64encode(nonce + ct).decode()
def decrypt(token: str) -> str:
raw = base64.b64decode(token)
nonce, ct = raw[:NONCE_SIZE], raw[NONCE_SIZE:]
pt = aesgcm.decrypt(nonce, ct, None)
return pt.decode()
# ========== Auth Function ==========
def verify_identity() -> bool:
# TODO: implement JWT / CERT / Attestation validation
return True
# ========== Decorator Factory ==========
def secure_wrapper(deco, auth=None, encrypt_io=False, *args, **kwargs):
def decorator(func):
@deco(*args, **kwargs) # wrap original MCP decorator
@functools.wraps(func)
async def wrapper(*f_args, **f_kwargs):
# Auth check
if auth and not auth():
raise Error(code=403, message="Authentication failed")
# Decrypt inputs
if encrypt_io:
f_kwargs = {k: decrypt(v) if isinstance(v, str) else v for k, v in f_kwargs.items()}
# Execute
result = await func(*f_args, **f_kwargs) if callable(func) else func
# Encrypt outputs
if encrypt_io and isinstance(result, str):
result = encrypt(result)
return result
return wrapper
return decorator
# Three secure variants
def secure_tool(auth=None, encrypt_io=False, *args, **kwargs):
return secure_wrapper(tool, auth, encrypt_io, *args, **kwargs)
def secure_resource(auth=None, encrypt_io=False, *args, **kwargs):
return secure_wrapper(resource, auth, encrypt_io, *args, **kwargs)
def secure_prompt(auth=None, encrypt_io=False, *args, **kwargs):
return secure_wrapper(prompt, auth, encrypt_io, *args, **kwargs)
# ========== Usage Example ==========
@secure_tool(auth=verify_identity, encrypt_io=True)
async def add(a: int, b: int) -> str:
return f"sum={a+b}"
@secure_resource("secure://greet/{name}", auth=verify_identity, encrypt_io=True)
def greeting(name: str) -> str:
return f"Hello, {name}!"
@secure_prompt(auth=verify_identity, encrypt_io=True)
def greet_user(name: str) -> str:
return f"Write a secure greeting for {name}"

🔹 Encrypted I/O Flow

Input: client encrypts arguments with session key → sends

Server: decrypts args → executes function

Output: result encrypted → returned to client

Client: decrypts result with the same session key

✅ Summary

tool, resource, and prompt can all uniformly support auth + encrypted I/O.

Implemented via decorator factory pattern, keeping code clean.

Supports pluggable JWT, Cert, TEE Attestation validation.

Session key negotiation can use TLS/mTLS or ECDH.

This would make MCP safer to use in environments where sensitive data and secure tool execution are required.

References

MR#1309

Metadata

Metadata

Assignees

No one assigned

    Labels

    authIssues and PRs related to Authentication / OAuthenhancementRequest for a new feature that's not currently supported

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions