Zero-Knowledge Architecture
Checking...
MCP Integration

Give Your AI Secrets. Securely.

IronShare + MCP lets AI assistants retrieve encrypted secrets on-demand. Zero-knowledge. Self-destructing. No plaintext ever touches the server.

What is Model Context Protocol?

MCP is an open standard that lets AI assistants securely access external tools. With IronShare's MCP support, your AI retrieves secrets on-demand — but only with your explicit permission.

Zero-knowledge guaranteed: Decryption happens locally in the MCP server using the same AES-256-GCM encryption you trust in your browser. The IronShare server only stores encrypted blobs — never plaintext.

Use Cases

🔑 Share Credentials Without Exposure
Give your AI assistant API keys or passwords for one-off tasks — without them appearing in chat logs. Perfect for debugging authenticated services or temporary deployments.
🚀 Automate DevOps Securely
Let AI retrieve deployment secrets or config values during CI/CD runs — with explicit approval each time. No hardcoded credentials, no persistent storage.
👥 Team AI Workflows
Safely hand off database credentials, staging keys, or tokens to team AI assistants. Secrets burn after use — no lingering access.
🔥 Burn After AI Reads
Create self-destructing secrets that vanish after your AI retrieves them once. Maximum security for high-stakes tasks — zero persistence after completion.

How It Works

1
You Create a Secret
Use IronShare to encrypt sensitive data in your browser. You get a link and a passphrase.
2
Share with Your AI
Provide both the IronShare URL and passphrase to your AI assistant (e.g., "Retrieve this secret: [URL] with passphrase [PASSPHRASE]").
3
MCP Server Retrieves
The MCP server fetches the encrypted blob from IronShare and decrypts it locally using the passphrase you provided.
4
AI Gets Plaintext
Your AI assistant receives the decrypted secret and can use it to complete your task. The secret is automatically deleted after retrieval (if set to burn-after-read).

In Practice

# You tell your AI assistant:
"Retrieve the secret at https://your-domain.com/api/secret/abc123 
 with passphrase xY7k9mQ2pR3nF4sL and use it to deploy the staging server"

# What happens:
MCP Server → Fetches encrypted blob
MCP Server → Decrypts locally with your passphrase
AI → Gets the plaintext, completes your task
IronShare → Secret self-destructs

Developer Docs

MCP Tool Schema

{
  "name": "retrieve_ironshare_secret",
  "description": "Retrieve and decrypt a secret from IronShare",
  "inputSchema": {
    "type": "object",
    "properties": {
      "url":  { "type": "string", "description": "IronShare URL" },
      "passphrase": { "type": "string", "description": "Decryption passphrase" }
    },
    "required": ["url", "passphrase"]
  }
}

API Endpoints

GET /api/secret/{id}/check Check existence (no view consumed)
POST /api/secret/{id} Retrieve encrypted blob (consumes view)

Encryption

Key:  PBKDF2-SHA256(passphrase, salt, 600000 iterations) → 256-bit key
Enc:  AES-256-GCM(plaintext, key, iv) → ciphertext
Dec:  AES-256-GCM(ciphertext, key, iv) → plaintext

Quick Start — Retrieve & decrypt in your language:

import { webcrypto } from 'crypto';

const res = await fetch(`${baseUrl}/api/secret/${id}`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: '{}'
});
const { ciphertext, iv, salt } = await res.json();

// Derive key
const keyMaterial = await webcrypto.subtle.importKey(
  'raw', new TextEncoder().encode(passphrase), 'PBKDF2', false, ['deriveKey']
);
const key = await webcrypto.subtle.deriveKey(
  { name: 'PBKDF2', salt: Buffer.from(salt, 'base64'),
    iterations: 600000, hash: 'SHA-256' },
  keyMaterial,
  { name: 'AES-GCM', length: 256 }, false, ['decrypt']
);

// Decrypt
const plaintext = new TextDecoder().decode(
  await webcrypto.subtle.decrypt(
    { name: 'AES-GCM', iv: Buffer.from(iv, 'base64') },
    key, Buffer.from(ciphertext, 'base64')
  )
);
import base64, hashlib, requests
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC

res = requests.post(f"{base_url}/api/secret/{id}", json={})
data = res.json()

# Derive key
kdf = PBKDF2HMAC(
    algorithm=hashlib.sha256(), length=32,
    salt=base64.b64decode(data["salt"]),
    iterations=600000
)
key = kdf.derive(passphrase.encode())

# Decrypt
aesgcm = AESGCM(key)
plaintext = aesgcm.decrypt(
    base64.b64decode(data["iv"]),
    base64.b64decode(data["ciphertext"]),
    None
).decode()
use aes_gcm::{Aes256Gcm, KeyInit, aead::Aead, Nonce};
use pbkdf2::pbkdf2_hmac;
use sha2::Sha256;
use base64::Engine;

let body: serde_json::Value = reqwest::Client::new()
    .post(format!("{base_url}/api/secret/{id}"))
    .json(&serde_json::json!({}))
    .send().await?.json().await?;

