nextviper_aisdk
v0.2.0aiMulti-provider AI SDK and remote MCP client for NextViper
AI SDK NextViper AIsdk
A small synchronous AI SDK for NextViper. It gives applications one normalized chat result across several model APIs, plus a remote Model Context Protocol (MCP) client for discovering and calling tools.
Supported providers
/v1 endpoint, and compatible gateways or self-hosted endpoints such as OpenRouter, Groq, and Together. Set the provider's base URL explicitly when it is not OpenAI.The SDK is written in NextViper and uses its standard HTTP, JSON, process, string, and collections modules. Provider calls are synchronous and non-streaming. OpenAI-compatible endpoints can be used from Linux, macOS, and Windows wherever the NextViper runtime and its HTTP module are available. MCP wire behavior follows the [2025-11-25 Streamable HTTP transport](https://modelcontextprotocol.io/specification/2025-11-25/basic/transports) and [tools protocol](https://modelcontextprotocol.io/specification/2025-11-25/server/tools).
Quickstart: OpenAI
export OPENAI_API_KEY="your-api-key"
nextviper run examples/quickstart.nvimport nextviper_aisdk
let client = nextviper_aisdk.create_openai_client_from_env("gpt-4o-mini")
let result = nextviper_aisdk.generate_text(client, "Say hello in one sentence.")
if result["ok"]:
print(result["text"])
else:
print("Request failed:", result["status"], result["error"])Other providers
Use an explicit constructor for the two native provider APIs:
import nextviper_aisdk
let anthropic = nextviper_aisdk.create_anthropic_client_from_env("claude-3-5-haiku-latest")
let gemini = nextviper_aisdk.create_gemini_client_from_env("gemini-2.0-flash")
let answer = nextviper_aisdk.chat(anthropic, [
nextviper_aisdk.message("user", "Explain MCP briefly.")
], {"max_tokens": 256})Set ANTHROPIC_API_KEY or GEMINI_API_KEY (or GOOGLE_API_KEY for Gemini) in the environment for the corresponding *_from_env constructor. Anthropic's chat() accepts provider-native request fields in options; pass a system prompt as options["system"]. Gemini accepts fields such as generationConfig and systemInstruction through options; use systemInstruction rather than a system-role message for Gemini.
generate_object() selects JSON mode for OpenAI-compatible APIs and Gemini; for Anthropic it asks for JSON in the prompt and parses the response.
For Ollama, use the OpenAI-compatible endpoint:
let local = nextviper_aisdk.create_ollama_client("llama3.2", "http://localhost:11434/v1")
let answer = nextviper_aisdk.generate_text(local, "Summarize this sentence.")For any compatible gateway, keep the original constructor or use create_provider_client(provider, api_key, base_url, model). Use create_client_from_env(base_url, model) to keep existing code working.
MCP tools over Streamable HTTP
The MCP helper implements the Streamable HTTP transport and JSON-RPC initialization, then exposes tool listing and invocation. Supply custom authorization headers when the MCP server requires them:
import nextviper_aisdk
import std.process
let token = process.env("MCP_SERVER_TOKEN")
let mut headers = {}
if token != nil and token != "":
headers = {"Authorization": "Bearer " + token}
let connected = nextviper_aisdk.mcp_connect("https://tools.example.com/mcp", headers)
if not connected["ok"]:
print("MCP connection failed:", connected["error"])
else:
let server = connected["server"]
let tools = nextviper_aisdk.mcp_list_tools(server)
let result = nextviper_aisdk.mcp_call_tool(server, "lookup", {"query": "NextViper"})
nextviper_aisdk.mcp_close(server)mcp_list_tools() returns the first page and its next_cursor; use mcp_list_tools_page(server, cursor) for subsequent pages. mcp_call_tool() preserves the complete MCP result, including isError, structured content, and content blocks. Stateful sessions are closed with mcp_close() where the server allows HTTP DELETE.
For a one-call OpenAI-compatible tool loop, chat_with_mcp(client, messages, server, options, max_tool_rounds) converts the MCP catalog to model tools and dispatches requested calls:
import nextviper_aisdk
let connected = nextviper_aisdk.mcp_connect("https://tools.example.com/mcp", {})
let answer = nextviper_aisdk.chat_with_mcp(
nextviper_aisdk.create_openai_client_from_env("gpt-4o-mini"),
[nextviper_aisdk.message("user", "Look up the current project status.")],
connected["server"],
{},
4
)Security: chat_with_mcp() executes model-selected tools automatically. Only connect trusted servers and expose tools appropriate for unattended execution. For destructive, financial, or otherwise sensitive actions, use mcp_list_tools() and mcp_call_tool() under your application's own confirmation/authorization flow. Never pass untrusted server descriptions as instructions.
The HTTP runtime buffers response bodies, so MCP request replies must complete as a finite JSON response or finite SSE response. This implementation does not open a long-lived SSE subscription or support the legacy HTTP+SSE transport.
API and result shape
create_openai_client(api_key, model) / create_openai_client_from_env(model)create_openai_compatible_client(api_key, base_url, model)create_anthropic_client(api_key, model) / create_anthropic_client_from_env(model)create_gemini_client(api_key, model) / create_gemini_client_from_env(model)create_ollama_client(model, base_url)create_client(api_key, base_url, model) and create_client_from_env(base_url, model) for compatible endpointscreate_provider_client(provider, api_key, base_url, model) for custom adapters compatible with the supported wire formatsmessage(role, content), chat(client, messages, options), generate_text(client, prompt), and generate_object(client, prompt)mcp_connect(url, headers), mcp_list_tools(server), mcp_list_tools_page(server, cursor), mcp_call_tool(server, name, arguments), mcp_close(server), and chat_with_mcp(...)Successful model results contain ok, status, text, model, usage, finish_reason, and raw; OpenAI-compatible responses also include tool_calls and assistant_message. Failures contain ok: false, status, and error; local configuration failures use status 0. Successful MCP operations preserve their raw JSON-RPC response.
Install from the NextViper registry
nextviper add nextviper_aisdkimport nextviper_aisdk
let client = nextviper_aisdk.create_openai_client_from_env("gpt-4o-mini")
let result = nextviper_aisdk.generate_text(client, "Say hello.")Validation
tests/contract.nv exercises client configuration and message construction without network access. Run nextviper test tests/contract.nv with NextViper installed; no live provider or MCP API calls are needed.

