@safenode/sdk
v0.1.1
Published
Official Node.js SDK for SafeNode — zero-knowledge credential vault
Readme
safenode
Official Node.js/TypeScript SDK for SafeNode — a zero-knowledge credential vault.
Requirements
- Node.js 18 or later (uses native
fetch) - Zero runtime dependencies
Installation
npm install @safenode/sdkQuick Start
import { createClient } from "@safenode/sdk";
const client = await createClient({
token: process.env.SAFENODE_TOKEN,
});
console.log(client.vaultId);Or use new SafeNode() + connect() for explicit control:
import { SafeNode } from "@safenode/sdk";
const client = new SafeNode({ token: process.env.SAFENODE_TOKEN });
await client.connect();Authentication
MCP Token (recommended)
const client = await createClient({
token: "kvt_your_token_here",
});The SDK automatically re-validates the token before expiry on any 401 response.
Email + Password
const client = await createClient({
email: "[email protected]",
password: "your-password",
passphrase: "vault-passphrase",
vaultId: "your-vault-id",
});Examples
Proxy
Forward HTTP requests through a stored credential:
const response = await client.proxy.request({
credential_name: "my-api",
method: "GET",
path: "/users",
query_params: { page: "1" },
});
console.log(response.status_code);
console.log(response.body);POST with a body:
const response = await client.proxy.request({
credential_name: "my-api",
method: "POST",
path: "/users",
body: { name: "Alice", email: "[email protected]" },
headers: { "X-Custom-Header": "value" },
timeout: 10000,
});SSH
Execute commands on remote servers:
const result = await client.ssh.exec({
credential_name: "my-server",
command: "ls -la /var/log",
timeout: 30000,
});
console.log(result.stdout);
console.log(result.exit_code);Database
Run SQL queries:
const result = await client.db.query({
credential_name: "my-postgres",
sql: "SELECT id, name FROM users WHERE active = $1",
params: [true],
});
console.log(result.columns);
console.log(result.rows);
console.log(result.row_count);Credentials
List all credentials:
const creds = await client.credentials.list();Filter by type:
const apiCreds = await client.credentials.list({ type: "http" });Get a single credential:
const cred = await client.credentials.get("credential-id");Create a credential:
const cred = await client.credentials.create({
name: "my-new-api",
type: "http",
data: {
base_url: "https://api.example.com",
headers: { Authorization: "Bearer secret" },
},
});Update a credential:
const updated = await client.credentials.update("credential-id", {
data: { base_url: "https://api2.example.com" },
});Delete a credential:
await client.credentials.delete("credential-id");TypeScript Types
import type {
SafeNodeOptions,
ProxyRequest,
ProxyResponse,
SSHRequest,
SSHResult,
DBRequest,
DBResult,
Credential,
CreateCredentialRequest,
ListCredentialsParams,
} from "@safenode/sdk";Error Handling
import {
createClient,
AuthError,
VaultLockedError,
RateLimitError,
NotFoundError,
ProxyError,
GatewayTimeoutError,
SafeNodeError,
} from "@safenode/sdk";
try {
const client = await createClient({ token: process.env.SAFENODE_TOKEN });
const result = await client.proxy.request({
credential_name: "my-api",
method: "GET",
path: "/data",
});
} catch (err) {
if (err instanceof VaultLockedError) {
console.error("Vault is locked — unlock it before making requests");
} else if (err instanceof RateLimitError) {
console.error(`Rate limited. Retry after ${err.retryAfter} seconds`);
} else if (err instanceof AuthError) {
console.error("Authentication failed:", err.message);
} else if (err instanceof NotFoundError) {
console.error("Resource not found");
} else if (err instanceof ProxyError) {
console.error("Upstream error from proxied service");
} else if (err instanceof GatewayTimeoutError) {
console.error("Request timed out");
} else if (err instanceof SafeNodeError) {
console.error(`SafeNode error ${err.statusCode}: ${err.detail}`);
} else {
throw err;
}
}Environment Variables
| Variable | Description |
| ------------------ | --------------------------------- |
| SAFENODE_TOKEN | MCP token (kvt_...) |
const client = await createClient({
token: process.env.SAFENODE_TOKEN,
});License
MIT
