Skip to content

Commit 7549fe9

Browse files
sametbasbugclaude
andcommitted
Selene için MCP köprüsü devir belgesi
Kontrat neyin doğru olduğunu söylüyor; bu belge köprüyü yazarken verilecek kararları ve canlıda çarptığım köşeleri söylüyor. Taşıyıcı öneri: işlem başına araç değil, iki genel araç. İşlem listesi siteden geliyor ve site yeni işlem eklediğinde Orbit'e kod girmiyor; işlem başına araç yazmak o kazancı çöpe atar. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 51a20ef commit 7549fe9

1 file changed

Lines changed: 126 additions & 0 deletions

File tree

‎docs/mcp-baglisite-koprusu.md‎

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# MCP köprüsü — bağlı sitelerde ajan eylemleri
2+
3+
Kime: Selene, `orbit-remote-mcp` tarafını kuran taraf.
4+
Durum: **Orbit ucu canlıda ve iki siteyle doğrulandı.** Eksik olan tek şey MCP
5+
köprüsü.
6+
7+
Sözleşmenin kendisi `baglisite-ajan-eylemleri.md`. Bu dosya onu tekrarlamıyor;
8+
köprüyü yazarken verilmesi gereken kararları ve benim canlıda çarptığım
9+
köşeleri yazıyor.
10+
11+
## Kaç araç eklemeli — iki, işlem başına bir değil
12+
13+
`PRIVATE_OPERATIONS` statik ve bunu sen söyledin: API'ye eklenen bir uç MCP'de
14+
kendiliğinden görünmüyor. Buradaki tasarımın taşıyıcı kısıtı da bu yüzden
15+
önemli — **Orbit sitelerin işlerini bilmiyor.** İşlem listesi siteden geliyor
16+
ve site yeni bir işlem eklediğinde Orbit'e kod girmiyor.
17+
18+
İşlem başına bir MCP aracı yazarsan bu kazanç çöper: beşinci site, ya da
19+
Haber'in eklediği üçüncü bir işlem, seni tekrar `orbit-remote-mcp`'ye gitmeye
20+
zorlar. Dolayısıyla **iki genel araç** öneriyorum:
21+
22+
| araç | ne yapar |
23+
|---|---|
24+
| `baglisite_islemleri_listele` | Ajan erişimi açık siteleri ve her birinin işlemlerini şemalarıyla döndürür. |
25+
| `baglisite_islem_calistir` | `grantId` + `operationId` + `input` ile bir işlemi çalıştırır. |
26+
27+
Birincisinin çıktısı ikincisinin girdisini tarif ediyor; model şemayı çalışma
28+
anında okuyup çağrıyı kuruyor. Ajanın hiçbir şey saklamasına gerek yok, ki
29+
zaten saklayacak yeri yok.
30+
31+
## Uçlar
32+
33+
### 1. Katalog
34+
35+
```
36+
GET /v1/me/connected-sites/actions
37+
Authorization: Bearer <ajan credential>
38+
```
39+
40+
Erişimi **kapalı** siteler listede hiç görünmez. Yani liste boşsa cevap
41+
"yapabileceğin bir şey yok" değil, "insan henüz hiçbir siteyi açmamış".
42+
Modele bunu ayırt ettir; yoksa kullanıcıya yanlış şeyi söyler.
43+
44+
Bugün canlıda dönen:
45+
46+
```
47+
Equinox Haber (2 işlem) · Equinox Rota (4 işlem)
48+
```
49+
50+
### 2. Çalıştırma
51+
52+
```
53+
POST /v1/me/connected-sites/{grantId}/actions
54+
Authorization: Bearer <ajan credential>
55+
Content-Type: application/json
56+
57+
{ "operationId": "...", "input": { ... }, "idempotencyKey": "..." }
58+
```
59+
60+
Canlıda doğrulanmış bir örnek ve cevabı:
61+
62+
```json
63+
{ "operationId": "rota.listeyiOku", "input": { "limit": 2 }, "idempotencyKey": "…" }
64+
→ { "action": { "operationId": "rota.listeyiOku", "status": "applied", "output": { … } } }
65+
```
66+
67+
## Köşeler
68+
69+
**Gövde TAM olarak üç alan taşır.** `operationId`, `input`, `idempotencyKey`.
70+
Fazladan alan 400 `invalid_site_action_fields` alıyor — `clientId` göndererek
71+
denedim, reddedildi. `input` işlem parametresizse bile `{}` olarak gitmeli.
72+
73+
**`idempotencyKey` zorunlu ve mantıksal işlem başına üretilmeli, deneme başına
74+
değil.** 1–128 basılabilir ASCII. Aynı anahtar + aynı gövde ilk çalışmanın
75+
cevabını döndürür (`status: "replayed"`); aynı anahtar + FARKLI gövde 409
76+
`idempotency_conflict` alır. Yani modelin her denemede yeni anahtar üretmesi
77+
tekrar korumasını tamamen kapatır — asıl kazanç orada.
78+
79+
**Sitenin hata GÖVDESİ ajana taşınmıyor.** Orbit bunu bilerek yapmıyor: içeriği
80+
doğrulanmamış bir metni kendi cevabı gibi göstermek olurdu. Sonucu şu: siteden
81+
dönen her 4xx sana içeriksiz bir `site_action_failed` (502) olarak geliyor.
82+
83+
Haber bu yüzden **alan kararlarını 2xx ile döndürüyor** ve çıktıda
84+
`uygulandi: false` + sebep taşıyor. Yani `status: "applied"` "iş oldu" demek
85+
DEĞİL; `output.uygulandi` okunmalı. Rota'da böyle bir ayrım yok, orada 4xx
86+
gerçekten hata. Köprü her iki biçimi de modele düz aktarsın, yorumlamasın.
87+
88+
**Katalog 10 dakika önbellekte.** Site yeni işlem eklediyse hemen görünmez.
89+
Kullanıcı "az önce ekledim" diyorsa cevap "yok" değil, "en geç 10 dakika".
90+
91+
**Şema dili dar bir alt küme.** `$ref`, `pattern`, `allOf`/`anyOf`/`oneOf` yok;
92+
nesnelerde `additionalProperties` varsayılan olarak kapalı. Şemayı MCP
93+
`inputSchema`'sına düz geçirebilirsin ama tam JSON Schema varsayan bir
94+
doğrulayıcıya verme.
95+
96+
**403 `agent_access_closed` bir arıza değil, bir kapı.** İnsan Orbit panelinden
97+
kapatmış ya da hiç açmamış. Tekrar denenmemeli; modele "Orbit panelinde
98+
Bağlı siteler → <site> → ajan erişimini aç" dedirtmeli.
99+
100+
## Haber'e özel iki şey
101+
102+
**İşlem sırası var.** `haber.panoYaz` bir `briefId` döndürüyor, `haber.yayinla`
103+
onu tüketiyor. Pano **tek kullanımlık** ve 6 saat sonra doluyor. Tek çağrıda
104+
yayın yok ve olmayacak: panoyu sabitlemek, seçimin hangi adaylar arasından
105+
yapıldığını kayda geçiriyor.
106+
107+
**Yayın imzası senin elinde değil.** Gövdeye yazar alanı koyma — reddedilir.
108+
İmza Haber'in `publishers` tablosundan okunuyor ve senin satırın orada hazır:
109+
`Selene AI`. Bu kasıtlı; kimse başkasının imzasıyla yayımlayamasın diye.
110+
111+
## Nasıl sınarsın
112+
113+
Rota'da `rota.listeyiOku` ile başla — okuma, geri dönüşü yok, katalogdan
114+
çağrıya kadar bütün zinciri yürütüyor. Sonra `rota.katalogdaAra`. Yazma
115+
işlemlerine ancak bu ikisi çalıştıktan sonra geç.
116+
117+
Haber'de `haber.panoYaz` güvenli: pano satırı yazıyor ama hiçbir şey
118+
yayımlamıyor ve 6 saat sonra kendiliğinden düşüyor. `haber.yayinla`yı canlıda
119+
denemeden önce Samet'e söyle — o çağrı gerçekten haber yayımlıyor.
120+
121+
## Dokunmaman gerekenler
122+
123+
Orbit'in kendi ajan yolu (`mcp_authorization_grants`, `posts:write` vb.) bu
124+
işin dışında ve karışmamalı. Orada ajan **kendi adına** davranıyor; burada
125+
insanın adına. İkisini tek araçta birleştirmek, "kimin adına" sorusunu
126+
kaybetmek olur.

0 commit comments

Comments
 (0)