cagataycali/strands-transformers

Run any HuggingFace transformers model from a Strands agent. A tool for every task, or the agent's own multimodal brain. Local. No API keys.

5

stars

7

commits

Python

primary language

Jul 23, 2026

updated

cagataycali.github.io/strands-transformers/
strands-agents
transformers

README

Strands Transformers - every modality in, every modality out: one tool, one local brain, zero hardcoding

Run any HuggingFace transformers model from a Strands agent. A tool for every task, or the agent's own multimodal brain. Local. No API keys.

pypi docs build docs site python transformers license Awesome Strands Agents

πŸ“– Docs Β Β·Β  ⚑ 60-second hello Β Β·Β  πŸ‘οΈ See it work Β Β·Β  🧩 Two ways Β Β·Β  πŸ”Œ MCP Β Β·Β  πŸ§ͺ Examples


πŸ€” The idea

HuggingFace transformers already runs every model on earth. The missing piece is a clean, dynamic bridge into an agent loop - without writing per-model glue every time. This library is that bridge, two ways:

What it isYou get
πŸ› οΈ use_transformersone tool exposing every transformers taskdiscover Β· run a pipeline Β· call any class/method
🧠 TransformerModela local model as your Agent(model=…) brainit sees, hears & speaks via content blocks

Zero hardcoding. core/registry.py reads transformers' own SUPPORTED_TASKS taxonomy at runtime - the day a task or model lands upstream, it works here. No code change. No version bump.

πŸ“¦ Install

uv pip install strands-transformers          # from PyPI
PYTHONPATH=. python examples/smoke.py         # verify β†’ "18/18 checks passed"
From source Β· optional extras (audio Β· vision Β· training)
uv pip install -e .                # editable from source
uv pip install -e ".[audio]"       # soundfile, librosa  (mp3/flac/ogg decode)
uv pip install -e ".[vision]"      # torchvision (needed by VLMs!), opencv, av
uv pip install -e ".[training]"    # trl, peft, accelerate
uv pip install -e ".[all]"         # everything

WAV audio works with no extras. Vision models (SmolVLM, Qwen-VL, …) need [vision]. device="auto" picks cuda β†’ mps β†’ cpu (bf16 on GPU).

⚑ 60-second hello

A 256M-param vision model, seeing pixels in the standard Strands loop - no key, no server:

import io
from PIL import Image
from strands import Agent
from strands_transformers import TransformerModel

buf = io.BytesIO(); Image.new("RGB", (64, 64), (20, 200, 40)).save(buf, "PNG")  # a green square

model = TransformerModel(model_path="HuggingFaceTB/SmolVLM-256M-Instruct")
agent = Agent(model=model, system_prompt="You are concise.")

print(agent([
    {"image": {"format": "png", "source": {"bytes": buf.getvalue()}}},
    {"text": "Color? One word."},
]))
# β†’ Green.

Swap model_path for any HF VLM and the code is identical.

πŸ‘οΈ See it work

Every result below is a real model output (CUDA Β· transformers 5.12 Β· torch 2.10):

You give itIt returnsExample
πŸ–ΌοΈ a green image + "Color?""Green."multimodal_agent.py
🎬 brightening video frames"BRIGHTER."multimodal_advanced.py
🧰 a blue tool screenshot (in toolResult)"Blue."multimodal_advanced.py
πŸ“„ a text documentrecovers BANANA-42document_and_audio.py
πŸ”Š a 440 Hz tone (Omni)"It's a pure tone."omni_audio.py
πŸ’¬ "say: …can speak" (Omni)πŸ”Š real 24 kHz speechomni_audio.py
🦾 camera + "pick the cube"actions [1, 30, 6]molmoact_vla.py
πŸ“‹ Copy-paste & run - the snippet behind each row
# πŸ–ΌοΈ image β†’ "Green."   (local VLM brain, content blocks)
import io
from PIL import Image
from strands import Agent
from strands_transformers import TransformerModel

