Library Registration

When embedding Scriptling in a Go application, you control which libraries are available to scripts. Libraries are not loaded unless you explicitly register them.

Standard Libraries

23 built-in libraries available without any configuration.

Register All at Once

import "github.com/paularlott/scriptling/stdlib"

stdlib.RegisterAll(p)

Register Individually

p.RegisterLibrary(stdlib.JSONLibrary)
p.RegisterLibrary(stdlib.MathLibrary)
p.RegisterLibrary(stdlib.ReLibrary)
p.RegisterLibrary(stdlib.TimeLibrary)
Namespace Constant
base64 Base64Library
collections CollectionsLibrary
contextlib ContextlibLibrary
datetime DatetimeLibrary
difflib DifflibLibrary
functools FunctoolsLibrary
hashlib HashlibLibrary
hmac HmacLibrary
html HTMLLibrary
io IOLibrary
itertools ItertoolsLibrary
json JSONLibrary
math MathLibrary
platform PlatformLibrary
random RandomLibrary
re ReLibrary
statistics StatisticsLibrary
string StringLibrary
textwrap TextwrapLibrary
time TimeLibrary
urllib URLLibLibrary
urllib.parse URLParseLibrary
uuid UUIDLibrary

Extended Libraries

These are in the root extlibs package and provide Python-compatible functionality.

Simple Registration

import "github.com/paularlott/scriptling/extlibs"

extlibs.RegisterRequestsLibrary(p)
extlibs.RegisterYAMLLibrary(p)
extlibs.RegisterTOMLLibrary(p)
extlibs.RegisterSecretsLibrary(p)
extlibs.RegisterSubprocessLibrary(p)
extlibs.RegisterHTMLParserLibrary(p)
extlibs.RegisterShlexLibrary(p)
Namespace Function
requests RegisterRequestsLibrary(p)
yaml RegisterYAMLLibrary(p)
toml RegisterTOMLLibrary(p)
secrets RegisterSecretsLibrary(p)
subprocess RegisterSubprocessLibrary(p)
html.parser RegisterHTMLParserLibrary(p)
shlex RegisterShlexLibrary(p)
scriptling.csv RegisterCsvLibrary(p)
scriptling.xml RegisterXmlLibrary(p)

Filesystem Libraries

These accept allowedPaths to restrict filesystem access. Pass nil for unrestricted access.

extlibs.RegisterOSLibrary(p, []string{"/tmp", "/data"})
extlibs.RegisterPathlibLibrary(p, []string{"/tmp", "/data"})
extlibs.RegisterFSLibrary(p, []string{"/tmp", "/data"})
extlibs.RegisterGlobLibrary(p, []string{"/tmp", "/data"})
extlibs.RegisterTempfileLibrary(p, []string{"/tmp"})
extlibs.RegisterShutilLibrary(p, []string{"/tmp", "/data"})
extlibs.RegisterZipfileLibrary(p, []string{"/tmp", "/data"})
extlibs.RegisterTarfileLibrary(p, []string{"/tmp", "/data"})
extlibs.RegisterGrepLibrary(p, []string{"/tmp"})
extlibs.RegisterFindLibrary(p, []string{"/tmp"})
extlibs.RegisterSedLibrary(p, []string{"/tmp"})
Namespace Function
os + os.path RegisterOSLibrary(p, allowedPaths)
pathlib RegisterPathlibLibrary(p, allowedPaths)
fs RegisterFSLibrary(p, allowedPaths)
glob RegisterGlobLibrary(p, allowedPaths)
tempfile RegisterTempfileLibrary(p, allowedPaths)
shutil RegisterShutilLibrary(p, allowedPaths)
zipfile RegisterZipfileLibrary(p, allowedPaths)
tarfile RegisterTarfileLibrary(p, allowedPaths)
scriptling.grep RegisterGrepLibrary(p, allowedPaths)
scriptling.find RegisterFindLibrary(p, allowedPaths)
scriptling.sed RegisterSedLibrary(p, allowedPaths)

Custom Configuration

// sys: requires argv and stdin
extlibs.RegisterSysLibrary(p, []string{"script.py"}, os.Stdin)

// logging: requires a logger instance (or use default)
extlibs.RegisterLoggingLibraryDefault(p)
// or with custom logger:
// extlibs.RegisterLoggingLibrary(p, myLogger)

// secrets provider: requires a secret registry
extlibs.RegisterSecretLibrary(p, registry)

// wait_for, websocket, templates
extlibs.RegisterWaitForLibrary(p)
extlibs.RegisterWebSocketLibrary(p)
extlibs.RegisterTemplateHTMLLibrary(p)
extlibs.RegisterTemplateTextLibrary(p)
Namespace Function
sys RegisterSysLibrary(p, argv []string, stdin io.Reader)
logging RegisterLoggingLibrary(p, logger) or RegisterLoggingLibraryDefault(p)
scriptling.secret RegisterSecretLibrary(p, registry *secretprovider.Registry)
scriptling.wait_for RegisterWaitForLibrary(p)
scriptling.net.websocket RegisterWebSocketLibrary(p)
scriptling.template.html RegisterTemplateHTMLLibrary(p)
scriptling.template.text RegisterTemplateTextLibrary(p)

Runtime Libraries

Background tasks, HTTP routing, JSON-RPC, key-value store, concurrency, and sandboxing.

// Register http, kv, sync, sandbox, jsonrpc, and mcp at once (not plugin, see below)
extlibs.RegisterRuntimeLibraryAll(p, []string{"/tmp"})

// Or register individually
extlibs.RegisterRuntimeLibrary(p)          // scriptling.runtime (background tasks)
extlibs.RegisterRuntimeHTTPLibrary(p)      // scriptling.runtime.http
extlibs.RegisterRuntimeJSONRPCLibrary(p)   // scriptling.runtime.jsonrpc
extlibs.RegisterRuntimeMCPLibrary(p)       // scriptling.runtime.mcp
extlibs.RegisterRuntimeKVLibrary(p)        // scriptling.runtime.kv
extlibs.RegisterRuntimeSyncLibrary(p)      // scriptling.runtime.sync
extlibs.RegisterRuntimeSandboxLibrary(p, []string{"/tmp"})  // scriptling.runtime.sandbox
Namespace Function
scriptling.runtime RegisterRuntimeLibrary(p)
scriptling.runtime.http, .kv, .sync, .sandbox, .jsonrpc, .mcp RegisterRuntimeLibraryAll(p, allowedPaths)
scriptling.runtime.http RegisterRuntimeHTTPLibrary(p)
scriptling.runtime.jsonrpc RegisterRuntimeJSONRPCLibrary(p)
scriptling.runtime.mcp RegisterRuntimeMCPLibrary(p)
scriptling.runtime.kv RegisterRuntimeKVLibrary(p) or RegisterRuntimeKVLibraryWithSecurity(p, allowedPaths)
scriptling.runtime.sync RegisterRuntimeSyncLibrary(p)
scriptling.runtime.sandbox RegisterRuntimeSandboxLibrary(p, allowedPaths)

scriptling.runtime.plugin is registered separately and is not included in RegisterRuntimeLibraryAll. Register it when the embedded application needs to expose a Scriptling script as a plugin server:

extlibs.RegisterRuntimePluginLibrary(p)  // scriptling.runtime.plugin
Namespace Function
scriptling.runtime.plugin RegisterRuntimePluginLibrary(p)

Scriptling-Specific Libraries

These live in subpackages under extlibs/ and each expose a Register function.

AI & Agent

import (
    "github.com/paularlott/scriptling/extlibs/ai"
    "github.com/paularlott/scriptling/extlibs/agent"
    aimemory "github.com/paularlott/scriptling/extlibs/ai/memory"
    aitools "github.com/paularlott/scriptling/extlibs/ai/tools"
)

ai.Register(p)                  // scriptling.ai
agent.Register(p)               // scriptling.ai.agent (returns error)
agent.RegisterInteract(p)       // scriptling.ai.agent.interact (returns error)
aimemory.Register(p)            // scriptling.ai.memory
aitools.Register(p)             // scriptling.ai.tools
Namespace Import Path Call
scriptling.ai extlibs/ai ai.Register(p)
scriptling.ai.agent extlibs/agent agent.Register(p)
scriptling.ai.agent.interact extlibs/agent agent.RegisterInteract(p)
scriptling.ai.memory extlibs/ai/memory memory.Register(p)
scriptling.ai.tools extlibs/ai/tools tools.Register(p)

MCP Protocol & TOON

import "github.com/paularlott/scriptling/extlibs/mcp"

mcp.Register(p)             // scriptling.mcp
mcp.RegisterToolHelpers(p)  // scriptling.mcp.tool
mcp.RegisterToon(p)         // scriptling.toon
Namespace Call
scriptling.mcp mcp.Register(p)
scriptling.mcp.tool mcp.RegisterToolHelpers(p)
scriptling.toon mcp.RegisterToon(p)

