Tenuo MCP Server

by tenuo-ai• 104•• Scanned•Claim this listing•Request removal
Finance & Tradinga2aaccess controlagent securityagentsai agents

Task-scoped authorization for AI agents. Cryptographic warrants constrain tools and arguments, prevent privilege escalation at every delegation hop, and produce signed evidence of what was allowed or denied.

Tenuo is an open-source mcp server by tenuo-ai, written mainly in Rust, with 104 GitHub stars and the Apache-2.0 license. Its code was last updated Oct 31, 2026. The latest PyPI release is tenuo 0.3.7, published Nov 12, 2026, with 5,339 downloads last week.

<p align="center"> <img src="docs/images/tenuo-logo.svg" alt="tenuo" width="200"> </p> <p align="center"> <strong>Task-scoped authorization for AI agents.</strong> </p> <p align="center"> <a href="https://github.com/tenuo-ai/tenuo/actions/workflows/ci.yml"><img src="https://github.com/tenuo-ai/tenuo/actions/workflows/ci.yml/badge.svg" alt="CI"></a> <a href="https://crates.io/crates/tenuo"><img src="https://img.shields.io/crates/v/tenuo.svg" alt="Crates.io"></a> <a href="https://pypi.org/project/tenuo/"><img src="https://img.shields.io/pypi/v/tenuo.svg" alt="PyPI"></a> <a href="https://hub.docker.com/r/tenuo/authorizer"><img src="https://img.shields.io/docker/v/tenuo/authorizer?label=docker&sort=semver" alt="Docker"></a> <a href="https://tenuo.ai"><img src="https://img.shields.io/badge/docs-tenuo.ai-blue" alt="Docs"></a> <a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-blue.svg" alt="License"></a> <a href="https://deepwiki.com/tenuo-ai/tenuo"><img src="https://img.shields.io/badge/Ask-DeepWiki-blue.svg" alt="Ask DeepWiki"></a> </p>

Tenuo lets you define what an agent may do for a task, carry that authority across services and agent handoffs, and enforce it where actions execute. Each handoff can only narrow the authority granted.

That authority travels as a warrant: a signed grant specifying allowed tools, argument constraints, and an expiry.

  • Across frameworks and runtimes. Delegate between agents and services using different languages and frameworks.
  • Across organizations and trust domains. Grant limited authority to others and independently verify the authority you receive.
  • Online or air-gapped. Verify locally without contacting a central authorization service, using provisioned trust keys and local revocation state.

Open source. Works alongside your existing identity and policy systems.

Install

# Python
pip install tenuo

# TypeScript (beta, Node 20+)
npm install @tenuo/core@beta

# Rust
cargo add tenuo --features sdk

To try Tenuo without installing an SDK:

<a href="https://colab.research.google.com/github/tenuo-ai/tenuo/blob/main/notebooks/tenuo_demo.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"></a> <a href="https://tenuo.ai/explorer/"><img src="https://img.shields.io/badge/Explorer-decode_warrants-1a1a1a" alt="Explorer"></a> <a href="https://tenuo.ai/demo.html"><img src="https://img.shields.io/badge/Docker_Demo-delegation_chain-333333" alt="Docker Demo"></a> <a href="https://niyikiza.com/posts/tenuo-launch/"><img src="https://img.shields.io/badge/Blog-Why_Tenuo%3F-ff6b6b" alt="Blog"></a>

<a id="quick-start-from-one-tool-to-delegated-work"></a>

Quick Start

Give an agent permission to request up to ten replicas. Calls outside that limit are blocked before the function executes. These examples simulate the action by returning a message.

Python

Save as quickstart.py and run python quickstart.py.

from tenuo import Capability, Range, SigningKey, configure, guard, mint_sync
from tenuo.exceptions import AuthorizationDenied

# Local development setup.
configure(issuer_key=SigningKey.generate(), dev_mode=True, audit_log=False)

@guard(tool="scale")
def scale(replicas: int) -> str:
    return f"Requested {replicas} replicas"

