View full policy →

COTI MCP Server: 17 unrestricted tools

The COTI MCP Server MCP server exposes tools that can move money, delete data, or destroy resources. Without policy enforcement, an autonomous agent has unrestricted access to every one of them.

3 move money
5 execute code
9 modify data
Write / Execute (14) Destructive / Financial (3)

Financial operations (transfer_native, transfer_private_erc20, transfer_private_erc721) can move real money. An agent caught in a loop could drain accounts before anyone notices.

Write operations (approve_erc20_spender, approve_private_erc721, call_contract_function) modify state. Without rate limits, an agent can make hundreds of changes in seconds -- faster than any human can review or revert.

Execute tools (compile_and_deploy_contract, compile_contract, deploy_private_erc20_contract) trigger processes with side effects. Builds, notifications, workflows -- all fired without throttling.

These COTI MCP Server tools can modify, create, or destroy resources. Without a policy, your agent has unrestricted access to all of them.

approve_erc20_spender Approve another address to spend tokens on behalf of the owner. This is used for allowing another address (like a contract) to transfer your tokens. Requires token contract address, spender address, and amount as input. Returns the transaction hash upon successful approval. Write
approve_private_erc721 Approve an address to transfer a specific private ERC721 NFT token on the COTI blockchain. This allows the approved address to transfer the specified NFT on behalf of the owner. Requires token contract address, token ID, and spender address as input. Returns the transaction hash upon successful approval. Write
call_contract_function Call any function on a smart contract on the COTI blockchain. Supports both read-only (view/pure) functions and state-changing (write) functions. Read-only functions return data without creating a transaction. State-changing functions create transactions and may require gas_limit. Returns the function result in a human-readable format. Write
create_account Create a new COTI account with a randomly generated private key and AES key. Returns the new account details for the AI assistant to track in conversation context. The AI should remember these credentials for use in subsequent operations. Write
generate_aes_key Generate or recover an AES key for a COTI account. Requires the account to be funded. The AI assistant should track the returned AES key for use in private transactions. Write
import_account_from_private_key Import a COTI account using only a private key. The public key will be derived automatically, and the AES key placeholder will be set (fund the account to generate a real AES key). Write
send_private_message Send an encrypted message to a specific recipient address on a deployed PrivateMessage contract. The message is encrypted using COTI MPC so only the recipient can decrypt it with their own AES key. Requires the contract address and ABI returned by deploy_private_message_contract. Write
set_private_erc721_approval_for_all Approve or revoke an operator to transfer all private ERC721 NFT tokens on the COTI blockchain. This allows the operator to transfer any NFT owned by the caller in this collection. Requires token contract address, operator address, and approval status as input. Returns the transaction hash upon successful approval setting. Write
switch_network Switch between COTI testnet and mainnet networks. The AI assistant should remember this network selection and pass it to subsequent blockchain operations. Returns the new network to be tracked by the AI. Write
transfer_native Transfer native COTI tokens to another wallet. This is used for sending COTI tokens from your wallet to another address. Requires private key, recipient address, and amount in Wei as input. The AI assistant should track and pass the account private key from context. Returns the transaction hash upon successful transfer. Financial
transfer_private_erc20 Transfer private ERC20 tokens on the COTI blockchain. This is used for sending private tokens from your wallet to another address. Requires token contract address, recipient address, and amount as input. Returns the transaction hash upon successful transfer. Financial
transfer_private_erc721 Transfer a private ERC721 NFT token on the COTI blockchain. This is used for sending a private NFT from your wallet to another address. Requires token contract address, recipient address, and token ID as input. Returns the transaction hash upon successful transfer. Financial
compile_and_deploy_contract Compiles Solidity source code and immediately deploys it to the COTI blockchain in a single operation. This tool avoids bytecode truncation issues that can occur when passing large bytecode strings between tools. Accepts full Solidity source code, compiles it, and deploys the result. Returns the contract address, transaction hash, and ABI (for future interactions). This is the recommended tool for most deployment scenarios. Execute
compile_contract Compiles Solidity source code without deploying it to the blockchain. Returns bytecode, ABI, and compilation metadata (compiler version, EVM version, optimization settings). Useful for: - Testing that a contract compiles without errors - Getting the ABI for contract interaction - Analyzing bytecode size and structure - Preparing compilation metadata for later deployment or verification - Debugging compilation issues in isolation Execute
deploy_private_erc20_contract Deploy a new standard private ERC20 token contract on the COTI blockchain. This creates a new private token with the specified name, symbol, and decimals. Returns the deployed contract address upon successful deployment. Execute
deploy_private_erc721_contract Deploy a new standard private ERC721 NFT contract on the COTI blockchain. This creates a new private NFT collection with the specified name and symbol. Returns the deployed contract address upon successful deployment. Execute
deploy_private_message_contract Deploys the PrivateMessage contract on the COTI blockchain. This contract allows sending encrypted messages to specific addresses. Only the intended recipient can decrypt a message using their own AES key. Returns the contract address and ABI needed for send_private_message and read_private_message. Execute

These rules are based on the tool categories exposed by the COTI MCP Server MCP server. Adjust the limits to match your use case.

Block financial tools by default
transfer_native:
    rules:
      - action: deny
        on_deny: "Financial operations require approval"

Financial tools should be explicitly enabled per use case, not open by default.

Rate limit write operations
approve_erc20_spender:
    rules:
      - name: "write-rate-limit"
        rate_limit: 30/hour
        on_deny: "Write rate limit reached"