png = io.BytesIO(); Image.new("RGB", (224, 224), (20, 200, 40)).save(png, "PNG")
agent = Agent(model=TransformerModel(model_path="HuggingFaceTB/SmolVLM-256M-Instruct"))
print(agent([
    {"image": {"format": "png", "source": {"bytes": png.getvalue()}}},
    {"text": "What color is this image? One word."},
]))  # β†’ Green.
# 🎬 video β†’ "BRIGHTER."   (a video content block of brightening frames)
import asyncio, numpy as np
from PIL import Image
from strands_transformers import TransformerModel

model = TransformerModel(model_path="HuggingFaceTB/SmolVLM2-500M-Video-Instruct",
                         params={"max_tokens": 48, "do_sample": False})
frames = [Image.fromarray(np.full((224, 224, 3), v, np.uint8)) for v in (10,40,80,120,160,200,230,250)]
msgs = [{"role": "user", "content": [
    {"video": {"format": "mp4", "fps": 2.0, "source": {"bytes": frames}}},
    {"text": "Does this video get brighter or darker? Answer brighter or darker."},
]}]
async def go():
    return "".join([e.get("contentBlockDelta",{}).get("delta",{}).get("text","")
                    async for e in model.stream(msgs)])
print(asyncio.run(go()))  # β†’ ...brighter...
# 🧰 tool screenshot β†’ "Blue."   (an image returned inside a toolResult)
import asyncio, io
from PIL import Image
from strands_transformers import TransformerModel

blue = io.BytesIO(); Image.new("RGB", (224, 224), (25, 25, 210)).save(blue, "PNG")
model = TransformerModel(model_path="HuggingFaceTB/SmolVLM-256M-Instruct",
                         params={"max_tokens": 32, "do_sample": False})
msgs = [
    {"role": "user", "content": [{"text": "Capture the screen, then name its color."}]},
    {"role": "assistant", "content": [{"toolUse": {"name": "capture", "toolUseId": "t1", "input": {}}}]},
    {"role": "user", "content": [{"toolResult": {"toolUseId": "t1", "status": "success", "content": [
        {"text": "Here is the captured screen:"},
        {"image": {"format": "png", "source": {"bytes": blue.getvalue()}}}]}}]},
    {"role": "user", "content": [{"text": "Dominant color of the captured screen? One word."}]},
]
async def go():
    return "".join([e.get("contentBlockDelta",{}).get("delta",{}).get("text","")
                    async for e in model.stream(msgs)])
print(asyncio.run(go()))  # β†’ Blue.
# πŸ“„ document β†’ recovers "BANANA-42"   (a document content block β†’ text LM prompt)
import asyncio
from strands_transformers import TransformerModel

model = TransformerModel(model_path="Qwen/Qwen3-0.6B", enable_thinking=False,
                         params={"max_tokens": 64, "do_sample": False})
body = b"The secret passphrase for the vault is BANANA-42. Keep it safe."
msgs = [{"role": "user", "content": [
    {"document": {"name": "secret", "format": "txt", "source": {"bytes": body}}},
    {"text": "What is the secret passphrase? Answer with just the passphrase."},
]}]
async def go():
    return "".join([e.get("contentBlockDelta",{}).get("delta",{}).get("text","")
                    async for e in model.stream(msgs)])
print(asyncio.run(go()))  # β†’ BANANA-42
# πŸ”Š text β†’ speech β†’ text   (TTS then ASR, the tool path; the library narrating itself)
from strands_transformers import use_transformers

tts = use_transformers(action="run", task="text-to-audio",
                       model="facebook/mms-tts-eng",
                       inputs="the quick brown fox jumps over the lazy dog")
wav = tts["artifacts"][0]
asr = use_transformers(action="run", task="automatic-speech-recognition",
                       model="openai/whisper-tiny", inputs=wav)
print(asr["content"][0]["text"])  # β†’ "...quick brown fox..."
# 🦾 camera + instruction β†’ robot actions [1, 30, 6]   (VLA via the `call` path)
import numpy as np
from PIL import Image
from huggingface_hub import hf_hub_download
from strands_transformers import use_transformers