with mint_sync(Capability("scale", replicas=Range.max_value(10)), ttl=60):
    print(scale(3))

    try:
        scale(20)
    except AuthorizationDenied:
        print("Blocked before the function ran")

TypeScript · Beta

Save as quickstart.mts and run npx tsx quickstart.mts.

import { AuthorizationDeniedError, createTenuo, range } from "@tenuo/core";

// Local development setup: this process holds the issuance key.
const tenuo = createTenuo({
  root: createTenuo.issuerKeyFromBytes(createTenuo.generateIssuerKey()),
});

const scale = tenuo.tool(
  {
    execute: async ({ replicas }: { replicas: number }) =>
      `Requested ${replicas} replicas`,
  },
  { capability: "scale", allow: { replicas: range({ max: 10 }) } },
);

const session = tenuo.session({ tools: [scale], ttlSeconds: 60 });

await tenuo.withSession(session, async () => {
  console.log(await scale.execute({ replicas: 3 }));

  try {
    await scale.execute({ replicas: 20 });
  } catch (error) {
    if (!(error instanceof AuthorizationDeniedError) ||
        error.code !== "TENUO_CONSTRAINT_VIOLATION") throw error;
    console.log("Blocked before the function ran");
  }
});

Both examples produce:

Requested 3 replicas
Blocked before the function ran

These examples keep issuance and enforcement in one process for development. Python's dev_mode=True also relaxes trust-root and audit-log checks. To enforce limits against an untrusted agent, keep issuance keys outside its reach and verify at a tool service or gateway it cannot bypass. The MCP walkthrough shows that setup with a server that holds only the issuer's public key. The Production Guide covers enforcement modes, rollout, and key management.

Leaving the scoped block ends its local authorization context; it does not revoke a signed warrant. Keep warrant lifetimes short.

Continue with: Python guide · TypeScript guide · Rust guide · MCP walkthrough

For the TypeScript guide's development examples, set NODE_ENV=development.

Delegate Across Boundaries

A task can move between agents, frameworks, and services while retaining its authorization limits.

Issuer                  Orchestrator               Worker
Grants authority   →    Narrows for a subtask   →   Presents warrant
                                                    ↓
                                               Receiving service
                                               Verifies before acting

For example, a Python orchestrator can delegate a narrower warrant to a TypeScript worker calling a Rust service. The receiving service verifies the chain against its configured trusted roots, then checks the caller's proof of possession and the requested action against the warrant.

A delegated warrant can only narrow its parent.

Examples: Python delegation example · TypeScript delegation guide

<a id="python-delegation-example"></a>

<details> <summary>Python delegation example</summary>
from tenuo import Range, SigningKey, Warrant
from tenuo.exceptions import MonotonicityError

issuer = SigningKey.generate()
orchestrator = SigningKey.generate()
worker = SigningKey.generate()

root = (Warrant.mint_builder()
    .capability("scale", replicas=Range.max_value(10))
    .holder(orchestrator.public_key)
    .ttl(300)
    .mint(issuer))

# The orchestrator hands the worker a lower limit and a shorter lifetime.
worker_warrant = (root.grant_builder()
    .capability("scale", replicas=Range.max_value(5))
    .holder(worker.public_key)
    .ttl(60)
    .grant(orchestrator))

try:
    (root.grant_builder()
        .capability("scale", replicas=Range.max_value(50))
        .holder(worker.public_key)
        .ttl(60)
        .grant(orchestrator))
except MonotonicityError:
    print("Rejected: a child cannot raise the limit")
</details>

Sensitive actions can also require a signed human approval.

Explore: Python MCP delegation demo · Security model · Supported integrations

Integrate at the Boundary You Control

Tenuo uses the same warrant format and attenuation rules everywhere. Pick the enforcement point that fits. Authority crosses these boundaries without translation.

