Skip to main content
Glama
tecof
by tecof

@tecof/mcp

stdio MCP server for the Tecof Developer API v1. Runs from inside a Tecof theme repo; reads theme components from disk (AST), converts the agent's simple "section" definitions into editor documents, and creates/updates draft pages via the Developer API. Publishing is always done from the panel (there is no publish in the API).

  • SDK: @modelcontextprotocol/server@^2 (+ zod@^4) — McpServer + serveStdio

  • Node ≥ 20, ESM

  • Tool annotations (readOnlyHint, destructiveHint) and _meta["anthropic/requiresUserInteraction"] (delete) supported

Installation

At the root of the theme repo:

# 1) Panelden API anahtarı üretin: Ayarlar → Geliştirici / API Anahtarları (scope: pages:read, pages:write)
# 2) .env (gitignore'da) içine yazın
echo 'TECOF_API_TOKEN=tcf_...' >> .env

The server runs via npx; no global install needed:

npx -y @tecof/mcp@latest

Environment variables

The project directory is resolved in the order TECOF_PROJECT_DIRCLAUDE_PROJECT_DIRprocess.cwd(); .env and .env.local are read from there. process.env is not overwritten — file values only fill in keys that are empty (.env.local > .env).

Variable

Required

Description

TECOF_API_TOKEN

yes

tcf_… personal access token

TECOF_API_URL

yes*

Backend address; if missing, NEXT_PUBLIC_BASE_URL is used

TECOF_THEME_ID

no

Global theme id; if missing, NEXT_PUBLIC_THEME_ID, and if that is also missing, the store's active theme

TECOF_LOCAL_URL

no

Local preview root (default http://localhost:3000)

TECOF_PROJECT_DIR

no

If the theme repo is in a different directory

If the token/URL is missing, the server still starts; list_components and validate_document work, page tools return an error with guidance. Logs are written only to stderr; uncaught errors also go to stderr, the process does not crash.

Security: TECOF_API_URL must be https. If an http:// (non-loopback) address is given, a stderr warning is printed at startup and the same hint is appended to every tool error; http→https redirects are not followed (Node fetch drops Authorization on redirect, producing a misleading 401) — a 3xx response is converted to a "TECOF_API_URL scheme/host is wrong" error. The request timeout (30 sec) covers the entire header + body read.

Claude Code — .mcp.json

{
  "mcpServers": {
    "tecof": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "${TECOF_MCP_PACKAGE:-@tecof/mcp@latest}"]
    }
  }
}

The TECOF_MCP_PACKAGE env overrides the package spec — before publishing to npm or for local development, point it at this repo folder (npx -y /path/to/tecof-mcp runs the bin in the folder):

export TECOF_MCP_PACKAGE=/Users/<siz>/Desktop/Tecof/tecof-mcp   # claude'u bu shell'den başlatın

Publishing (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ı hesap

Codex — .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"]
    }
  }
}

The token is never written to any configuration file; it stays in .env. The client process starts at the root of the theme repo, and the server reads .env from there.

Related MCP server: anticms-mcp

Tools

Tool

Input

What it does

get_site_context

Store, languages, theme (themeId/merchantThemeId/domain), token scope/expiry, page count

list_components

category?, component?, detail?: summary|full

Theme catalog (AST from disk, mtime cache). full: fields, options, slot allow, defaultProps, variants

list_pages

includeTemplates?

Page list (slug ascending)

get_page

page (id|slug), mode?: outline|full

outline: section/slot tree (id, type, short text); full: draftData

validate_document

{ sections } or { document }

Validates without saving; returns ok, errors, warnings, normalizedDocument

create_page

slug, title, sections, meta?, layoutFrom?, dryRun?

Creates a draft; Header/Footer are copied from shared components in the layoutFrom page (default home)

update_page

page, operations or document, meta?, dryRun?

GET → apply operations → validate → PUT (optimistic lock with expectedModifiedDate; clear message on 409)

delete_page

page, confirm: true

Soft delete — user confirmation required

get_preview_url

page, locale?

1-hour draft preview links (storefront + local)

Results are returned as content[0].text (JSON) + structuredContent; errors carry field/path info with isError: true (so the agent can fix them).

update_page operations

append_section{section} (before the Footer), insert_section{section, before?|after?} (if no anchor, appends like before the Footer), replace_section{id, section}, remove_section{id}, move_section{id, before?|after?}, set_props{id, props} (shallow merge), set_slot{id, slot, children} (replaces the slot entirely; new children are built first, old content is kept on failure), set_root_props{props}.

Behavior notes:

  • Shared components are read-only — including their child nodes. A node carrying sharedComponentId (Header/Footer) and all its descendants under its zones (Logo, NavLink, FooterColumn…) cannot be modified with set_props/set_slot/replace_section/remove_section; a "shared component — edit from the panel editor" error is returned. The shared root itself can be removed from the page with remove_section (with a warning; the master is not affected). These nodes are marked shared: true in the get_page outline.

  • Error / warning distinction (operations mode): The document from GET is first normalized (inline slot arrays left in props → zones; SharedComponentRef nodes whose master was deleted are dropped with a warning — the backend does the same on PUT). Nodes added/changed by the agent in this round are strictly validated (unknown type, allow violation, element-at-root → error); violations in pre-existing, untouched nodes are only warnings — an unrelated update is not blocked just because the theme changed. In document mode and in create_page/validate_document, all nodes are strictly validated.

  • Empty operations: [] (if there is no meta either) → "no operations to apply" error; no PUT is sent. If only meta is given, draftData is not sent (status does not go published→changed, no unnecessary revision is opened); the savedDraft field in the response indicates this.

  • Backend save warnings (in the envelope root warnings: [{code,path,message}], e.g. dropping a Header link whose master was deleted) are returned in the create_page/update_page response as server: [code] path: message lines.

Authoring format

The agent writes a section tree, not document JSON; id generation, defaultProps merging, slot → zone conversion, and multilingual shortcuts are done on the server.

{
  "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>" } } ] } }
    ]
  }
}

Conversion rules:

  1. If type is not in the catalog → error; element category at the root → error; slot child outside allow → error.

  2. props = defaultProps (−id, −inline slot children) ← variants[variant].props (+_variant) ← user props.

  3. If slots[slot] is given, use it; if not, the sample children from defaultProps; if [] is given, empty. All are written to zones["<id>:<slot>"], and props[slot] = [].

  4. Multilingual shortcuts: "text"[{code: defaultLanguage, value}]; {tr, en}[{code,value}]; missing language is a warning. link: "/path"[{code, value:{url, target:"_self"}}]. upload: URL string → external file record.

  5. If a select/radio value is outside options → error. Keys prefixed with _ → error (className is free).

  6. id: 8 characters [A-Za-z0-9_-], unique across the document (a valid and unique props.id is accepted if provided).

Development

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ıp initialize + tools/list doğrular

Tests do not make requests to a real backend (fetch mock); the theme catalog is read from the copied components under test/fixtures/theme.

Programmatic use (HTTP transport, etc.):

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
Install Server
F
license - not found
A
quality
C
maintenance

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • MCP server for AgentDocs (agentdocs.eu): read, search, write, comment on & share Markdown docs.

  • MCP server for the PDFGate API. Generate PDFs, manage documents and handle e-signatures.

  • A MCP server built for developers enabling Git based project management with project and personal…

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/tecof/tecof-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server