
Security News
Socket Releases Free Certified Patches for Nuxt Security Vulnerabilities
Socket releases free Certified Patches for high-severity Nuxt vulnerabilities, including server-side remote code execution through server island props.
@nimblebrain/mpak-sdk
Advanced tools
TypeScript SDK for mpak registry - MCPB bundles and Agent Skills
TypeScript SDK for the mpak registry — search, download, cache, configure, and run MCPB bundles and Agent Skills.
pnpm add @nimblebrain/mpak-sdk
The MpakSDK facade is the primary entry point. It wires together the registry client, local cache, and config manager:
import { MpakSDK } from '@nimblebrain/mpak-sdk';
const mpak = new MpakSDK();
// Prepare a bundle for execution (downloads if not cached)
const server = await mpak.prepareServer('@nimblebraininc/echo');
// Spawn the MCP server
import { spawn } from 'child_process';
const child = spawn(server.command, server.args, {
env: { ...server.env, ...process.env },
cwd: server.cwd,
stdio: 'inherit',
});
prepareServer handles the full lifecycle: download, cache, read manifest, validate config, and resolve the command:
const mpak = new MpakSDK();
// Latest version
const server = await mpak.prepareServer('@scope/bundle');
// Pinned version (inline)
const server = await mpak.prepareServer('@scope/bundle@1.2.0');
// Pinned version (option) + force re-download
const server = await mpak.prepareServer('@scope/bundle', {
version: '1.2.0',
force: true,
});
// Custom workspace directory for stateful bundles
const server = await mpak.prepareServer('@scope/bundle', {
workspaceDir: '/path/to/project/.mpak',
});
// Extra env vars merged on top of manifest env
const server = await mpak.prepareServer('@scope/bundle', {
env: { DEBUG: 'true' },
});
The returned ServerCommand contains everything needed to spawn:
server.command; // e.g. 'node', 'python3', or '/path/to/binary'
server.args; // e.g. ['/cache/dir/index.js']
server.env; // manifest env + user config substitutions + overrides
server.cwd; // extracted bundle cache directory
server.name; // resolved package name
server.version; // resolved version string
Bundles can declare required configuration (API keys, ports, etc.) in their manifest. Store values before running:
const mpak = new MpakSDK();
// Set a config value
mpak.config.setPackageConfigValue('@scope/bundle', 'api_key', 'sk-...');
// Values are substituted into ${user_config.*} placeholders in the manifest env
// If required config is missing, prepareServer throws with a clear message
Validate and parse @scope/name or @scope/name@version strings:
MpakSDK.parsePackageSpec('@scope/name');
// { name: '@scope/name' }
MpakSDK.parsePackageSpec('@scope/name@1.0.0');
// { name: '@scope/name', version: '1.0.0' }
MpakSDK.parsePackageSpec('invalid');
// throws: Invalid package spec
const mpak = new MpakSDK();
const results = await mpak.client.searchBundles({ q: 'mcp', limit: 10 });
for (const bundle of results.bundles) {
console.log(`${bundle.name}@${bundle.latest_version}`);
}
const bundle = await mpak.client.getBundle('@nimblebraininc/echo');
console.log(bundle.description);
console.log(`Versions: ${bundle.versions.map(v => v.version).join(', ')}`);
const platform = MpakClient.detectPlatform();
const download = await mpak.client.getBundleDownload(
'@nimblebraininc/echo',
'0.1.3',
platform
);
const mpak = new MpakSDK();
// Download and cache a bundle
const result = await mpak.cache.loadBundle('@scope/name');
console.log(result.cacheDir); // path to extracted bundle
console.log(result.version); // resolved version
console.log(result.pulled); // true if downloaded, false if from cache
// Read a cached bundle's manifest
const manifest = mpak.cache.readManifest('@scope/name');
// List all cached bundles
const bundles = mpak.cache.listCachedBundles();
// Check for updates (fire-and-forget, logs via logger callback)
await mpak.cache.checkForUpdateAsync('@scope/name');
// Read/write cache metadata
const meta = mpak.cache.getCacheMetadata('@scope/name');
const mpak = new MpakSDK();
// Registry URL
mpak.config.getRegistryUrl();
mpak.config.setRegistryUrl('https://custom.registry.dev');
// Per-package config
mpak.config.setPackageConfigValue('@scope/name', 'api_key', 'sk-...');
mpak.config.getPackageConfigValue('@scope/name', 'api_key');
mpak.config.getPackageConfig('@scope/name'); // all values for a package
mpak.config.clearPackageConfig('@scope/name'); // remove all config for a package
mpak.config.clearPackageConfigValue('@scope/name', 'api_key'); // remove one key
mpak.config.listPackagesWithConfig(); // list configured packages
const mpak = new MpakSDK();
const skills = await mpak.client.searchSkills({ q: 'crm', limit: 10 });
for (const skill of skills.skills) {
console.log(`${skill.name}: ${skill.description}`);
}
// Download skill with SHA256 integrity verification
const download = await mpak.client.getSkillDownload('@nimbletools/folk-crm');
const data = await mpak.client.downloadContent(download.url, download.skill.sha256);
const mpak = new MpakSDK({
mpakHome: '~/.mpak', // Root directory for config + cache
registryUrl: 'https://registry.mpak.dev', // Registry API URL
timeout: 30000, // Request timeout in ms
userAgent: 'my-app/1.0', // User-Agent header
logger: (msg) => console.error(msg), // Logger for cache operations
});
import {
MpakSDK,
MpakNotFoundError,
MpakIntegrityError,
MpakNetworkError,
} from '@nimblebrain/mpak-sdk';
try {
const server = await mpak.prepareServer('@nonexistent/bundle');
} catch (error) {
if (error instanceof MpakNotFoundError) {
console.error('Bundle not found:', error.message);
} else if (error instanceof MpakIntegrityError) {
// Content was NOT returned (fail-closed)
console.error('Expected SHA256:', error.expected);
console.error('Actual SHA256:', error.actual);
} else if (error instanceof MpakNetworkError) {
console.error('Network error:', error.message);
}
}
| Method | Description |
|---|---|
prepareServer(packageName, options?) | Resolve a bundle into a ready-to-spawn ServerCommand |
MpakSDK.parsePackageSpec(spec) | Parse and validate a @scope/name[@version] string |
Properties: config (ConfigManager), client (MpakClient), cache (BundleCache).
mpak.client)| Method | Description |
|---|---|
searchBundles(params?) | Search for bundles |
getBundle(name) | Get bundle details |
getBundleVersions(name) | List all versions |
getBundleVersion(name, version) | Get specific version info |
getBundleDownload(name, version, platform?) | Get download URL and metadata |
downloadBundle(name, version?) | Download bundle with integrity verification |
downloadContent(url, sha256) | Download any content with SHA256 verification |
| Method | Description |
|---|---|
searchSkills(params?) | Search for skills |
getSkill(name) | Get skill details |
getSkillDownload(name) | Get latest version download info |
getSkillVersionDownload(name, version) | Get specific version download info |
downloadSkillBundle(name, version?) | Download skill bundle with integrity verification |
| Method | Description |
|---|---|
MpakClient.detectPlatform() | Detect current OS and architecture |
mpak.cache)| Method | Description |
|---|---|
loadBundle(name, options?) | Download and cache a bundle (skips if cached) |
readManifest(packageName) | Read and validate a cached bundle's manifest.json |
getCacheMetadata(packageName) | Read cache metadata for a package |
writeCacheMetadata(packageName, metadata) | Write cache metadata |
listCachedBundles() | List all cached registry bundles |
getPackageCachePath(packageName) | Get the cache directory path for a package |
checkForUpdateAsync(packageName) | Fire-and-forget update check (logs result) |
Standalone functions exported from the package (not methods on any class):
| Export | Description |
|---|---|
extractZip(zipPath, destDir, options?) | Async. Stream-extract a ZIP with zip-bomb, path-traversal, and symlink protection. Pass { maxUncompressedSize } to override the default cap. |
MAX_UNCOMPRESSED_SIZE | Default uncompressed-size cap applied by extractZip (2 GB). |
isSemverEqual(a, b) | Compare semver strings (ignores v prefix) |
validateMcpb(path) | Async. Validate a local .mcpb file (manifest schema + entry-point existence) without touching the cache. Returns { valid: true, manifest } or { valid: false, errors }. |
mpak.config)| Method | Description |
|---|---|
getRegistryUrl() | Get the registry URL (respects MPAK_REGISTRY_URL env var) |
setRegistryUrl(url) | Override the registry URL |
getPackageConfig(packageName) | Get all stored config for a package |
getPackageConfigValue(packageName, key) | Get a single config value |
setPackageConfigValue(packageName, key, value) | Store a config value |
clearPackageConfig(packageName) | Remove all config for a package |
clearPackageConfigValue(packageName, key) | Remove a single config key |
listPackagesWithConfig() | List packages that have stored config |
Property: mpakHome (readonly) — the root directory for mpak state.
| Class | Description |
|---|---|
MpakError | Base error class |
MpakNotFoundError | Resource not found (404) |
MpakIntegrityError | SHA256 hash mismatch (content NOT returned) |
MpakNetworkError | Network failures, timeouts |
| Type | Description |
|---|---|
MpakSDKOptions | Constructor options for MpakSDK |
MpakClientConfig | Constructor options for MpakClient |
PrepareServerOptions | Options for prepareServer |
ServerCommand | Return type of prepareServer |
McpbManifest | Parsed MCPB manifest schema |
UserConfigField | User config field definition from manifest |
pnpm install # Install dependencies
pnpm test # Run unit tests
pnpm test:integration # Run integration tests (hits live registry)
pnpm typecheck # Type check
pnpm build # Build
Run all checks before submitting changes:
pnpm --filter @nimblebrain/mpak-sdk lint
pnpm --filter @nimblebrain/mpak-sdk typecheck
pnpm --filter @nimblebrain/mpak-sdk test
pnpm --filter @nimblebrain/mpak-sdk test:integration
Releases are automated via GitHub Actions. The publish workflow is triggered by git tags.
Version is defined in one place: package.json.
Bump version in package.json:
cd packages/sdk-typescript
npm version patch # 0.1.0 -> 0.1.1
npm version minor # 0.1.0 -> 0.2.0
npm version major # 0.1.0 -> 1.0.0
Commit and push:
git commit -am "sdk-typescript: bump to X.Y.Z"
git push
Tag and push (this triggers the publish):
git tag sdk-typescript-vX.Y.Z
git push origin sdk-typescript-vX.Y.Z
CI will run the full verification suite, verify the tag matches package.json, build, and publish to npm. See sdk-typescript-publish.yml.
Apache-2.0
FAQs
TypeScript SDK for mpak registry - MCPB bundles and Agent Skills
We found that @nimblebrain/mpak-sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Socket releases free Certified Patches for high-severity Nuxt vulnerabilities, including server-side remote code execution through server island props.

Security News
An open letter signed by 50 companies, from NVIDIA and Microsoft to Mistral and Hugging Face, urges Washington not to restrict open weight AI.

Security News
/Research
A fake corepack.org site is impersonating the Node.js tool and delivers an infostealer and proxyware to developers who download it.