Enforcement pointUse it whenIntegrationsStart here
Inside the agent runtimeYou own the application and want the shortest path to enforcementPython functions, OpenAI, LangChain, LangGraph, Google ADK, CrewAI, AutoGen, Hermes Agent, Rust Guard@guard, OpenAI, Hermes, Rust, framework guides
At the MCP tool serverAgents call tools across a process or vendor boundaryFastMCP, official MCP SDK, custom MCP serversMCP guide
At an API or service edgeMultiple agent runtimes share the same downstream servicesFastAPI, authorizer sidecar, gateway, KubernetesFastAPI, Kubernetes
Inside a durable workflowAuthority must survive retries, queues, and long-running executionTemporalTemporal guide
At an agent handoffOne agent delegates part of a task to another agentA2A, MCP warrant stacksA2A guide, delegation demo

These are deployment choices for one authorization system. A warrant can be verified anywhere its issuer is trusted, and every delegated warrant must remain within its parent.


Security Boundaries

Tenuo checks the warrant and the actual tool arguments before an action executes. Enforcement must run at a boundary the agent cannot modify or bypass; an in-process guard alone does not isolate an untrusted agent.

Tenuo complements your identity system and policy controls. Use a container or VM when you need process isolation. For disconnected deployments, provision trusted keys and revocation state in advance; offline verification cannot discover revocations it has not received.

See the security model for guarantees and limitations.

Deploying to Production

The self-hosted core and sidecar are Apache-2.0 and run entirely in your infrastructure, with no external calls at verification time.

Self-hosted checklist:

  • Store signing keys in a secrets manager (Vault, AWS Secrets Manager, GCP Secret Manager). Keep them out of environment variables
  • Configure trusted_roots with your control plane's public keys
  • Ensure dry_run is disabled and warrants are required in all enforcement points
  • Enable audit callbacks and metrics for observability

See the Production Guide for enforcement modes, gradual rollout, and key management, and the Security Model for the full threat model.

Tenuo Cloud (Optional)

Tenuo Cloud is an optional managed control plane for issuance, key rotation, hosted revocation distribution, observability, and multi-tenant isolation. Verification stays local. Self-hosted Tenuo already verifies warrants and signed revocation lists (SRLs) in your own infrastructure.


Docker & Kubernetes

Try the Demo:

docker compose up

This runs the orchestrator -> worker -> authorizer stack: issuance, delegation, and verification.

Official Images on Docker Hub:

docker pull tenuo/authorizer:0.3.7  # Sidecar for warrant verification
docker pull tenuo/control:0.3.7     # Control plane (demo/reference)

Helm Chart:

helm install tenuo-authorizer ./charts/tenuo-authorizer \
  --set config.trustedRoots[0]="YOUR_CONTROL_PLANE_PUBLIC_KEY"

See Helm chart README and Kubernetes guide.


Documentation

ResourceDescription
AI Agent Delegation Security LabA hands-on lab: six agents, one rogue, five core levels plus two optional bosses
QuickstartGet running in 5 minutes
ConceptsHow warrants and attenuation work
ConstraintsAll 11 constraint types explained
SecurityThreat model and guarantees
OpenAIDirect API protection with streaming
Google ADKADK agent tool protection
AutoGenAgentChat tool protection
Hermes AgentOfficial Hermes plugin for signed, expiring tool authorization
A2AInter-agent delegation
FastAPIProtect FastAPI routes
LangChainTool protection
LangGraphMulti-agent graph security
CrewAIMulti-agent crew protection
TemporalDurable workflow authorization
MCPModel Context Protocol client + server verification

AI Coding Agents

Install Tenuo's implementation skill so a supported coding agent can place authorization at the effect boundary, use the SDK version in your project, and generate both allow and deny-before-effect tests:

npx skills add tenuo-ai/tenuo --skill tenuo-agent-authorization

The skill distinguishes an in-process guardrail from an independently enforced boundary and reports the guarantee and remaining bypasses explicitly. It does not ask the agent to reimplement Tenuo's cryptography or protocol.

Try It: The AI Agent Delegation Security Lab

A travel assistant made of six AI agents is booking a spring-break trip. One of them has been told to do something it shouldn't. Secure the system so the trip still happens and the rogue agent gets nowhere.

git clone https://github.com/tenuo-ai/tenuo
cd tenuo/labs/agent-delegation
npm install
npm run lab

