
SooTool
โ 3from JinHo-von-Choi
Precision Calc MCP: Decimal-only deterministic calculation server for LLM tool use
SooTool
Precision Calc MCP for LLM tool use.
LLM์ด ํ๋ฅ ์ถ๋ก ์ผ๋ก ์ฐ์๋ฅผ ํ๋ฆฌ๋ ๊ตฌ์กฐ์ ํ๊ณ๋ฅผ ์ฐจ๋จํ๊ณ , ๊ทธ ํ๋ฆฌ๋ ์์
์ ํ ๋ฒ์ 500๊ฑด๊น์ง ๊ฒฐ์ ์ ๋ณ๋ ฌ๋ก ๋๋ ค ์ค๋ฌด์ ํฌ์
ํ ์ ์๊ฒ ๋ง๋๋ ์ ๋ฐ ๊ณ์ฐ MCP ์๋ฒ. Python 3.12 ยท Decimal ์ ์ฉ ์ปค๋ ยท 18๊ฐ ๊ณ์ฐ ๋๋ฉ์ธ 254๊ฐ ๊ธฐ๋ณธ ๋๊ตฌ + 10๊ฐ admin ์ ์ฑ
๋๊ตฌ ยท core.batch 500 items ๋ณ๋ ฌ ยท core.pipeline DAG ์ฒด์ธ ยท ๊ฐ์ฌ ํธ๋ ์ด์ค ยท ์ ์ฑ
YAML ์ธ๋ถํ ยท 5์ข
์ ์ก(stdio/HTTP/SSE/WebSocket/Unix).
์ ํ์ํ๊ฐ
LLM์ ์ซ์๋ฅผ ํ ํฐ ์ํ์ค๋ก ์์ฑํ๋ค. ๋ถ๊ฐ์ธ ์ญ์ฐ, ๋ณต๋ฆฌ ์ด์, ๋์ง์ธ ๊ตฌ๊ฐ, ์๋์๋์ธ ์ฅ๊ธฐ๋ณด์ ํน๋ณ๊ณต์ , ์ดํญ๋ถํฌ CDF ๊ฐ์ ์ค๋ฌด ๊ณ์ฐ์์ ๋ฐ์ฌ๋ฆผ ๋ฐฉํฅยท๊ตฌ๊ฐ ๊ฒฝ๊ณยท์ ์ฑ ํด์์ด ๋ฏธ๋ฌํ๊ฒ ์ด๊ธ๋๋ค. ๊ฒ์ฆ ์์ด LLM ์ฐ์ถ์ ๊ทธ๋๋ก ์ฐ๋ฉด ์ธ๋ฌด ์ ๊ณ ยท์ฌ๋ฌด ์์ฌ๊ฒฐ์ ยท์๋ฃ ์ฉ๋ยท๊ณตํ ์ค๊ณ์์ ์น๋ช ์ ์ค์ฐจ๊ฐ ๋์ ๋๋ค.
๋ฌธ์ ์ ์ธต์๋ ๋ ๊ฒน์ด๋ค. ์ฒซ์งธ, ๋ชจ๋ธ ์์ฒด๊ฐ ์ฐ์ ์ ์ํํ์ง ์๋๋ค. ํ๋ฅ ์ถ๋ก ์ผ๋ก ๊ทธ๋ด๋ฏํ ์ซ์๋ฅผ ๋ด๋์ ๋ฟ์ด๋ผ ํ๊ณยท์ธ๋ฌดยท์ฝ์ ์ฉ๋ ํ์ฅ์์ ์๋ชป๋ ์์น๊ฐ ๊ทธ๋๋ก ๋ณด๊ณ ์ยท์ ํยท์ฒ๋ฐฉ์ ๋จ๋๋ค. ๊ฒ์ฆ ์ฌ๋ ฅ์ด ๋น ๋ฏํ ์ ๋ฌธ์ง ์ค๋ฌด์์๋ ์ค์ฐจ ํ ๊ฑด์ด ์ ๊ณ ์ค๋ฅยทํ๋ถยท์๋ฃ ์ฌ๊ณ ๋ก ์ง๊ฒฐ๋๋ค.
๋์งธ, ์ต์ ๋ํ LLM์ ๋ด๋ถ์ ๊ณ์ฐ๊ธฐยทPython ์ธํฐํ๋ฆฌํฐ๋ฅผ ๋ด์ฅํ๊ณ ์์ง๋ง ๊ทธ ๋๊ตฌ๋ฅผ ํธ์ถํ ์ง๋ ์ฌ์ ํ ๋ชจ๋ธ ์ฌ๋์ด๋ค. MCP ๋๊ตฌ๋ ๊ฐ์ ์ ์ฝ์ ๊ณต์ ํ๋ค. ๊ตฌ์กฐ์ ํ๊ณ๊ฐ ๋จ์ผ ๋ฐฉ์ด๋ง ํ๋๋ก๋ ๋ซํ์ง ์๋๋ค๋ ๋ป์ด๋ค. SooTool์ ๋ชจ๋ธ ๋ด์ฅ ๋๊ตฌ์ ๋ ๋ฆฝ๋ ๋ ๋ฒ์งธ ์ธต์ MCP ์๋ฒ๋ก์ ๊ฒฐ์ ์ Decimal ๊ฒฝ๋ก, ์ธ๋ถํ๋ ์ ์ฑ ๋ฐ์ดํฐ, ๊ฐ์ฌ ๊ฐ๋ฅํ ํธ๋ ์ด์ค๋ฅผ ์ ๊ณตํด ๋ฐฉ์ด ๊น์ด๋ฅผ ๋๋ฆฐ๋ค. ํธ์ถ ์ฌ๋ถ ์์ฒด๋ AI ์ฌ๋์ผ๋ก ๋จ์ง๋ง, ๋ถ๋ฆฌ๋ฉด ๊ฒฐ๊ณผ๋ ์ฐ์ ์ ์ผ๋ก ์ ํํ๋ค๋ ์ ์ด ๋ณด์ฆ๋๋ค.
์
์งธ, ์ค๋ฌด๋ ํ ๊ฑด์ฉ ๋ฌป์ง ์๋๋ค. ์ง์ 500๋ช
์๊ธยท4๋๋ณดํยท์๋์ธ ์ผ๊ด ์ ์ฐ, ๋์ถ 50์ข
NPVยทIRRยท๋๋ ์ด์
๋น๊ต, ๊ฑฐ๋๋ช
์ธ์ ์์ฒ ๊ฑด VAT ์ญ์ฐ, ์๋์ธ ์๋๋ฆฌ์ค ์์ญ ๊ฐ์ง ๊ต์ฐจ ๊ฒ์ฆ์ ํ ๋ฒ์ LLM ๋ํ๋ก๋ ์ ๋ขฐํ ์ ์๋ค. SooTool์ core.batch๋ก N๊ฐ ๋
๋ฆฝ ์ฐ์ฐ์ ThreadPool ๋ณ๋ ฌ ์คํํ๊ณ ์
๋ ฅ id ์์ผ๋ก ๊ฒฐ์ ์ ์ฌ์ ๋ ฌํ๋ฉฐ, core.pipeline์ผ๋ก DAG ์์กด(์ฐ๋ดโ์ธ์กโ์ค์๋ น์ก) ์ฒด์ธ์ ํ ์๋ณต์ ๋๋ธ๋ค. LLM์ด ๋๊ตฌ ํธ์ถ ํ ๋ฒ ํ๋ฉด ์ค๋ฌด ์๋ฐฑ ํ์ ๊ฒฐ์ ์ ๊ณ์ฐ์ด ์ฆ์ ๋ฐํ๋๋ค.
SooTool์ ๊ทธ ๊ฒฝ๋ก๋ฅผ ์์ฒ ์ฐจ๋จํ๋ค.
- Decimal ์ ์ฉ ์ปค๋. ์
๋ ฅ JSON์
parse_float=Decimal๋ก ํ์ฑ๋์ด float์ด ๋๋ฉ์ธ ๋ด๋ถ๋ก ์ ์ ๋์ง ๋ชปํ๋ค. - ๋ฐ์ฌ๋ฆผ ์ ์ฑ 6์ข (HALF_EVEN ยท HALF_UP ยท DOWN ยท UP ยท FLOOR ยท CEIL)์ enum์ผ๋ก ๊ณ ์ ํ๊ณ ๋๊ตฌ ๊ธฐ๋ณธ๊ฐ์ ๊ธ์งํ๋ค. ํธ์ถ์๊ฐ ๋ฐ๋์ ์ ํํ๋ค(ADR-002).
- ์ธ๋ฒยท๋ถ๋์ฐ ๊ท์ ๋ฐ์ดํฐ๋ฅผ
src/sootool/policies/{domain}/{key}_{year}.yaml๋ก ์ธ๋ถํํ๊ณ SHA-256 ๋ฌด๊ฒฐ์ฑ ๊ฒ์ฆ + lru_cache๋ก ๋ก๋ํ๋ค(ADR-009). - ๋ชจ๋ ์๋ต์
trace.{tool, formula, inputs, steps, output}ํ๋๋ฅผ ํฌํจํ๋ค. ๊ณ์ฐ ๊ทผ๊ฑฐ๋ฅผ ์ฌ์ฉ์์๊ฒ ์ง์ ๋ณด์ฌ์ค ์ ์๋ค(ADR-003). - ๊ฒฐ์ ๋ก . ThreadPool ๊ฒฐ๊ณผ๋ ์
๋ ฅ id ์์ผ๋ก ์ฌ์ ๋ ฌํ๊ณ , ๋น๊ฒฐ์ ํ์ฉ ์
non_deterministic:trueํ๋๊ทธ๋ฅผ ๊ฐ์ ํ๋ค(ADR-011).
๊ฐ์ฌ ํธ๋ ์ด์ค ์ค๋ฌผ ์ํ
"์ด ์ซ์๋ ์ด๋ป๊ฒ ๋์๋๊ฐ"์ ์ฆ๋ตํ๊ธฐ ์ํด ๋ชจ๋ ๋๊ตฌ๋ trace ํ๋๋ฅผ ๋ฐํํ๋ค. ์๋๋ finance.npv(rate=0.08, cashflows=[-1000, 300, 400, 500, 200], rounding=HALF_EVEN, decimals=2) ์ค์ ์๋ต์ด๋ค. ๊ณต์ยท์
๋ ฅยท์ค๊ฐ ๋จ๊ณยท์ถ๋ ฅ์ด ์์์ ์ผ๋ก ๊ธฐ๋ก๋๋ค.
{
"npv": "164.64",
"trace": {
"tool": "finance.npv",
"formula": "NPV = sum(CF_t / (1+r)^t, t=0..n)",
"inputs": {
"rate": "0.08",
"cashflows": ["-1000", "300", "400", "500", "200"],
"rounding": "HALF_EVEN",
"decimals": 2
},
"steps": [
{
"label": "npv_raw",
"value": "164.63539696786661172171511042618089308126395968697"
}
],
"output": "164.64"
},
"_meta": {
"hints": [],
"session_stats": {"tool_calls": 1, "unique_tools": 1}
}
}์ค๊ฐ ๋จ๊ณ์ npv_raw๋ ๋ฐ์ฌ๋ฆผ ์ด์ ์์ ์ ๋ฐ Decimal ๊ฐ์ผ๋ก, ๋ฐ์ฌ๋ฆผ ์ ์ฑ
(HALF_EVEN)์ด ์์์ 2์๋ฆฌ(decimals=2)์ ์ ์ฉ๋ ๊ฒฐ๊ณผ๊ฐ output๊ณผ npv ํ๋์ ์ผ์นํ๊ฒ ๋
ธ์ถ๋๋ค. ๊ฐ์ฌ ์ถ์ ์ trace ํ๋๋ง ๋ณด๋ฉด ์ถฉ๋ถํ๋ฉฐ, _meta๋ ๋ฏธ๋ค์จ์ด ์ฃผ์
์์ญ(ADR-014)์ผ๋ก ๊ฒฐ๊ณผ ์ ๋ขฐ์ ์ํฅ์ ์ฃผ์ง ์๋๋ค(ADR-011).
๋ฒค์น๋งํฌ ๊ฒฐ๊ณผ (2026-04-24)
20 ์ผ์ด์ค(ํ๊ตญ ์๋์ธ 8 ยท ๋ถ๊ฐ์ธ 3 ยท ๋ณต๋ฆฌ 2 ยท ํ๋ฅ ํต๊ณ 3 ยท ๊ณตํ 2 ยท ์๋์ธ 2) ร ๋ํ LLM ์ค์ธก. exact ๋ฌธ์์ด ์ผ์น, approx ์๋์ค์ฐจ โค 0.01%, wrong ๊ทธ ์ธ.
ํ์ค ๋ชจ๋ธ
| Provider | Model | Exact | Approx | Wrong | ์ ํ์จ |
|---|---|---|---|---|---|
| SooTool | Decimal ์ปค๋ | 20 | 0 | 0 | 100% |
| gemini-2.5-pro | 13 | 3 | 4 | 65% | |
| Anthropic | claude-sonnet-4-5 | 3 | 3 | 13 | 15% |
| OpenAI | gpt-4o | 2 | 4 | 14 | 10% |
ํ์กด ์ต๊ณ ๋ชจ๋ธ (SOTA)
| Provider | Model | Exact | Approx | Wrong | ์ ํ์จ |
|---|---|---|---|---|---|
| SooTool | Decimal ์ปค๋ | 20 | 0 | 0 | 100% |
| gemini-3-pro-preview | 12 | 4 | 4 | 60% | |
| Anthropic | claude-opus-4-7 | 9 | 3 | 8 | 45% |
| OpenAI | gpt-5.4 | 5 | 3 | 12 | 25% |
๋ชจ๋ธ์ ์ต์ SOTA๋ก ์ฌ๋ ค๋ ์ด๋ LLM๋ 20/20์ ๋๋ฌํ์ง ๋ชปํ๋ค. Claude 3โ9 (3๋ฐฐ ๊ฐ์ ), OpenAI 2โ5 (2.5๋ฐฐ), Gemini๋ ๋ณดํฉ. ๊ณตํต ์คํจ ์ง์ ์ ๋์ง์ธ ๊ตฌ๊ฐ ๊ฒฝ๊ณ, ์๋์๋์ธ ์ฅ๊ธฐ๋ณด์ ํน๋ณ๊ณต์ (์ค์ธ์ก 8% ์ด์ ์ค์ฐจ), ๋ถ๊ฐ์ธ HALF_EVEN ๋ฐ์ฌ๋ฆผ, AC ์ํผ๋์ค ์ ๋ฐ๋๋ค. ๋ชจ๋ธ ๋ฐ์ ๋ง์ผ๋ก ๋ซํ์ง ์๋ ๊ตฌ์กฐ์ ํ๊ณ๋ฅผ SooTool์ด Decimal + ์ ์ฑ
YAML + ๋ช
์์ rounding enum ์ธ ์ธต์๋ก ๋ฉ์ด๋ค. ์์ธ: bench/results/2026-04-24-final.md (ํ์ค), bench/results/2026-04-24-sota.md (SOTA).
์ค์น
cd SooTool
uv sync์คํ
๊ธฐ๋ณธ(stdio, MCP ํด๋ผ์ด์ธํธ ์ฐ๋):
uv run python -m sootool์ ์ก๋ณ ๋จ์ผ ๊ธฐ๋:
uv run python -m sootool --transport http --port 10535
uv run python -m sootool --transport sse-legacy --port 10536
uv run python -m sootool --transport websocket --port 10537
uv run python -m sootool --transport unix --socket /tmp/sootool.sock๋ค์ค ์ ์ก ๋์ ๊ธฐ๋:
uv run python -m sootool --transports stdio,http,websocket๊ธฐ๋ณธ ๋ฐ์ธ๋ฉ์ 127.0.0.1. ์ธ๋ถ ๋
ธ์ถ์ --host 0.0.0.0 + Bearer ํ ํฐ์ด ์๋ฌด๋ค(ADR-014).
Claude Code ์ฐ๋
user-scope๋ก ๊ธ๋ก๋ฒ ๋ฑ๋ก (๊ถ์ฅ, ์ด๋ ๋๋ ํ ๋ฆฌ์์๋ ํธ์ถ ๊ฐ๋ฅ):
claude mcp add --scope user sootool -- uv run --directory /path/to/SooTool python -m sootool๋๋ ํ๋ก์ ํธ ์ค์ฝํ๋ก SooTool ์ ์ฅ์ ๋ด์์๋ง:
cd SooTool
claude mcp add sootool -- uv run python -m sootool๋๊ตฌ ์นดํ๋ก๊ทธ (254๊ฐ ๊ธฐ๋ณธ + 10๊ฐ admin, 18 ๊ณ์ฐ ๋๋ฉ์ธ + sootool ์ด์ ๋๊ตฌ)
| Namespace | Count | ๋ํ ๋๊ตฌ |
|---|---|---|
| core | 8 | add, sub, mul, div, calc, batch, pipeline, pipeline_resume |
| accounting | 11 | vat_extract, vat_add, balance, depreciation 3์ข , interest_compound ์ธ |
| finance | 15 | pv, fv, npv, irr, loan_schedule, bond_ytm, bond_duration, black_scholes, var_parametric, sharpe ์ธ |
| tax | 10 | progressive, kr_income, kr_withholding_simple, capital_gains_kr, kr_local_income_tax, kr_education_tax_add, kr_rural_special_tax ์ธ |
| realestate | 8 | kr_ltv, kr_dti, kr_dsr, kr_acquisition_tax, kr_transfer_tax, rental_yield ์ธ |
| stats | 14 | descriptive, ttest 3์ข , chi_square_independence, ci_mean, regression_linear, anova, correlation ์ธ |
| probability | 30 | normal/binomial/poisson, gamma, beta, exponential, lognormal, chi_square, F, bayes, factorial, nCr, nPr, expected_value |
| datetime | 14 | add/count_business_days, day_count, age, diff, tz_convert, solarโlunar, solar_terms, lunar_holiday, fiscal_year, fiscal_quarter, tax_period_kr, payroll_period |
| math | 10 | integrate_simpson, integrate_gauss_legendre, diff_central, diff_five_point, interpolate_linear, interpolate_cubic_spline, polynomial_roots, polynomial_horner, fft, ifft |
| geometry | 15 | areaยทvolume 7์ข , vector dot/cross/norm, matrix 4์ข , haversine |
| engineering | 56 | electrical_*, electrical_ac 11์ข , fluid, thermal, mechanical, structural, control 5์ข , si_prefix_convert |
| units | 8 | convert (pint), fx_convert, fx_triangulate, temperature, energy_convert, pressure_convert, data_size_convert, time_small_convert |
| medical | 12 | bmi, bsa, dose_weight_based, egfr, pregnancy_weeks, cha2ds2_vasc, has_bled, framingham_cvd_10y, qtc_bazett/fridericia/framingham/hodges |
| science | 11 | half_life, ideal_gas, molar_mass, stoichiometry, nernst, faraday_electrolysis, battery_capacity, snell_law, thin_lens, bragg, intensity |
| crypto | 10 | gcd, lcm, hash, is_prime, modinv, modpow, egcd, crt, euler_totient, carmichael_lambda |
| pm | 5 | critical_path (CPM), evm, pert, earned_schedule, monte_carlo_schedule |
| payroll | 5 | kr_net_monthly, kr_severance_pay, kr_year_end_tax_settlement, kr_bonus_tax, hourly_to_monthly_net |
| sootool | 1+10 | skill_guide (ํญ์) + policy_mgmt 10์ข (admin ๋ชจ๋) |
์ ์ฒด ๋๊ตฌ ์ฌ์์ docs/user_guide.md ๋ฐ sootool.skill_guide MCP ํธ์ถ๋ก ์กฐํํ๋ค.
์ค์ ์์
์ธ๋ฌด ์ฒด์ธ ํ์ดํ๋ผ์ธ. ์๊ธ 3,000,000์์ ์ฐ์๋์ผ๋ก ํ์ฐํ ๋ค 2026๋ ํ๊ตญ ์๋์ธ๋ฅผ ๊ณ์ฐํ๋ค.
{
"name": "core.pipeline",
"arguments": {
"steps": [
{"id": "annual", "tool": "core.mul", "args": {"operands": ["3000000", "12"]}},
{"id": "tax", "tool": "tax.kr_income", "args": {"taxable_income": "${annual.result.result}", "year": 2026}}
]
}
}์ฌ๋ฌด ์๋๋ฆฌ์ค ๋น๊ต ๋ฐฐ์น. ๋์ผ ํ๊ธํ๋ฆ์ ๋ํด ํ ์ธ์จ 3์ข NPV๋ฅผ ๋์ ์ฐ์ถํ๋ค.
{
"name": "core.batch",
"arguments": {
"items": [
{"id": "s1", "tool": "finance.npv", "args": {"rate": "0.05", "cashflows": ["-100","30","40","50"], "rounding": "HALF_EVEN", "decimals": 2}},
{"id": "s2", "tool": "finance.npv", "args": {"rate": "0.08", "cashflows": ["-100","30","40","50"], "rounding": "HALF_EVEN", "decimals": 2}},
{"id": "s3", "tool": "finance.npv", "args": {"rate": "0.10", "cashflows": ["-100","30","40","50"], "rounding": "HALF_EVEN", "decimals": 2}}
]
}
}๊ณตํ ๋ ์ด๋์ฆ ์. ๋ฐ๋ยท์๋ยทํน์ฑ๊ธธ์ดยท์ ์ฑ์ผ๋ก ์ธต๋ฅ/์ ์ด/๋๋ฅ ์์ญ์ ํ์ ํ๊ณ trace์ ๊ณต์์ ๋จ๊ธด๋ค.
{
"name": "engineering.fluid_reynolds",
"arguments": {"density": "1000", "velocity": "2", "length": "0.05", "viscosity": "0.001"}
}ํต๊ณ ํ๊ท + ์ ๋ขฐ๊ตฌ๊ฐ ๋ฐฐ์น. ๋จ์ผ ์๋ณต์ผ๋ก ์ ํํ๊ท ๊ณ์ยทp-value์ ํ๊ท 95% ์ ๋ขฐ๊ตฌ๊ฐ์ ๋์ ๋ฐํํ๋ค.
{
"name": "core.batch",
"arguments": {
"items": [
{"id": "reg", "tool": "stats.regression_linear", "args": {"X": [[1],[2],[3],[4]], "y": [2.1, 4.0, 6.2, 8.1]}},
{"id": "ci", "tool": "stats.ci_mean", "args": {"data": [2.1, 4.0, 6.2, 8.1], "confidence": 0.95}}
]
}
}์ค๋ฌด ๋๋ ์ฒ๋ฆฌ
LLM์ด ํ ๊ฑด์ฉ ์ฐ์ถํ๋ฉด ์ฌํ์ฑยท์ ๋ขฐ์ฑ์ด ํ๋ค๋ฆฐ๋ค. SooTool์ ํ ํธ์ถ๋ก ์๋ฐฑ ํ์ ๊ฒฐ์ ์ ๊ณ์ฐ์ ์ฆ์ ๋ฐํํ๋ค.
| ์๋๋ฆฌ์ค | ๊ท๋ชจ | ๋๊ตฌ ์กฐํฉ | ๋ฐํ |
|---|---|---|---|
| ๊ธ์ฌ ๋ง๊ฐ | ์ง์ 500๋ช | core.batch + payroll.kr_salary | ํ๋ณ netยท4๋๋ณดํยท์๋์ธยทtrace |
| ํฌ์ ๋ฏผ๊ฐ๋ | ํ ์ธ์จ 9 ร ํ๊ธํ๋ฆ 5 = 45 ์ง์ | core.batch + finance.npvยทfinance.irr | ์๋๋ฆฌ์ค๋ณ NPV/IRR ํ |
| ๊ฑฐ๋๋ช ์ธ์ VAT ๋ถ๋ฆฌ | ์๋ฐฑ~์์ฒ ๊ฑด | core.batch + accounting.vat_extract | ๊ณต๊ธ๊ฐ ํฉ๊ณยทVAT ํฉ๊ณ |
| ์ฑ๊ถ ํฌํธํด๋ฆฌ์ค | ์ข ๋ชฉ ์์ญ | core.batch + finance.bond_ytmยทbond_duration | ์ข ๋ชฉ๋ณ ์์ต๋ฅ ยท๋๋ ์ด์ |
| ์๋์ธ ๊ต์ฐจ ๊ฒ์ฆ | ๋ณด์ ๊ธฐ๊ฐ 10์ข ร ์ทจ๋ยท์๋๊ฐ ์ธํธ | core.batch + tax.capital_gains_kr | ์๋๋ฆฌ์ค๋ณ ์ค์ธ์ก |
| ์ธ๋ฌด ์ฒด์ธ | ์๊ธโ์ฐ๋ดโ์๋์ธโ์ค์๋ น์ก | 4 ๋จ๊ณ core.pipeline | ๋จ์ผ ์๋ณต |
๊ตฌํ ์ธ๋ถ:
core.batchโ N๊ฐ ๋ ๋ฆฝ ์ฐ์ฐ์ ThreadPoolExecutor๋ก ๋ณ๋ ฌ ์คํ. id ์ค๋ณต ๊ฑฐ๋ถ, per-item ๊ฒฉ๋ฆฌ(ok|error|timeout|skipped), ์ต๋ 500 items, per-item 10s, batch 60s ์ ํ. ๊ฒฐ๊ณผ๋ ์ ๋ ฅ id ์์ผ๋ก ๊ฒฐ์ ์ ์ฌ์ ๋ ฌ๋๋ค(ADR-011).core.pipelineโgraphlib.TopologicalSorter๊ธฐ๋ฐ DAG ์คํ๊ธฐ.${step_id.result.field}์ฐธ์กฐ ๋ฌธ๋ฒ์ผ๋ก ๋จ๊ณ ๊ฐ ๋ฐ์ดํฐ ์ ๋ฌ. max_steps=50, max_depth=10, step_timeout_s=2.0, pipeline_timeout_s=30.0(ADR-006).core.pipeline_resumeโ ์คํจํ ์คํ ์ TTL 10๋ถ in-memory ์บ์๋ก๋ถํฐ ๋ถ๋ถ ์ฌ์คํ.
์ ์ก ์ง์
| Transport | ์ฉ๋ | Flag |
|---|---|---|
| stdio | Claude CodeยทDesktop ๊ธฐ๋ณธ | --transport stdio |
| http | Streamable HTTP, ๊ถ์ฅ ์๊ฒฉ | --transport http |
| sse-legacy | 2024-11 ํ๋กํ ์ฝ ํธํ | --transport sse-legacy |
| websocket | ์ ์ง์ฐ ์๋ฐฉํฅ | --transport websocket |
| unix | ๋ก์ปฌ ๊ณ ์ฒ๋ฆฌ | --transport unix --socket PATH |
| multi | ๋์ ๊ธฐ๋ | --transports stdio,http,... |
๋ชจ๋ HTTP ๊ณ์ด ์ ์ก์ Bearer ์ธ์ฆ, Accept-Language ๊ธฐ๋ฐ ๋ก์ผ์ผ ๊ฐ์ง(ko ๊ธฐ๋ณธ), ์ ๋๊ตฌ _meta.hints ์๋ ์ฃผ์
, CORS ํ์ดํธ๋ฆฌ์คํธ๋ฅผ ๊ณตํต ๋ฏธ๋ค์จ์ด๋ก ์ ์ฉํ๋ค(ADR-014).
๊ฐ๋ฐ
- ํ
์คํธ:
make test(pytest 1097๊ฑด, 97% ์ปค๋ฒ๋ฆฌ์ง) - ๋ฆฐํธ:
make lint(ruff) - ํ์
์ฒดํฌ:
make typecheck(mypy) - ํฌ๋งท:
make format - ์ ์ก ์ค๋ชจํฌ:
uv run python scripts/mcp_smoke_{stdio,http,sse,ws,unix}.py
์ ๋๋ฉ์ธ ๋๊ตฌ ์ถ๊ฐ๋ src/sootool/modules/<domain>/<tool>.py์ @REGISTRY.tool(namespace, name, description, version) ๋ฐ์ฝ๋ ์ดํฐ๋ก ๊ตฌํํ๊ณ ๋๋ฉ์ธ __init__.py์์ importํ๋ฉด ๋ฐํ์ ์๋ ๋ฑ๋ก๋๋ค(ADR-004).
์ํคํ ์ฒ
์ค๊ณ ๊ฒฐ์ ๊ณผ ๊ทผ๊ฑฐ๋ docs/architecture.md ADR-001~017์ ๊ธฐ๋ก๋์ด ์๋ค. ํต์ฌ invariant:
- Decimal-only ๊ฒฝ๊ณ ยท ๋ช ์์ rounding ยท ๊ฐ์ฌ ํธ๋ ์ด์ค ยท ๋ชจ๋ stateless / batch-safe
- ์๋ฃํ ์ด์ํ: ํ๊ณยท์ธ๋ฌดยท๊ธ์ต์ ์ ๊ตฌ๊ฐ Decimal, ํต๊ณยท๊ธฐํยทํ๋ฅ ์ ๋ด๋ถ float64 + ๊ฒฝ๊ณ Decimal ์ง๋ ฌํ(ADR-008)
- ์ ์ฑ YAML ์ธ๋ถํ + SHA-256 ๋ฌด๊ฒฐ์ฑ(ADR-009)
- trace_level noneยทsummaryยทfull + SOOTOOL_MAX_PAYLOAD_KB(๊ธฐ๋ณธ 512KB) ์ด๊ณผ ์ trace.steps tail ์ ๋จ(ADR-010)
- KRWMoney๋ Decimal ์์ ๋์ ํฉ์ฑ(ADR-013)
- ๋๋ฉ์ธ๋ณ
*_bulk๋๊ตฌ ๊ธ์ง,core.batch์ผ๋ฐํด๋ก ํต์ผ(ADR-006)
์คํฌ ๊ฐ์ด๋
์์ด์ ํธ๊ฐ ์ธ์ ์ด๋ค ๋๊ตฌ๋ฅผ ํธ์ถํด์ผ ํ๋์ง ๊ธฐ์ ํ ํธ๋ฆฌ๊ฑฐ ํ
์ด๋ธยท์์ยทํ๋ ์ด๋ถ์ sootool.skill_guide MCP ๋๊ตฌ๋ฅผ ํธ์ถํ์ฌ ์กฐํํ๋ค. ์น์
์ triggers | examples | anti_patterns | playbooks | all, ์ธ์ด๋ ko | en.
๋ผ์ด์ ์ค
LICENSE ํ์ผ ์ฐธ์กฐ.
cd SooTool
uv syncNo common issues documented yet. If you hit a problem, the repository's GitHub Issues page is the best place to look.
Licensed under MITโ you can use, modify, and redistribute it under that license's terms.
View the full license file on GitHub โ