REPO = "allenai/MolmoAct2-SO100_101"
top  = Image.open(hf_hub_download(REPO, "assets/sample_realsense_top_rgb.png")).convert("RGB")
side = Image.open(hf_hub_download(REPO, "assets/sample_realsense_side_rgb.png")).convert("RGB")
state = [-0.527, 189.14, 181.41, 60.64, -3.60, 1.097]

use_transformers(action="call", target="AutoProcessor.from_pretrained",
    parameters={"pretrained_model_name_or_path": REPO, "trust_remote_code": True}, cache_key="proc")
use_transformers(action="call", target="AutoModelForImageTextToText.from_pretrained",
    parameters={"pretrained_model_name_or_path": REPO, "trust_remote_code": True, "dtype": "float32"}, cache_key="vla")
print(use_transformers(action="call", target="cached:vla.predict_action",
    parameters={"processor": "cached:proc", "images": [top, side],
                "task": "Pick up the lemon and drop it in the red bowl.",
                "state": state, "norm_tag": "so100_so101_molmoact2",
                "inference_action_mode": "continuous", "num_steps": 10})["content"][0]["text"][:200])
# β†’ MolmoAct2ActionOutput ... actions [1, 30, 6]

Omni audio-in + speech-out needs one bigger model - see examples/omni_audio.py.

Vision tasks on one COCO photo - detection Β· depth Β· panoptic segmentation:

object detection, depth estimation, and panoptic segmentation on a single photo

video understanding demo Β Β  generated speech waveform

🎬 video β†’ label Β Β·Β  πŸ”Š text-to-audio then re-transcribed by whisper (the library narrating itself)
▢️ Hear it speak & play every example on the docs site β†’

🧩 Two ways to use it

πŸ› οΈ As a tool - use_transformers

from strands import Agent
from strands_transformers import use_transformers

agent = Agent(tools=[use_transformers])
agent("Transcribe recording.wav")                  # automatic-speech-recognition
agent("What's in scene.jpg?")                       # image-text-to-text
agent("Say 'hello from strands' as audio")          # text-to-audio
agent("Detect objects in https://.../street.jpg")   # object-detection

Discover everything at runtime (action="tasks" | "modalities" | "inspect" | …), run high-level pipelines, or call any class / fn / method for custom models. β†’ The tool guide

🧠 As the agent's brain - TransformerModel

Pass image / video / audio / document blocks (and media inside a toolResult) - the provider auto-detects the model's processor and routes them.

Content blockVerified outputExample
image"Green."multimodal_agent.py
video (with fps)"BRIGHTER."multimodal_advanced.py
image in toolResult"Blue."multimodal_advanced.py
documentrecovers BANANA-42document_and_audio.py
audio (our schema extension)audio β†’ textaudio_content_block.py
audio in and speech outhears + speaksomni_audio.py

β†’ Agent brain Β· Content blocks Β· Audio

🦾 Robotics / VLA - camera + instruction β†’ actions

Two transformers-native layers, both GPU-verified:

  • 🧠 reason β€” Cosmos-Reason2-2B (a physical-AI VLM) plans over a scene via run: "the red cube is bottom-left, move the arm there first."
  • βš™οΈ act β€” VLA models expose predict_action via call: MolmoAct2 β†’ [1,30,6]; OpenVLA-7b β†’ 7-DoF (auto 4.xβ†’5.x shims).

πŸ”— Full agentic loop (robot_reason_act_agent.py): Cosmos plans over real RealSense frames β†’ MolmoAct acts β€” perception β†’ plan β†’ action through one tool. (Lerobot policies like SmolVLA / Ο€0 / GR00T run their own runtimes β€” pair with use_lerobot.) β†’ Robotics guide

πŸ”Œ MCP server

Use it from Claude Code, Claude Desktop, Cursor, or any MCP client β€” same tool, over MCP.

No install needed β€” just uvx:

uvx strands-transformers                    # stdio (Claude Code / Desktop)
uvx strands-transformers --http --port 8021 # HTTP multi-client

Claude Code: claude mcp add transformers -- uvx strands-transformers

Claude Desktop:

{"mcpServers": {"transformers": {"command": "uvx", "args": ["strands-transformers"]}}}
Prefer pip?
pip install "strands-transformers[mcp]"
strands-transformers-mcp

