OptimizelyOpal.OpalToolsSDK 0.1.0

dotnet add package OptimizelyOpal.OpalToolsSDK --version 0.1.0
                    
NuGet\Install-Package OptimizelyOpal.OpalToolsSDK -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="OptimizelyOpal.OpalToolsSDK" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="OptimizelyOpal.OpalToolsSDK" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="OptimizelyOpal.OpalToolsSDK" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add OptimizelyOpal.OpalToolsSDK --version 0.1.0
                    
#r "nuget: OptimizelyOpal.OpalToolsSDK, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package OptimizelyOpal.OpalToolsSDK@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=OptimizelyOpal.OpalToolsSDK&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=OptimizelyOpal.OpalToolsSDK&version=0.1.0
                    
Install as a Cake Tool

Opal Tools SDK for C#

This SDK helps you create tool services for the Opal AI Assistant platform using C# and ASP.NET Core.

Installation

You can install the SDK using NuGet:

dotnet add package OptimizelyOpal.OpalToolsSDK

Quick Start

Here's a simple example of how to create a tools service with two tools:

using Microsoft.AspNetCore.Builder;
using OpalToolsSDK;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// Create and register the tools service
var toolsService = app.AddOpalToolsService();

// Register all tools from this assembly
toolsService.RegisterToolsFromExecutingAssembly(app);

// Start the app
app.Run();

// Tool parameter models
public class GreetingParameters
{
    [Required]
    [Description("Name of the person to greet")]
    public string Name { get; set; } = string.Empty;

    [Description("Language for greeting (defaults to random)")]
    public string? Language { get; set; }
}

public class DateParameters
{
    [Description("Date format (defaults to ISO format)")]
    public string Format { get; set; } = "yyyy-MM-dd";
}

// Tool implementations
public static class Tools
{
    [Tool("greeting", "Greets a person in a random language (English, Spanish, or French)")]
    public static async Task<object> Greeting(GreetingParameters parameters)
    {
        // Get parameters
        var name = parameters.Name;
        var language = parameters.Language;

        // If language not specified, choose randomly
        if (string.IsNullOrEmpty(language))
        {
            var random = new Random();
            var languages = new[] { "english", "spanish", "french" };
            language = languages[random.Next(languages.Length)];
        }

        // Generate greeting based on language
        string greeting;
        if (language.ToLower() == "spanish")
        {
            greeting = $"¡Hola, {name}! ¿Cómo estás?";
        }
        else if (language.ToLower() == "french")
        {
            greeting = $"Bonjour, {name}! Comment ça va?";
        }
        else // Default to English
        {
            greeting = $"Hello, {name}! How are you?";
        }

        return new
        {
            greeting,
            language
        };
    }

    [Tool("todays-date", "Returns today's date in the specified format")]
    public static async Task<object> TodaysDate(DateParameters parameters)
    {
        // Get parameters
        var format = parameters.Format;

        // Get today's date
        var today = DateTime.Now;

        // Format the date
        var formattedDate = today.ToString(format);

        return new
        {
            date = formattedDate,
            format,
            timestamp = ((DateTimeOffset)today).ToUnixTimeSeconds()
        };
    }
}

Authentication

To create a tool that requires authentication:

[Tool("get-calendar", "Gets user's calendar events")]
[RequiresAuth("google", "calendar")]
public static async Task<object> GetCalendar(CalendarParameters parameters, AuthData authData)
{
    // Use authData.Provider and authData.Credentials to authenticate
    // ...

    return new
    {
        events = new[] { "Event 1", "Event 2" }
    };
}

You can also add multiple authentication requirements to a tool:

[Tool("get-combined-data", "Gets data from multiple services")]
[RequiresAuth("google", "calendar")]
[RequiresAuth("microsoft", "outlook")]
public static async Task<object> GetCombinedData(DataParameters parameters, AuthData authData)
{
    // Check authData.Provider to determine which credentials to use
    if (authData.Provider == "google")
    {
        // Use Google authentication
    }
    else if (authData.Provider == "microsoft")
    {
        // Use Microsoft authentication
    }

    return new
    {
        data = new[] { "Item 1", "Item 2" }
    };
}