let salt = base64::engine::general_purpose::STANDARD
    .decode(body["salt"].as_str().unwrap())?;
let iv = base64::engine::general_purpose::STANDARD
    .decode(body["iv"].as_str().unwrap())?;
let ct = base64::engine::general_purpose::STANDARD
    .decode(body["ciphertext"].as_str().unwrap())?;

// Derive key
let mut key = [0u8; 32];
pbkdf2_hmac::<Sha256>(passphrase.as_bytes(), &salt, 600_000, &mut key);

// Decrypt
let cipher = Aes256Gcm::new_from_slice(&key)?;
let plaintext = cipher.decrypt(
    Nonce::from_slice(&iv), ct.as_ref()
)?;
import (
    "crypto/aes"
    "crypto/cipher"
    "crypto/sha256"
    "encoding/base64"
    "golang.org/x/crypto/pbkdf2"
)

// POST /api/secret/{id} → parse JSON response
salt, _ := base64.StdEncoding.DecodeString(data.Salt)
iv, _ := base64.StdEncoding.DecodeString(data.IV)
ct, _ := base64.StdEncoding.DecodeString(data.Ciphertext)

// Derive key
key := pbkdf2.Key([]byte(passphrase), salt, 600000, 32, sha256.New)

// Decrypt
block, _ := aes.NewCipher(key)
gcm, _ := cipher.NewGCM(block)
plaintext, _ := gcm.Open(nil, iv, ct, nil)
using System.Security.Cryptography;
using System.Net.Http.Json;

var res = await new HttpClient()
    .PostAsJsonAsync($"{baseUrl}/api/secret/{id}", new {});
var data = await res.Content.ReadFromJsonAsync<SecretResponse>();

var salt = Convert.FromBase64String(data.Salt);
var iv   = Convert.FromBase64String(data.Iv);
var ct   = Convert.FromBase64String(data.Ciphertext);

// Derive key
using var pbkdf2 = new Rfc2898DeriveBytes(
    passphrase, salt, 600_000, HashAlgorithmName.SHA256);
var key = pbkdf2.GetBytes(32);

// Decrypt
using var aes = new AesGcm(key, 16);
var tag = ct[^16..];
var ciphertext = ct[..^16];
var plainBytes = new byte[ciphertext.Length];
aes.Decrypt(iv, ciphertext, tag, plainBytes);
var plaintext = Encoding.UTF8.GetString(plainBytes);
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.*;
import java.net.http.*;
import java.util.Base64;

var client = HttpClient.newHttpClient();
var req = HttpRequest.newBuilder()
    .uri(URI.create(baseUrl + "/api/secret/" + id))
    .POST(HttpRequest.BodyPublishers.ofString("{}"))
    .header("Content-Type", "application/json").build();
var body = new JSONObject(client.send(req,
    HttpResponse.BodyHandlers.ofString()).body());

var salt = Base64.getDecoder().decode(body.getString("salt"));
var iv   = Base64.getDecoder().decode(body.getString("iv"));
var ct   = Base64.getDecoder().decode(body.getString("ciphertext"));

// Derive key
var keySpec = new PBEKeySpec(passphrase.toCharArray(), salt, 600_000, 256);
var key = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256")
    .generateSecret(keySpec).getEncoded();

// Decrypt
var cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"),
    new GCMParameterSpec(128, iv));
var plaintext = new String(cipher.doFinal(ct));
require 'net/http'
require 'json'
require 'openssl'
require 'base64'

uri = URI("#{base_url}/api/secret/#{id}")
res = Net::HTTP.post(uri, '{}',
  'Content-Type' => 'application/json')
data = JSON.parse(res.body)

salt = Base64.decode64(data['salt'])
iv   = Base64.decode64(data['iv'])
ct   = Base64.decode64(data['ciphertext'])

# Derive key
key = OpenSSL::KDF.pbkdf2_hmac(
  passphrase, salt: salt, iterations: 600_000,
  length: 32, hash: 'SHA256'
)

# Decrypt (GCM tag is last 16 bytes)
decipher = OpenSSL::Cipher.new('aes-256-gcm').decrypt
decipher.key = key
decipher.iv = iv
decipher.auth_tag = ct[-16..]
plaintext = decipher.update(ct[0..-17]) + decipher.final
<?php
$res = file_get_contents("{$baseUrl}/api/secret/{$id}", false,
    stream_context_create(['http' => [
        'method' => 'POST',
        'header' => 'Content-Type: application/json',
        'content' => '{}'
    ]]));
$data = json_decode($res, true);

$salt = base64_decode($data['salt']);
$iv   = base64_decode($data['iv']);
$ct   = base64_decode($data['ciphertext']);

// Derive key
$key = hash_pbkdf2('sha256', $passphrase, $salt, 600000, 32, true);

// Decrypt (GCM tag is last 16 bytes)
$tag = substr($ct, -16);
$ciphertext = substr($ct, 0, -16);
$plaintext = openssl_decrypt(
    $ciphertext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag
);

Compatible AI Tools

Any MCP-compatible AI assistant can integrate with IronShare: