Scriptling:面向 Go 的类 Python 沙箱脚本语言,支持 MCP 与 LLM 智能体
paularlott/scriptling
paularlott/scriptling 是一款面向 Go 的类 Python 沙箱解释器,专为 LLM 智能体执行代码和调用 REST API 设计,支持 MCP 集成。
Scriptling - Python-like Scripting Language for Go
A minimal, sandboxed interpreter for LLM agents to execute code and interact with REST APIs. Python-inspired syntax designed for embedding in Go applications.
Features
- Python-like syntax with indentation-based blocks
- Core types: integers, floats, strings, booleans, lists, dictionaries
- Control flow: if/elif/else, while, for loops, break, continue
- Object-oriented: Classes with single inheritance, methods, and constructors
- Advanced features: functions, lambda, list comprehensions, error handling
- Libraries: including json, regex, math, time, requests, subprocess (load on demand)
- Databases: SQLite, MySQL/MariaDB, PostgreSQL, Valkey/Redis and BadgerDB plugins with a shared API and a script-side ORM (query builders, model gateways)
- Plugins: extend with Go, C, PHP or any language speaking JSON-RPC, loaded from disk or http(s)
- Go integration: Register functions, exchange variables
- Fast: Lightweight interpreter, only loads what you need
- Sandboxed: No filesystem or network access unless enabled via libraries
- MCP support: Model Context Protocol for LLM integration
- CLI tool: Run scripts, start HTTP server with MCP support
- Script metadata: Scripts declare their requirements — scriptling version, libraries, plugins — in a PEP 723-style
# /// scriptblock, checked before they run - Extensible: Create custom functions, libraries, and classes in Go or Scriptling
- Linter: Built-in linter for syntax checks
- OpenAPI support: Generate Scriptling client libraries from OpenAPI specs with o2s tool
Differences from Python
While Scriptling is inspired by Python, it has some key differences:
- Single Inheritance Only: Classes support single inheritance (e.g.,
class Dog(Animal):), but not multiple inheritance. - No
async/awaitoryieldgenerators. - Simplified Scope:
nonlocalandglobalkeywords work slightly differently. - Eager
lazy import: PEP 810lazy import x/lazy from x import yis accepted, but the hint is ignored and the module is imported immediately. - Go Integration: Designed primarily for embedding in Go, with direct type mapping.
- Sandboxed: No direct access to filesystem or network unless explicitly enabled via libraries.
Installation
CLI
brew install paularlott/tap/scriptling
The sqlite, sql, valkey and badgerdb database plugins are compiled in.
Prefer a leaner binary without them? scriptling-slim installs the same
CLI with no database drivers — load them at runtime with the
scriptling-plugins formula instead:
brew install paularlott/tap/scriptling-slim brew install paularlott/tap/scriptling-plugins export SCRIPTLING_PLUGIN_DIR="$(brew --prefix)/opt/scriptling-plugins/libexec/plugins" # or pass per run: scriptling --plugin-dir "$(brew --prefix)/opt/scriptling-plugins/libexec/plugins" script.py
Release zips and plugin binaries are on the
releases page — every
zip (default and slim alike) contains the binary named plainly scriptling,
and the plugins zip for your platform
(plugins-linux-arm64.zip and friends) contains all four binaries named
plainly (sqlite, sql, valkey, badgerdb). Unzip it and point
--plugin-dir at the folder, or set SCRIPTLING_PLUGIN_DIR.
Go Library
go get github.com/paularlott/scriptling
Quick Start
package main import ( "fmt" "github.com/paularlott/scriptling" "github.com/paularlott/scriptling/stdlib" ) func main() { // Create interpreter p := scriptling.New() // Register all standard libraries stdlib.RegisterAll(p) // Execute Scriptling code result, err := p.Eval(` # Variables and types x = 42 name = "Alice" numbers = [1, 2, 3] # Functions def greet(n): return "Hello " + n # Output print(greet(name)) print("Sum:", x + len(numbers)) `) if err != nil { fmt.Println("Error:", err) } }
CLI Tool
Scriptling includes a command-line interface for running scripts directly:
# Install Task (build tool) brew install go-task/tap/go-task # Build CLI for current platform task build # Run scripts ./bin/scriptling script.py echo 'print("Hello")' | ./bin/scriptling ./bin/scriptling --interactive # Build for all platforms task build-all
HTTP, MCP, and JSON-RPC Server
The CLI can also run as an HTTP server with MCP (Model Context Protocol) and JSON-RPC support:
# Start HTTP server on port 8000 ./bin/scriptling --server :8000 script.py # With MCP tools for LLM integration ./bin/scriptling --server :8000 --mcp-tools ./tools script.py # With JSON-RPC over HTTP at /json-rpc ./bin/scriptling --server :8000 --json-rpc script.py # MCP and JSON-RPC can run side by side ./bin/scriptling --server :8000 --mcp-tools ./tools --json-rpc script.py # With TLS and authentication ./bin/scriptling --server :8443 --tls-generate --bearer-token secret script.py
See scriptling-cli/README.md for details.
Go API
Basic Usage
import ( "github.com/paularlott/scriptling" "github.com/paularlott/scriptling/libloader" "github.com/paularlott/scriptling/stdlib" ) p := scriptling.New() // Register libraries as needed stdlib.RegisterAll(p) // Register all standard libraries // Or register individual libraries: // p.RegisterLibrary(stdlib.JSONLibraryName, stdlib.JSONLibrary) // p.RegisterLibrary(stdlib.MathLibraryName, stdlib.MathLibrary) // Execute code result, err := p.Eval("x = 5 + 3") // Exchange variables p.SetVar("name", "Alice") value, objErr := p.GetVarAsString("name") // Register Go functions p.RegisterFunc("custom", func(ctx context.Context, kwargs map[string]object.Object, args ...object.Object) object.Object { return object.NewString("result") }) // Register Scriptling functions p.RegisterScriptFunc("my_func", ` def my_func(x): return x * 2 my_func `) // Register Scriptling libraries p.RegisterScriptLibrary("mylib", ` def add(a, b): return a + b PI = 3.14159 `) // Set up library loader for dynamic loading from filesystem // Supports Python-style folder structure: libs/knot/groups.py → import knot.groups loader := libloader.NewFilesystem("/app/libs") p.SetLibraryLoader(loader)
Libraries
import ( "github.com/paularlott/scriptling" "github.com/paularlott/scriptling/stdlib" "github.com/paularlott/scriptling/extlibs" ) // Create interpreter p := scriptling.New() // Register all standard libraries stdlib.RegisterAll(p) // Or register individual standard libraries p.RegisterLibrary(stdlib.JSONLibrary) p.RegisterLibrary(stdlib.MathLibrary) // Register additional custom libraries p.RegisterLibrary(extlibs.RequestsLibrary) // Register os and pathlib with security restrictions extlibs.RegisterOSLibrary(p, []string{"/tmp", "/home/user/data"}) extlibs.RegisterPathlibLibrary(p, []string{"/tmp", "/home/user/data"}) // Import libraries programmatically (no need for import statements in scripts) p.Import("json") // Use in scripts p.Eval(` import requests import os response = requests.get("https://api.example.com/data") data = json.parse(response["body"]) # json already imported via p.Import() files = os.listdir("/tmp") `)
Examples
See examples/ directory:
- scripts/ - Script examples and Go integration
- openai/scriptlingcoder/ - AI coding assistant with custom tools (inspired by nanocode)
- mcp-tools/ - MCP tools for use with CLI MCP server
Run examples:
cd examples/scripts go run main.go test_basics.py # AI coding assistant (⚠️ executes AI-generated code) cd examples/openai/scriptlingcoder ../../../bin/scriptling scriptlingcoder.py
Tools
- o2s - OpenAPI to Scriptling converter. Generate HTTP client libraries from OpenAPI v3 specs
Documentation
Full documentation is available at scriptling.dev
- Quick Start - Get up and running quickly
- Language Guide - Complete syntax reference
- Go Integration - Embedding Scriptling in Go applications
- Libraries - Standard and extended library reference
- CLI Reference - Command-line tool documentation
Testing
# Run all tests go test ./... # Run benchmarks go test -bench=. -run=Benchmark
License
MIT
Contributing
Contributions are welcome! See CONTRIBUTING.md for guidelines.
来源:GitHub · github.com
