mmsp-typescript
Guidance for using the MMSP TypeScript SDK (`@prismshadow/mmsp`). Use when developing agents that call different LLM APIs, need a…
Guidance for using the MMSP Python SDK (`mmsp`). Use when developing agents that call different LLM APIs, need a unified interface for LLM providers, mention MMSP, request `mmsp`, or already import it.
$ npx -y skills add Prism-Shadow/model-message-stream-protocol --skill mmsp-python --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/mmsp-pythonContext preview
The summary Claude sees to decide when to auto-load this skill.
Guidance for using the MMSP Python SDK (`mmsp`). Use when developing agents that call different LLM APIs, need a unified interface for LLM providers, mention MMSP, request `mmsp`, or already import it.
name: mmsp-python description: Guidance for using the MMSP Python SDK (`mmsp`). Use when developing agents that call different LLM APIs, need a unified interface for LLM providers, mention MMSP, request `mmsp`, or already import it.
MMSP is a unified SDK for calling LLMs across providers with shared data models, tool calling, tracing, and playground support.
uv add mmsp # or pip install mmsp
For model IDs, API keys, and base URLs, see [Model selection](reference/models.md).
This example asks GPT to call a weather tool, runs the tool, then sends the result back.
import asyncio
from mmsp import AutoLLMClient
def get_weather(location: str) -> str:
return f"Temperature in {location}: 22 C"
# Map tool names to their implementations so calls can be dispatched by name.
TOOLS = {"get_weather": get_weather}
async def main():
weather_function = {
"name": "get_weather",
"description": "Gets the current weather for a given location.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city name"
}
},
"required": ["location"]
}
}
client = AutoLLMClient(model="gpt-5.5")
config = {"tools": [weather_function]}
tool_call = None
async for event in client.streaming_response_stateful(
message={
"role": "user",
"content_items": [{"type": "text.done", "text": "What's the weather in London?"}]
},
config=config
):
if event["event_type"] == "stop":
# Always the last event, exactly once: the response has finished.
print(event["finish_reason"], event["usage_metadata"])
for item in event["content_items"]:
if item["type"] == "tool_call.done": # the complete call; tool_call.delta items are fragments
tool_call = item
if tool_call:
# Dispatch by tool name instead of hardcoding the function.
result = TOOLS[tool_call["name"]](**tool_call["arguments"])
async for event in client.streaming_response_stateful(
message={
"role": "user",
"content_items": [
{
"type": "tool_result.done",
"text": result,
"tool_call_id": tool_call["tool_call_id"]
}
]
},
config=config
):
print(event)
# Streams the answer as text.delta fragments, closes it with text.done, then one stop event carrying usage:
# {'role': 'assistant', 'event_type': 'delta', 'content_items': [{'type': 'text.delta', 'text': 'The'}], 'usage_metadata': None, 'finish_reason': None}
# {'role': 'assistant', 'event_type': 'delta', 'content_items': [{'type': 'text.delta', 'text': ' weather'}], 'usage_metadata': None, 'finish_reason': None}
# {'role': 'assistant', 'event_type': 'delta', 'content_items': [{'type': 'text.delta', 'text': ' is 22 C.'}], 'usage_metadata': None, 'finish_reason': None}
# {'role': 'assistant', 'event_type': 'delta', 'content_items': [{'type': 'text.done', 'text': 'The weather is 22 C.'}], 'usage_metadata': None, 'finish_reason': None}
# {'role': 'assistant', 'event_type': 'stop', 'content_items': [], 'usage_metadata': {'cached_tokens': 0, 'prompt_tokens': 12, 'thoughts_tokens': 0, 'response_tokens': 8}, 'finish_reason': 'stop'}
asyncio.run(main())Agent loop rules:
Integrate every model the same way, and keep one API in your head instead of one per provider.
Guidance for using the MMSP TypeScript SDK (`@prismshadow/mmsp`). Use when developing agents that call different LLM APIs, need a…