Networking

import (
    "github.com/paularlott/scriptling/extlibs/net/resolve"
    "github.com/paularlott/scriptling/extlibs/net/multicast"
    "github.com/paularlott/scriptling/extlibs/net/unicast"
    "github.com/paularlott/scriptling/extlibs/net/gossip"
)

resolve.Register(p, myResolver) // scriptling.net.resolve (requires a Resolver implementation)
multicast.Register(p)       // scriptling.net.multicast
unicast.Register(p)         // scriptling.net.unicast
gossip.Register(p, nil)     // scriptling.net.gossip (nil = null logger)
Namespace Import Path Call
scriptling.net.resolve extlibs/net/resolve resolve.Register(p, resolver)
scriptling.net.multicast extlibs/net/multicast multicast.Register(p)
scriptling.net.unicast extlibs/net/unicast unicast.Register(p)
scriptling.net.gossip extlibs/net/gossip gossip.Register(p, logger)

Network Policy

The outbound networking libraries — requests, scriptling.wait_for, and scriptling.net.websocket — accept an optional *netsecurity.Config that restricts where scripts may connect. Pass nil (or omit the argument) for no restrictions; a non-nil policy blocks loopback, link-local (cloud metadata), private, unspecified, and multicast addresses, and IP-literal URLs, by default.

import "github.com/paularlott/scriptling/extlibs/netsecurity"

policy := &netsecurity.Config{
    RequireHTTPS: true,
    AllowHosts:   []string{"api.example.com"},
}

extlibs.RegisterRequestsLibrary(p, policy)
extlibs.RegisterWaitForLibrary(p, policy)
extlibs.RegisterWebSocketLibrary(p, policy)

// Or load the same TOML file the CLI's --network-policy flag uses
policy, err := netsecurity.LoadConfig("policy.toml")
if err != nil {
    return err // invalid policies are an error, never an open policy
}

Config options (all optional — the zero value plus a non-nil pointer is a safe default policy):

Option Type Default Meaning
RequireHTTPS bool false Reject plain http:// and ws:// URLs
AllowIPLiterals bool false Permit URLs that name an IP directly; granted addresses still face the address rules
AllowLoopback bool false Permit 127.0.0.0/8 and ::1
AllowPrivateIPs bool false Permit RFC1918 and IPv6 unique-local ranges
AllowHosts []string nil Host allowlist; when set, only these hosts may be contacted. Listed hosts are trusted — they may resolve to internal addresses. Exact names match themselves; a leading dot (.corp.example.com) matches the domain and all subdomains
DenyHosts []string nil Host denylist; always wins, even over AllowHosts. Same syntax
AllowedCIDRs []string nil Address ranges permitted explicitly, overriding the built-in blocks (how you grant one slice of a LAN)
DeniedCIDRs []string nil Address ranges blocked explicitly; wins over everything, including AllowedCIDRs
DNSServers []string nil Resolve through these servers ("1.1.1.1" or "8.8.8.8:53", plain DNS) instead of the host resolver; the same resolver then serves scriptling.net.resolve too
AllowAll bool false Host-use only (not settable from policy files): disable every address and host check, leaving only the shared DNS resolver — the way to configure nameservers without imposing a policy
ClientTimeout time.Duration 0 Optional end-to-end cap on each HTTP request — dial, TLS, redirects, reading the body — for the client the guard hands to script libraries. 0 enforces no cap: requests run as long as their own per-request timeout allows, which long-running calls such as LLM APIs need. Policy files set it as client_timeout = "45s"

An invalid config (bad CIDR, malformed DNS server) fails netsecurity.NewGuard / LoadConfig with an error — treat it as a startup failure. netsecurity.FailClosed(err) returns a guard that rejects every request if you need to keep serving after a config error.

Messaging

import (
    "github.com/paularlott/scriptling/extlibs/messaging/console"
    "github.com/paularlott/scriptling/extlibs/messaging/telegram"
    "github.com/paularlott/scriptling/extlibs/messaging/discord"
    "github.com/paularlott/scriptling/extlibs/messaging/slack"
)

