systa-mcp 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +7 -3
  2. package/SKILL.md +36 -4
  3. package/package.json +4 -2
  4. package/server.js +1342 -128
package/README.md CHANGED
@@ -101,7 +101,7 @@ claude mcp add systa \
101
101
 
102
102
  ## Araçlar (tools)
103
103
 
104
- Toplam **44 araç** vardır; `tools/list` yanıtı anahtarın kapsamına göre filtrelenir
104
+ Toplam **64 araç** vardır; `tools/list` yanıtı anahtarın kapsamına göre filtrelenir
105
105
  (bkz. "Scope-aware araç listesi"). Aşağıdakiler en sık kullanılan çekirdek araçlardır —
106
106
  tam katalog `list_capabilities` ile keşfedilir.
107
107
 
@@ -190,8 +190,12 @@ printf '%s\n' \
190
190
  ## Yayınlama (maintainer)
191
191
 
192
192
  Paket sıfır bağımlılıklıdır; `files` whitelist'i yalnızca `server.js`, `SKILL.md`,
193
- `README.md` içerir. SKILL.md kaynağı `Analiz Dökümanları/12_AI_ve_Otomasyon/systa_client_skill_TASLAK.md`'dir
194
- — güncellenince pakete tekrar kopyalanmalıdır.
193
+ `README.md` içerir.
194
+
195
+ > **SKILL.md'nin tek kaynağı bu dizindeki `mcp-server/SKILL.md` dosyasıdır.** Doğrudan burada
196
+ > düzenlenir. (Eskiden `Analiz Dökümanları/.../systa_client_skill_TASLAK.md` kaynak gösteriliyordu;
197
+ > o dosya 2026-06-16'da donmuş bir taslaktır ve gerçek SKILL.md'nin yarısı kadardır. Oradan
198
+ > kopyalamak içeriğin yarısını siler.)
195
199
 
