خادم MCP
تشغّل TakeTheme خادم Model Context Protocol (MCP) ليتمكن المساعدون الأذكياء — ChatGPT أو Claude أو Cursor أو GitHub Copilot أو Codex أو Gemini أو وكيل ذكي تبنيه بنفسك أو أي عميل آخر يتحدث بالبروتوكول — من قراءة بيانات متجرك مباشرة: أرقام المبيعات والطلبات والمنتجات والعملاء والتقييمات.
فبدل كتابة تكامل كامل مع الـ REST API، توجّه عميل MCP إلى عنوان واحد وتصادقه مرة واحدة، ليكتشف المساعد الأدوات المتاحة بنفسه.
POST https://api.taketheme.com/mcp
الوصول بمفتاح API متاح في باقتَي Pro وScale — راجع مفاتيح API. أما الربط عبر OAuth فلا يحتاج مفتاحًا، لكن الأدوات نفسها تظل محكومة بالباقة: أي إمكانية لا تشملها باقتك تجيب بـ plan_upgrade_required أيًّا كانت طريقة مصادقتك.
أدوات التجارة والتحليلات للقراءة فقط. أما أدوات منشئ المتجر فتستطيع تعديل واجهة متجرك — لكن كل كتابة تقع على مسودة لا ينشرها إلا إنسان، وتُؤخذ نقطة استعادة قبل كل كتابة، ويُرفض الوكيل ما دام شخص يحرّر تلك المسودة فعليًا. ولا تكتب أي أداة في المتجر المباشر، عدا builder_create_menu التي تنشئ قوائم تنقّل جديدة مباشرةً لأن القوائم غير محفوظة بنسخ. راجع أدوات منشئ المتجر أدناه.
نظرة سريعة
| اسم الخادم | taketheme-commerce |
| وسيلة النقل | Streamable HTTP (بلا حالة) |
| إصدار البروتوكول | 2025-06-18 |
| الإمكانات | tools وresources (كتالوج المكونات) — بلا prompts أو sampling أو إشعارات من الخادم |
| الأدوات | 33 أداة — قراءات التجارة والتحليلات إضافة إلى حزمة منشئ المتجر؛ راجع مرجع الأدوات |
| المصادقة | ترويسة مفتاح API ثابتة، أو OAuth 2.1 مع تسجيل عملاء ديناميكي |
| النطاق | بيانات اعتماد واحدة = متجر واحد. ولا تستطيع الوصول إلى أي متجر آخر. |
البداية السريعة
هناك طريقان. إن كان لدى عميلك زر «اربط تطبيقًا» — مثل ChatGPT أو claude.ai — فسيشغّل مسار OAuth: يسجّل نفسه، ويوافق التاجر مرة واحدة من لوحة التحكم، ولا ينتقل أي مفتاح بين الطرفين. انتقل إلى مساعدون يربطون أنفسهم.
وما عدا ذلك يحتاج مفتاح API.
1. أنشئ مفتاح API
من لوحة التحكم، اذهب إلى الإعدادات ← مفاتيح API وأنشئ مفتاحًا يحمل صلاحية READ على الموارد التي تريد أن يصل إليها المساعد — غالبًا ANALYTICS وORDERS وPRODUCTS وCUSTOMERS وCATEGORIES وREVIEWS وSTORE_SETTINGS. ولأدوات منشئ المتجر، أضف THEME بإجراءَي READ وWRITE — فالقراءات تحتاج الأول، وترحيل التعديلات على مسودة يحتاج الثاني. تتحقق كل أداة من صلاحيتها عند الاستدعاء، فالمفتاح الأضيق يعني ببساطة عددًا أقل من الأدوات الناجحة. ويسرد مرجع الأدوات الصلاحية التي تحتاجها كل أداة.
2. اربط عميلًا
كل العملاء في هذا القسم يحتاجون الشيئين نفسيهما: العنوان https://api.taketheme.com/mcp والترويسة Authorization: Bearer tt_YOUR_API_KEY. وإن لم يكن عميلك مذكورًا، فابحث عن المكان الذي يضبط فيه خادم MCP بعيدًا (عبر HTTP أو ما يسمّى streamable HTTP) مع ترويسات مخصصة — فهذا كل ما يحتاجه هذا الخادم.
المساعدون وبيئات التطوير
Claude Code
claude mcp add --transport http taketheme https://api.taketheme.com/mcp \
--header "Authorization: Bearer tt_YOUR_API_KEY"
claude.ai (موصّل مخصص)
أضف موصّلًا مخصصًا يشير إلى https://api.taketheme.com/mcp، واضبط ترويسة ثابتة:
Authorization: Bearer tt_YOUR_API_KEY
Cursor — في ~/.cursor/mcp.json لكل المشاريع، أو في .cursor/mcp.json لمشروع واحد:
{
"mcpServers": {
"taketheme": {
"url": "https://api.taketheme.com/mcp",
"headers": { "Authorization": "Bearer tt_YOUR_API_KEY" }
}
}
}
VS Code (وضع الوكيل في GitHub Copilot) — في .vscode/mcp.json:
{
"servers": {
"taketheme": {
"type": "http",
"url": "https://api.taketheme.com/mcp",
"headers": { "Authorization": "Bearer tt_YOUR_API_KEY" }
}
}
}
Gemini CLI — في ~/.gemini/settings.json:
{
"mcpServers": {
"taketheme": {
"httpUrl": "https://api.taketheme.com/mcp",
"headers": { "Authorization": "Bearer tt_YOUR_API_KEY" }
}
}
}
Codex CLI — في ~/.codex/config.toml:
[mcp_servers.taketheme]
url = "https://api.taketheme.com/mcp"
bearer_token_env_var = "TAKETHEME_API_KEY"
صدّر TAKETHEME_API_KEY قبل تشغيل Codex، أو سجّل الخادم بالأمر:
codex mcp add taketheme --url https://api.taketheme.com/mcp \
--bearer-token-env-var TAKETHEME_API_KEY
دعم Codex لخوادم MCP البعيدة أحدث من دعمه لـ stdio، وقد شُحن في بعض الإصدارات خلف experimental_use_rmcp_client = true. فإن جرى تجاهل url أو رفضه، اربطه عبر mcp-remote كما في الأسفل.
Claude Desktop وWindsurf والعملاء الذين يدعمون stdio فقط
اربط الخادم البعيد عبر mcp-remote:
{
"mcpServers": {
"taketheme": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://api.taketheme.com/mcp",
"--header",
"Authorization: Bearer tt_YOUR_API_KEY"
]
}
}
}
الوكلاء الأذكياء الذين تبنيهم بنفسك
OpenAI Responses API — تتيح أداة MCP المستضافة أن تتولى OpenAI الاتصال بالخادم نيابةً عنك:
import os
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-5",
tools=[{
"type": "mcp",
"server_label": "taketheme",
"server_url": "https://api.taketheme.com/mcp",
"headers": {"Authorization": f"Bearer {os.environ['TAKETHEME_API_KEY']}"},
"require_approval": "never",
}],
input="How did the store do last week, and what's running low on stock?",
)
print(response.output_text)
ولأن الأداة مستضافة، ينتقل مفتاحك إلى OpenAI مع كل طلب، وخوادم OpenAI — لا جهازك — هي التي تفتح الاتصال. فاستخدم مفتاحًا مخصصًا بأضيق صلاحيات ممكنة.
LangChain / LangGraph — عبر langchain-mcp-adapters الذي يحوّل الأدوات إلى أدوات LangChain:
import os
from langchain_mcp_adapters.client import MultiServerMCPClient
client = MultiServerMCPClient({
"taketheme": {
"transport": "http", # تسمّيه الإصدارات الأقدم "streamable_http"
"url": "https://api.taketheme.com/mcp",
"headers": {"Authorization": f"Bearer {os.environ['TAKETHEME_API_KEY']}"},
}
})
tools = await client.get_tools()
وللاتصال المباشر عبر حزم التطوير، راجع استخدام حزم MCP أدناه.
تشغّل واجهة الموصّلات في ChatGPT مسار OAuth بدل أخذ مفتاح — راجع مساعدون يربطون أنفسهم أدناه. ويظل Responses API أعلاه الخيار الأنسب للاستخدام البرمجي.
مساعدون يربطون أنفسهم
ChatGPT — من الإعدادات ← الموصّلات أضف موصّلًا مخصصًا في وضع المطوّر، بالعنوان https://api.taketheme.com/mcp ونوع المصادقة OAuth. لا مفتاح ولا معرّف عميل تلصقه: يكتشف ChatGPT خادم التفويض، ويسجّل نفسه، ويرسل التاجر إلى لوحة تحكم TakeTheme للموافقة. ووافق على صلاحية الكتابة إن أردت أدوات منشئ المتجر — فالموافقة على القراءة وحدها تترك كل تلك ال أدوات مرفوضة.
claude.ai — إضافة العنوان نفسه كموصّل مخصص دون ضبط ترويسة تسلك مسار OAuth أيضًا.
وفي الحالتين يظهر الاتصال تحت الإعدادات ← MCP في لوحة التحكم، حيث يستطيع التاجر إلغاؤه. راجع OAuth للمسار الكامل والصلاحيات وطريقة تنفيذه يدويًا.
تشترط موصّلات البحث العميق أن يتيح الخادم أداتين باسمَي search وfetch حرفيًا. وهذا الخادم يسمّي أدواته بحسب وظيفتها (search_products وget_order وغيرها)، فهو يعمل كموصّل في وضع المطوّر لكنه لن يظهر كمصدر للبحث العميق.
3. اسأل سؤالًا
"كيف كان أداء المتجر الأسبوع الماضي مقارنة بالذي قبله، وما المنتجات التي أوشكت على النفاد؟"
سيست دعي المساعد get_store_metrics وget_low_stock_products ويجيب من نتائجهما.
المصادقة
يقبل الخادم بيانات الاعتماد نفسها التي تقبلها الـ REST API، إضافة إلى رموز OAuth:
Authorization: Bearer tt_YOUR_API_KEY
tt-api-key: tt_YOUR_API_KEY
استخدم صيغة Authorization مع عملاء MCP — فمعظمها لا يستطيع إرسال سوى الترويسات القياسية. وكلتا الصيغتين تشيران إلى المفتاح نفسه.
أما العملاء الذين يشغّلون مسار تفويض فيقدّمون رمز وصول OAuth في ترويسة Authorization: Bearer نفسها. وهذه الرموز مقيّدة بجمهور /mcp ومرفوضة على كل مسارات REST.
تحدد بيانات الاعتماد المتجر. وstoreId ليس وسيطًا لأي أداة على الإطلاق: تحقنه الخوادم من المفتاح أو الرمز المُصادَق عليه، فلا يستطيع أي توجيه نصي — ولا أي محاولة حقن — أن يوجّه أداة نحو بيانات تاجر آخر.
| الحالة | الاستجابة |
|---|---|
| بلا بيانات اعتماد | 401 — AUTHENTICATION_REQUIRED مع ترويسة WWW-Authenticate |
| رمز Bearer ليس مفتاح TakeTheme ولا رمز OAuth | 403 |
| مفتاح غير معروف أو ملغى أو منتهي | 401 |
| رمز وصول OAuth منتهي | 401 — JWT_EXPIRED؛ جدّده |
| رمز OAuth ملغى | 401 — TOKEN_REVOKED |
رمز OAuth على مسار غير /mcp | 403 — ACCESS_DENIED |
| بيانات اعتماد صالحة | 200 مع استجابة JSON-RPC |
أخطاء المصادقة أخطاء HTTP عادية وليست أخطاء JSON-RPC — فهي تقع قبل أن تصل الطلبات إلى طبقة البروتوكول.
استدعاء الخادم مباشرة
يصلح أي عميل HTTP. وترويستان مهمتان:
Content-Type: application/jsonAccept: application/json, text/event-stream— كلا النوعين، حسب مواصفة MCP
curl -sS -X POST https://api.taketheme.com/mcp \
-H "Authorization: Bearer $TAKETHEME_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
إغفال text/event-stream من ترويسة Accept يُرجع 406 Not Acceptable قبل أن يصل طلبك إلى الخادم. فإذا فشل أول طلب تكتب ه يدويًا بالرمز 406، فهذا هو السبب.
تعود الاستجابات على هيئة إطار Server-Sent Events يحمل رسالة JSON-RPC واحدة:
event: message
data: {"jsonrpc":"2.0","id":1,"result":{"tools":[ ... ]}}
استدعاء أداة:
curl -sS -X POST https://api.taketheme.com/mcp \
-H "Authorization: Bearer $TAKETHEME_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_store_metrics",
"arguments": { "period": "last_7_days", "compareToPrevious": true }
}
}'
نتائج الأدوات بصيغة JSON، وتُنقل كمحتوى نصي في MCP:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [
{
"type": "text",
"text": "{\n \"period\": \"the last 7 days\",\n \"currency\": \"EGP\",\n \"metrics\": { \"total_sales\": 48200, \"total_orders\": 316 }\n}"
}
]
}
}
حلّل result.content[0].text كـ JSON للحصول على الحمولة الموصوفة في مرجع الأدوات.
استخدام حزم MCP
TypeScript
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const transport = new StreamableHTTPClientTransport(
new URL("https://api.taketheme.com/mcp"),
{
requestInit: {
headers: { Authorization: `Bearer ${process.env.TAKETHEME_API_KEY}` },
},
},
);
const client = new Client({ name: "my-agent", version: "1.0.0" });
await client.connect(transport);
const { tools } = await client.listTools();
const result = await client.callTool({
name: "get_top_products",
arguments: { period: "last_30_days", sortBy: "revenue", limit: 5 },
});
Python
import os
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
url = "https://api.taketheme.com/mcp"
headers = {"Authorization": f"Bearer {os.environ['TAKETHEME_API_KEY']}"}
async with streamablehttp_client(url, headers=headers) as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools()
result = await session.call_tool(
"get_top_products",
{"period": "last_30_days", "sortBy": "revenue", "limit": 5},
)
سلوك البروتوكول
بلا حالة. لا يُصدر الخادم معرّف جلسة ولا يحتفظ بأي حالة للعميل. فلا توجد ترويسة Mcp-Session-Id في الاستجابات، وكل طلب مستقل بذاته — وهذا ما يتيح توسيع الـ API أفقيًا دون ربط عميلك بنسخة واحدة. وإذا أرسلت ترويسة Mcp-Session-Id فتُستخدم فقط لربط سجلات الطلب ببعضها.
initialize مدعوم لكنه غير إلزامي. تنفّذ العملاء السليمة مصافحة البدء وتحصل على معلومات الخادم وإمكاناته، أما tools/list أو tools/call المُرسَل دونها فيُجاب عليه بشكل طبيعي.
GET /mcp يُرجع 405. في النشر ذي الحالة يفتح GET قناة SSE من الخادم إلى العميل. وهذا الخادم بلا حالة، فلا توجد قناة يتصل بها، ويردّ بخطأ JSON-RPC بدل إبقاء اتصالك مفتوحًا:
{
"jsonrpc": "2.0",
"error": { "code": -32000, "message": "Method not allowed: this server is stateless." },
"id": null
}
قائمة الأدوات واحدة لكل المتاجر. لا تُخفى الأدوات بناءً على صلاحيات مفتاحك. فالأداة التي لا تملك صلاحيتها تظهر في tools/list وتُرجع رفضًا منظمًا عند استدعائها — وهذا يخبر مساعدك لماذا الأداة غير متاحة بدل حذفها بصمت.
الأخطاء
هناك طبقتان منفصلتان.
أخطاء النقل (HTTP / JSON-RPC)
خطأ وقع قبل استدعاء الأداة أو تحته.
| الرمز | المعنى |
|---|---|
401 | مفتاح API غير معروف أو ملغى أو منتهي |
403 | بيانات اعتماد مفقودة، أو رمز Bearer ليس مفتاح TakeTheme |
405 | GET /mcp — هذا الخادم بلا حالة |
406 | ترويسة Accept لا تتضمن text/event-stream |
429 | تجاوز حد المعدل في HTTP — راجع حدود المعدل |
500 | خطأ داخلي في JSON-RPC (-32603) |
أخطاء الأدوات
الأداة التي تعذّر تنفيذها تُرجع 200 عاديًا مع isError: true وجسم JSON يستطيع مساعدك قراءته والتصرف بناءً عليه. وهذا مقصود: مشكلة الصلاحيات معلومة ينبغي أن ينقلها المساعد إليك، لا طلبًا فاشلًا.
{
"isError": true,
"content": [
{
"type": "text",
"text": "{\n \"error\": \"permission_denied\",\n \"message\": \"This API key's ORDERS scope doesn't allow this action.\",\n \"details\": { \"requiredPermission\": \"ORDERS\" }\n}"
}
]
}
error | ما حدث |
|---|---|
unknown_capability | لا توجد أداة بهذا الاسم |
not_on_surface | الأداة موجودة لكنها غير متاحة عبر MCP |
invalid_arguments | الوسائط لم تجتز التحقق من المخطط — يذكر message الحقل المخالف |
permission_denied | مفتاحك لا يحمل الصلاحية المطلوبة أو لا يحمل READ عليها |
plan_upgrade_required | باقتك لا تشمل هذه الإمكانية |
store_not_writable | المتجر للقراءة فقط أو موقوف (لأدوات الكتابة فقط) |
rate_limited | بلغ المتجر الحد اليومي لاستدعاءات أدوات MCP |
execution_failed | فشلت العملية في الخادم |
بيانات متاحة جزئيًا
لا تُبلّغ أدوات التحليلات أبدًا عن صفر مؤكد حين تكون خدمة التحليلات في وضع متدهور. فإذا تعذّر حساب بعض الأرقام، تحمل الحمولة ملاحظة _degraded تسمّي تلك الحقول، وتُحذف الحقول المتأثرة بدل إرجاعها بقيمة 0:
{
"period": "the last 30 days",
"currency": "EGP",
"metrics": { "total_orders": 412 },
"_degraded": {
"reason": "Some analytics could not be loaded right now. Treat the affected figures as unavailable — do not report them as zero.",
"unavailableFields": ["total_sales", "aov"]
}
}
تعامل مع تلك الحقول على أنها غير معروفة، لا على أنها أصفار.
حدود الاستخدام
يُطبَّق حدّان مستقلان.
استدعاءات الأدوات اليومية. لكل متجر 30 استدعاء أداة MCP يوميًا، ويُعاد الضبط عند الساعة 00:00 بتوقيت UTC. ولا تُحتسب سوى الاستدعاءات الناجحة. وتجاوز الحد يُرجع خطأ أداة بالرمز rate_limited.
يكلّف السؤال الواحد عادةً استدعاءين أو ثلاثة، فـ 30 استدعاءً تعادل تقريبًا 10 إلى 15 سؤالًا في اليوم.
حدود المعدل في HTTP. تنطبق حدود معدل الـ API المعتادة على /mcp أيضًا. راجع حدود المعدل.
لمتابعة الاستهلاك، استدعِ عنوان ملخص الاستخدام وابحث عن سطر mcp-tool-call (يتطلب صلاحية MARKETING بإجراء READ):
curl -X GET "https://api.taketheme.com/api/v1/ai/usage/summary" \
-H "tt-api-key: $TAKETHEME_API_KEY"
{
"feature": "mcp-tool-call",
"limit": 30,
"usedToday": 7,
"remainingToday": 23,
"usedThisMonth": 194,
"resetAt": "2026-07-28T00:00:00.000Z"
}
نموذج الأمان
- مفتاح واحد لمتجر واحد. يأتي نطاق المتجر من المفتاح المُصادَق عليه، لا من وسيط أداة.
- تُفرض الصلاحيات عند كل استدعاء، بنموذج المورد والإجراء نفسه المستخدم في الـ REST API. فالمفتاح الذي يحمل
READفقط لا يصل إلى أداة كتابة حتى على مورد يستطيع رؤيته. - الحمولات مختصرة عمدًا. تُرجع أدوات الطلبات بنود الطلب والإجماليات دون بيانات التواصل مع المشتري أو عناوين IP أو درجات المخاطرة؛ فلا يدخل سياق المساعد إلا ما يحتاجه فعلًا.
- الإلغاء فوري. إلغاء المفتاح — أو فصل عميل OAuth من الإعدادات ← MCP — يقطع الاتصال عند الطلب التالي.
- رموز OAuth لا تغادر
/mcp. فهي مقيّدة بالجمهور، ولا يمكن إعادة استخدام رمز مسرَّب على الـ REST API. - تعامل مع المفتاح كبيانات اعتماد. فمن يملكه يستطيع قراءة كل ما تسمح به صلاحياته. استخدم مفتاحًا مخصصًا وبأضيق صلاحيات ممكنة لكل مساعد، وبدّله فور تسربه.
أدوات منشئ المتجر
إلى جانب قراءات التجارة، يتيح الخادم منشئ المتجر نفسه: يستطيع المساعد قراءة الصفحات وإعدادات الثيم ومكونات Custom Liquid وتعديلها، واكتشاف كتالوج المكونات كاملًا، و— حيثما كانت خدمة المعاينة مفعّلة — أن يرى عمله على هيئة لقطات شاشة، وأن يقارن مسودة بتصميم مرجعي ملتقط.
نموذج الأمان موحّد عبر كل كتابات منشئ المتجر:
- المسودات فقط. تقع الكتابات على مسودة؛ والكتابة في المتجر المباشر مرفوضة. إنسان هو من يراجع وينشر. والاستثناء الوحيد هو
builder_create_menuالتي تنشئ قائمة جديدة مباشرةً لأن القوائم غير محفوظة بنسخ — وهو آمن لأن القائمة الجديدة لا تُعرض في أي مكان حتى يشير إليها شيء عبر معرّفها النصي، وتلك الإشارة نفسها تعديل مرحَّل على مسودة. أما تعديل قائمة قائمة فعلًا فغير متاح لأي أداة. - نقطة استعادة أولًا. تلتقط كل كتابة لقطة من المسودة قبل تغييرها، فكل ما يفعله وكيل يمكن التراجع عنه من نقاط الاستعادة في منشئ المتجر.
- الأشخاص مقدَّمون على الوكلاء. ما دام شخص يحرّر مسودة فعليًا في منشئ المتجر، تُرفض كتابات الوكلاء على تلك المسودة بالخطأ
DRAFT_UI_LOCKED. - كتالوج المكونات يُقدَّم ولا يُخمَّن. يكتشف المساعدون أنواع الأقسام الصالحة وإعداداتها وقواعد تداخلها وأمثلة عملية لها عبر أدوات مخصصة — وهو العقد نفسه الذي يعرض منه منشئ المتجر.
راجع مرجع الأدوات للحزمة الكاملة.
القيود الحالية
- بيانات التجارة للقراءة فقط — أدوات الطلبات والمنتجات والعملاء لا تعدّل شيئًا؛ وكتابات واجهة المتجر لا تقع إلا على مسودات، عدا
builder_create_menuالتي تنشئ قوائم جديدة مباشرةً. - تتطلب أدوات المعاينة ولقطات الشاشة تفعيل خدمة متصفح المعاينة في بيئة النشر؛ وبدونها تجيب بـ
PREVIEW_UNAVAILABLEويعمل كل ما عداها. - بلا
prompts؛toolsوresourcesفقط. - بلا بث من الخادم إلى العميل أو إشعارات أو sampling (نتيجة للعمل بلا حالة).
- عبر OAuth لا يمكن الوصول إلى
get_review_summary: فهي تحتاج صلاحيةREVIEWSالتي لا يمنحهاmcp:readولاmcp:write. استخدم مفتاح API لبيانات التقييمات. - لا توجد أداتان باسمَي
search/fetch، فلا يصلح الخادم مصدرًا للبحث العميق في ChatGPT.
التالي
- مرجع الأدوات — كل أداة ووسائطها وصلاحيتها وما تُرجعه
- OAuth — مسار التفويض والصلاحيات والرموز والإلغاء
- مرجع الصلاحيات — نموذج المورد والإجراء كاملًا
- مفاتيح API — إنشاء المفاتيح وتقييدها وتبديلها