@tecof/mcp
v0.2.6
Published
Tecof Developer API için stdio MCP sunucusu — tema reposundan sayfa oluşturma/güncelleme araçları
Maintainers
Readme
@tecof/mcp
Tecof Developer API v1 için stdio MCP sunucusu. Bir Tecof tema reposunun içinden çalışır; tema bileşenlerini diskten (AST) okur, ajanın yazdığı basit "bölüm" tanımlarını editör dokümanına çevirir ve Developer API ile taslak sayfa oluşturur/günceller. Sayfa yayınlama her zaman panelden yapılır (API'de publish yok). Aynı sunucu headless CMS içeriklerini ve e-ticaret kataloğunu (ürün) da yönetir — ürün yazması taslak DEĞİLDİR.
- SDK:
@modelcontextprotocol/server@^2(+zod@^4) —McpServer+serveStdio - Node ≥ 20, ESM
- Tool annotations (
readOnlyHint,destructiveHint) ve_meta["anthropic/requiresUserInteraction"](silme) destekli - İki çalışma modu (0.2.0):
local(varsayılan — 26 araç bu pakette, Developer API v1 doğrudan) veremote(araç kataloğu backend'in Tools API'sinden canlı gelir; paketteki snapshot yalnız yayın anındaki backendmcpkataloğunun kopyasıdır ve canlı katalog önceliklidir, bkz. remote mod). stdio hiç istemiyorsanız backend'in kendi uzak HTTP MCP sunucusu var:https://api.tecof.com/mcp.
Kurulum
Tema reposunun kökünde:
# 1) Panelden API anahtarı üretin: Ayarlar → Geliştirici / API Anahtarları
# (scope: pages:read, pages:write; CMS için cms:*, ürün araçları için products:read/products:write)
# 2) .env (gitignore'da) içine yazın
echo 'TECOF_API_TOKEN=tcf_...' >> .envSunucu npx ile çalışır; global kurulum gerekmez:
npx -y @tecof/mcp@latestOrtam değişkenleri
TECOF_PROJECT_DIR → CLAUDE_PROJECT_DIR → process.cwd() sırasıyla proje dizini bulunur;
.env ve .env.local buradan okunur. process.env ezilmez — dosya değerleri yalnız
boş olan anahtarları doldurur (.env.local > .env).
| Değişken | Zorunlu | Açıklama |
|---|---|---|
| TECOF_API_TOKEN | evet | tcf_… kişisel erişim anahtarı |
| TECOF_API_URL | evet* | Backend adresi; yoksa NEXT_PUBLIC_BASE_URL kullanılır |
| TECOF_THEME_ID | hayır | Global tema id; yoksa NEXT_PUBLIC_THEME_ID, o da yoksa mağazanın aktif teması |
| TECOF_LOCAL_URL | hayır | Yerel önizleme kökü (varsayılan http://localhost:3000) |
| TECOF_PROJECT_DIR | hayır | Tema reposu başka dizindeyse |
| TECOF_MCP_MODE | hayır | local (varsayılan) | remote — bkz. remote mod |
| TECOF_TOOLSETS | hayır | remote modda yalnız bu modüller (virgülle: pages,cms,media,products,domains,general) |
Eksik token/URL durumunda sunucu yine başlar; list_components ve validate_document
çalışır, sayfa araçları yol gösteren bir hata döner. Loglar yalnız stderr'e yazılır;
yakalanmamış hatalar da stderr'e düşer, süreç çökmez.
Güvenlik: TECOF_API_URL https olmalı. http:// (loopback dışı) bir adres verilirse
başlangıçta stderr uyarısı basılır ve her tool hatasına aynı ipucu eklenir; http→https
yönlendirmeleri takip edilmez (Node fetch yönlendirmede Authorization'ı düşürür,
yanıltıcı 401 çıkardı) — 3xx yanıtı "TECOF_API_URL şeması/host'u yanlış" hatasına çevrilir.
İstek zaman aşımı (30 sn) header + gövde okumasının tamamını kapsar.
Claude Code — .mcp.json
{
"mcpServers": {
"tecof": {
"type": "stdio",
"command": "npx",
"args": ["-y", "${TECOF_MCP_PACKAGE:-@tecof/mcp@latest}"]
}
}
}TECOF_MCP_PACKAGE env'i paket spec'ini ezer — npm'e yayınlanmadan önce ya da yerel
geliştirme için bu repo klasörünü verin (npx -y /path/to/tecof-mcp klasördeki bin'i çalıştırır):
export TECOF_MCP_PACKAGE=/Users/<siz>/Desktop/Tecof/tecof-mcp # claude'u bu shell'den başlatınYayınlama (npm)
npm run build && npm test && node scripts/smoke.mjs
npm version patch # ya da minor
npm publish --access public # @tecof kapsamı — tecof-theme-editor/analytics ile aynı hesapCodex — .codex/config.toml
[mcp_servers.tecof]
command = "npx"
args = ["-y", "@tecof/mcp@latest"]Gemini CLI — .gemini/settings.json
{
"mcpServers": {
"tecof": {
"command": "npx",
"args": ["-y", "@tecof/mcp@latest"]
}
}
}Token hiçbir yapılandırma dosyasına yazılmaz; .env içinde kalır. İstemci süreci tema
reposunun kökünde başlatır, sunucu .env'i oradan okur.
Uzak MCP (HTTP) — api.tecof.com/mcp
Backend, aynı araç kayıt defterini Streamable HTTP MCP sunucusu olarak da sunar:
https://api.tecof.com/mcp. stdio paketi kurmadan, tema reposu olmadan (ör. Claude Desktop,
claude.ai, Cursor) bağlanmak için bunu kullanın. Kimlik yine PAT'tir — Authorization: Bearer tcf_…
static header olarak verilir (OAuth girişi faz 2'de; "sunucu isterse OAuth" seçenekleri
yer tutucu sayfaya düşer). Araç adları, şemalar, hata kodları ve sonuç biçimi bu paketle birebirdir.
Toolset daraltma: X-Tecof-Toolsets: pages,cms başlığı ya da ?toolsets=pages,cms (modül adları;
bilinmeyen yok sayılır). İlerleme bildirimi yalnız istemci progressToken gönderdiyse.
Claude Code
claude mcp add --transport http tecof https://api.tecof.com/mcp --header "Authorization: Bearer ${TECOF_API_TOKEN}"ya da .mcp.json:
{
"mcpServers": {
"tecof": {
"type": "http",
"url": "${TECOF_API_URL:-https://api.tecof.com}/mcp",
"headers": { "Authorization": "Bearer ${TECOF_API_TOKEN}" },
"timeout": 600000
}
}
}--header/headers OLMADAN Claude Code 401 challenge'ını izleyip OAuth yer tutucu sayfasına düşer.
Codex — ~/.codex/config.toml:
[mcp_servers.tecof]
url = "https://api.tecof.com/mcp"
bearer_token_env_var = "TECOF_API_TOKEN"
startup_timeout_sec = 20
tool_timeout_sec = 300
[mcp_servers.tecof.tools.delete_page]
approval_mode = "prompt" # onay isteyen her araç için tekrarlayın (delete_cms_item, delete_product, domain_dns_*)Gemini CLI — .gemini/settings.json:
{
"mcpServers": {
"tecof": {
"httpUrl": "https://api.tecof.com/mcp",
"headers": { "Authorization": "Bearer $TECOF_API_TOKEN" },
"timeout": 600000
}
}
}Cursor — .cursor/mcp.json:
{
"mcpServers": {
"tecof": {
"url": "https://api.tecof.com/mcp",
"headers": { "Authorization": "Bearer ${env:TECOF_API_TOKEN}" }
}
}
}Claude Desktop / claude.ai — Settings → Connectors → Add custom connector → URL
https://api.tecof.com/mcp, Authentication "None" + Request header
Authorization: Bearer tcf_… (beta; "Required when the server asks" SEÇMEYİN). Static header
desteği yoksa claude_desktop_config.json içinde köprü:
{
"mcpServers": {
"tecof": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://api.tecof.com/mcp", "--header", "Authorization: Bearer ${TECOF_API_TOKEN}"]
}
}
}remote mod (stdio proxy)
TECOF_MCP_MODE=remote ile bu paket, araçları kendi içinden değil backend'in Tools API
kataloğundan alır ve her çağrıyı sunucuya iletir:
| Adım | Ne olur |
|---|---|
| Başlangıç | GET /api/v1/tools?surface=mcp[&toolsets=…] — 3 sn bütçe, arka planda. Yetişmezse/erişilemezse paketle gelen snapshot (src/remote/catalog.snapshot.json — yayın anındaki backend mcp kataloğunun kopyası; canlı katalog önceliklidir) kullanılır ve stderr'e uyarı basılır; tools/list çevrimdışı da deterministiktir. Canlı katalog sonradan gelirse eksik araçlar eklenir ve tools/list_changed gönderilir. |
| Çağrı | POST /api/v1/tools/:name?stream=1 — başlıklar Authorization: Bearer <TECOF_API_TOKEN>, X-Tecof-Surface: mcp. SSE çerçeveleri progress / result / error; sunucu düz application/json dönerse (idempotency replay, kimlik zinciri) zarf olduğu gibi okunur. |
| İlerleme | SSE progress çerçeveleri yalnız istek _meta.progressToken taşıyorsa notifications/progress olur. |
| Sonuç | content[0].text = JSON + structuredContent (+ credit, warnings). Hata isError:true, metin "<messageCode>: <mesaj>" + ipucu, structuredContent = { error: messageCode, message, status, …data, needsConfirmation? }. |
| Onay | confirm:"required" araçları (delete_*, domain_dns_*, domain_nameservers_set) confirm:true olmadan 409 confirmation-required + confirmId döner; kullanıcı onayladıysa AYNI girdiyle confirm:true + confirmId gönderilir (PAT yüzeyinde tek geçişli onay). |
| Yerel katalog | Tema reposunda components/ varsa list_components ve validate_document diskten çalışır; create_page/update_page hibrit: bölümler/operation'lar yerel katalogla inşa edilip doğrulanır, hazır document sunucuya gider (sunucu kendi kataloğuyla bir kez daha doğrular — yayında olmayan bileşen unknown-type). components/ yoksa dört araç da sunucudan. |
| Yetki | Anahtarın scope'u yetmeyen araçlar da listelenir; hata çağrı anında insufficient-scope olarak döner. |
Snapshot'ı yenilemek (backend reposunda): npm run -s tools:list -- --json > ../tecof-mcp/src/remote/catalog.snapshot.json
(-s şart: npm'in başlık satırları JSON'u bozar). test/remote.test.ts snapshot sözleşmesini denetler —
kritik tema/kod araçları ve şema alanları eksikse kırmızı, generatedAt 14 günden eskiyse uyarı basar.
remote modda öne çıkan katalog araçları
Aşağıdakiler local modda yoktur; tanım ve şema backend kataloğundan gelir (kesin liste ve güncel
şema için tools/list ya da src/remote/catalog.snapshot.json):
| Tool | Girdi (özet) | Ne yapar |
|---|---|---|
| publish_page | page, confirm | Taslağı yayına alır — onay özeti taslak↔yayın farkını gösterir |
| search_site_content | query, in?, types?, props?, pages?, includeSymbols? | Metni/bağlantıyı TÜM sayfalarda (taslak + yayın) ve ortak bileşenlerde arar; sayfa → düğüm → alan → dil |
| replace_in_site | find, replace, süzgeçler, includeSymbols?, dryRun? | Toplu değiştirir; sayfalarda yalnız TASLAK (ortak bileşen includeSymbols ile CANLI) — onay ister |
| diff_page | page | Taslak ile yayındaki sürümün farkı; son değiştiren başka kullanıcı mı |
| publish_pages | pages[] | all, expectedModifiedDates? | Birden çok sayfayı TEK onayla yayınlar; özet her sayfanın farkını gösterir |
| add_variants | product, expand | combinations, price?, stock?, dryRun? | Var olan ürüne kombinasyon ekler ("her renge XL ekle"); var olan kombinasyon atlanır — onay ister |
| bulk_update_variants | scope, select, price | setPrice | stock | isActive…, dryRun? | Seçilen varyantların fiyat/stok/aktifliğini tek çağrıda yazar (≤200 ürün) — onay ister |
| delete_variants | product, select, mode?: remove\|hide, dryRun? | TEK ürünün varyantlarını siler (varsayılan; 30 gün çöp kutusunda) ya da gizler; açık siparişte geçen varyantı silmez — onay ister |
| restore_variants | product (ya da silinen SKU), variants?, dryRun? | Silinen varyantı 30 gün içinde AYNI kimlikle geri yükler (sipariş/fiyat geçmişi bağları geri gelir) — onay ister |
| variant_performance | product?, period?, sortBy?, includeUnsold? | Kombinasyon bazında satış + stok kaç gün yeter; üründe beden/renk dağılımı ve hiç satmayanlar (salt-okunur) |
| update_variant_type | type, rename?, values?[{value, rename?, colorCode?, order?}], removeValues?, dryRun? | Varyant tipini/değerlerini yeniden adlandırır (bütün katalogda anında), kullanılmayan değeri siler — onay ister |
| merge_variant_values | type + (values, into) ya da intoType, dryRun? | Kopya değerleri ("siyah"→"Siyah") ya da tipleri ("Bedenler"→"Beden") birleştirir, ürün bağlarını yeniden yazar; çakışmada hiçbir şey yazmaz — onay ister |
| list_themes / create_theme / theme_job_status / activate_theme | themeId, jobId, waitFor? | Özel tema aç (arka plan işi, onay + kredi), iş durumunu bekle, canlıya al (onay) |
| theme_commit_files | message, files?, deletions?, confirm | Dosya yazma ve/veya silmeyi tek commit'te depoya gönderir; yalnız silme için files verilmeyebilir — onay ister |
| theme_deploy_status | deploymentId?, waitFor?: none\|terminal, sinceDeploymentId?, timeoutSeconds? | Dağıtım durumu; sinceDeploymentId (commit yanıtındaki previousDeploymentId) eski READY'ye kanmadan yeni dağıtımı bekler |
| theme_deploy_logs | deploymentId, errorsOnly?, limit? | ERROR veren dağıtımın derleme günlüğü (değerler maskelenir) |
| ide_delete_files | sessionId, paths | Sandbox'tan dosya siler; silme ide_commit_push'ta depoya gider |
| list_discounts / list_flash_sales | q?, isActive? / state?, page?, limit? | Kuponları / flaş satışları sayfalı listeler |
Araçlar
Aşağıdaki 26 araç local modun kendi tanımlarıdır. remote modda liste backend kataloğundan gelir:
aynı 26 araç (aynı ad/şema) + domain, sipariş, müşteri, pazarlama, ayar, tema/kod ve genel modüllerin
araçları ve backend'e eklenen her yeni araç — bkz. remote modda öne çıkan katalog araçları.
| Tool | Girdi | Ne yapar |
|---|---|---|
| get_site_context | — | Mağaza, diller, tema (themeId/merchantThemeId/domain), token scope/bitiş, sayfa sayısı |
| list_components | category?, component?, detail?: summary\|full | Tema kataloğu (diskten AST, mtime cache). full: alanlar, seçenekler, slot allow, defaultProps, variants |
| list_pages | includeTemplates? | Sayfa listesi (slug artan) |
| get_page | page (id|slug), mode?: outline\|full | outline: bölüm/slot ağacı (id, type, kısa metin); full: draftData |
| validate_document | { sections } veya { document } | Kaydetmeden doğrular; ok, errors, warnings, normalizedDocument |
| create_page | slug, title, slugs?, titles?, sections, meta?, layoutFrom?, dryRun? | Taslak oluşturur; Header/Footer layoutFrom sayfasındaki (varsayılan home) ortak bileşenlerden kopyalanır. slugs/titles dile göre adres/ad verir ({tr:"hakkimizda", en:"about"}); verilmezse slug/title tüm açık dillerde kullanılır |
| update_page | page, operations veya document, meta?, dryRun? | GET → işlemleri uygula → doğrula → PUT (expectedModifiedDate ile iyimser kilit; 409'da net mesaj) |
| delete_page | page, confirm: true | Soft delete — kullanıcı onayı şart |
| get_preview_url | page, locale? | 1 saatlik taslak önizleme linkleri (storefront + yerel) |
| list_cms_collections | — | Headless CMS içerik tipleri (slug, ad, alan/içerik sayısı) |
| get_cms_collection | collection (id|slug) | Alan şeması + her alan için beklenen veri biçimi (çok dilli mi, dosya objesi mi, referans id'si mi) — içerik yazmadan önce çağrılır |
| create_cms_collection | slug, name?, fields?, displayField?, icon? | İçerik tipi açar; alan şeması katı doğrulanır (shortcode, tip, option, repeater, reference) |
| update_cms_collection | collection, fields?, slug?, displayField?, allowFieldLoss? | Şemayı günceller; fields verilirse tamamen değişir. Veri taşıyan alanı silmek/tipini değiştirmek allowFieldLoss:true ister |
| list_cms_items | collection, status?, search?, page?, limit? | İçerik listesi (özet; data dönmez) |
| get_cms_item | collection, item (id|slug) | İçeriğin tamamı + modifiedDate (iyimser kilit için) |
| create_cms_item | collection, slug, data?, metaTitle?, metaDescription? | TASLAK içerik oluşturur; data alan şemasına göre katı doğrulanır |
| update_cms_item | collection, item, data?, dataMode?, slug?, allowPublishedEdit? | data varsayılan olarak birleştirilir (verilmeyen alan korunur); silmek için dataMode:"replace". İyimser kilit otomatik. Yayındaki içerik allowPublishedEdit:true ister |
| delete_cms_item | collection, item, confirm: true, allowPublishedEdit? | Soft delete — kullanıcı onayı şart; yayındaki içerik ayrıca onay ister |
| list_products | search?, status?, category?, brand?, tag?, updatedSince?, page?, limit?, detail?: summary\|full | Katalog listesi (ad, durum, marka/kategori/etiket adları, stok, kapak görseli). full: varyant sku/fiyat/stok + fiyat aralığı |
| get_product | product (id|slug|SKU) | Ürünün tamamı: çok dilli alanlar, görseller (CDN URL), varyantlar. Güncellemeden önce çağrılır |
| upsert_products | items (≤200), dryRun? | Oluşturur/günceller; anahtar slug → varyant sku. Marka/kategori/etiket adıyla çözülür, yoksa açılır; görsel URL'i sunucuda indirilir |
| delete_product | product, confirm: true | Soft delete — kullanıcı onayı şart |
| get_product_import_template | — | Panelin CSV içe aktarma şablonu (sütunlar + örnek satırlar + ham metin) |
Sonuçlar content[0].text (JSON) + structuredContent olarak döner; hatalar isError: true
ile alan/yol bilgisi taşır (ajan düzeltebilsin diye).
Headless CMS akışı
list_cms_collections → get_cms_collection (alan biçimleri) → create_cms_item / update_cms_item.
Sözleşme, sayfa araçlarıyla aynı: yazmalar taslaktır, yayınlamayı kullanıcı panelden yapar
(status göndermek hata verir). Sayfalardan farklı olarak CMS'te taslak katmanı yoktur — yayındaki
bir içeriği değiştirmek/silmek anında canlıya yansır, bu yüzden allowPublishedEdit: true istenir;
bu bayrağı yalnız kullanıcı açıkça onayladıysa gönderin. Alan şeması değişikliğinde veri kaybı
riski varsa (allowFieldLoss) aynı kural geçerlidir.
Veri biçimleri (data içinde): çok dilli alanlar [{code,value}]; görsel/dosya alanları
list_media / import_image / generate_image çıktısındaki tam dosya objesi dizisi;
reference alanları hedef içeriğin 24 haneli id'si; repeater satır nesnesi dizisi.
Kesin liste her zaman get_cms_collection çıktısındadır.
Ürün (e-ticaret) akışı
list_products → get_product → upsert_products (önce dryRun: true).
Scope: products:read / products:write (anahtarı panelden bu yetkilerle üretin).
delete_product silmenin kendisi için yalnız products:write ister; ancak ürünü adres (slug) ya da
SKU ile verirseniz araç önce ürünü okuyup id'ye çevirmek zorundadır, o okuma products:read gerektirir.
Yalnız yazma yetkili bir anahtarla çalışıyorsanız ürünün 24 haneli id'sini verin.
Sayfa/CMS araçlarından iki farkı vardır ve ikisi de kritiktir:
- Yazma taslak değildir.
status: "active"ürünü anında vitrine çıkarır;statushiç gönderilmezse mevcut durum korunur (yeni üründe varsayılandraft). - Ürün temaya bağlı değildir —
themeIdgönderilmez; teması bozuk/eksik bir mağazada da katalog yönetilebilir.
upsert_products "yalnız dolu alan yazılır" kuralıyla çalışır ve bu kural varyant
içinde de geçerlidir: göndermediğiniz price, compareAtPrice, isActive alanına
dokunulmaz; stock kısayolu yalnız ilk depo satırını günceller, diğer depoların stoğunu
silmez. variants listesinin KENDİSİ de opsiyoneldir: hiç göndermezseniz mevcut
varyantlara dokunulmaz ({slug, status} ile yalnız durumu değiştirebilirsiniz), gönderirseniz
boş olamaz. price de opsiyoneldir — yeni üründe boşsa 0, mevcut varyantta boşsa fiyat
korunur. Eşleşmeyen SKU yeni varyant EKLER, listede olmayan varyant SİLİNMEZ (varyant
silme panel işidir); bu yüzden bir ürünü baştan kurgularken get_product → değerleri
kopyala → değiştireceğini değiştir → upsert_products akışı hâlâ en güvenlisidir.
Diğer notlar: marka/kategori/etiket adıyla verilir (yoksa açılır); images[] hem
kütüphane dosyası ({uploadId} / {name}) hem uzak URL ({url}; SSRF korumalı indirilir,
aynı URL bir kez) kabul eder; varyant ekseni options: {"Beden":"S"} biçimindedir.
Fiyat ve stok kuralları sunucudadır. Alan tablosu, dosyayla (CSV/XLSX/JSON) içe aktarma ve
sınırlar: backend docs/PRODUCT_IMPORT_EXPORT.md.
update_page operation'ları
append_section{section} (Footer'ın önüne), insert_section{section, before?|after?} (anchor yoksa append gibi Footer'ın önüne),
replace_section{id, section}, remove_section{id}, move_section{id, before?|after?},
set_props{id, props} (sığ birleşim), set_slot{id, slot, children} (slotu komple değiştirir; önce yeni çocuklar inşa edilir, başarısızsa eski içerik korunur),
set_root_props{props}.
Davranış notları:
- Ortak bileşenler salt-okunur — alt düğümleri dahil.
sharedComponentIdtaşıyan düğüm (Header/Footer) ve onun zones altındaki tüm torunları (Logo, NavLink, FooterColumn…)set_props/set_slot/replace_section/remove_sectionile değiştirilemez; "ortak bileşen — panel editöründen düzenleyin" hatası döner. Ortak kökün kendisiremove_sectionile sayfadan kaldırılabilir (uyarıyla; master etkilenmez).get_pageoutline'ında bu düğümlershared: trueile işaretlidir. - Hata / uyarı ayrımı (operations modu): GET'ten gelen doküman önce normalize edilir (props'ta kalmış inline slot dizileri → zones; master'ı silinmiş
SharedComponentRefdüğümleri uyarıyla düşer — backend PUT'ta aynısını yapar). Ajanın bu turda eklediği/değiştirdiği düğümler katı denetlenir (bilinmeyen type, allow ihlali, element-at-root → hata); önceden var olan, dokunulmayan düğümlerdeki ihlaller yalnız uyarıdır — tema değişmiş diye ilgisiz bir güncelleme kilitlenmez.documentmodunda vecreate_page/validate_document'ta tüm düğümler katı denetlenir. - Boş
operations: [](meta da yoksa) → "uygulanacak işlem yok" hatası; PUT atılmaz. YalnızmetaverilirsedraftDatagönderilmez (status published→changed olmaz, gereksiz revizyon açılmaz); yanıttasavedDraftalanı bunu gösterir. - Backend'in kaydetme uyarıları (zarf kökündeki
warnings: [{code,path,message}], örn. master'ı silinmiş Header bağının düşürülmesi)create_page/update_pageyanıtındasunucu: [code] path: messagesatırları olarak döner.
Yazarlık biçimi
Ajan doküman JSON'u değil, bölüm ağacı yazar; id üretimi, defaultProps birleşimi, slot → zone dönüşümü ve çok dilli kısayollar sunucuda yapılır.
{
"type": "FeaturesSection",
"props": { "columns": "3", "background": "dark" },
"variant": "dark", // bileşenin variants anahtarı (varsa)
"slots": {
"contentSlot": [
{ "type": "Title", "props": { "text": { "tr": "Neden biz?", "en": "Why us?" }, "size": "lg" } }
],
"itemsSlot": [
{ "type": "Card", "props": { "href": "/hakkimizda" },
"slots": { "contentSlot": [ { "type": "Paragraph", "props": { "text": "<p>Hızlı teslimat</p>" } } ] } }
]
}
}Dönüşüm kuralları:
typekatalogda yoksa hata; kökteelementkategorisi hata; slot çocuğuallowdışında hata.props=defaultProps(−id, −inline slot çocukları) ←variants[variant].props(+_variant) ← kullanıcıprops.slots[slot]verildiyse o; verilmediyse defaultProps'taki örnek çocuklar;[]verilirse boş. Hepsizones["<id>:<slot>"]'a yazılır,props[slot] = [].- Çok dilli kısayollar:
"metin"→[{code: varsayılanDil, value}];{tr, en}→[{code,value}]; eksik dil uyarı.link:"/yol"→[{code, value:{url, target:"_self"}}].upload: URL string → dış dosya kaydı. select/radiodeğerioptionsdışındaysa hata._önekli anahtarlar hata (classNameserbest).- id: 8 karakter
[A-Za-z0-9_-], doküman genelinde tekil (geçerli+tekil birprops.idverilirse kabul edilir).
Geliştirme
npm install
npm run build # tsc → dist/ (+ dist/bin.js +x)
npm test # vitest (parser, build, validate, operations, api mock, config, uçtan uca MCP)
node scripts/smoke.mjs # dist/bin.js'i stdio ile ayağa kaldırır: 1) local, 2) geçersiz /me, 3) remote + sahte katalog (SSE), 4) remote + erişilemeyen API → snapshotTestler gerçek backend'e istek atmaz (fetch mock'u; remote testleri node:http ile yalnız
127.0.0.1'de sahte Tools API kurar); tema kataloğu test/fixtures/theme altındaki kopya
bileşenlerden okunur.
Programatik kullanım (HTTP transport vb.):
import { buildServer, ServerContext, loadConfig } from "@tecof/mcp";
const ctx = new ServerContext({ config: loadConfig() });
const server = buildServer({ ctx }); // McpServer — istediğiniz transport'a bağlayın
// remote mod: kataloğu (≤3 sn) bekleyip kurun; yetişmezse snapshot ile kurulur
const remoteCtx = new ServerContext({ config: { ...loadConfig(), mode: "remote" } });
await remoteCtx.remoteCatalog.ready();
const proxy = buildServer({ ctx: remoteCtx });Proje geliştirme bilgisi
Docs indeksi ve MCP protokol haritası, güncel kaynak ve test sınırlarını gösterir. Protokol/SDK/bağlantı işleri için tecof-mcp-protocol skill’i kullanılabilir; Claude aynı kaynağı .claude/skills bağlantısından okur.