Five main levels plus two optional bosses, no agent-framework experience needed. Book the trip, stop the rogue agent, and learn why each handoff should carry only the authority its task needs. Runs offline with free retries and no API key. The guide is at tenuo.ai/lab; the code is in labs/agent-delegation.


Requirements

ComponentSupported
Python3.9 - 3.14
Node.jsBeta. Node 20+ (npm i @tenuo/core@beta)
OSLinux, macOS, Windows
Python installationPrebuilt wheels for Linux (x86_64 and aarch64), macOS (arm64), and Windows (x64). Other platforms build from source and need Rust

Optional Dependencies

With uv, use uv pip install in place of pip install.

pip install tenuo                     # Core only
pip install "tenuo[openai]"           # + OpenAI Agents SDK
pip install "tenuo[google_adk]"       # + Google ADK
pip install "tenuo[a2a]"              # + A2A (inter-agent delegation)
pip install "tenuo[fastapi]"          # + FastAPI integration
pip install "tenuo[langchain]"        # + LangChain (langchain-core ≥0.2)
pip install "tenuo[langgraph]"        # + LangGraph (includes LangChain)
pip install "tenuo[crewai]"           # + CrewAI
pip install "tenuo[temporal]"         # + Temporal workflows
pip install "tenuo[autogen]"          # + AutoGen AgentChat (Python ≥3.10)
pip install "tenuo[mcp]"              # + official MCP SDK, client & server verification (Python ≥3.10)
pip install "tenuo[fastmcp]"          # + FastMCP (TenuoMiddleware / FastMCP servers)
pip install "tenuo[cloud]"            # + Tenuo Cloud SDK (proprietary control-plane client)

Rust

The core crate is the protocol. The sdk feature is the enforcement surface: a guard that checks a call before it runs, an authority that binds a warrant chain to a signing key, cryptographic delegation, an observe mode, and MCP and HTTP transports.

[dependencies]
tenuo = { version = "0.3.7", features = ["sdk"] }
use std::time::Duration;
use tenuo::sdk::prelude::*;
use tenuo::{args, constraints};

let root = SigningKey::generate(); // in production this lives in your control plane
let holder = SigningKey::generate();

let warrant = Warrant::builder()
    .capability("read_file", constraints! { "path" => Pattern::new("/data/*")? })
    .holder(holder.public_key())
    .ttl(Duration::from_secs(300))
    .build(&root)?;

let runtime = Runtime::builder()
    .holder(holder)
    .trusted_root(root.public_key())
    .revocation(RevocationMode::TtlOnly { max_lifetime: Duration::from_secs(600) })
    .build()?;
let session = runtime.session_from_warrant(warrant)?;

let allowed = Call::owned("read_file", args! { "path" => "/data/report.csv" })?;
let out = session.guard(&allowed, |_| Ok::<_, std::io::Error>("read"))?;
assert_eq!(out.into_inner(), "read");

let refused = Call::owned("read_file", args! { "path" => "/etc/shadow" })?;
assert!(session.check(&refused).is_err());

The closure runs only after an allow. A call outside the constraint is denied before it runs, same as Python @guard. A guard with no trust root or no revocation policy does not compile.

Features, all off by default: sdk, mcp-transport, http-transport, async, receipts, otel, test-utils. The default build adds no extra crates.

Use Rust for authorizer sidecars, gateways, MCP servers built on rmcp, and any service that needs enforcement without a Python runtime.


How It Works

Tenuo is capability-based authorization. A warrant is a capability: a signed grant that lists the tools an agent may call, the argument values it may pass, the key that may use it, and when it expires. The warrant travels with the request. The verifier uses the trusted issuer key and locally available revocation state.

Holder-bound. Every warrant names a public key. Every call carries a signature from that key over the warrant, the tool, the exact arguments, and a short time window. A copied warrant is useless without the key.

Verified offline. The warrant carries its own authority and signature. Checking it needs no lookup and no network. Checks run in under 50 μs, and enforcement keeps working when the control plane is down.

Attenuates monotonically. Delegation mints a child warrant signed by the parent's holder. The verifier walks the whole chain from a trusted root to the leaf. Each link may drop tools, tighten constraints, or shorten expiry. No delegated warrant can exceed its parent. Tenuo calls this Subtractive Delegation.

