
Product
Socket Now Protects the Microsoft Edge Extension Ecosystem
Enterprise security teams can now detect malware, credential theft, suspicious network activity, and risky updates across Microsoft Edge extensions.
@nimbus-dev/sdk
Advanced tools
[](https://www.npmjs.com/package/@nimbus-dev/sdk) [](./LICENSE)
The MIT-licensed, dependency-free TypeScript authoring contract for Nimbus MCP (Model Context Protocol) connectors and extensions. It ships types, small pure helpers, and test utilities — no runtime dependencies, no I/O, no credentials.
The gateway, Vault, HITL (human-in-the-loop) gate, and connector sandbox all live in the Nimbus monorepo. This package is just the stable surface you compile against.
npm install @nimbus-dev/sdk # or: bun add @nimbus-dev/sdk
Scaffold a connector that performs the contract-version handshake and then serves MCP tools over the same two streams. Full walkthrough: quickstart-typescript.md (or quickstart-python.md).
npm create @nimbus-dev/connector@latest weather-connector
Usage: npx @nimbus-dev/create-connector@latest <name> [--lang ts|python] [--dir <path>]
<name> lowercase kebab-case, starting with a letter (e.g. weather-connector)
--lang ts (default) or python
--dir where to write it (default: ./<name>)
<name> has to be an npm package name, a Python module name, and a directory name at
once, so the CLI takes the intersection of all three: lowercase kebab-case starting with
a letter. my_connector, MyConnector and 2fa-connector are refused rather than
quietly rewritten. Then:
cd ~/src/weather-connector
npm install
npm test # typechecks, builds, then runs unit + acceptance tests
npm start # node dist/main.js
You get ten files, five of them source. manifest.ts is the contract the gateway reads:
import type { ExtensionManifest } from "@nimbus-dev/sdk";
export const manifest: ExtensionManifest = {
id: "nimbus-quickstart-connector",
displayName: "Nimbus Quickstart Connector",
version: "0.1.0",
description: "A Nimbus connector that echoes what it is given.",
author: "you",
entrypoint: "./dist/main.js",
runtime: "node",
permissions: ["read"],
hitlRequired: [],
// …
contractVersions: ["1"],
minNimbusVersion: "0.1.0",
};
export const TOOLS = [{ name: "echo", description: "Echoes its input" }] as const;
handlers.ts holds your logic and imports no protocol. main.ts is the only file that
knows a protocol exists — it handshakes, then serves MCP over what the handshake did not
consume. It is shown here as plain text, not as a checked snippet: it imports
@modelcontextprotocol/sdk and zod, which this dependency-free repository does not
install, so nothing here could compile it. The generated project is where it is
typechecked, built and executed, on every CI run.
import { Readable } from "node:stream";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { CONTRACT_HANDSHAKE_EXIT } from "@nimbus-dev/sdk";
import { createRegisterSimpleTool, mcpJsonResult } from "@nimbus-dev/sdk/connector-kit";
import { NdjsonLineReader, performHandshake } from "@nimbus-dev/sdk/ipc";
import { z } from "zod";
import { echo } from "./handlers.js";
import { manifest, TOOLS } from "./manifest.js";
// …
async function run(): Promise<void> {
const reader = new NdjsonLineReader();
const result = await performHandshake(
{
read: readChunk,
write: async (chunk) => {
process.stdout.write(chunk);
},
},
{ localVersions: manifest.contractVersions ?? ["1"], reader },
);
if (!result.ok) {
process.stderr.write(`handshake refused: ${result.reason}\n`);
process.exitCode = CONTRACT_HANDSHAKE_EXIT;
// Release stdin so the process can exit on its own. `process.exit()` here would risk
// truncating the hello we just wrote to a pipe.
await stdinChunks.return?.(undefined);
return;
}
// …
const replay = Readable.from(
(async function* stream(): AsyncGenerator<Uint8Array> {
for (const frame of result.pending) {
yield frameOf(frame);
}
for (;;) {
const next = await stdinChunks.next();
if (next.done === true) {
break;
}
for (const frame of reader.push(new Uint8Array(next.value))) {
yield frameOf(frame);
}
}
for (const frame of reader.flushFrames().frames) {
yield frameOf(frame);
}
})(),
{ objectMode: false },
);
await connectTransport(createMcpServer(), replay);
}
The transport is deliberately not given process.stdin. Both peers announce
unprompted, so the gateway's hello and its first MCP request routinely arrive in one
read: performHandshake returns the complete frames it read past the hello as
result.pending, and leaves a half-written one inside the NdjsonLineReader it was
given. Serving on raw stdin drops both, silently. The generated main.test.ts guards
each half with its own test — keep them.
exports map)@nimbus-dev/sdk — the main contract: NimbusExtensionServer, the plugin
API types, ExtensionManifest / NimbusItem, HITL requests, distribution-channel
resolution, the scoped audit logger (its free-form payload is @deprecated in favor
of @nimbus-dev/sdk/diagnostics below), iCalendar + JMAP helpers, and the
crypto / data-profile / agents helper modules.@nimbus-dev/sdk/testing — MockGateway + contract-test / sandbox-probe
utilities for connector test suites.@nimbus-dev/sdk/ipc — the NDJSON line-reader + IPC framing helpers.@nimbus-dev/sdk/connector-kit — helpers for hand-rolled MCP connectors:
createRegisterSimpleTool / registerZodTool for Zod-validated tool registration,
mcpJsonResult and friends for MCP tool results, and makeRestFetcher — a Bearer-auth
JSON fetcher with origin-locked URL resolution. Still dependency-free: ZodObjectSchema
is a structural type, not an import of zod. This is the entry point the generated
main.ts above imports from.@nimbus-dev/sdk/diagnostics — the diagnostics / telemetry contract v0:
encodeDiagnostic / parseDiagnostic / isDiagnosticEvent / meetsLevel, the
closed DiagnosticEvent envelope, and createEmitter for building a sink-backed
DiagnosticEmitter. Validated rather than trusted — a fields member holds only
numbers and booleans, so there is nowhere in a fields value for a secret or a row
of user data to go. That guarantee covers fields, not every string on the
envelope: extensionId, event, and error.code are still caller-controlled
strings this contract does not length-bound (spec §8). The redaction-safe
replacement for the scoped audit logger's free-form payload above.Changing an exported type is a semver-relevant change.
ExtensionManifest / NimbusItem and the language-neutral
conformance fixtures every binding validates against.See CONTRIBUTING.md.
In short: Bun v1.2+, TypeScript strict,
Biome, no any, and no runtime dependencies — the published surface stays
dependency-free.
MIT © Nimbus Contributors
FAQs
[](https://www.npmjs.com/package/@nimbus-dev/sdk) [](./LICENSE)
The npm package @nimbus-dev/sdk receives a total of 1,948 weekly downloads. As such, @nimbus-dev/sdk popularity was classified as popular.
We found that @nimbus-dev/sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Product
Enterprise security teams can now detect malware, credential theft, suspicious network activity, and risky updates across Microsoft Edge extensions.

Research
/Security News
Socket researchers found 18 Chrome extensions and one Edge extension delivering a wallet drainer, credential theft, and other malicious payloads.

Product
Create ClickUp tasks from Socket alerts, automate ticketing with custom rules, and keep alert and task status synchronized.