Tool Request/Response Format

The tool request format follows the Opal Tools Management Service specification:

{
  "parameters": {
    "name": "John",
    "language": "spanish"
  },
  "auth": {
    "provider": "google",
    "credentials": {
      "token": "access_token_value"
    }
  }
}

The response is the direct JSON serialization of the object returned by your tool method:

{
  "greeting": "¡Hola, John! ¿Cómo estás?",
  "language": "spanish"
}

For tools with multiple auth requirements, the service discovery endpoint will list them in the auth_requirements array:

{
  "functions": [
    {
      "name": "get-combined-data",
      "description": "Gets data from multiple services",
      "parameters": [...],
      "endpoint": "/tools/get-combined-data",
      "auth_requirements": [
        {
          "provider": "google",
          "scope_bundle": "calendar",
          "required": true
        },
        {
          "provider": "microsoft",
          "scope_bundle": "outlook",
          "required": true
        }
      ]
    }
  ]
}

Building and Publishing the NuGet Package

The SDK includes scripts to help with building and publishing the NuGet package.

Building the Package

You can build the NuGet package using the provided scripts:

Windows (PowerShell)
.\publish.ps1 -Build
macOS/Linux (Bash)
./publish.sh

The package will be built in the bin/Release directory.

Publishing to NuGet

To publish the package to NuGet.org, you'll need an API key from your NuGet account:

Windows (PowerShell)
.\publish.ps1 -Push -ApiKey "your-nuget-api-key"
macOS/Linux (Bash)
./publish.sh --push --api-key "your-nuget-api-key"

You can also specify a different NuGet feed:

Windows (PowerShell)
.\publish.ps1 -Push -ApiKey "your-api-key" -Source "https://your-nuget-feed"
macOS/Linux (Bash)
./publish.sh --push --api-key "your-api-key" --source "https://your-nuget-feed"

API Reference

Models

  • ParameterType: Enum for parameter types (String, Integer, Number, Boolean, Array, Object)
  • Parameter: Parameter definition for a tool
  • AuthRequirement: Authentication requirements for a tool
  • Function: Function definition for a tool
  • AuthData: Authentication data from a request

Attributes

  • [Tool(name, description)]: Marks a method as an Opal tool
  • [RequiresAuth(provider, scopeBundle, required)]: Specifies authentication requirements

ToolsService

  • AddOpalToolsService(): Extension method to add the tools service to a WebApplication
  • RegisterToolsFromCallingAssembly(): Registers all tools from the calling assembly
  • RegisterToolsFromExecutingAssembly(): Registers all tools from the executing assembly
  • RegisterToolsFromAssembly(assembly): Registers all tools from the specified assembly

Best Practices

  1. Use the [Tool] attribute on static methods
  2. Define parameter models with clear property descriptions
  3. Return simple objects that can be serialized to JSON
  4. Use async methods for tools that perform I/O operations
  5. Handle errors gracefully within your tool methods
  6. Provide clear descriptions for tools and parameters

Advanced Usage

Custom Parameter Validation

You can use standard .NET validation attributes:

public class GreetingParameters
{
    [Required]
    [StringLength(100)]
    public string Name { get; set; } = string.Empty;

    [RegularExpression("english|spanish|french", ErrorMessage = "Language must be english, spanish, or french")]
    public string? Language { get; set; }
}

Dependency Injection

For tools that need access to services:

[Tool("get-weather", "Gets the weather for a location")]
public static async Task<object> GetWeather(WeatherParameters parameters, HttpContext context)
{
    var weatherService = context.RequestServices.GetRequiredService<IWeatherService>();
    var forecast = await weatherService.GetForecastAsync(parameters.Location);

    return new
    {
        location = parameters.Location,
        forecast
    };
}

License

MIT License

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0 160 5/5/2025