Examples use tiny models so they run in seconds. Point the same code at any current library_name: transformers model - swap the id, the plumbing is identical:

ModalityStrong open modelHow
Vision-languageQwen/Qwen3-VL-8B-Instruct Β· google/gemma-3-4b-itbrain or run (image-text-to-text)
Speech β†’ textopenai/whisper-large-v3-turborun (automatic-speech-recognition)
Audio in + speech outQwen/Qwen2.5-Omni-3Bbrain (speak=True)
Multimodal (audio+vision+text)microsoft/Phi-4-multimodal-instructbrain
Robot actions (VLA)allenai/MolmoAct2 Β· openvla/openvla-7bcall β†’ predict_action
Embodied reasoningnvidia/Cosmos-Reason2-2Brun (image-text-to-text)
# swap the tiny demo model for a SOTA one - same code:
model = TransformerModel(model_path="Qwen/Qwen3-VL-8B-Instruct")

πŸ—οΈ How it works

strands_transformers/
β”œβ”€β”€ tools/use_transformers.py            # the one @tool: discover Β· run Β· call
β”œβ”€β”€ models/transformers.py               # TransformerModel - local multimodal brain
β”œβ”€β”€ types/audio.py                       # audio content-block extension
└── core/{registry,engine,io,compat}.py  # taxonomy Β· load/cache Β· I/O Β· legacy shims

Nothing is hardcoded per task - registry.py reads transformers' SUPPORTED_TASKS at runtime, so coverage tracks upstream automatically. β†’ Architecture Β· API reference

πŸ§ͺ Examples

Runnable, GPU-verified examples in examples/ - image, video, audio, document, Omni speech, VLA, and pipelines. Run any:

PYTHONPATH=. python examples/<name>.py

β†’ Examples & FAQ

⭐ Star history

Star History Chart

License

MIT - built with the Strands Agents SDK and HuggingFace Transformers.

If this saved you a pile of per-model glue code, consider giving it a ⭐

Contributors

cagataycali

5 commits

strands-agent

2 commits

cagataycali/strands-transformers

Run any HuggingFace transformers model from a Strands agent. A tool for every task, or the agent's own multimodal brain. Local. No API keys.

5

stars

7

commits

Python

primary language

Jul 23, 2026

updated

cagataycali.github.io/strands-transformers/
strands-agents
transformers

README

Strands Transformers - every modality in, every modality out: one tool, one local brain, zero hardcoding

Run any HuggingFace transformers model from a Strands agent. A tool for every task, or the agent's own multimodal brain. Local. No API keys.

pypi docs build docs site python transformers license Awesome Strands Agents

πŸ“– Docs Β Β·Β  ⚑ 60-second hello Β Β·Β  πŸ‘οΈ See it work Β Β·Β  🧩 Two ways Β Β·Β  πŸ”Œ MCP Β Β·Β  πŸ§ͺ Examples


πŸ€” The idea

HuggingFace transformers already runs every model on earth. The missing piece is a clean, dynamic bridge into an agent loop - without writing per-model glue every time. This library is that bridge, two ways:

What it isYou get
πŸ› οΈ use_transformersone tool exposing every transformers taskdiscover Β· run a pipeline Β· call any class/method
🧠 TransformerModela local model as your Agent(model=…) brainit sees, hears & speaks via content blocks

Zero hardcoding. core/registry.py reads transformers' own SUPPORTED_TASKS taxonomy at runtime - the day a task or model lands upstream, it works here. No code change. No version bump.

πŸ“¦ Install

uv pip install strands-transformers          # from PyPI
PYTHONPATH=. python examples/smoke.py         # verify β†’ "18/18 checks passed"
From source Β· optional extras (audio Β· vision Β· training)
uv pip install -e .                # editable from source
uv pip install -e ".[audio]"       # soundfile, librosa  (mp3/flac/ogg decode)
uv pip install -e ".[vision]"      # torchvision (needed by VLMs!), opencv, av
uv pip install -e ".[training]"    # trl, peft, accelerate
uv pip install -e ".[all]"         # everything

