---
title: 独自の Package を書く
description: テンプレートから Package を作ります。
---

[クイックスタート](/ja/functions/quickstart) では、ほかの人が書いた Package をデプロイしました。このページでは、テンプレートをもとに自分の Package を作ります。どのテンプレートにも、動作する Tool が 1 つと、Subako にアップロードする Bundle をまとめるビルドスクリプト、Tool を普通のコードとして実行するテストが入っています。

## テンプレートから始める

**Rust**

`wasm32-wasip1` ターゲットを追加した Rust と、[cargo-generate](https://github.com/cargo-generate/cargo-generate) が必要です。

```bash
rustup target add wasm32-wasip1
cargo install cargo-generate
cargo generate subako-ai/subako-function-template-rust --name hello
cd hello
```

`src/main.rs` には Tool が 1 つ定義されています。doc コメントはモデルが読む説明に、入力の型は Tool の Schema になります。

```rust src/main.rs
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],
}
```

```bash
cargo test
./package.sh        # dist/hello.tar.gz に書き出します
```

**TypeScript**

Node 20 以降が必要です。

```bash
git clone https://github.com/subako-ai/subako-function-template-typescript hello
cd hello
```

`package.json` と `subako-package.json` の `my-function` を `hello` に変更します。`src/index.ts` には Tool が 1 つ定義されており、その Schema は zod で書かれています。

```ts src/index.ts
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]);
```

```bash
npm install
npm run typecheck
npm run build                       # dist/ に書き出します
npx @subako-ai/function-sdk pack    # hello.tar.gz に書き出します
```

**Go**

Go 1.25 以降が必要です。

```bash
go run golang.org/x/tools/cmd/gonew@latest \
  github.com/subako-ai/subako-function-template-go example.com/hello
cd hello
```

`main.go` は、公式の MCP Go SDK で書かれた MCP サーバーです。`mcp.AddTool` で追加したものがそれぞれ Tool になり、入力の struct が Tool の Schema になります。

```go main.go
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)
}
```

```bash
go test ./...
bash package.sh     # dist/hello.tar.gz に書き出します
```

ビルドすると **Bundle** ができます。`subako-package.json`、`module.wasm`、Module が読む `assets/` (あれば) をまとめた `.tar.gz` です。詳しくは [Package とバージョン](/ja/functions/packages) を参照してください。

## 手元のマシンで試す

Rust と Go のテンプレートのテスト (`cargo test` と `go test`) は、Subako を介さずに Tool を普通のコードとして呼び出します。TypeScript の Package は、`npm run typecheck` でランタイムが提供するグローバルに対して型チェックできます。ビルドした Module そのものを Subako と同じように実行するには、ABI の [ローカルでのテスト](/ja/functions/abi#ローカルでのテスト) を参照してください。

## アップロードと新しいバージョンの追加

**コンソール**

[クイックスタート](/ja/functions/quickstart#アップロードする) と同じように、**Function** › **Package をアップロード** で Archive をアップロードします。2 回目以降のビルドは、Package のページの **新しいバージョンをアップロード** からアップロードします。

**CLI**

```bash
subako function create dist/hello.tar.gz              # バージョン 1
subako function push <function-id> dist/hello.tar.gz  # 以降のすべてのバージョン
```

どちらのコマンドも、Archive の代わりに Bundle にまとめる前のディレクトリを指定できます。これを使えば、CI からマージのたびに新しいバージョンを push できます。詳しくは [CLI](/ja/build/cli#function) を参照してください。

アップロードしたら、クイックスタートと同じように **Function package** で Agent に付与します。Agent のバージョンが Package の **最新** を使う設定なら、push 以降に開始した Session から新しいバージョンが使われます。

## 次のステップ

**[ランタイム](/ja/functions/runtime)**

Volume、Asset、HTTP、画像、そして呼び出しに適用される制限。

**[Rust](/ja/functions/rust)**

Rust SDK で扱う Tool、エラー、ファイル、HTTP、画像。

**[TypeScript](/ja/functions/typescript)**

同じことを TypeScript SDK で。WebAssembly のツールチェーンなしでビルドできます。

**[サンプル](/ja/functions/examples)**

そのまま読めて、出発点にもできる完成した Package。
