Synoema Packages
Discover and share reusable .sno libraries
From LLM prompt to working package in one command. Install community libraries, publish your own, and let the MCP server auto-suggest what to add during AI code generation.
First-Party Packages
Synoema ships with bundled packages maintained in the core repository. They are available immediately via sno pkg run — no installation required. They are also publishable to the registry for import in your own code.
sno-http — HTTP / HTTPS Server
A full HTTP/HTTPS server library and standalone binary in one package.
As a library — import into your .sno code:
sno pkg add sno-http
import "sno-http"
use Http (http_serve, http_router, http_get_route, http_json)
let routes = http_router [
http_get_route "/" (\_ -> http_json "{\"ok\":true}")
]
let _ = http_serve 8080 routes
As a standalone binary — run it directly, no code required:
sno pkg run sno-http -- --port 8080
sno pkg run sno-http -- --port 8443 --cert cert.pem --key key.pem
Configurable via environment variables: SNO_PORT, SNO_TLS_CERT, SNO_TLS_KEY.
Dual-Mode Packages
A Synoema package can act as both an importable library and a standalone executable server. Declare both main (library entry) and bin (binary entry) in sno.toml:
[package]
name = "sno-http"
version = "0.1.0"
main = "lib.sno" # library mode: import "sno-http"
bin = "server.sno" # standalone mode: sno pkg run sno-http
The two modes are completely independent. Users can install and import the library, run the binary directly, or do both — based on their use case:
| Mode | Command | Use case |
|---|---|---|
| Library | import "sno-http" | Embed HTTP serving in your .sno app |
| Standalone | sno pkg run sno-http -- --port 8080 | Drop-in HTTP server, no .sno code needed |
Arguments after -- are passed to the package's binary entry point. If a package has no bin field, sno pkg run prints a clear error.
Using Packages
Four steps from discovery to running code. No build system configuration, no dependency hell — the Synoema runtime resolves and loads packages automatically.
Step 1 — Search
Find packages by name, keyword, or description:
sno pkg search "json"
Or browse the full registry at synoema.tech/pkg.
Step 2 — Install
Add a package to your project. Semver ranges, local paths, and URLs all work:
sno pkg add json
sno pkg add json@2.0
sno pkg add ./my-lib
sno pkg add https://synoema.tech/pkg/json/2.1.0/download
The package is recorded in your project's sno.toml under [dependencies].
Step 3 — Import in .sno
Use the package in your source file:
import "json"
use Json (parseJson, formatJson)
main =
let result = parseJson "{\"key\": 42}"
result
The use declaration brings specific names into scope. The compiler verifies all types at import time.
Step 4 — Manage
List installed packages, remove one you no longer need, or run a standalone binary:
sno pkg list
sno pkg remove json
sno pkg run sno-http -- --port 8080
Publishing a Package
Publishing is four steps: write a manifest, get an API key via GitHub, log in, and publish. No account form, no email verification — GitHub identity is the auth.
Step 1 — Create sno.toml
Add a sno.toml manifest at the root of your library:
[package]
name = "my-lib" # kebab-case identifier
version = "1.0.0" # semver
description = "My Synoema library"
license = "MIT"
authors = ["Your Name <you@example.com>"]
keywords = ["utilities"] # for search
categories = ["general"] # taxonomy
main = "lib.sno" # entry point file
[lang]
min_version = "0.8.0" # minimum Synoema version
[dependencies]
# other sno packages (optional)
Step 2 — Get an API Key
Visit synoema.tech/pkg and click Sign in with GitHub. After OAuth completes, the page displays your API key of the form sno_pkg_.... Copy it.
Step 3 — Log In
Store the key in your local Synoema config:
sno pkg login --key "sno_pkg_..."
The key is saved to ~/.sno/config.toml and used automatically for all publish operations.
Step 4 — Publish
From your project root:
sno publish
The CLI validates sno.toml, packages your source into a .tar.gz, and uploads it to the registry. Once published, the version is immutable — republishing the same version returns an error.
MCP / AI Agents
When an LLM agent writes Synoema code that references an unknown identifier, the MCP server automatically queries the package registry and the bundled first-party package library, then injects a suggestion into retrieval_context:
-- Agent writes:
result = parseJson "{\"key\": 42}"
-- MCP detects unknown identifier parseJson, searches registry + bundled packages, injects:
{
"retrieval_context": {
"packages": [{
"name": "json",
"version": "2.1.0",
"install": "sno pkg add json",
"import_hint": "import \"json\"\nuse Json (parseJson, formatJson)"
}]
}
}
The agent reads the suggestion, runs sno pkg add json as a tool call, and retries — fully automatic when MCP is connected.
Two explicit MCP tools are also available for package discovery:
| Tool | Input | Returns |
|---|---|---|
search_packages | { query, lang_version? } | Registry + installed + bundled packages with name, version, install, import_hint |
suggest_packages | { code } | Same shape — infers query from the code snippet |
Both tools include bundled first-party packages (like sno-http) with source: "bundled" so agents can discover them without a registry round-trip. The same mechanism works with sno fix --with-rag: the ReAct agent's search_corpus action includes package metadata with install commands inline.
Connect the MCP server:
sno setup claude # Claude Desktop
sno setup cursor # Cursor
Registry API
The registry exposes a stable REST API. All GET endpoints are public (no auth). POST /pkg/upload requires an API key. All GET responses include Access-Control-Allow-Origin: * for browser access.
| Method | Path | Description | Auth |
|---|---|---|---|
GET | /pkg | List all packages | None |
GET | /pkg/search?q=<query> | Search packages by name, description, keywords | None |
GET | /pkg/:name | Package info + readme (latest version) | None |
GET | /pkg/:name/:version | Package info for a specific version | None |
GET | /pkg/:name/:version/download | Tarball download (.tar.gz) | None |
POST | /pkg/upload | Publish a package | Authorization: Bearer sno_pkg_... |
Package info JSON schema
All package info endpoints return objects with this shape:
{
"name": "json",
"version": "2.1.0",
"description": "JSON parsing and formatting for Synoema",
"authors": ["Alice <alice@example.com>"],
"keywords": ["json", "parsing"],
"categories": ["serialization"],
"repository": "https://github.com/example/sno-json",
"lang_min": "0.8.0",
"lang_max": "",
"provides": ["parseJson", "formatJson", "JsonValue"],
"downloads": 1423,
"published_at": "2026-04-19T10:00:00Z"
}
All fields are required. repository, lang_max, keywords, categories, and provides may be empty strings or empty arrays.
Browse Packages
Loading packages…
What is not yet available
The following items are deferred to post-v1:
- Registry backend — the server at
synoema.tech/pkgis not yet live. The API contract above is the normative spec the backend will implement.sno pkg addfrom the registry requires this backend. - Private registries — only the public registry is planned for v1.
- Package version management UI — deprecation, yanking, ownership transfer are post-v1.
- Server-side search ranking — v1 is full-text match; relevance ranking is post-v1.
Already shipped: sno pkg add ./path (local), sno pkg add https://... (URL), sno pkg list, sno pkg remove, sno pkg run, sno publish.