WAV audio works with no extras. Vision models (SmolVLM, Qwen-VL, …) need [vision]. device="auto" picks cuda β†’ mps β†’ cpu (bf16 on GPU).

⚑ 60-second hello

A 256M-param vision model, seeing pixels in the standard Strands loop - no key, no server:

import io
from PIL import Image
from strands import Agent
from strands_transformers import TransformerModel

buf = io.BytesIO(); Image.new("RGB", (64, 64), (20, 200, 40)).save(buf, "PNG")  # a green square

model = TransformerModel(model_path="HuggingFaceTB/SmolVLM-256M-Instruct")
agent = Agent(model=model, system_prompt="You are concise.")

print(agent([
    {"image": {"format": "png", "source": {"bytes": buf.getvalue()}}},
    {"text": "Color? One word."},
]))
# β†’ Green.

Swap model_path for any HF VLM and the code is identical.

πŸ‘οΈ See it work

Every result below is a real model output (CUDA Β· transformers 5.12 Β· torch 2.10):

You give itIt returnsExample
πŸ–ΌοΈ a green image + "Color?""Green."multimodal_agent.py
🎬 brightening video frames"BRIGHTER."multimodal_advanced.py
🧰 a blue tool screenshot (in toolResult)"Blue."multimodal_advanced.py
πŸ“„ a text documentrecovers BANANA-42document_and_audio.py
πŸ”Š a 440 Hz tone (Omni)"It's a pure tone."omni_audio.py
πŸ’¬ "say: …can speak" (Omni)πŸ”Š real 24 kHz speechomni_audio.py
🦾 camera + "pick the cube"actions [1, 30, 6]molmoact_vla.py
πŸ“‹ Copy-paste & run - the snippet behind each row
# πŸ–ΌοΈ image β†’ "Green."   (local VLM brain, content blocks)
import io
from PIL import Image
from strands import Agent
from strands_transformers import TransformerModel

png = io.BytesIO(); Image.new("RGB", (224, 224), (20, 200, 40)).save(png, "PNG")
agent = Agent(model=TransformerModel(model_path="HuggingFaceTB/SmolVLM-256M-Instruct"))
print(agent([
    {"image": {"format": "png", "source": {"bytes": png.getvalue()}}},
    {"text": "What color is this image? One word."},
]))  # β†’ Green.
# 🎬 video β†’ "BRIGHTER."   (a video content block of brightening frames)
import asyncio, numpy as np
from PIL import Image
from strands_transformers import TransformerModel

model = TransformerModel(model_path="HuggingFaceTB/SmolVLM2-500M-Video-Instruct",
                         params={"max_tokens": 48, "do_sample": False})
frames = [Image.fromarray(np.full((224, 224, 3), v, np.uint8)) for v in (10,40,80,120,160,200,230,250)]
msgs = [{"role": "user", "content": [
    {"video": {"format": "mp4", "fps": 2.0, "source": {"bytes": frames}}},
    {"text": "Does this video get brighter or darker? Answer brighter or darker."},
]}]
async def go():
    return "".join([e.get("contentBlockDelta",{}).get("delta",{}).get("text","")
                    async for e in model.stream(msgs)])
print(asyncio.run(go()))  # β†’ ...brighter...
# 🧰 tool screenshot β†’ "Blue."   (an image returned inside a toolResult)
import asyncio, io
from PIL import Image
from strands_transformers import TransformerModel

blue = io.BytesIO(); Image.new("RGB", (224, 224), (25, 25, 210)).save(blue, "PNG")
model = TransformerModel(model_path="HuggingFaceTB/SmolVLM-256M-Instruct",
                         params={"max_tokens": 32, "do_sample": False})
msgs = [
    {"role": "user", "content": [{"text": "Capture the screen, then name its color."}]},
    {"role": "assistant", "content": [{"toolUse": {"name": "capture", "toolUseId": "t1", "input": {}}}]},
    {"role": "user", "content": [{"toolResult": {"toolUseId": "t1", "status": "success", "content": [
        {"text": "Here is the captured screen:"},
        {"image": {"format": "png", "source": {"bytes": blue.getvalue()}}}]}}]},
    {"role": "user", "content": [{"text": "Dominant color of the captured screen? One word."}]},
]
async def go():
    return "".join([e.get("contentBlockDelta",{}).get("delta",{}).get("text","")
                    async for e in model.stream(msgs)])
