Action SDKs
Ce contenu n’est pas encore disponible dans votre langue.
mashin provides SDKs in six languages for building external action services. Each SDK implements the same HTTP contract, so your action service works the same way regardless of what language it is written in.
For a guided walkthrough of building an action service, see Building Action Services.
Available SDKs
Section titled “Available SDKs”The SDKs live in the mashin repository under sdks/. None of them is published to a package registry yet, so today you consume them from source: clone the repository and point your project at the directory for your language.
| Language | Module you import | Source directory |
|---|---|---|
| Python | mashin_effects |
sdks/python |
| TypeScript | @mashin/effects |
sdks/typescript |
| Swift | MashinEffects |
sdks/swift |
| Go | effects |
sdks/go |
| Rust | mashin_effects |
sdks/rust |
| Elixir | MashinEffects |
sdks/elixir |
Publishing these to PyPI, npm, hex, crates.io and the Swift package index is a launch checklist item. Until that happens, an install command on this page would 404 on the reader’s first line, so the page shows the source directory instead. The quick starts below are the code you write once the SDK is on your path.
The HTTP contract
Section titled “The HTTP contract”Every action service exposes three HTTP endpoints:
| Endpoint | Method | Purpose |
|---|---|---|
/execute |
POST | Run the action. Receives {"input": {...}, "context": {...}}, returns {"status": "completed", "output": {...}, "audit": {"duration_ms": N}} |
/governance |
GET | Return the action.s name, version, capabilities, and input/output schema |
/health |
GET | Return {"status": "healthy", "version": "0.1.0"} |
The SDK handles the HTTP server, routing, request parsing, error handling, and audit timing. You implement two functions: execute (your logic) and governance (your declaration).
Quick start by language
Section titled “Quick start by language”Python
Section titled “Python”The distribution is mashin-effects and the import package is mashin_effects. Until it is on PyPI, install it from your clone with pip install -e sdks/python.
from mashin_effects import EffectService
class SentimentAnalyzer(EffectService): name = "sentiment-analyzer" version = "1.0.0" capabilities = ["external_api_call"] inputs = [{"name": "text", "type": "string", "required": True}] outputs = [{"name": "sentiment", "type": "string"}, {"name": "score", "type": "number"}]
def execute(self, input, context): text = input.get("text", "") # Your analysis logic here return {"sentiment": "positive", "score": 0.85}
if __name__ == "__main__": SentimentAnalyzer().serve(port=8080)TypeScript
Section titled “TypeScript”The package is @mashin/effects. Until it is on npm, add it from your clone: "@mashin/effects": "file:../mashin-core/sdks/typescript" in your package.json dependencies.
import { EffectService } from "@mashin/effects";
class SentimentAnalyzer extends EffectService { governance() { return { name: "sentiment-analyzer", version: "1.0.0", capabilities: ["external_api_call"], inputs: [{ name: "text", type: "string", required: true }], outputs: [{ name: "sentiment", type: "string" }, { name: "score", type: "number" }], }; }
async execute(input: Record<string, any>, context: Record<string, any>) { const text = input.text ?? ""; // Your analysis logic here return { sentiment: "positive", score: 0.85 }; }}
new SentimentAnalyzer().serve({ port: 8080 });The module is declared as github.com/mashin-live/effects-go. It is not fetchable yet, so add a replace pointing at your clone:
require github.com/mashin-live/effects-go v0.0.0replace github.com/mashin-live/effects-go => ../mashin-core/sdks/gopackage main
import effects "github.com/mashin-live/effects-go"
type SentimentAnalyzer struct{}
func (s SentimentAnalyzer) Execute(input, context map[string]any) (map[string]any, error) { text, _ := input["text"].(string) _ = text // Your analysis logic here return map[string]any{"sentiment": "positive", "score": 0.85}, nil}
func (s SentimentAnalyzer) Governance() effects.GovernanceDeclaration { return effects.GovernanceDeclaration{ Name: "sentiment-analyzer", Version: "1.0.0", Capabilities: []string{"external_api_call"}, Inputs: []effects.FieldSpec{{Name: "text", Type: "string", Required: true}}, Outputs: []effects.FieldSpec{{Name: "sentiment", Type: "string"}, {Name: "score", Type: "number"}}, }}
func main() { effects.Serve(SentimentAnalyzer{}, effects.WithPort(8080))}The crate is mashin-effects, not yet on crates.io, so depend on it by path:
[dependencies]mashin-effects = { path = "../mashin-core/sdks/rust" }tokio = { version = "1", features = ["full"] }async-trait = "0.1"serde_json = "1"use async_trait::async_trait;use mashin_effects::{EffectService, GovernanceDeclaration, serve};use std::collections::HashMap;use serde_json::Value;
struct SentimentAnalyzer;
#[async_trait]impl EffectService for SentimentAnalyzer { async fn execute( &self, input: HashMap<String, Value>, _context: HashMap<String, Value>, ) -> Result<HashMap<String, Value>, Box<dyn std::error::Error + Send + Sync>> { let mut output = HashMap::new(); output.insert("sentiment".into(), Value::from("positive")); output.insert("score".into(), Value::from(0.85)); Ok(output) }
fn governance(&self) -> GovernanceDeclaration { GovernanceDeclaration { name: "sentiment-analyzer".into(), version: "1.0.0".into(), capabilities: vec!["external_api_call".into()], inputs: vec![], outputs: vec![], rate_limits: None, } }}
#[tokio::main]async fn main() { serve(SentimentAnalyzer, 8080).await.unwrap();}MashinEffects is a library product of the MashinSDK package in sdks/swift. It is not on the Swift package index yet, so depend on your clone by path:
dependencies: [ .package(path: "../mashin-core/sdks/swift"),]import MashinEffects
struct SentimentAnalyzer: EffectService { func execute(input: [String: Any], context: [String: Any]) async throws -> [String: Any] { return ["sentiment": "positive", "score": 0.85] }
func governance() -> GovernanceDeclaration { GovernanceDeclaration( name: "sentiment-analyzer", version: "1.0.0", capabilities: ["external_api_call"], inputs: [FieldSpec(name: "text", type: "string", required: true)], outputs: [FieldSpec(name: "sentiment", type: "string"), FieldSpec(name: "score", type: "number")] ) }}
@main struct Main { static func main() async throws { let server = EffectServer(service: SentimentAnalyzer(), host: "0.0.0.0", port: 8080) try await server.run() }}Elixir
Section titled “Elixir”The app is :mashin_effects, not yet on hex, so depend on it by path:
def deps do [{:mashin_effects, path: "../mashin-core/sdks/elixir"}]enddefmodule SentimentAnalyzer do @behaviour MashinEffects.Service
@impl true def execute(input, _context) do {:ok, %{"sentiment" => "positive", "score" => 0.85}} end
@impl true def governance do %{ "name" => "sentiment-analyzer", "version" => "1.0.0", "capabilities" => ["external_api_call"], "inputs" => [%{"name" => "text", "type" => "string", "required" => true}], "outputs" => [%{"name" => "sentiment", "type" => "string"}, %{"name" => "score", "type" => "number"}] } endend
# StandaloneMashinEffects.start(SentimentAnalyzer, port: 8080)
# Or in a supervision treechildren = [ {MashinEffects, service: SentimentAnalyzer, port: 8080}]Testing your action service
Section titled “Testing your action service”All SDKs expose the same endpoints, so you can test with curl:
# Health checkcurl http://localhost:8080/health
# Governance declarationcurl http://localhost:8080/governance
# Executecurl -X POST http://localhost:8080/execute \ -H "Content-Type: application/json" \ -d '{"input": {"text": "This product is great"}, "context": {}}'Or use the CLI:
mashin action test http://localhost:8080Additional language examples
Section titled “Additional language examples”Beyond the six SDKs, the sdks/examples/ directory has standalone examples in Bun, Deno, Gleam, Zig, Kotlin, Ruby, and C#. These implement the HTTP contract directly without an SDK, proving that any language can participate as a mashin action service.
Next steps
Section titled “Next steps”- Building Action Services - Full guide to creating and registering actions
- CLI Action Commands - Managing action services from the terminal