196
200
  ```bash
197
201
  cd Backend/mcp-server
package/SKILL.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- version: 1.1.0
2
+ version: 1.2.0
3
3
  name: systa
4
4
  description: |
5
5
  Drive SysTa (Talep Takip Sistemi / SysTa) — a
@@ -108,10 +108,16 @@ veya `describe_endpoint` ile gövdeyi netleştir.
108
108
  | pano, board, kanban / kolon, column, asama, liste | kanban | get_request_board / create_request_board |
109
109
  | durum gecisi onizle, izinli gecisler, hangi duruma gecebilir | request | list_allowed_transitions |
110
110
  | plan modu, sprint kapsami, plan mode setup | plan | create_plan_mode |
111
- | efor, durum, oncelik, atanan, planla, denetim, gecmis | request | get_request / list_requests |
111
+ | durum, oncelik, atanan, planla, denetim, gecmis | request | get_request / list_requests |
112
+ | tahmini efor, planlanan sure (estimatedEffort) | request | update_request (TAHMIN alani, defter DEGIL) |
113
+ | efor gir, efor yaz, calistigim sure, efor defteri, mesai | effort | log_effort / list_effort_targets / list_effort_entries |
114
+ | eksik efor girisim var mi, efor uyumu | effort | get_effort_compliance |
112
115
  | proje, klonla | project | list_projects / create_project |
113
116
  | onaya sunma, snapshot, sprint, sprinti kapat, optimize et | plan | submit_plan_for_approval / create_plan_baseline |
114
117
  | onay, onayla, reddet | approvals | list_pending_approvals / respond_to_approval |
118
+ | onay tipleri, kime onaya gonderelim | approvals | list_approval_types |
119
+ | red nedeni, neden reddedildi, gecerli red sebepleri | approvals | list_rejection_reasons |
120
+ | bu talep neden dondu, neden yazamiyorum, kilitli alan | approvals | get_request_freeze |
115
121
  | sla, sure taahhudu | sla | (sla endpoints) |
116
122
  | release, surum, go/no-go, deployment | release | create_release_list / add_release_item |
117
123
  | musaitlik, izin (leave), vekil | user/automation | systa_api_call /user-availability, /user-leaves |
@@ -130,7 +136,8 @@ veya `describe_endpoint` ile gövdeyi netleştir.
130
136
  | urun guncellemesi, surum notu, yenilikler, changelog | product-update | GET /api/product-updates |
131
137
  | not, kisisel not, hatirlatma | note | GET /api/dashboard/notes |
132
138
  | yer imi, favori, bookmark, kisayol | bookmark | GET /api/dashboard/bookmarks |
133
- | degerlendirme, puanlama, anket, memnuniyet, geri bildirim | ratings | POST /api/ratings |
139
+ | degerlendirme, puanlama, memnuniyet, geri bildirim | ratings | POST /api/ratings |
140
+ | anket, oylama, karar alalim, ekibe soralim, secenek sun | decisions | systa_api_call POST /requests/:n/decisions |
134
141
  | github, repo, pull request, commit, issue aktar | github | systa_api_call /github/me/{connection,repos,import,push} |
135
142
  | gosterge paneli, dashboard, widget, ozet, grafik, panel | dashboard | GET /api/dashboard/init |
136
143
 
@@ -164,7 +171,7 @@ Each maps a P0 user verb to a tool/endpoint, with the opinionated defaults from
164
171
 
165
172
  1. Need `title` (min 5 chars) — if missing or too short, ask once. Never invent it.
166
173
  2. Defaults: `channel='API'` (AI/MCP source), `statusId` ← default open/new status (resolve via `GET /api/statuses`, pick the non-final entry status), `priority='normal'` unless the user signals "acil/critical". `description` can be a plain string. **`companyId` — DIKKAT:** genelde `user.companyId` DEĞİL — B2B talepler MÜŞTERİ şirketi için açılır. Şirket adı netlesmediyse `systa_api_call GET /companies?search=<ad>` ile çöz veya kullanıcıya SOR. `prepare_create_request(companyId)` proaktif seçenekleri döner.
167
- 3. **Efor** (`estimatedEffort`/`personDay`): KANONIK GÜN. Kullanıcı "N saat" derse ÖNCE `list_capabilities.effortPolicy.hoursPerDay` ile böl (varsayılan 8), sonra yaz. "8 saat" → `estimatedEffort=1` (8/8=1 gün), "4 saat" → `estimatedEffort=0.5`. Aynı kural `manage_request_card.estimatedEffort` ve `bulk_update_requests.updates.estimatedEffort` için de geçerli.
174
+ 3. **Efor** (`estimatedEffort`/`personDay`): bu alan **PLANLANAN TAHMİN**tir; gerçekleşen çalışma kaydı DEĞİLDİR (onun için `log_effort` / efor defteri kullanılır — ayrı modül, ayrı uç). KANONIK GÜN. Kullanıcı "N saat" derse ÖNCE `list_capabilities.effortPolicy.hoursPerDay` ile böl (varsayılan 8), sonra yaz. "8 saat" → `estimatedEffort=1` (8/8=1 gün), "4 saat" → `estimatedEffort=0.5`. Aynı kural `manage_request_card.estimatedEffort` ve `bulk_update_requests.updates.estimatedEffort` için de geçerli.
168
175
  4. Submit; report "Talep #<num> açıldı — '<title>'". If the user also said "bana ata", chain assignment below.
169
176
 
170
177
  ### Üzerimdeki işler / talepleri listele (what's on my plate) — `list_requests` → `GET /api/requests`
@@ -242,6 +249,27 @@ Kullanıcının kendi GitHub bağlantısı üzerinden talep açma/aktarma. Tüm
242
249
  - **Issue içe aktar (GitHub → SysTa talep):** `systa_api_call` `POST /github/me/import` — seçili repo'nun issue'larını kullanıcının KENDİ talepleri olarak içe aktarır (idempotent, createdBy=self). "şu repodan issue'ları SysTa'ya aktar / GitHub'dan talep aç" → bu. Mutating + canlı: hangi repo / kaç issue özetini göster, **onay al**.
243
250
  - **Talep push (SysTa → GitHub issue):** `systa_api_call` `POST /github/me/push` — kullanıcının talebini kendi repo'suna GitHub issue'su olarak gönderir/günceller (idempotent, node_id). Dış yan-etki (GitHub'a yazar) → **onay al**.
244
251
 
252
+ ### Efor gir (log worked time) — `log_effort`
253
+
254
+ SysTa'da "efor" iki ayrı şeydir ve karıştırılması veri bozar:
255
+
256
+ - **Tahmini efor** (`estimatedEffort` / `personDay`): talebin PLANLANAN süresi. `update_request` ile yazılır.
257
+ - **Efor defteri** (`log_effort`): kullanıcının GERÇEKLEŞEN çalışma kaydı. Ayrı modül, ayrı uç, ayrı izin.
258
+
259
+ Kullanıcı "bu haftaki eforumu yaz / 3 saat çalıştım / dün toplantıdaydım" derse **defter** kastedilir.
260
+
261
+ 1. **Önce `list_effort_targets`** çağır (`from`/`to` ver; aralık en fazla 366 gün). Dönen `enabledTargets` hangi hedef türünün açık olduğunu söyler: kapalı bir hedefi kullanıcıya ÖNERME. `candidates` son dokunulan talep/projeleri, `categories` efor türlerini, `activityTypes` serbest aktivite türlerini verir. Kimlikler uydurulamaz.
262
+ 2. **`log_effort`** ile yaz. `requestId` / `projectId` / `activityTypeId` üçlüsünden **TAM BİRİ** verilmelidir; sıfır da iki de reddedilir. `inputUnit` ZORUNLUDUR (`minute|hour|day`) — saat/gün çevrimini sen yapma, sunucu kanonik güne çevirir. `entryDate` boşsa bugün yazılır; **gelecek tarih reddedilir**.
263
+ 3. Hata karşılıkları: `403 EFFORT_TARGET_DISABLED` → o hedef türü vendor ayarında kapalı (adım 1'i oku). `403 EFFORT_SCOPE_DENIED` → kullanıcı efor modülü kapsamı dışında. `409 EFFORT_TARGET_IMMUTABLE` → bir kaydın hedefi **asla** değiştirilemez; sil ve yeniden gir.
264
+ 4. Okuma: `list_effort_entries(from, to)` kendi defterini döner; başkasınınki için `userId` ver (ek yetki ister). "Eksiğim var mı" sorusu tek çağrıyla `get_effort_compliance`.
265
+
266
+ 5. **BİRİM: iki farklı kural, karıştırma.** `log_effort`'ta çevrimi SEN YAPMA — kullanıcı ne dediyse o birimle gönder (`3 saat` → `inputValue:3, inputUnit:'hour'`; `yarım gün` → `inputValue:0.5, inputUnit:'day'`; `45 dakika` → `inputValue:45, inputUnit:'minute'`). Sunucu kanonik güne çevirir ve çevrimde HEDEFİN şirketinin `hoursPerDay` değerini kullanır; senin bölmen yanlış şirketin katsayısını uygulayabilir. Buna karşılık `estimatedEffort` (tahmin) alanına yazarken çevrimi SEN yaparsın (bkz. "Talep aç" adım 3). Sonucu kullanıcıya bildirirken vendor'un görünüm birimini kullan: `list_capabilities.effortPolicy.displayUnit` saat ise "3 saat işlendi" de, "0,375 gün" deme.
267
+
268
+ 6. **Kullanıcı efor girişine TABİ İSE proaktif ol.** Efor takibi vendor ayarıyla açılır ve kullanıcı kapsam içindeyse zorunlu hale gelir. Bunu `list_effort_targets` yanıtındaki `settings` (compliance alanları) ya da tek çağrıyla `get_effort_compliance` söyler; `satisfied:false` "bu kullanıcının eksik girişi var" demektir.
269
+ - Kullanıcı MCP üzerinden bir işi TAMAMLADIĞINDA (talep kapatma, statü ilerletme, kart tamamlama gibi), efor modülü açıksa **süreyi sor**: "Bu işe ne kadar zaman ayırdın? Efor defterine işleyeyim mi?" Süreyi UYDURMA ve kullanıcı vermeden yazma — defter kaydı kullanıcının beyanıdır.
270
+ - Kullanıcı "bugün ne yapmalıyım / eksiğim var mı" diye sorduğunda `get_effort_compliance` çağır ve eksik varsa hangi güne ne kadar gerektiğini söyle.
271
+ - Efor modülü bu vendor'da kapalıysa ya da kullanıcı kapsam dışındaysa (`403 EFFORT_SCOPE_DENIED`) hatırlatma YAPMA; olmayan bir yükümlülüğü dayatmak gürültüdür.
272
+
245
273
  ## Zincirleme & hata kurtarma (chaining & error recovery)
246
274
 
247
275
  SysTa returns structured errors. Recover deterministically instead of giving up.
@@ -258,6 +286,10 @@ SysTa returns structured errors. Recover deterministically instead of giving up.
258
286
  6. **`409 conflict`** (optimistic concurrency on cards/edits) — re-read the entity to get the latest `updatedAt`, then retry the mutation once with the fresh value; warn the user only if it conflicts again.
259
287
  7. **Dual-path "list vs create" endpoints** (e.g. `POST /api/sla/definitions`, `POST /api/sla/standby-configs`) — an empty/filter-only body lists; a full body creates. Choose the body shape that matches the intent; don't accidentally create when the user asked to list.
260
288
  8. **Multi-tenant safety.** Never carry an id across vendors. If a resolved id isn't found in the caller's vendor scope, treat it as not-found (step 3), not as a public-schema fallback.
289
+ 9. **`409 REQUEST_FROZEN_BY_APPROVAL`** — the request is FROZEN by a pending approval, so every write on it is refused (update, status change, assignment, comment, kanban card, file upload). This is **not** a permission problem and **not** a transition problem: retrying, calling `list_allowed_transitions` or re-authenticating will not help. Call `get_request_freeze(requestId)` to see which approval froze it and which fields are still writable (`writableFieldKeys` — non-empty only under a custom freeze scope). Then either write only those fields, or tell the user the request is waiting on an approval and offer to wait / cancel it. `list_requests` and `get_request` both carry `isFrozen` — check it BEFORE attempting a write.
290
+ 10. **`403 FEATURE_NOT_ENABLED`** — the vendor's API/MCP module is off, either because the licence lacks `api_access` or because a vendor admin disabled the `mcp` preference. This gate runs before any scope check, so **every** tool fails the same way. Do not tell the user to regenerate the key; tell them to have the vendor administrator enable API/MCP access.
291
+ 11. **`422 REJECTION_REASON_*` / `409 APPROVAL_SEQUENCE_NOT_ACTIVE`** — rejection reasons come from a per-approval-type catalog: call `list_rejection_reasons(approvalTypeId)` and send a `key` from it (`REJECTION_REASON_NOT_ALLOWED` means the code is not bound to that type; `REJECTION_REASON_NOTE_REQUIRED` means that reason needs a non-empty `rejectionReasonText`). `APPROVAL_SEQUENCE_NOT_ACTIVE` means a sequential chain has not reached your group yet — report that it is waiting on an earlier step instead of retrying.
292
+ 12. **Partial success is real.** `bulk_update_requests` can return HTTP 200 while skipping frozen requests; the tool adds a `partialSuccess` block when fewer rows changed than you asked for. Always compare the requested count with `updatedCount` and name the ids that did not change. Never report "all done" from a 200 alone.
261
293
 
262
294
  ## DX / Keşif Notları (talep 166 — prod'da doğrulanmış)
263
295
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "systa-mcp",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "MCP stdio server for SysTa (Talep Takip Sistemi) — lets AI agents (Claude, Codex) use the SysTa REST API via a scoped API key. Zero npm dependencies (native Node).",
5
5
  "type": "commonjs",
6
6
  "main": "server.js",
@@ -15,7 +15,9 @@
15
15
  "scripts": {
16
16
  "start": "node server.js",
17
17
  "check:version-sync": "node scripts/check-version-sync.js",
18
- "prepublishOnly": "node scripts/check-version-sync.js"
18
+ "prepublishOnly": "node scripts/check-version-sync.js && node scripts/check-release-integrity.js --skip-npm",
19
+ "check:release-integrity": "node scripts/check-release-integrity.js",
20
+ "check:release-integrity:self-test": "node scripts/check-release-integrity.js --self-test"
19
21
  },
20
22
  "engines": {
21
23
  "node": ">=18"