print(asyncio.run(go()))  # β†’ Blue.
# πŸ“„ document β†’ recovers "BANANA-42"   (a document content block β†’ text LM prompt)
import asyncio
from strands_transformers import TransformerModel

model = TransformerModel(model_path="Qwen/Qwen3-0.6B", enable_thinking=False,
                         params={"max_tokens": 64, "do_sample": False})
body = b"The secret passphrase for the vault is BANANA-42. Keep it safe."
msgs = [{"role": "user", "content": [
    {"document": {"name": "secret", "format": "txt", "source": {"bytes": body}}},
    {"text": "What is the secret passphrase? Answer with just the passphrase."},
]}]
async def go():
    return "".join([e.get("contentBlockDelta",{}).get("delta",{}).get("text","")
                    async for e in model.stream(msgs)])
print(asyncio.run(go()))  # β†’ BANANA-42
# πŸ”Š text β†’ speech β†’ text   (TTS then ASR, the tool path; the library narrating itself)
from strands_transformers import use_transformers

tts = use_transformers(action="run", task="text-to-audio",
                       model="facebook/mms-tts-eng",
                       inputs="the quick brown fox jumps over the lazy dog")
wav = tts["artifacts"][0]
asr = use_transformers(action="run", task="automatic-speech-recognition",
                       model="openai/whisper-tiny", inputs=wav)
print(asr["content"][0]["text"])  # β†’ "...quick brown fox..."
# 🦾 camera + instruction β†’ robot actions [1, 30, 6]   (VLA via the `call` path)
import numpy as np
from PIL import Image
from huggingface_hub import hf_hub_download
from strands_transformers import use_transformers

REPO = "allenai/MolmoAct2-SO100_101"
top  = Image.open(hf_hub_download(REPO, "assets/sample_realsense_top_rgb.png")).convert("RGB")
side = Image.open(hf_hub_download(REPO, "assets/sample_realsense_side_rgb.png")).convert("RGB")
state = [-0.527, 189.14, 181.41, 60.64, -3.60, 1.097]

use_transformers(action="call", target="AutoProcessor.from_pretrained",
    parameters={"pretrained_model_name_or_path": REPO, "trust_remote_code": True}, cache_key="proc")
use_transformers(action="call", target="AutoModelForImageTextToText.from_pretrained",
    parameters={"pretrained_model_name_or_path": REPO, "trust_remote_code": True, "dtype": "float32"}, cache_key="vla")
print(use_transformers(action="call", target="cached:vla.predict_action",
    parameters={"processor": "cached:proc", "images": [top, side],
                "task": "Pick up the lemon and drop it in the red bowl.",
                "state": state, "norm_tag": "so100_so101_molmoact2",
                "inference_action_mode": "continuous", "num_steps": 10})["content"][0]["text"][:200])
# β†’ MolmoAct2ActionOutput ... actions [1, 30, 6]

Omni audio-in + speech-out needs one bigger model - see examples/omni_audio.py.

Vision tasks on one COCO photo - detection Β· depth Β· panoptic segmentation:

object detection, depth estimation, and panoptic segmentation on a single photo

video understanding demo Β Β  generated speech waveform

🎬 video β†’ label Β Β·Β  πŸ”Š text-to-audio then re-transcribed by whisper (the library narrating itself)
▢️ Hear it speak & play every example on the docs site β†’

🧩 Two ways to use it

πŸ› οΈ As a tool - use_transformers

from strands import Agent
from strands_transformers import use_transformers

agent = Agent(tools=[use_transformers])
agent("Transcribe recording.wav")                  # automatic-speech-recognition
agent("What's in scene.jpg?")                       # image-text-to-text
agent("Say 'hello from strands' as audio")          # text-to-audio
agent("Detect objects in https://.../street.jpg")   # object-detection

Discover everything at runtime (action="tasks" | "modalities" | "inspect" | …), run high-level pipelines, or call any class / fn / method for custom models. β†’ The tool guide

