Fishjam JS Server SDK
software-mansion-labs/skills
Node.js / TypeScript server SDK for Fishjam — backends that create rooms, mint peer tokens, listen to server notifications, and run agents.
A skill your agent uses when building TypeScript RPC with kkrpc stable APIs, choosing native Transport<RPCMessage adapters, or integrating validation, middleware, transferables, streaming, remote…
$ npx skills add kunkunsh/kkrpc --skill kkrpc -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install kunkunsh/kkrpc kkrpc --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/kunkunsh/kkrpc.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/kkrpc .claude/skills/kkrpc && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "kkrpc" agent skill from https://github.com/kunkunsh/kkrpc/tree/main/skills/kkrpc into .claude/skills/kkrpc/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "kkrpc", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/kunkunsh/kkrpc/tree/main/skills/kkrpcType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add kunkunsh/kkrpc --skill kkrpc -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install kunkunsh/kkrpc kkrpc --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kunkunsh/kkrpc.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/kkrpc .agents/skills/kkrpc && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "kkrpc" agent skill from https://github.com/kunkunsh/kkrpc/tree/main/skills/kkrpc into .agents/skills/kkrpc/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "kkrpc", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add kunkunsh/kkrpc --skill kkrpc -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install kunkunsh/kkrpc kkrpc --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kunkunsh/kkrpc.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/kkrpc .cursor/skills/kkrpc && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "kkrpc" agent skill from https://github.com/kunkunsh/kkrpc/tree/main/skills/kkrpc into .cursor/skills/kkrpc/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "kkrpc", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/kunkunsh/kkrpc.git --path skills/kkrpc--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add kunkunsh/kkrpc --skill kkrpc -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install kunkunsh/kkrpc kkrpc --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kunkunsh/kkrpc.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/kkrpc .gemini/skills/kkrpc && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "kkrpc" agent skill from https://github.com/kunkunsh/kkrpc/tree/main/skills/kkrpc into .gemini/skills/kkrpc/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "kkrpc", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install kunkunsh/kkrpc kkrpcInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add kunkunsh/kkrpc --skill kkrpc -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/kunkunsh/kkrpc.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/kkrpc .github/skills/kkrpc && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "kkrpc" agent skill from https://github.com/kunkunsh/kkrpc/tree/main/skills/kkrpc into .github/skills/kkrpc/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "kkrpc", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add kunkunsh/kkrpc --skill kkrpc -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install kunkunsh/kkrpc kkrpc --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kunkunsh/kkrpc.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/kkrpc .opencode/skills/kkrpc && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "kkrpc" agent skill from https://github.com/kunkunsh/kkrpc/tree/main/skills/kkrpc into .opencode/skills/kkrpc/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "kkrpc", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
kkrpcA skill your agent uses when building TypeScript RPC with kkrpc stable APIs, choosing native Transport<RPCMessage adapters, or integrating validation, middleware, transferables, streaming, remote…
Kkrpc is an agent skill from kunkunsh/kkrpc. Use when building TypeScript RPC with kkrpc stable APIs, choosing native Transport<RPCMessage adapters, or integrating validation, middleware, transferables, streaming, remote references, relay, or inspector tooling.
Its SKILL.md is about 3.1k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts. Compatibility notes: Works in Node.js, Deno, Bun, browsers, Electron, Tauri, Chrome extensions, and queue-backed runtimes with the correct stable entry point and transport.
It sits in Backend & APIs, covering Realtime and WebSockets. It works with TypeScript, Hono and Chrome Extensions. The repository describes itself as: A TypeScript RPC protocol for multiple environments (iframe, web worker, stdio, http, WebSocket). The licence is MIT.
4 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit e558873. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are typescript).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Works in Node.js, Deno, Bun, browsers, Electron, Tauri, Chrome extensions, and queue-backed runtimes with the correct stable entry point and transport.
From compatibility in the SKILL.md frontmatter.
Kkrpc loads about 3.1k tokens when it runs. Until then it costs about 56 tokens; SKILL.md has 618 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from kunkunsh/kkrpc at commit e558873, republished under its MIT licence (© kunkunsh). 618 words, ~3,058 tokens.
.claude/skills/kkrpc/SKILL.md (or your agent's skills folder).Use kkrpc to expose a local TypeScript object and call the remote side as a typed proxy. The stable API is native Transport<RPCMessage> based. Start with the small default kkrpc entry, then opt into kkrpc/streaming or kkrpc/remote-refs only when the API needs those features.
import { expose, wrap } from "kkrpc"
const controller = expose(localAPI, serverTransport)
const remote = wrap<RemoteAPI>(clientTransport)
controller.dispose()Use low-level RPCChannel when both sides expose APIs or when you need explicit channel ownership:
import { RPCChannel } from "kkrpc"
const channel = new RPCChannel<LocalAPI, RemoteAPI>(transport, { expose: localAPI })
const remote = channel.getAPI()| Runtime or feature | Import path | Notes |
|---|---|---|
| Core | kkrpc | Browser-safe wrap, expose, RPCChannel, protocol and transport types |
| Browser core | kkrpc/browser | Explicit browser entry when package conditions are not enough |
| Worker | kkrpc/worker | workerTransport, workerSelfTransport |
| stdio | kkrpc/stdio | Native JSON-line stdio transports |
| HTTP | kkrpc/http | HTTP client and handler helpers |
| WebSocket | kkrpc/ws | WebSocket client/server transports |
| Hono WebSocket | kkrpc/ws/hono | Optional hono peer |
| Elysia WebSocket | kkrpc/ws/elysia | Optional elysia peer |
| iframe | kkrpc/iframe | iframe postMessage transports |
| Chrome extension | kkrpc/chrome-extension | Chrome runtime port transports |
| Electron | kkrpc/electron | Electron IPC and utility process transports |
| Tauri | kkrpc/tauri | Tauri shell plugin transport |
| Validation | kkrpc/validation | Standard Schema validation plugin |
| Middleware | kkrpc/middleware | Interceptor middleware plugin |
| SuperJSON | kkrpc/superjson | SuperJSON codecs |
| Streaming | kkrpc/streaming | Async iterable arguments/results with pull-based backpressure |
| Remote refs | kkrpc/remote-refs | Explicit proxy(value) references, callback return values, object handles, releaseProxy() |
| Relay | kkrpc/relay | Transport-to-transport relay helper |
| Inspector | kkrpc/inspector | Native plugin/event traffic logging |
| Queues | kkrpc/rabbitmq, kkrpc/kafka, kkrpc/redis-streams, kkrpc/nats | Optional peer dependencies; set remotePeerId for point-to-point streaming or remote refs |
Prefer explicit local and remote API types. In bidirectional RPC, each side can expose its own API and call the other side.
type ServerAPI = {
math: {
add(a: number, b: number): Promise<number>
}
version(): Promise<string>
}
type ClientAPI = {
notify(message: string): Promise<void>
}
const clientAPI: ClientAPI = {
async notify(message) {
console.log(message)
}
}
const channel = new RPCChannel<ClientAPI, ServerAPI>(transport, { expose: clientAPI })
const server = channel.getAPI()
console.log(await server.math.add(1, 2))Remote property access is supported:
const counter = await api.counter
const nested = await api.nested.deepObj.propTop-level callbacks can be passed as arguments for fire-and-forget progress notifications:
await api.process("input", (progress) => {
console.log("progress", progress)
})Default callbacks do not propagate return values or thrown errors. Use kkrpc/remote-refs and proxy(callback) when the remote side must await the callback result.
kkrpc/remote-refs is explicit: unmarked function values are rejected rather than passed by raw object identity. Wrap each callback, returned function leaf, or object handle that should remain remote with proxy(value).
Remote proxies are channel-scoped. Do not pass a remote proxy decoded from one RPCChannel through a different channel; expose an explicit bridge method if that is truly required.
import { expose, wrap } from "kkrpc/streaming"
type LogAPI = {
tail(service: string): AsyncIterable<string>
}
for await (const line of wrap<LogAPI>(transport).tail("api")) {
console.log(line)
}import { proxy, releaseProxy, wrap } from "kkrpc/remote-refs"
const result = await wrap<RemoteAPI>(transport).useCallback(
proxy(async (value) => `callback:${value}`)
)
const counter = await wrap<RemoteAPI>(transport).createCounter()
await releaseProxy(counter)Parent side:
import { wrap } from "kkrpc"
import { workerTransport } from "kkrpc/worker"
const worker = new Worker(new URL("./worker.ts", import.meta.url), { type: "module" })
const api = wrap<WorkerAPI>(workerTransport(worker))
console.log(await api.ping())Worker side:
import { expose } from "kkrpc"
import { workerSelfTransport } from "kkrpc/worker"
expose(
{
async ping() {
return "pong"
}
},
workerSelfTransport()
)import { wrap } from "kkrpc"
import { webSocketClientTransport } from "kkrpc/ws"
const api = wrap<RemoteAPI>(webSocketClientTransport("ws://localhost:3000/rpc"))import { expose, wrap } from "kkrpc"
import { validationPlugin } from "kkrpc/validation"
const plugins = [validationPlugin(validators)]
const controller = expose(localAPI, serverTransport, { plugins })
const remote = wrap<RemoteAPI>(clientTransport, { plugins })import { middlewarePlugin } from "kkrpc/middleware"
const plugins = [
middlewarePlugin([
async (ctx, next) => {
console.log(ctx.method)
return next()
}
])
]Use kkrpc/superjson only when the application needs SuperJSON value support. Do not import it from the main kkrpc entry.
import { superJsonCodec } from "kkrpc/superjson"
import { createTransport } from "kkrpc/transport"
const transport = createTransport({ platform, codec: superJsonCodec() })import { createInspector, MemoryBackend } from "kkrpc/inspector"
const memory = new MemoryBackend()
const inspector = createInspector({ backends: [memory], options: { trackLatency: true } })
const channel = new RPCChannel<LocalAPI, RemoteAPI>(transport, {
expose: localAPI,
plugins: [inspector.plugin("server")]
})import { relayTransport } from "kkrpc/relay"
const relay = relayTransport(leftTransport, rightTransport)
relay.dispose()kkrpc instead of old experimental native entry paths.kkrpc entry.| Pitfall | Fix |
|---|---|
Importing optional transport peers from kkrpc | Import from the specific subpath, such as kkrpc/ws or kkrpc/electron |
| Pulling SuperJSON into every browser bundle | Import codecs from kkrpc/superjson only where needed |
Expecting async iterables from kkrpc | Import wrap/expose/RPCChannel from kkrpc/streaming on both sides |
| Expecting callback return values from default callbacks | Import from kkrpc/remote-refs and pass proxy(callback) |
| Returning unmarked nested functions as remote handles | Wrap the function leaf with proxy(fn) in kkrpc/remote-refs; unmarked functions are rejected |
| Using remote refs over broadcast message buses | Configure a point-to-point bus transport with remotePeerId |
| Passing a remote proxy through another channel | Keep remote proxies on the channel that decoded them, or build an explicit bridge |
| Forgetting to dispose channels | Keep the controller/channel and call dispose() or destroy() |
| Using old blocking IO adapter names | Use native transport factories that return Transport<RPCMessage> |
| Treating validation as core behavior | Add validationPlugin() explicitly through channel options |
© kunkunsh, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in skills/kkrpc of kunkunsh/kkrpc.
Open the folder on GitHubat commit e558873
Kkrpc next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Kkrpc this skillkunkunsh/kkrpc | 174 | — | ~3.1k | Automated safety check: Pass | MIT | |
| Fishjam JS Server SDKsoftware-mansion-labs/skills | 291 | — | ~1.4k | Automated safety check: Pass | MIT | |
| HonoEpicenterHQ/epicenter | 4.8k | — | ~513 | Automated safety check: Pass | Custom licence | |
| Gemini Live API Devgoogle-gemini/gemini-skills | 4.3k | — | ~4.6k | Automated safety check: Pass | Apache-2.0 | |
| Trigger.dev Realtimepapermark/papermark | 9.2k | — | ~1.7k | Automated safety check: Pass | Custom licence | |
| Web3 PolymarketPolymarket/agent-skills | 191 | 1 repos | ~2k | Automated safety check: Pass | None |
software-mansion-labs/skills
Node.js / TypeScript server SDK for Fishjam — backends that create rooms, mint peer tokens, listen to server notifications, and run agents.
EpicenterHQ/epicenter
Hono patterns for TypeScript API routes, middleware, request and response typing, streaming, WebSockets, and Cloudflare Workers deployment.
google-gemini/gemini-skills
A skill your agent uses when building real-time, bidirectional streaming applications with the Gemini Live API, or migrating legacy Live models (2.0/2.5/3.1) to Gemini 3.8 Live.
papermark/papermark
Shows how to subscribe to Trigger.dev task runs from the backend and from React for progress indicators, live dashboards, AI response streams and approval waits.
Polymarket/agent-skills
Polymarket integration for prediction market trading on Polygon.
0xSero/parchi
Use Parchi Relay to control a real browser via the Parchi extension agent (WebSocket) or directly via JSON-RPC from a CLI/tooling workflow.
kunkunsh/kkrpc
A skill your agent uses when implementing kkrpc clients or servers in non-TypeScript languages, speaking the stable compact protocol, transports, and reference implementations in Go, Python, Rust…
kunkunsh/kkrpc
A skill your agent uses when migrating kkrpc projects across breaking stable API changes, replacing classic IoInterface/IO adapters, next entries, validation/interceptor options, transport imports…
Works with
Categories
A skill your agent uses when building TypeScript RPC with kkrpc stable APIs, choosing native Transport<RPCMessage adapters, or integrating validation, middleware, transferables, streaming, remote…. Kkrpc is an agent skill from kunkunsh/kkrpc. Use when building TypeScript RPC with kkrpc stable APIs, choosing native Transport<RPCMessage adapters, or integrating validation, middleware, transferables, streaming, remote references, relay, or inspector tooling.
Kkrpc fits situations like: building TypeScript RPC with kkrpc stable APIs; choosing native Transport<RPCMessage adapters; integrating validation; remote references.
Run `npx skills add kunkunsh/kkrpc --skill kkrpc -a claude-code`. Or copy the skill folder (skills/kkrpc in kunkunsh/kkrpc) into .claude/skills/kkrpc in your project. Claude Code loads it when a task matches its description.
Run `npx skills add kunkunsh/kkrpc --skill kkrpc -a codex`. Or copy the skill folder (skills/kkrpc in kunkunsh/kkrpc) into .agents/skills/kkrpc in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add kunkunsh/kkrpc --skill kkrpc -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/kkrpc, .gemini/skills/kkrpc, .github/skills/kkrpc and .opencode/skills/kkrpc in your project.
SKILL.md names no scripts, command-line tools or credentials: Kkrpc is instructions for the agent only. Our summary lists: Node.js. Compatibility (from SKILL.md): Works in Node.js, Deno, Bun, browsers, Electron, Tauri, Chrome extensions, and queue-backed runtimes with the correct stable entry point and transport..
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Kkrpc is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.1k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Kkrpc: Fishjam JS Server SDK (software-mansion-labs/skills, 291 stars), Hono (EpicenterHQ/epicenter, 4.8k stars), Gemini Live API Dev (google-gemini/gemini-skills, 4.3k stars) and Trigger.dev Realtime (papermark/papermark, 9.2k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
kunkunsh (a GitHub organization) maintains it in kunkunsh/kkrpc, which has 174 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on September 11, 2026.
Source: kunkunsh/kkrpc on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.