Generative AI/UI sandbox for Python
Project description
Belgie: Generative AI/UI Sandbox for Python
Belgie is a sandboxed TypeScript environment for Python that lets you build React MCP Apps and have agents write code in a sandbox.
- MCP Apps: Attach React widgets to Python MCP tools in one project.
- AI agents: Sandboxed
run_codeso Pydantic AI and LangChain can run TypeScript. - Sandbox: Deno is bundled, so you do not need to install Node.js.
Installation
uv add belgie
uvx library-skills install # optional: install the use-belgie skill for Cursor, Codex, Claude, etc.
For MCP Apps, install the MCP and CLI extras:
uv add "belgie[mcp,cli]"
MCP Apps
Skip the second package manager. Attach a React widget to a Python MCP tool.
BelgieExtension starts Vite in the background for development and runs a one-time production build.
from datetime import UTC, datetime
from pathlib import Path
from mcp.server import MCPServer
from belgie.mcp import BelgieExtension
belgie = BelgieExtension(project=".")
@belgie.tool(
widget=Path("src/widgets/get-time/widget.tsx"),
name="get-time",
title="Get Time",
description="Get the current server time in ISO 8601 format.",
)
def get_time() -> dict[str, str]:
return {"time": datetime.now(tz=UTC).isoformat()}
mcp = MCPServer(name="Get Time Server", extensions=[belgie])
The widget is a normal React entry. @belgie/mcp connects the MCP Apps host and surfaces the
opening tool result:
import { Widget, useToolResult } from "@belgie/mcp";
import { getTime } from "@widgets/tools";
function AppView() {
const { data, isLoading, execute } = useToolResult(getTime);
return (
<main>
<p>{data?.time ?? (isLoading ? "Waiting..." : "No time returned.")}</p>
<button onClick={() => void execute()}>Refresh</button>
</main>
);
}
export default function GetTime() {
return (
<Widget metadata={{ name: "Get Time", version: "1.0.0" }}>
<AppView />
</Widget>
);
}
Declare JS deps under [tool.belgie.dependencies], then:
uv run belgie lock
uv run belgie install
# start your MCP server; Belgie starts Vite with widget HMR
Pass build=False to BelgieExtension when Vite is managed separately or production assets are already built.
Runnable projects:
- mcp: Minimal MCP Apps widget.
- shadcn: Same pattern with Tailwind CSS and shadcn/ui.
- tanstack: TanStack Start SPA and MCP widget served together through FastAPI.
AI agents
When an agent needs an npm package, a browser-style API, or a JS-side transform, give it
run_code. Belgie executes the TypeScript or JavaScript in the embedded Deno sandbox. No
separate Node install.
Pydantic AI
Install with uv add "belgie[pydantic-ai]", set OPENAI_API_KEY, then:
from pydantic_ai import Agent
from belgie.pydantic_ai import BelgieCapability
agent = Agent("openai:gpt-5", capabilities=[BelgieCapability()])
result = agent.run_sync(
"Convert 'foo-bar' to camelCase using TypeScript and the camelcase npm package.",
)
print(result.output)
LangChain
Install with uv add "belgie[langchain]", set OPENAI_API_KEY, then:
from langchain.agents import create_agent
from belgie.langchain import BelgieMiddleware
agent = create_agent(
model="openai:gpt-5",
tools=[],
middleware=[BelgieMiddleware()],
system_prompt="You can execute JS/TS in a Deno sandbox with run_code.",
)
result = agent.invoke(
{
"messages": [
(
"user",
"Convert 'foo-bar' to camelCase using TypeScript and the camelcase npm package.",
),
],
},
)
print(result["messages"][-1].content)
Under the hood: Deno in Python
MCP Apps and agent run_code both use Belgie’s embedded Deno runtime. Call it directly when you
need JS/TS from Python without MCP or an agent framework:
- Scripts: Inline or file-based JS/TS with
RuntimeandScript, sync or async. - Inline dependencies: Import npm, JSR, and URL modules from source.
- Environments: Lockfiles, custom cache/options, local packages, and
Commandfor npm binaries (Vite, esbuild, etc.). - Data bridge: Pass JSON-safe dicts, lists, and primitives across the boundary.
import asyncio
from belgie import Runtime, Script
script = Script[[str], str](
"""
import camelcase from "npm:camelcase@8.0.0";
export default function run(input: string): string {
return camelcase(input);
}
"""
)
async def main() -> None:
async with Runtime() as run:
print(await run(script)("foo-bar")) # prints: fooBar
asyncio.run(main())
Examples
Small, runnable projects. Each focuses on one capability.
UI
- mcp: MCP Apps extension with a React widget built through Belgie.
- shadcn: MCP Apps widget styled with Tailwind CSS and shadcn/ui.
- tanstack: TanStack Start SPA and MCP widget served together through FastAPI.
AI
- pydantic-ai: Pydantic AI agent with
BelgieCapability()for sandboxed JS/TS execution. - langchain: LangChain agent with
BelgieMiddleware()for sandboxed JS/TS execution.
Basic
- simple: Async
Runtimewith a TypeScript file on disk. - inline-deps: Direct
npm:,jsr:, and URL imports in a script. - jsr-deps: JSR packages declared through an explicit
Environment. - pyproject: Manage project package dependencies with
belgie[cli]and[tool.belgie.dependencies]. - environment: Sync and async
Environmentsetup withpath. - commands: npm package binaries via
RuntimeandCommand.
For deeper integration guidance, optionally install the use-belgie skill with
uvx library-skills install.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file belgie-0.35.0.tar.gz.
File metadata
- Download URL: belgie-0.35.0.tar.gz
- Upload date:
- Size: 756.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3df8fe477893dbeef8ac8a049a78c123a846edf3479b185c0f8b9308827c0996
|
|
| MD5 |
a66748ae5ace6582aa8d3c334fff6da5
|
|
| BLAKE2b-256 |
1f911b8ad08cb51190e93fba61a130736a5a4e90cc013aa7e81833615f0427f0
|
File details
Details for the file belgie-0.35.0-cp312-abi3-win_amd64.whl.
File metadata
- Download URL: belgie-0.35.0-cp312-abi3-win_amd64.whl
- Upload date:
- Size: 54.0 MB
- Tags: CPython 3.12+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17ff36c1404686c65154c4ae4a9279486ed9c504584bf36865b062d9e23fb37e
|
|
| MD5 |
e603f937d49d0fe68b4e558b14ca1b8b
|
|
| BLAKE2b-256 |
095eda4cbcc0c4fb1de1a5deeb1e0c8186f97d0838e8b30d2c9f5f1210416af9
|
File details
Details for the file belgie-0.35.0-cp312-abi3-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: belgie-0.35.0-cp312-abi3-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 61.0 MB
- Tags: CPython 3.12+, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
75b0df09ab23578e30ac635fc86baca5f86cc2924b5ae5db1cf81d2c84676b79
|
|
| MD5 |
322a7700ba8eca3253a9f3e1a6edc2b1
|
|
| BLAKE2b-256 |
98f1e83eee5f47457dc4219a5d1be24eb9d86e493354fe5f9bdb0f5bab8e269d
|
File details
Details for the file belgie-0.35.0-cp312-abi3-manylinux_2_28_aarch64.whl.
File metadata
- Download URL: belgie-0.35.0-cp312-abi3-manylinux_2_28_aarch64.whl
- Upload date:
- Size: 64.5 MB
- Tags: CPython 3.12+, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a734d251d647261123d99e9a74a5730391845972dc7ba86052416a4da2c4bef5
|
|
| MD5 |
c0dddad609409be10b92a41202c98213
|
|
| BLAKE2b-256 |
6bc90cba5e74ff27b053d25bf5da20dc6d104df13a6683c91a6f530b0a40a171
|
File details
Details for the file belgie-0.35.0-cp312-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: belgie-0.35.0-cp312-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 55.1 MB
- Tags: CPython 3.12+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cb55af610050d6ba1a91636f9441df49e4510dee7f810d71d54009b10ede9486
|
|
| MD5 |
646ebf70dbf347e6132edf28558b9f83
|
|
| BLAKE2b-256 |
2815da5fe5e7694d69dde5a058dc97dfa3b691ac63ef2b7de758129a142b4300
|
File details
Details for the file belgie-0.35.0-cp312-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: belgie-0.35.0-cp312-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 57.1 MB
- Tags: CPython 3.12+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b3955a4f06a5b4ff247066653b0cef1d20e9671620eeac36bb491c49b200b8d3
|
|
| MD5 |
eb71e11e1c977fdc8a0acc477dfee1db
|
|
| BLAKE2b-256 |
4300cb72332b72a26cf1cf39ef62682e360af75d2bfcf8278b652d0d999f2c69
|