console.Register(p)          // scriptling.messaging.console
telegram.Register(p, nil)   // scriptling.messaging.telegram
discord.Register(p, nil)    // scriptling.messaging.discord
slack.Register(p, nil)      // scriptling.messaging.slack
Namespace Import Path Call
scriptling.messaging.console extlibs/messaging/console console.Register(p)
scriptling.messaging.telegram extlibs/messaging/telegram telegram.Register(p, logger)
scriptling.messaging.discord extlibs/messaging/discord discord.Register(p, logger)
scriptling.messaging.slack extlibs/messaging/slack slack.Register(p, logger)

Utilities

import (
    "github.com/paularlott/scriptling/extlibs/console"
    "github.com/paularlott/scriptling/extlibs/container"
    "github.com/paularlott/scriptling/extlibs/nomad"
    "github.com/paularlott/scriptling/extlibs/similarity"
    "github.com/paularlott/scriptling/extlibs/provision/fetch"
    "github.com/paularlott/scriptling/extlibs/provision/file"
)

console.Register(p)                        // scriptling.console
container.Register(p, "", "")              // scriptling.container (empty = default sockets)
nomad.Register(p)                          // scriptling.nomad
similarity.Register(p)                     // scriptling.similarity
file.Register(p)                           // scriptling.provision.file
fetch.Register(p)                          // scriptling.provision.fetch
extlibs.RegisterMarkdownLibrary(p)         // scriptling.markdown
Namespace Import Path Call
scriptling.console extlibs/console console.Register(p)
scriptling.container extlibs/container container.Register(p, dockerSock, podmanSock)
scriptling.nomad extlibs/nomad nomad.Register(p)
scriptling.similarity extlibs/similarity similarity.Register(p)
scriptling.provision.file extlibs/provision/file file.Register(p)
scriptling.provision.fetch extlibs/provision/fetch fetch.Register(p)
scriptling.markdown root extlibs extlibs.RegisterMarkdownLibrary(p)

Executable Plugins

scriptling.plugin (the control library for executable plugins, listing/calling/loading them at runtime) lives in the root plugin package, not extlibs, and needs a *plugin.Manager rather than just the interpreter:

import (
    "github.com/paularlott/scriptling/plugin"
)

manager := plugin.NewManager(myLogger, func(name string, err error) {
    myLogger.Error("plugin process exited", "plugin", name, "error", err)
})
manager.AddDir("./plugins")
if err := manager.Load(ctx); err != nil {
    // handle error
}

plugin.RegisterLibraries(p, manager)  // scriptling.plugin, plus plugin.<name> for each loaded executable
Namespace Import Path Call
scriptling.plugin plugin plugin.RegisterLibraries(p, manager)

See Plugins for the full plugin embedding guide.

Security Considerations

When embedding Scriptling, you have full control over what scripts can access. See the Security Guide for best practices.

Never register these libraries when running untrusted code:

  • subprocess: allows arbitrary command execution
  • sys: provides access to environment variables and system internals
  • scriptling.container: controls Docker/Podman containers on the host
  • scriptling.nomad: grants full control over a Nomad cluster (CSI volumes, jobs)
  • scriptling.runtime.sandbox: can execute arbitrary code
  • scriptling.ai.agent: can execute AI-generated code with tools

See Also

  • Basics: creating interpreters and exchanging variables
  • Security Guide: security best practices for embedding
  • Libraries: usage reference for all libraries

Database Drivers in Embedded Hosts

Scriptling is the library; your application is the host, and the database drivers are optional at every level — you may compile them in, load them as external plugin binaries, or have neither. One call covers all three cases:

import scriptlingplugin "github.com/paularlott/scriptling/plugin"

// On every interpreter your host spins up — main instances, HTTP request
// environments, MCP sessions, sandbox/background factories:
scriptlingplugin.RegisterLibraries(p, pluginManager, scriptlingplugin.PolicyFromSecurity(netPolicy, allowedPaths))
  • Compiled in (build tags plugin_sqlite / plugin_sql / plugin_valkey / plugin_badgerdb, or import the plugin packages and call sqlite.RegisterInProcess(p, policy)): registers regardless of the manager — a nil pluginManager is fine.
  • External plugin binaries: pass your *plugin.Manager (see Plugin Manager) and the proxy libraries register per instance.
  • Neither: nothing registers; scripts importing scriptling.sqlite fail with a named unknown library error.

The CLI is exactly this pattern — its --plugin-dir handling, exe-relative discovery and per-mode wiring are host choices, not library behaviour. Inside handler scripts, open a connection per run and let the environment’s teardown collect it (Connection closes itself when instances are collected; explicit conn.close() is still good manners).