# Custom MCP ควรอยู่ใน repo ของคุณ: ทางแก้ agent drift ที่ใช้เวลา 60 วินาที

> AI agent drift — พวกมันคิด shell command ขึ้นมาเอง, hallucinate URL, เดา CLI ภายใน วิธีแก้มาตรฐานคือ "เขียน custom MCP server" แต่โปรเจกต์ส่วนใหญ่ไม่ต้องการ server Octomind 0.29.0 ให้คุณวางสคริปต์ shebang ลงใน .agents/tools/, commit เข้า git, และเปลี่ยน shell wrapper 50 บรรทัดให้กลายเป็น MCP ระดับโปรเจกต์ที่ agent ของนักพัฒนาทุกคนใช้ในทุก turn

ในเดือน October 2025 GitHub commit เดียวปล่อย "skills" ที่ generate ด้วย LLM จำนวน 47 ตัวลงใน agent repository ยอดนิยม หนึ่งในนั้นสอนให้ Claude รัน `npx react-codeshift` แต่ package นั้นไม่มีอยู่ ไม่เคยมีอยู่เลย Claude hallucinate ขึ้นมาในช่วง training ผู้เขียนไม่ได้ตรวจสอบ และภายในไม่กี่สัปดาห์ไฟล์นั้น[แพร่กระจายไปยัง 237 forks](https://www.aikido.dev/blog/agent-skills-spreading-hallucinated-npx-commands) นักพัฒนาจริงรัน command นั้นใน terminal จริง `npm` พยายาม resolve package ที่เป็นภาพลวงตาหลายพันครั้งอย่างเต็มใจ

นี่คือส่วนหนึ่งของเรื่องราว AI agent ที่ไม่ได้ขึ้น keynote **Agent drift** เมื่อให้ shell และงานคลุมเครือ พวกมันจะหยิบ command ที่ฟังดูสมเหตุสมผลที่สุด แม้มันจะไม่มีอยู่ — และยิ่งให้ tool ทั่วไปมากเท่าไหร่ พวกมันยิ่ง drift มากขึ้น

คำตอบมาตรฐานในปี 2026 คือ: _เขียน custom MCP server_ กำหนด action ที่อยากให้ agent ทำ ให้ schema เข้มงวด ship เป็น binary แยก register ใน config ของ agent จำกัด model โดยให้ tool เฉพาะแทนที่จะให้ `bash`

คำตอบมาตรฐานนั้นถูกในหลักการแต่ผิดในทางปฏิบัติ การเขียน MCP server จริง — JSON-RPC framing, stdio handshake, schema definition, dependency tree แยก — เพื่อ shell command เดียวคือ engineering theater ทีมส่วนใหญ่ยอมแพ้และอยู่กับ drift

[Octomind 0.29.0](/blog/release-round-may-2026) ปิดช่องว่างนั้น **Custom MCP ไม่ควรเป็นโปรเจกต์ มันควรเป็นไฟล์ใน repo ของคุณ**

---

## ปัญหา Drift ที่มีตัวเลขสนับสนุน

ถ้าคุณดู agent รันมาสักพัก คุณจะเห็น drift:

- มันรัน `npm test` ใน `pnpm` monorepo
- มัน curl `https://staging.example.com/api` แทน `https://api-staging.acme.internal/v3` ตัวจริงที่มี auth-gated
- มันพยายามติดตั้ง package ที่ชื่อเกือบใช่แต่ไม่ใช่
- มันใช้ `git tag` ดิบแทน release script ของทีม

paper เดือน May 2025 _[RAG-MCP: Mitigating Prompt Bloat in LLM Tool Selection](https://arxiv.org/abs/2505.03275)_ (Gan & Sun) ทำ MCP stress test และพบว่า baseline tool-selection accuracy ลดลงเหลือ **13.62%** เมื่อ scale — model ไม่สามารถเลือก tool ที่ถูกได้อย่างน่าเชื่อถืออีกต่อไป เพราะ description ของทุก tool ที่มันต้องพิจารณานั้นเบียดเสียด prompt และเจือจาง attention วิธีแก้แบบ retrieval ของพวกเขาทำให้สูงขึ้นกว่าสามเท่าเป็น 43.13% พร้อมลด prompt token ลงกว่า 50% accuracy ยังแย่อยู่ แต่ทิศทางของกราฟคือประเด็น: ยิ่งยัด tool เข้าไปมากเท่าไหร่ model ยิ่งเลือกได้แย่ลง

Anthropic ผู้*เขียน* MCP protocol [ยอมรับประเด็นเดียวกันเมื่อ November 4, 2025](https://www.anthropic.com/engineering/code-execution-with-mcp):

> "In cases where agents are connected to thousands of tools, they'll need to process hundreds of thousands of tokens before reading a request." (ในกรณีที่ agent เชื่อมต่อกับ tool หลายพันตัว พวกมันต้องประมวลผล token หลายแสนตัวก่อนอ่าน request)

benchmark ของพวกเขาเองแสดงว่า flow Drive → Salesforce ใช้ **150,000 token** ภายใต้ MCP loading แบบ naive ด้วย code-execution และ on-demand tool discovery flow เดียวกันรันใน **2,000 token** — ลดลง 98.7% [Tool Search Tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool) ตามมา (API version `20251119`) เลื่อน tool definition ไว้จนกว่าจะต้องการ documentation ระบุว่าโดยทั่วไปลด context bloat ลง**กว่า 85%** และระบุว่า "Claude's ability to correctly pick the right tool degrades significantly once you exceed 30–50 available tools." (ความสามารถของ Claude ในการเลือก tool ที่ถูกต้องเสื่อมลงอย่างมีนัยสำคัญเมื่อเกิน 30–50 available tools)

บทเรียนที่ทุกคนกำลังหลอมรวม: **tool ที่น้อยกว่า แคบกว่า เกี่ยวข้องกับโปรเจกต์ ชนะ catalog ขนาดใหญ่ทุกครั้ง** model ทำงานได้ดีกว่า ค่า token ลดลง drift ลดลงตามไปด้วย

ดังนั้นคำถามที่ถูกไม่ใช่ "ฉันจะเขียน MCP เพิ่มอย่างไร" แต่เป็น "ฉันจะทำให้ MCP ที่ฉันต้องการจริงๆ เขียนและ ship โดยไม่มีต้นทุนได้อย่างไร"

---

## ทำไม "แค่เขียน MCP server" ถึง scale ไม่ได้

[การวิเคราะห์ MCP server 1,412 ตัวของ Bloomberry](https://bloomberry.com/blog/we-analyzed-1400-mcp-servers-heres-what-we-learned/) เดือน February 2026 พบว่า **38.7% ของพวกมัน ship โดยไม่มี authentication เลย** median server expose แค่ five tools และประมาณครึ่งหนึ่งของบริษัทที่ publish ไม่มี public API ตั้งแต่แรก กรอบของ Bloomberry: "MCP might not be a wrapper on an existing API. It might be the first machine-readable interface they've ever shipped." (MCP อาจไม่ใช่ wrapper บน API ที่มีอยู่ มันอาจเป็น machine-readable interface แรกที่พวกเขาเคย ship) การระเบิดส่วนใหญ่คือการ ship โดยคนที่กำลังคิดออกใน production

ปัญหาไม่ใช่ว่า protocol พัง แต่ **unit of work ผิด** สำหรับ action เฉพาะโปรเจกต์ การเขียน MCP server ภาษา Python หรือ Node ด้วย stdio framing, schema registration และ deployment pipeline แยกนั้นเป็นรูปทรงที่ถูกสำหรับ "GitHub API" หรือ "Postgres database" มันเป็นรูปทรงที่ผิดสำหรับ "รัน staging deploy script ของเรา" — โค้ดที่เป็น bash สี่สิบบรรทัด อยู่ใน `bin/deploy` แล้ว ที่คุณอยากให้ agent เรียกตามชื่อแทนที่จะเดา

ผู้ปฏิบัติงานก็มาถึงข้อสรุปเดียวกัน จากกระทู้ Hacker News "MCP explained without hype or fluff" ([item 44063141](https://news.ycombinator.com/item?id=44063141)), commenter _0x457_:

> "Many of MCPs shouldn't have existed, IMO. […] I wanted amazon q to interact with github, so I added to its context that it can use `gh-cli` and it it worked pretty well. […] To make its and mine life easier, common things were saved as scripts in `bin/` and Justfile (also generated by it). […] Using github's official MCP bricks chat session every time for me."

และ _dvt_:

> "MCP is bloated AI hype that basically solves nothing […]. It's APIs talking to APIs that talk to other APIs."

ทั้งสองความเห็นถูกต้องเกี่ยวกับเคสที่พวกเขาอธิบาย CLI ทำงานได้ Local script ใน `bin/` ทำงานได้ การ wrap shell command บรรทัดเดียวใน MCP server 200 บรรทัดเพราะนั่นคือ pattern ที่ถูก bless อย่างเดียวคือสิ่งที่พัง

---

## MCP tool คืออะไรจริงๆ

ลอก protocol ออก MCP tool คือสามอย่าง:

1. **ชื่อและ description** เพื่อให้ model รู้ว่าเมื่อไหร่ควรหยิบมาใช้
2. **Parameter schema** เพื่อให้ model รู้ว่าควรส่งอะไร
3. **Executable** ที่ทำงาน

ทุกอย่างที่เหลือ — JSON-RPC framing, stdio handshake, capability negotiation — เป็นเรื่องของ _runtime_ ไม่ใช่เรื่องของ author paper ปี 2023 _[Tool Documentation Enables Zero-Shot Tool-Usage with Large Language Models](https://arxiv.org/abs/2308.00675)_ (Hsieh et al.) แสดงเชิงประจักษ์ว่าสำหรับ tool ที่ไม่คุ้นเคย **documentation ที่ชัดเจนชนะ few-shot demonstration** — และว่า "zero-shot prompts with only tool documentation" สามารถเทียบเท่า few-shot prompt บนงาน out-of-distribution นัยยะ: description ที่สั้นและแม่นยำบน tool มีค่ามากกว่า schema ซับซ้อนหรือกอง example

ถ้า tool _สั้น_ และ docs _สั้น_ interface ทั้งหมดควรแสดงได้ในไม่กี่บรรทัดของ header comment บนสคริปต์ที่ทำงาน

นั่นคือสิ่งที่ Octomind 0.29.0 ทำ

---

## Pattern: `.agents/tools/<name>`

นี่คือสัญญาทั้งหมด:

```bash
mkdir -p .agents/tools
cat > .agents/tools/deploy <<'EOF'
#!/usr/bin/env bash
# @description Deploy the API service to a target environment using our team's pipeline.
# @param *env string Target environment (staging|production)
# @param dry_run boolean If true, validate without applying

set -euo pipefail
cd "$OCTOMIND_WORKDIR"

env="$OCTOMIND_PARAM_ENV"
dry="${OCTOMIND_PARAM_DRY_RUN:-false}"

if [[ "$dry" == "true" ]]; then
  ./bin/deploy --env "$env" --dry-run
else
  ./bin/deploy --env "$env"
fi
EOF
chmod +x .agents/tools/deploy
```

มีสามอย่างเพิ่งเกิดขึ้น:

1. Octomind ค้นพบสคริปต์ครั้งถัดไปที่ session รัน
2. มัน parse บรรทัด `@description` และ `@param` เป็น JSON-Schema tool definition
3. model ตอนนี้เห็น tool `deploy` — scope กับ repo นี้ — ที่มี `env` (required) และ `dry_run` (optional) มันจะเลือก `deploy(env="staging")` มากกว่า `bash("./bin/deploy --env staging")` เพราะ named tool มี signal-to-noise ratio ที่ชัดเจนกว่า

ความพึงพอใจนั้นคือ guardrail ที่คุณต้องการ model ไม่ได้ free-associate จาก "deploy" ไปยัง "kubectl apply" ไปยัง "helm install" อีกต่อไป มัน entry point เดียว ด้วย typed parameter ที่ทำ deploy จริงของทีม

เพื่อตรวจสอบ wiring รัน validation บรรทัดเดียว:

```bash
echo "/mcp" | octomind run
```

คุณจะเห็น `local` MCP server ใน output โดยมี `deploy` listed ใต้ ถ้าสคริปต์ไม่ปรากฏ runtime จะบอกคุณว่าทำไม — permission ผิด, ขาด `@description`, มีจุดในชื่อไฟล์

---

## กายวิภาคของ Header

comment block นำหน้าคือ interface ทั้งหมด Octomind อ่านมันใหม่ทุก turn (ราคาถูก — `read_dir` หนึ่งครั้ง) และ rebuild schema แก้และ save call tool ครั้งถัดไปใช้ version ใหม่ ไม่ต้อง restart daemon

```bash
#!/usr/bin/env bash
# @description Short summary the model sees. Continuation lines without an
# @-tag append to the previous one, so multi-line descriptions Just Work.
# @param *target string Path to operate on (* prefix = required)
# @param force boolean Overwrite if the destination exists
# @param count integer Number of iterations
# @param tags array JSON list, e.g. ["foo","bar"]
```

prefix ของ comment สามารถเป็น `#` (bash, python, ruby, lua, perl, awk), `//` (node, deno), หรือ `--` (lua, SQL wrappers) runtime ไม่สนใจว่าภาษาไหนรันงาน

เมื่อ model เรียก tool octomind ส่ง parameter ให้คุณสองทาง:

| Channel   | Form                                                                                                           |
| --------- | -------------------------------------------------------------------------------------------------------------- |
| **stdin** | JSON object หนึ่งตัวตามด้วย EOF: `{"target":"src/x","force":true}`                                             |
| **env**   | `OCTOMIND_PARAM_TARGET=src/x`, `OCTOMIND_PARAM_FORCE=true`, รวมถึง `OCTOMIND_WORKDIR` และ `OCTOMIND_TOOL_NAME` |

Bash script มักอ่าน env var Python script มักอ่าน stdin JSON ทั้งสองมาถึงทุก call Stdout กลายเป็นผลลัพธ์ที่ model เห็น Stderr ถูก append ด้วย marker `[stderr]` Exit ไม่ใช่ศูนย์ → tool error

นั่นคือพื้นผิวทั้งหมด

---

## Drift จริงสี่อย่าง tool จริงสี่ตัว

เราเฝ้าดู agent ล้มเหลวในแต่ละสถานการณ์นี้ใน repo ของเราเองก่อนเขียน wrapper. Wrapper คือสิ่งที่หยุดมัน

### 1. Drift: "มันรัน `npm test` ใน `pnpm` monorepo"

agent เห็น `package.json` ที่ root พิมพ์ `npm test` ได้ error "no script found" เต็มหน้าจอ และรายงานว่าโปรเจกต์พัง

Wrapper — `.agents/tools/test`:

```bash
#!/usr/bin/env bash
# @description Run the project test suite. Defaults to fast unit tests.
# @param scope string One of: unit, integration, all (default: unit)
# @param package string Optional package filter, e.g. @acme/api

set -euo pipefail
cd "$OCTOMIND_WORKDIR"

scope="${OCTOMIND_PARAM_SCOPE:-unit}"
pkg="${OCTOMIND_PARAM_PACKAGE:-}"

case "$scope" in
  unit)        cmd=("pnpm" "-r" "test:unit") ;;
  integration) cmd=("pnpm" "-r" "test:integration" "--" "--runInBand") ;;
  all)         cmd=("pnpm" "-r" "test") ;;
  *) echo "Unknown scope: $scope" >&2; exit 2 ;;
esac

[[ -n "$pkg" ]] && cmd+=("--filter" "$pkg")
exec "${cmd[@]}"
```

ตอนนี้ agent เห็น `test(scope, package)` ใน tool list ของมัน description บอกค่า default มันเรียก `test()` และได้ผลจริงในครั้งแรก ไม่มีใครในทีมพิมพ์ "ใช้ `pnpm -r test:unit`" ลงในหน้าต่าง chat อีก

### 2. Drift: "มัน hallucinate URL ของ staging"

agent ต้องอ่าน record จาก staging API จริงของคุณที่ `https://api-staging.acme.internal/v3/users/42` ซึ่งต้องการ header `X-Acme-Token` มันกลับ curl `https://staging.example.com/api/users/42` — URL ที่มันแต่งขึ้นจากข้อมูล training — ไม่ได้อะไรกลับมาและรายงานว่า service down

Wrapper — `.agents/tools/api`:

```bash
#!/usr/bin/env bash
# @description Call our internal staging API. Returns raw JSON.
# @param *path string Path under /v3, e.g. /users/42
# @param method string HTTP method (default: GET)
# @param body string Optional JSON body for POST/PUT/PATCH

set -euo pipefail
: "${ACME_STAGING_TOKEN:?ACME_STAGING_TOKEN not set in environment}"

path="$OCTOMIND_PARAM_PATH"
method="${OCTOMIND_PARAM_METHOD:-GET}"
body="${OCTOMIND_PARAM_BODY:-}"
url="https://api-staging.acme.internal/v3${path}"

args=(-sS -X "$method" -H "X-Acme-Token: $ACME_STAGING_TOKEN")
[[ -n "$body" ]] && args+=(-H "Content-Type: application/json" --data "$body")

curl "${args[@]}" "$url"
```

URL ไม่ drift อีกต่อไปเพราะ URL ไม่ใช่หน้าที่ของ model อีก agent เรียก `api(path="/users/42")` และ URL จริงอยู่ในสคริปต์ Token มาจาก environment ของนักพัฒนา (`.envrc`, `direnv`, shell rc ของคุณ) — _tool_ ถูก commit, _secret_ ไม่

### 3. Drift: "มันอธิบาย feature flag service ซ้ำเป็นครั้งที่สี่"

agent debug ปัญหา UI คุณเตือนมัน (อีกครั้ง) ว่า feature-flag service มีอยู่ ว่า flag แตกต่างกันต่อ environment และ staging คือตัวที่เกี่ยวข้อง มันพยักหน้า ลืม ถามอีกครั้งใน session ถัดไป

Wrapper — `.agents/tools/flags`:

```python
#!/usr/bin/env python3
# @description Return the currently enabled feature flags for an environment.
# @param env string Environment to inspect (default: staging)

import json, os, sys, urllib.request

params = json.load(sys.stdin) if not sys.stdin.isatty() else {}
env = params.get("env") or os.environ.get("OCTOMIND_PARAM_ENV") or "staging"

url = f"https://flags.acme.internal/api/snapshot?env={env}"
req = urllib.request.Request(url, headers={"X-Acme-Token": os.environ["ACME_TOKEN"]})

with urllib.request.urlopen(req, timeout=10) as r:
    flags = json.load(r)

enabled = sorted(k for k, v in flags.items() if v.get("enabled"))
print("\n".join(enabled) if enabled else "(no flags enabled)")
```

ตอนนี้ model เปิด session เห็น `flags` ใน tool list และเรียกเองเมื่อต้องการ คุณหยุดเป็น cache มนุษย์สำหรับ "อะไรเปิดอยู่บน staging"

### 4. Drift: "มันใช้ `git tag` แทน release script ของเรา"

ทีมของคุณสร้าง `acme-cli` เพื่อให้ version bump, changelog, และ tag-then-push เกิดขึ้นในลำดับที่ถูก agent ข้ามมัน รัน `git tag v1.2.3` ดิบ ทำลาย convention และตอนนี้ CI run ครั้งถัดไปหา changelog ไม่เจอ

Wrapper — `.agents/tools/release`:

```bash
#!/usr/bin/env bash
# @description Cut a release using the team's acme-cli. Bumps version, updates
# CHANGELOG, tags the commit, and pushes. Use bump=patch unless minor or major
# is explicitly requested.
# @param *bump string One of: patch, minor, major
# @param dry_run boolean If true, show what would happen without pushing

set -euo pipefail
cd "$OCTOMIND_WORKDIR"

bump="$OCTOMIND_PARAM_BUMP"
dry="${OCTOMIND_PARAM_DRY_RUN:-false}"

args=(release --bump "$bump")
[[ "$dry" == "true" ]] && args+=(--dry-run)

acme-cli "${args[@]}"
```

นี่คือตัวที่ชนะใจเพื่อนร่วมทีม agent ตอนนี้ปฏิบัติตาม release convention ของทีมด้วยตัวเอง — version, changelog, tag, push — เพราะ tool มีอยู่ _ใน repo_ และ model เลือกมันมากกว่า `git` ดิบ

---

## Compounding Effect: มันอยู่ใน Repo

โพสต์ MCP code-execution ของ Anthropic เถียงว่าอนาคตคือ dynamic discovery: load tool เมื่อต้องการ drop เมื่อไม่ต้อง shebang pattern คือเวอร์ชัน local-first ของไอเดียนั้น สามคุณสมบัติซ้อนกัน:

**1. พื้นผิวแคบ drift ต่ำ** model เห็น action _ที่ตั้งชื่อแล้ว มี parameter_ พร้อม description บรรทัดเดียวแทน shell ทั่วไป Hsieh et al. พบว่า description เองทำงานส่วนใหญ่สำหรับ tool selection — example เป็นแค่ nice-to-have shebang header คือรูปทรงที่ถูกต้องสำหรับสิ่งนั้น: ชื่อ, description, typed param, ทุกอย่างใน comment block ที่ tool author maintain ควบคู่กับโค้ดอยู่แล้ว

**2. ทั้งทีมได้มาฟรี** MCP server แบบดั้งเดิมอยู่บน laptop ของนักพัฒนาคนเดียว เมื่อเพื่อนร่วมทีม clone repo server ไม่อยู่ที่นั่น agent ไม่เห็น tool และ drift กลับมา สคริปต์ `.agents/tools/` ถูก commit เข้า git Clone, `octomind run`, tool เดียวกันกับทุกคน

**3. tool วิวัฒน์ไปกับโค้ด** เปลี่ยนชื่อ service? อัปเดต wrapper ใน PR เดียวกัน เพิ่ม feature flag? อัปเดต wrapper ใน PR เดียวกัน AI tooling ของคุณอยู่ภายใต้ code review เหมือนสิ่งอื่นๆ drift ระหว่าง _สิ่งที่ agent คิดว่า repo เป็นยังไง_ และ _สิ่งที่ repo เป็นจริงๆ_ — ฆาตกร reliability ของ agent ที่เผาช้าๆ — ปิดเองอัตโนมัติ

หลังจากหนึ่งสัปดาห์ของสิ่งนี้ agent ใน terminal ของนักพัฒนาทุกคนหลอมรวมเป็นพฤติกรรมเดียวกันเพราะทุกคนรัน tool เดียวกันจาก repo เดียวกัน ความรู้เชิงสถาบันหยุดเป็น "สิ่งที่ฉันบอก agent ใน chat" และเริ่มเป็น artifact ที่มี version และตรวจสอบได้

---

## เมื่อไหร่ควรหันไปใช้ MCP Server แทน

Local tool ครอบคลุม 90% ที่เฉพาะโปรเจกต์ มันไม่ครอบคลุมทุกอย่าง ใช้ matrix นี้:

| คุณต้องการ…                                                           | ใช้                                         |
| --------------------------------------------------------------------- | ------------------------------------------- |
| _Action_ เฉพาะโปรเจกต์ (deploy, test, query flag, hit endpoint ภายใน) | **`.agents/tools/` shebang**                |
| ฉีด _instruction_ ของ domain เข้า context                             | [Skills](https://github.com/Muvon/octomind) |
| Tool ที่ใช้ซ้ำข้ามโปรเจกต์ที่มี schema รวยและ logic หลายขั้นตอน       | เขียน tap ด้วย MCP server                   |
| Process อายุยาว (connection pool, browser session, websocket)         | External `stdio`/`http` MCP server          |

Mental model: _ถ้าเนื้อหาของ MCP server ของคุณคือ "parse param, spawn binary นี้, return stdout" คุณไม่ต้องการ server — คุณต้องการ shell script 15 บรรทัด_

---

## Validation Loop

รันสิ่งนี้หลังเขียนหรือเปลี่ยน tool ใดๆ:

```bash
echo "/mcp" | octomind run
```

มัน boot session ใน directory ปัจจุบัน list ทุก MCP server ใน scope และออก คุณจะเห็น:

```
local: ✅ Running
  Type: LocalTools
  Configured tools: deploy, test, api, flags, release
```

ถ้า tool หาย:

| อาการ                    | สาเหตุ               | แก้                                                        |
| ------------------------ | -------------------- | ---------------------------------------------------------- |
| ไม่อยู่ใน `/mcp` output  | ไม่ executable       | `chmod +x .agents/tools/<name>`                            |
| ไม่อยู่ใน `/mcp` output  | ขาด `@description`   | เพิ่มบรรทัด                                                |
| ไม่อยู่ใน `/mcp` output  | ชื่อไฟล์มี `.`       | ตัด extension (`deploy`, ไม่ใช่ `deploy.sh`)               |
| Tool error เมื่อถูกเรียก | param-reading ไม่ตรง | ยืนยันว่าคุณอ่าน `OCTOMIND_PARAM_*` หรือ stdin ไม่ใช่ `$1` |

สำหรับ debug ที่ลึกกว่า: `OCTOMIND_LOG=debug echo "/mcp" | octomind run` แสดงว่าทำไมไฟล์ candidate แต่ละตัวถูกรับหรือข้าม

runtime ถือว่า `.agents/tools/` เป็น hot-reload — แก้, save, call tool ครั้งถัดไปใช้ version ใหม่ ไม่มี `octomind restart` ไม่มี daemon เขียน save เรียก

---

## เริ่มต้น

ถ้าคุณไม่มี octomind:

```bash
# macOS
brew install muvon/tap/octomind

# Any platform
cargo install octomind
```

จากนั้นใน repo ใดก็ได้:

```bash
mkdir -p .agents/tools
cat > .agents/tools/branch <<'EOF'
#!/usr/bin/env bash
# @description Print the current branch name.
git -C "$OCTOMIND_WORKDIR" rev-parse --abbrev-ref HEAD
EOF
chmod +x .agents/tools/branch

echo "/mcp" | octomind run
```

คุณควรเห็น `local` listed พร้อม `branch` Commit มัน:

```bash
git add .agents/tools/branch
git commit -m "agent: add branch-name tool for AI sessions"
```

นั่นคือ pattern ทั้งหมด ทุก dev ที่ pull repo มี tool ทุก agent run ใน directory เห็นมัน ไม่ต้อง setup เพิ่มที่ไหนบนเครื่องของใคร

---

## FAQ

**ทำไม wrapped tool ถึงลด drift ถ้า command ข้างใต้เหมือนกัน?**

เพราะ model ไม่ได้เลือกระหว่าง shell invocation หลายพันแบบที่ดูสมเหตุสมผลเท่ากันอีกต่อไป มันเลือกระหว่าง named, typed tool ไม่กี่ตัวพร้อม description ที่เขียนเพื่อมัน [RAG-MCP](https://arxiv.org/abs/2505.03275) วัดผล: tool-selection accuracy ลดลงเมื่อ catalog โต ชุดเล็กที่มีชื่อพร้อม description ชัดเจนคือรูปทรงที่*ถูกต้องเชิงประจักษ์*สำหรับ tool-using LLM

**นี่เป็นเรื่องของ Octomind เท่านั้นหรือ?**

การค้นพบ `.agents/tools/` เป็น feature ของ Octomind runtime ภายใน Octomind ทุก model — Claude, Kimi, GLM, GPT, local model — เห็นพวกมันเป็น MCP tool มาตรฐาน ถ้าคุณใช้ Claude Desktop หรือ Cursor ด้วย คุณสามารถ wrap `.agents/tools/` ด้วย MCP shim บาง แต่ leverage สูงสุดอยู่ใน Octomind ที่ discovery เป็นอัตโนมัติและ scope ระดับโปรเจกต์

**Secret ล่ะ?**

Tool อยู่ใน repo Secret ไม่อยู่ Script อ่าน `ACME_TOKEN` (หรือคล้ายกัน) จาก environment ของนักพัฒนา — `direnv`, `.envrc`, shell rc Commit tool ไม่ใช่ credential ถ้า env var หาย exit ไม่ใช่ศูนย์พร้อมข้อความชัดเจนเพื่อให้ model surface error จริงแทนการแต่งเอง

**agent รัน tool พวกนี้ได้โดยไม่ต้องอนุมัติทุก call หรือเปล่า?**

ได้ — permission flow เดียวกันกับ MCP tool ใดๆ Auto-approve tool ที่ read-only (`branch`, `flags`) ถามเสมอสำหรับตัวทำลาย (`deploy`, `release`) Octomind ถือว่า local tool เป็น first-class สำหรับระบบ permission

**ถ้าฉันต้องการ tool เดียวกันข้าม repo หลายๆ ตัว?**

สองตัวเลือก เบา: symlink `.agents/tools/foo` ไปยังที่ตั้งที่แชร์กัน ทางการ: เขียน [tap](https://github.com/Muvon/octomind) — registry แบบ Homebrew Local tool สำหรับ _repo นี้โดยเฉพาะ_ Tap สำหรับ _การใช้ซ้ำข้ามโปรเจกต์_

**มันทำงานใน CI / non-interactive run ไหม?**

ใช่ `octomind run --format=plain` และ `--format=jsonl` ทั้งคู่ honor `.agents/tools/` เรารัน agent-driven code review ใน CI ของเราเองแบบนี้ — tool `lint`, `test`, และ `coverage` ของ review agent ทั้งหมดอยู่ใน `.agents/tools/` และ wrap command ที่แน่นอนของทีม

**ชื่อ tool ชนกับ built-in จะเกิดอะไรขึ้น?**

Built-in ชนะ คุณ shadow `shell` หรือ `view` ด้วยการตั้งชื่อสคริปต์ว่า `shell` ไม่ได้ — octomind log การชนและเก็บตัวเดิม guardrail ที่ตั้งใจ

---

## การเปลี่ยนแปลง

มีเรื่องเล่าที่กำลังเล่าตอนนี้ว่าอนาคตของ agent คือ _MCP server เพิ่มขึ้น_ — catalog ใหญ่ขึ้น ecosystem รวยขึ้น integration มากขึ้น ข้อมูลจาก RAG-MCP, Bloomberry audit, [โพสต์ code-execution](https://www.anthropic.com/engineering/code-execution-with-mcp) ของ Anthropic เอง และนักพัฒนาที่กลับไปใช้ CLI เงียบๆ ทั้งหมดชี้ทิศทางที่ต่าง: **agent ที่ทำงานได้ดีที่สุดใน repo จริงเห็น tool น้อยลง tool แคบลง และ tool ที่เขียนสำหรับโปรเจกต์ที่พวกมันอยู่**

สคริปต์ `.agents/tools/` คือ unit ที่เล็กที่สุดเท่าที่เป็นไปได้ของ pattern นั้น หกสิบวินาทีจาก "ฉันเฝ้าดู agent drift ในเรื่องนี้ตลอด" เป็น "agent มี tool สำหรับมัน ทีมมี อยู่ใน git เราเดินต่อ"

ลองใช้กับสิ่งถัดไปที่คุณพบว่าตัวเองอธิบายซ้ำสองครั้ง

— Don

---

_[Octomind](https://github.com/Muvon/octomind) เป็น open source ภายใต้ Apache-2.0 feature local-tool ship ใน [0.29.0](/blog/release-round-may-2026) ถ้าสิ่งใดในนี้ปลดบล็อค workflow [เปิด issue](https://github.com/Muvon/octomind/issues) — feature ที่ถูกขอในเดือน May มักจะ ship ในเดือน June_
