独自の Package を書く
テンプレートから Package を作ります。
クイックスタート では、ほかの人が書いた Package をデプロイしました。このページでは、テンプレートをもとに自分の Package を作ります。どのテンプレートにも、動作する Tool が 1 つと、Subako にアップロードする Bundle をまとめるビルドスクリプト、Tool を普通のコードとして実行するテストが入っています。
テンプレートから始める
wasm32-wasip1 ターゲットを追加した Rust と、cargo-generate が必要です。
rustup target add wasm32-wasip1
cargo install cargo-generate
cargo generate subako-ai/subako-function-template-rust --name hello
cd hellosrc/main.rs には Tool が 1 つ定義されています。doc コメントはモデルが読む説明に、入力の型は Tool の Schema になります。
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use subako_function_sdk::{ToolError, function, package};
#[derive(Deserialize, JsonSchema)]
struct GreetInput {
/// Who to greet.
name: String,
}
#[derive(Serialize, JsonSchema)]
struct Greeting {
message: String,
}
/// Greet someone by name.
#[function]
fn greet(input: GreetInput) -> Result<Greeting, ToolError> {
Ok(Greeting { message: format!("Hello, {}!", input.name) })
}
package! {
name: "hello",
description: "Says hello.",
functions: [greet],
}cargo test
./package.sh # dist/hello.tar.gz に書き出しますNode 20 以降が必要です。
git clone https://github.com/subako-ai/subako-function-template-typescript hello
cd hellopackage.json と subako-package.json の my-function を hello に変更します。src/index.ts には Tool が 1 つ定義されており、その Schema は zod で書かれています。
import { serve, tool } from "@subako-ai/function-sdk";
import { z } from "zod";
const add = tool({
name: "add",
description: "Add two numbers.",
input: z.object({
a: z.number().describe("the first number"),
b: z.number().describe("the second number"),
}),
output: z.object({ sum: z.number() }),
run: ({ a, b }) => ({ sum: a + b }),
});
serve([add]);npm install
npm run typecheck
npm run build # dist/ に書き出します
npx @subako-ai/function-sdk pack # hello.tar.gz に書き出しますGo 1.25 以降が必要です。
go run golang.org/x/tools/cmd/gonew@latest \
github.com/subako-ai/subako-function-template-go example.com/hello
cd hellomain.go は、公式の MCP Go SDK で書かれた MCP サーバーです。mcp.AddTool で追加したものがそれぞれ Tool になり、入力の struct が Tool の Schema になります。
type GreetInput struct {
Name string `json:"name" jsonschema:"who to greet"`
}
type Greeting struct {
Message string `json:"message"`
}
func greet(ctx context.Context, req *mcp.CallToolRequest, in GreetInput) (*mcp.CallToolResult, Greeting, error) {
if in.Name == "" {
return nil, Greeting{}, errors.New("name must not be empty")
}
return nil, Greeting{Message: "Hello, " + in.Name + "!"}, nil
}
func main() {
server := mcp.NewServer(&mcp.Implementation{Name: "hello", Version: "0.1.0"}, nil)
mcp.AddTool(server, &mcp.Tool{Name: "greet", Description: "Greet someone by name."}, greet)
subakofn.Serve(server)
}go test ./...
bash package.sh # dist/hello.tar.gz に書き出しますビルドすると Bundle ができます。subako-package.json、module.wasm、Module が読む assets/ (あれば) をまとめた .tar.gz です。詳しくは Package とバージョン を参照してください。
手元のマシンで試す
Rust と Go のテンプレートのテスト (cargo test と go test) は、Subako を介さずに Tool を普通のコードとして呼び出します。TypeScript の Package は、npm run typecheck でランタイムが提供するグローバルに対して型チェックできます。ビルドした Module そのものを Subako と同じように実行するには、ABI の ローカルでのテスト を参照してください。
アップロードと新しいバージョンの追加
クイックスタート と同じように、Function › Package をアップロード で Archive をアップロードします。2 回目以降のビルドは、Package のページの 新しいバージョンをアップロード からアップロードします。
subako function create dist/hello.tar.gz # バージョン 1
subako function push <function-id> dist/hello.tar.gz # 以降のすべてのバージョンどちらのコマンドも、Archive の代わりに Bundle にまとめる前のディレクトリを指定できます。これを使えば、CI からマージのたびに新しいバージョンを push できます。詳しくは CLI を参照してください。
アップロードしたら、クイックスタートと同じように Function package で Agent に付与します。Agent のバージョンが Package の 最新 を使う設定なら、push 以降に開始した Session から新しいバージョンが使われます。