Holds under prompt injection. The check never asks the model. It runs at the tool boundary, on the real arguments, after the model has chosen what to call. A hijacked agent can only make the calls its warrant already allowed.

┌──────────────────┐     ┌──────────────────┐     ┌──────────────────┐
│  Control Plane   │     │  Orchestrator    │     │  Worker          │
│                  │     │                  │     │                  │
│  Issues root     │────▶│  Attenuates      │────▶│  Executes with   │
│  warrant         │     │  for task        │     │  proof           │
└──────────────────┘     └──────────────────┘     └──────────────────┘
     Full scope     -->     Narrower      -->      Narrowest
  1. Control plane issues a root warrant with broad capabilities
  2. Orchestrator attenuates it for a specific task; scope can only shrink
  3. Worker proves possession of the bound key and executes

See Concepts for the model and Related Work for how this compares to Biscuit, Macaroons, UCAN, and CaMeL.


Why Tenuo?

IAM answers who you are. Tenuo answers what this workload may do for this task, right now. Agents stay free to plan and pick tools. The warrant still applies after they choose.

Existing limitationTenuo
IAM typically grants authority by identity or roleWarrants limit authority to the current task
Conventional agent handoffs do not carry the original authorization contextAuthority travels with the work and can only narrow
Plain bearer tokens can be copied or replayedEvery warrant is bound to the key using it
Central policy checks introduce a runtime dependencySigned authority is verified locally at execution
Generic string matching can disagree with downstream systemsSemantic constraints interpret arguments as the target does (why this matters)

Signed authorization receipts are opt-in when you need to show why a call was allowed or denied.


Prior Art

Tenuo builds on capability token ideas described in CaMeL (Debenedetti et al., 2025). Inspired by Macaroons, Biscuit, and UCAN.

The token format and delegation protocol are specified in Attenuating Authorization Tokens for Agentic Delegation Chains, an active individual Internet-Draft in the IETF OAuth Working Group. The core attenuation rules are formally verified with Alloy (capability and argument-key monotonicity) and Z3 (constraint-type subsumption bounds).

See Related Work for detailed comparison.


Featured In


Etymology

Tenuo (/tɛn-ju-oʊ/ • Ten-YOO-oh)

From Latin tenuare: "to make thin; to attenuate." Authority starts broad at the root and is attenuated as it flows down the delegation chain.


Contributing

Tenuo is Apache-2.0 and built in the open. The core is Rust, with Python and TypeScript SDKs on top. Good places to start:

  • Framework integrations. Adapters live in tenuo-python/tenuo/. The integration guide covers the required API patterns and invariant tests. OpenAI and Google ADK are good templates.
  • Constraint types. There are 11 today. A new one has to parse input the same way the target system does.
  • The Rust SDK. New in 0.2.4. Adapters for Rust agent frameworks are open ground.
  • The TypeScript SDK. It is in beta and needs real-world use.
  • Docs and examples. If a guide confused you, that is a bug worth filing.

See CONTRIBUTING.md for setup, tests, and the PR process.

Security issues: Email security@tenuo.ai with PGP (key). Please do not open public issues for these.


License

Apache-2.0. See LICENSE for details.

Tenuo alternatives

View more →

Similar mcp servers in Finance & Trading, ranked by GitHub stars. Compare licence, recent activity and scan status before you choose.

NameStarsLicenceLast updatedScan
Tenuo (this page)
tenuo-ai
104Apache-2.0Oct 31, 2026Scanned, no flagged issues
QuantDinger
OpenByteInc
13kApache-2.0Nov 1, 2026Scanned, no flagged issues
FinanceToolkit
JerBouma
5.5kMITNov 1, 2026Scanned, no flagged issues
Tradingview MCP
atilaahmettaner
5.2kMITOct 29, 2026Scanned, no flagged issues
Aktools
akfamily
1.5kMITNov 1, 2026Scanned, no flagged issues
Tradememory Protocol
mnemox-ai
1.4kMITOct 23, 2026Scanned, no flagged issues