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
Automate DevOps Securely
Team AI Workflows
Burn After AI Reads
How It Works
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
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:
- ✅ Claude Desktop — Anthropic's desktop AI assistant
- ✅ Cursor — AI-powered code editor
- ✅ Cline — VS Code AI extension
- ✅ OpenClaw — Open-source AI assistant
- ✅ Custom MCP Servers — Build your own integration