🧠 As the agent's brain - TransformerModel

Pass image / video / audio / document blocks (and media inside a toolResult) - the provider auto-detects the model's processor and routes them.

Content blockVerified outputExample
image"Green."multimodal_agent.py
video (with fps)"BRIGHTER."multimodal_advanced.py
image in toolResult"Blue."multimodal_advanced.py
documentrecovers BANANA-42document_and_audio.py
audio (our schema extension)audio β†’ textaudio_content_block.py
audio in and speech outhears + speaksomni_audio.py

β†’ Agent brain Β· Content blocks Β· Audio

🦾 Robotics / VLA - camera + instruction β†’ actions

Two transformers-native layers, both GPU-verified:

  • 🧠 reason β€” Cosmos-Reason2-2B (a physical-AI VLM) plans over a scene via run: "the red cube is bottom-left, move the arm there first."
  • βš™οΈ act β€” VLA models expose predict_action via call: MolmoAct2 β†’ [1,30,6]; OpenVLA-7b β†’ 7-DoF (auto 4.xβ†’5.x shims).

πŸ”— Full agentic loop (robot_reason_act_agent.py): Cosmos plans over real RealSense frames β†’ MolmoAct acts β€” perception β†’ plan β†’ action through one tool. (Lerobot policies like SmolVLA / Ο€0 / GR00T run their own runtimes β€” pair with use_lerobot.) β†’ Robotics guide

πŸ”Œ MCP server

Use it from Claude Code, Claude Desktop, Cursor, or any MCP client β€” same tool, over MCP.

No install needed β€” just uvx:

uvx strands-transformers                    # stdio (Claude Code / Desktop)
uvx strands-transformers --http --port 8021 # HTTP multi-client

Claude Code: claude mcp add transformers -- uvx strands-transformers

Claude Desktop:

{"mcpServers": {"transformers": {"command": "uvx", "args": ["strands-transformers"]}}}
Prefer pip?
pip install "strands-transformers[mcp]"
strands-transformers-mcp

Examples use tiny models so they run in seconds. Point the same code at any current library_name: transformers model - swap the id, the plumbing is identical:

ModalityStrong open modelHow
Vision-languageQwen/Qwen3-VL-8B-Instruct Β· google/gemma-3-4b-itbrain or run (image-text-to-text)
Speech β†’ textopenai/whisper-large-v3-turborun (automatic-speech-recognition)
Audio in + speech outQwen/Qwen2.5-Omni-3Bbrain (speak=True)
Multimodal (audio+vision+text)microsoft/Phi-4-multimodal-instructbrain
Robot actions (VLA)allenai/MolmoAct2 Β· openvla/openvla-7bcall β†’ predict_action
Embodied reasoningnvidia/Cosmos-Reason2-2Brun (image-text-to-text)
# swap the tiny demo model for a SOTA one - same code:
model = TransformerModel(model_path="Qwen/Qwen3-VL-8B-Instruct")

πŸ—οΈ How it works

strands_transformers/
β”œβ”€β”€ tools/use_transformers.py            # the one @tool: discover Β· run Β· call
β”œβ”€β”€ models/transformers.py               # TransformerModel - local multimodal brain
β”œβ”€β”€ types/audio.py                       # audio content-block extension
└── core/{registry,engine,io,compat}.py  # taxonomy Β· load/cache Β· I/O Β· legacy shims

Nothing is hardcoded per task - registry.py reads transformers' SUPPORTED_TASKS at runtime, so coverage tracks upstream automatically. β†’ Architecture Β· API reference

πŸ§ͺ Examples

Runnable, GPU-verified examples in examples/ - image, video, audio, document, Omni speech, VLA, and pipelines. Run any:

PYTHONPATH=. python examples/<name>.py

β†’ Examples & FAQ

⭐ Star history

Star History Chart

License

MIT - built with the Strands Agents SDK and HuggingFace Transformers.

If this saved you a pile of per-model glue code, consider giving it a ⭐

Contributors

cagataycali

5 commits

strands-agent

2 commits

Languages

Python

100.0%