-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Description
Description
🚀 Feature Request
I would like to propose adding a secure wrapper layer to @mcp.tool, @mcp.resource, and @mcp.prompt that supports:
- 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:
- Client authentication - Is the client authorized to use the tool?
- Tool/Server authentication - Is the tool legitimate and trustworthy?
If authentication fails, return a proper MCP Error (e.g. 403 Forbidden).
- 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.
- 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.