Prevents bulk unintended modifications from agents caught in loops.

Cap read operations
decode_event_data:
    rules:
      - action: allow
        rate_limit: 60/minute

Controls API costs and prevents retry loops from exhausting upstream rate limits.

This is the complete policy file for COTI MCP Server. It lists every tool with suggested default rules. Download it, adjust the limits, and run with Intercept.

davibauer-coti-mcp.yaml
version: "1"
default: "deny"

tools:
  compile_and_deploy_contract:
    rules:
      - action: allow
        rate_limit: 10/hour
        validate:
          required_args: true
  compile_contract:
    rules:
      - action: allow
        rate_limit: 10/hour
        validate:
          required_args: true
  deploy_private_erc20_contract:
    rules:
      - action: allow
        rate_limit: 10/hour
        validate:
          required_args: true
  deploy_private_erc721_contract:
    rules:
      - action: allow
        rate_limit: 10/hour
        validate:
          required_args: true
  deploy_private_message_contract:
    rules:
      - action: allow
        rate_limit: 10/hour
        validate:
          required_args: true
  transfer_native:
    rules:
      - action: deny
        on_deny: "Financial operation requires approval"
  transfer_private_erc20:
    rules:
      - action: deny
        on_deny: "Financial operation requires approval"
  transfer_private_erc721:
    rules:
      - action: deny
        on_deny: "Financial operation requires approval"
  decode_event_data:
    rules:
      - action: allow
        rate_limit: 60/minute
  decrypt_message:
    rules:
      - action: allow
        rate_limit: 60/minute
  decrypt_value:
    rules:
      - action: allow
        rate_limit: 60/minute
  encrypt_message:
    rules:
      - action: allow
        rate_limit: 60/minute
  encrypt_value:
    rules:
      - action: allow
        rate_limit: 60/minute
  get_current_network:
    rules:
      - action: allow
        rate_limit: 60/minute
  get_current_rpc:
    rules:
      - action: allow
        rate_limit: 60/minute
  get_native_balance:
    rules:
      - action: allow
        rate_limit: 60/minute
  get_private_erc20_allowance:
    rules:
      - action: allow
        rate_limit: 60/minute
  get_private_erc20_balance:
    rules:
      - action: allow
        rate_limit: 60/minute
  get_private_erc20_decimals:
    rules:
      - action: allow
        rate_limit: 60/minute
  get_private_erc20_total_supply:
    rules:
      - action: allow
        rate_limit: 60/minute
  get_private_erc721_approved:
    rules:
      - action: allow
        rate_limit: 60/minute
  get_private_erc721_balance:
    rules:
      - action: allow
        rate_limit: 60/minute
  get_private_erc721_is_approved_for_all:
    rules:
      - action: allow
        rate_limit: 60/minute
  get_private_erc721_token_owner:
    rules:
      - action: allow
        rate_limit: 60/minute
  get_private_erc721_token_uri:
    rules:
      - action: allow
        rate_limit: 60/minute
  get_private_erc721_total_supply:
    rules:
      - action: allow
        rate_limit: 60/minute
  get_private_message_count:
    rules:
      - action: allow
        rate_limit: 60/minute
  get_private_message_senders:
    rules:
      - action: allow
        rate_limit: 60/minute
  get_transaction_logs:
    rules:
      - action: allow
        rate_limit: 60/minute
  get_transaction_status:
    rules:
      - action: allow
        rate_limit: 60/minute
  mint_private_erc20_token:
    rules:
      - action: allow
        rate_limit: 60/minute
  mint_private_erc721_token:
    rules:
      - action: allow
        rate_limit: 60/minute
  read_private_message:
    rules:
      - action: allow
        rate_limit: 60/minute
  sign_message:
    rules:
      - action: allow
        rate_limit: 60/minute
  verify_signature:
    rules:
      - action: allow
        rate_limit: 60/minute
  approve_erc20_spender:
    rules:
      - action: allow
        rate_limit: 30/hour
  approve_private_erc721:
    rules:
      - action: allow
        rate_limit: 30/hour
  call_contract_function:
    rules:
      - action: allow
        rate_limit: 30/hour
  create_account:
    rules:
      - action: allow
        rate_limit: 30/hour
  generate_aes_key:
    rules:
      - action: allow
        rate_limit: 30/hour
  import_account_from_private_key:
    rules:
      - action: allow
        rate_limit: 30/hour
  send_private_message:
    rules:
      - action: allow
        rate_limit: 30/hour
  set_private_erc721_approval_for_all:
    rules:
      - action: allow
        rate_limit: 30/hour
  switch_network:
    rules:
      - action: allow
        rate_limit: 30/hour

Two commands. Under two minutes.

01

Download the policy

curl -o davibauer-coti-mcp.yaml https://raw.githubusercontent.com/policylayer/intercept/main/policies/davibauer-coti-mcp.yaml
02

Run Intercept in front of the server

intercept -c davibauer-coti-mcp.yaml -- npx -y @davibauer/coti-mcp

Works with any MCP client:

Every tool call is now checked against your policy before it reaches COTI MCP Server. Denied calls are blocked and logged. Allowed calls pass through with no latency impact.

Enforce policies on COTI MCP Server

Open source. One binary. Zero dependencies.

npx -y @policylayer/intercept
github.com/policylayer/intercept →
// GET IN TOUCH

Have a question or want to learn more? Send us a message.

Message sent.

We'll get back to you soon.