Install
$ agentstack add skill-impertio-studio-speckle-claude-skill-package-speckle-impl-sharp-sdk ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
speckle-impl-sharp-sdk
Quick Reference
NuGet Packages
| Package | Purpose | Required | |---------|---------|----------| | Speckle.Sdk | Core: Send/Receive, Serialization, API client, Transports | YES | | Speckle.Objects | Domain model classes (geometry, BIM, structural) | YES for AEC data | | Speckle.Sdk.Dependencies | IL Repack dependency isolation for plugin environments | YES for connectors | | Speckle.Automate.Sdk | Speckle Automate function development | Only for Automate |
Target Framework
| Requirement | Value | |-------------|-------| | Target | .NET Standard 2.0 | | Development SDK | .NET 8.0.4xx | | Tested platforms | Windows, macOS | | License | Apache-2.0 | | Repository | specklesystems/speckle-sharp-sdk |
Critical Warnings
NEVER use the legacy speckle-sharp packages (Speckle.Core, old Speckle.Objects). They are DEPRECATED. ALWAYS use the new Speckle.Sdk packages from the speckle-sharp-sdk repository.
NEVER call .Result or .Wait() on async Send/Receive operations in UI applications. This causes deadlocks. ALWAYS use await.
NEVER build a connector for a host application (Revit, Rhino, etc.) without using Speckle.Sdk.Dependencies for dependency isolation. Version conflicts WILL crash the host application.
NEVER omit [DetachProperty] on large nested objects (meshes, display values). Without detachment, the entire child object is serialized inline, causing bloated payloads and severe performance degradation.
NEVER forget to pass a CancellationToken to Operations.Send() and Operations.Receive() in interactive applications. Without it, there is no way to gracefully cancel long-running operations.
NEVER hardcode personal access tokens in source code. ALWAYS use environment variables, secret managers, or the Speckle Manager account system.
Old vs New SDK: Migration Guide
DEPRECATED: speckle-sharp (Legacy)
The original C# SDK lived in the speckle-sharp repository with monolithic architecture:
| Legacy Package | Status | Replacement | |----------------|--------|-------------| | Speckle.Core | DEPRECATED | Speckle.Sdk | | Speckle.Objects (old) | DEPRECATED | Speckle.Objects (new, from speckle-sharp-sdk) | | Speckle.DesktopUI | DEPRECATED | Not replaced (connector-specific UI) |
CURRENT: speckle-sharp-sdk
The new SDK focuses on clean dependency boundaries, .NET Standard 2.0 targeting, and IL Repack isolation for safe embedding in host applications.
Migration checklist:
- Remove all
Speckle.CoreNuGet references - Install
Speckle.SdkandSpeckle.Objectsfrom NuGet - Update namespace imports:
Speckle.Core.*→Speckle.Sdk.* - For connectors: add
Speckle.Sdk.Dependenciesfor IL Repack isolation - Verify all
Operations.*calls compile against the new signatures
Installation
# CLI
dotnet add package Speckle.Sdk
dotnet add package Speckle.Objects
Client and Account Setup
Account Creation (Manual: No Speckle Manager)
var account = new Account();
account.token = "YOUR-PERSONAL-ACCESS-TOKEN";
account.serverInfo = new ServerInfo { url = "https://app.speckle.systems/" };
Account from Environment Variable
var account = new Account
{
token = Environment.GetEnvironmentVariable("SPECKLE_TOKEN"),
serverInfo = new ServerInfo
{
url = Environment.GetEnvironmentVariable("SPECKLE_SERVER_URL")
?? "https://app.speckle.systems/"
}
};
Client Initialization
var client = new Client(account);
The Client class wraps the Speckle Server GraphQL API. It provides methods for managing projects (streams), models (branches), versions (commits), and user operations.
Account from Speckle Manager
When Speckle Manager is installed, accounts are stored locally and can be retrieved:
// Get the default account configured in Speckle Manager
var account = AccountManager.GetDefaultAccount();
// Get all locally stored accounts
var accounts = AccountManager.GetAccounts();
// Get accounts for a specific server
var accounts = AccountManager.GetAccounts("https://app.speckle.systems");
Operations API
All operations in Speckle.Sdk are async. ALWAYS use await.
Send
var transport = new ServerTransport(account, streamId);
var (rootObjId, convertedRefs) = await Operations.Send(
baseObject,
new ITransport[] { transport },
onProgressAction: progress,
cancellationToken: cts.Token
);
Parameters:
value(Base) — the root object to sendtransports(IReadOnlyCollection) — destination transports (MUST NOT be empty)onProgressAction(IProgress?) — optional progress callbackcancellationToken(CancellationToken) — optional cancellation support
Returns: Tuple of (string rootObjId, IReadOnlyDictionary convertedReferences)
Flow:
- Validates inputs (non-null value, non-empty transports)
- Calls
BeginWrite()on all transports - Serializes the object tree via
SpeckleObjectSerializer - Writes serialized objects to ALL transports simultaneously
- Calls
EndWrite()on all transports (in finally block) - Returns root object hash and converted references
Receive
var transport = new ServerTransport(account, streamId);
var receivedObject = await Operations.Receive(
objectId,
remoteTransport: transport,
localTransport: null, // uses default SQLiteTransport
onProgressAction: progress,
cancellationToken: cts.Token
);
Parameters:
objectId(string) — hash of the root objectremoteTransport(ITransport?) — source transport (typically ServerTransport)localTransport(ITransport?) — cache transport (defaults to SQLiteTransport)onProgressAction(IProgress?) — optional progress callbackcancellationToken(CancellationToken) — optional cancellation support
Returns: Base — the deserialized root object with all children
Flow:
- If
localTransportis null, creates default SQLiteTransport - Checks local transport first (cache-first strategy)
- On cache miss, calls
CopyObjectAndChildren()on remote to populate local cache - Deserializes from local transport
- Returns reconstructed
Baseobject
Serialize / Deserialize
// Serialize to JSON
string json = Operations.Serialize(baseObject);
// Deserialize from JSON (async)
Base deserialized = await Operations.DeserializeAsync(json, cancellationToken);
Helpers: Simplified API
The Helpers class provides a streamlined API for common operations:
// Send — takes a stream URL directly
await Helpers.Send(streamUrl, baseObject, account);
// Receive — takes a stream URL directly
var received = await Helpers.Receive(streamUrl, account);
Helpers automatically resolve the stream URL into server address, stream ID, and branch/commit references. Use Helpers for quick prototyping and scripts. Use the full Operations API for production code requiring progress reporting, cancellation, and multi-transport patterns.
ServerTransport
var transport = new ServerTransport(
http, // ISpeckleHttp — HTTP client abstraction
activityFactory, // ISdkActivityFactory — telemetry
account, // Account — authentication
streamId, // string — project/stream ID
timeoutSeconds: 60,
blobStorageFolder: null
);
Key behaviors:
- Uses a background
SendingThreadMain()thread for upload processing - Implements server-side deduplication via
HasObjects()before uploading - Separates blob uploads from object uploads
BeginWrite()starts the background sending threadWriteComplete()polls until all queued data has been uploadedEndWrite()terminates the sending thread
The stream_id parameter corresponds to the project ID in current Speckle terminology. Projects were formerly called streams.
Base Class
The Base class is the foundation of all Speckle objects. It behaves as "a dictionary with added Speckle smarts."
Property Attributes
| Attribute | Purpose | When to Use | |-----------|---------|-------------| | [DetachProperty] | Stores object separately, referenced by hash | ALWAYS for large nested objects (meshes, display values) | | [Chunkable(size)] | Splits large lists into chunks during serialization | ALWAYS for large arrays (vertices, faces, colors) | | [SchemaInfo(name, desc)] | Metadata for schema generation | Documentation and tooling |
Dynamic Properties
var obj = new Base();
obj["customProperty"] = "value"; // Dictionary-style
obj["nestedObject"] = new Base(); // Nested objects
obj["numbers"] = new List(); // Collections
Flatten Extension
using Speckle.Sdk.Models.Extensions;
// Recursively flatten nested object hierarchies
IEnumerable allObjects = rootObject.Flatten();
Speckle.Objects Domain Model
The Speckle.Objects package provides typed classes for AEC data:
Geometry
| Class | Namespace | Key Properties | |-------|-----------|----------------| | Point | Speckle.Objects.Geometry | x, y, z | | Vector | Speckle.Objects.Geometry | x, y, z | | Line | Speckle.Objects.Geometry | start, end | | Polyline | Speckle.Objects.Geometry | value (flat coordinate list) | | Curve | Speckle.Objects.Geometry | Various curve types | | Mesh | Speckle.Objects.Geometry | vertices, faces, colors, textureCoordinates | | Brep | Speckle.Objects.Geometry | Surface representation | | Plane | Speckle.Objects.Geometry | origin, normal, xdir, ydir | | Box | Speckle.Objects.Geometry | basePlane, xSize, ySize, zSize | | Circle | Speckle.Objects.Geometry | plane, radius | | Arc | Speckle.Objects.Geometry | plane, radius, startAngle, endAngle |
Built Environment
| Class | Namespace | Key Properties | |-------|-----------|----------------| | Wall | Speckle.Objects.BuiltElements | height, baseLine, displayValue | | Floor | Speckle.Objects.BuiltElements | outline, displayValue | | Beam | Speckle.Objects.BuiltElements | baseLine, displayValue | | Column | Speckle.Objects.BuiltElements | baseLine, displayValue | | Room | Speckle.Objects.BuiltElements | name, number, displayValue | | Level | Speckle.Objects.BuiltElements | name, elevation | | GridLine | Speckle.Objects.BuiltElements | baseCurve, label |
Structural
| Class | Namespace | |-------|-----------| | Node | Speckle.Objects.Structural.Geometry | | Element1D | Speckle.Objects.Structural.Geometry | | Element2D | Speckle.Objects.Structural.Geometry | | Element3D | Speckle.Objects.Structural.Geometry | | Property1D | Speckle.Objects.Structural.Properties | | Property2D | Speckle.Objects.Structural.Properties | | Material | Speckle.Objects.Structural.Materials |
Every class extends Base and defines typed properties with serialization attributes.
IL Repack: Dependency Isolation
The Problem
Host applications (Revit, Rhino, Grasshopper, Blender) load their own dependencies at specific versions. Without isolation, Speckle's dependencies (Newtonsoft.Json, System.Text.Json, etc.) conflict with the host's versions, causing runtime crashes.
The Solution
Speckle.Sdk.Dependencies uses IL Repack to merge and internalize all external dependencies into a single assembly with internalized types. This prevents namespace collisions entirely.
When to Use IL Repack
| Scenario | Use IL Repack? | |----------|---------------| | Standalone .NET application | NO — no host dependency conflicts | | Revit add-in / connector | YES — Revit loads its own Newtonsoft.Json | | Rhino plugin / Grasshopper component | YES — Rhino has its own dependency set | | Blender add-on (via .NET interop) | YES — isolation prevents conflicts | | Unit test project | NO — test runners handle dependencies | | Speckle Automate function | NO — runs in isolated container | | Console tool / CLI | NO — no host application |
How It Works
Speckle.Sdk.Dependenciesis added as a NuGet reference- At build time, IL Repack merges external DLLs into the Speckle assembly
- All merged types become
internal, preventing namespace collisions - The connector DLL ships as a self-contained unit
Dependency Injection Patterns
Registering Speckle Services
// In your DI container setup (e.g., Microsoft.Extensions.DependencyInjection)
services.AddSingleton(provider =>
{
var account = new Account
{
token = Environment.GetEnvironmentVariable("SPECKLE_TOKEN"),
serverInfo = new ServerInfo
{
url = "https://app.speckle.systems/"
}
};
return account;
});
services.AddTransient(provider =>
{
var account = provider.GetRequiredService();
return new Client(account);
});
Transport as Transient
ALWAYS register transports as transient — each operation needs its own transport instance:
services.AddTransient(provider =>
{
var account = provider.GetRequiredService();
return new ServerTransport(account, streamId);
});
Progress Reporting
var progress = new Progress(args =>
{
Console.WriteLine($"{args.ProgressEvent}: {args.Count}");
});
await Operations.Send(data, transports, onProgressAction: progress);
await Operations.Receive(objectId, transport, onProgressAction: progress);
ALWAYS provide progress reporting in interactive applications to give users feedback on long-running operations.
Reference Links
- [references/methods.md](references/methods.md) — API signatures for Operations, Client, Base, ServerTransport, Helpers
- [references/examples.md](references/examples.md) — Working code examples for common Speckle C# workflows
- [references/anti-patterns.md](references/anti-patterns.md) — What NOT to do, with WHY explanations
Official Sources
- https://docs.speckle.systems/developers/sdks/dotnet/introduction.md
- https://github.com/specklesystems/speckle-sharp-sdk
- https://speckle.guide/dev/dotnet.html
- https://www.nuget.org/packages/Speckle.Sdk
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Impertio-Studio
- Source: Impertio-Studio/Speckle-Claude-Skill-Package
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.