meni.ge MCP Server — AI / GPT Integration Reference

This document is designed for AI assistants, GPT bots, and automated integrations. It provides exact protocol details, tool schemas, and authentication flow.

Server Information

Property Value
Server Name meni-user-data-mcp
Protocol MCP 2024-11-05 (Streamable HTTP)
Transport HTTP POST (stateless)
Base URL https://api.meni.ge/mcp
Content-Type application/json
Wire Format JSON-RPC 2.0

Authentication

All tool calls require an Authorization header.

Option 1: User MCP API Key (recommended)

Authorization: Bearer mk_XXXXXXXXXXXX...  (64 hex characters)

Scoped to a specific user account. The bot sees only that user's data.

Option 2: Cognito JWT Token

Authorization: Bearer eyJraWQi...  (JWT id_token)

Obtained via POST /auth/login. Expires in 1 hour.

Option 3: Admin API Key

Authorization: Bearer <admin_api_key>

Full access to all data. Only for system administrators.

Obtaining a JWT Token

POST https://api.meni.ge/mcp/auth/login
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "password123"
}

Response:

{
  "idToken": "eyJraWQi...",
  "accessToken": "eyJraWQi...",
  "refreshToken": "eyJjdHki...",
  "expiresIn": 3600,
  "tokenType": "Bearer"
}

MCP Protocol

Initialize

POST https://api.meni.ge/mcp
Authorization: Bearer <token>
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {},
    "clientInfo": { "name": "my-bot", "version": "1.0" }
  }
}

Response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2024-11-05",
    "capabilities": { "tools": {} },
    "serverInfo": { "name": "meni-user-data-mcp", "version": "1.0.0" }
  }
}

List Tools

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/list",
  "params": {}
}

Call Tool

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "tool_name",
    "arguments": { ... }
  }
}

Response on success:

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [
      { "type": "text", "text": "{\"key\": \"value\"}" }
    ]
  }
}

Response on error:

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [
      { "type": "text", "text": "error message" }
    ],
    "isError": true
  }
}

Endpoints

Method Path Auth Description
GET / No Server info + tool list
POST / Yes MCP JSON-RPC protocol
GET /health No Health check → {"status":"ok"}
POST /auth/login No Login → JWT tokens
GET /api/keys JWT only List user's API keys
POST /api/keys JWT only Generate new API key
DELETE /api/keys/{keyId} JWT only Revoke API key

All paths are relative to https://api.meni.ge/mcp.


Complete Tool Reference

Access Levels

  • USER — Available to all authenticated users (data scoped to own account)
  • ADMIN — Available only to administrators (full access)

Self-Service Tools

whoami

Access: USER — Arguments: none
Returns: userId, email, userRole, authMethod

my_profile

Access: USER — Arguments: none
Returns: full user profile from S3

update_my_profile

Access: USER

Argument Type Required Description
fields object yes Key-value pairs to update in profile

my_locations

Access: USER — Arguments: none
Returns: array of user's locations

my_orders

Access: USER

Argument Type Required Description
limit integer no Maximum number of results

my_images

Access: USER

Argument Type Required Description
type string no Enum: all, menu-photos, category-photos, locations

User Profiles

list_users

Access: ADMIN

Argument Type Required Description
limit integer no Maximum number of results

get_user_profile

Access: USER (own) / ADMIN (any)

Argument Type Required Description
userId string yes The user ID

update_user_profile

Access: ADMIN

Argument Type Required Description
userId string yes The user ID
fields object yes Key-value pairs to update

search_user_by_email

Access: ADMIN

Argument Type Required Description
email string yes Email address to search

Locations

list_locations

Access: USER (own) / ADMIN (any)

Argument Type Required Description
userId string yes Cognito user sub

get_location_profile

Access: USER (own) / ADMIN (any)

Argument Type Required Description
userId string no User ID (admin only, auto-resolved for regular users)
locationId string yes Location ID

Returns: status, displayName, phone, address, facebookUrl, instagramUrl, domainName, settings (currency, country, defaultLanguage, publicMenuEnabled, serviceChargeEnabled), workingHours.

update_location_profile

Access: USER (own) / ADMIN (any)

Argument Type Required Description
userId string no User ID (admin only, auto-resolved for regular users)
locationId string yes Location ID
fields object yes Fields to update: displayName, phone, address, facebookUrl, instagramUrl, status, settings, workingHours

Changes are synced to CDN automatically. Do NOT use this to change domainName — use set_location_domain instead.

get_location_menu

Access: USER (own) / ADMIN (any)

Argument Type Required Description
userId string no User ID (admin only, auto-resolved for regular users)
locationId string yes Location ID
language string no Language code (e.g. en, ru, ka) for localized names. Omit for all translations

Returns full menu with categories and enriched items (names, prices, translations).


Menu Items

list_menu_items

Access: USER (own) / ADMIN (any)

Argument Type Required Description
userId string no User ID (admin only, auto-resolved for regular users)
categoryId string no Category ID — recommended for detailed item data

With categoryId: returns full item data (name, price, translations). Without: returns item/category ID pairs.

get_menu_item

Access: USER (own) / ADMIN (any)

Argument Type Required Description
userId string no User ID (admin only, auto-resolved for regular users)
categoryId string no Category ID (optional — omit to search all categories)
itemId string yes Menu item ID

Returns full details: name, description, price, translations, tags, variantGroups, addons, image info.

update_menu_item

Access: USER (own) / ADMIN (any)

Argument Type Required Description
userId string no User ID (admin only, auto-resolved for regular users)
categoryId string no Category ID (optional — omit to auto-find)
itemId string yes Menu item ID
fields object yes Fields to merge: name, description, price, status, tags, variantGroups, addons, nameTranslations, descriptionTranslations, locationPrices, sortOrder

Changes sync automatically to CDN and userprofile.json.

create_menu_item

Access: USER (own) / ADMIN (any)

Argument Type Required Description
userId string no User ID (admin only, auto-resolved for regular users)
locationId string yes Location ID
categoryId string yes Category ID to put the item in
itemId string yes Unique item ID
name string yes Item name (primary language)
price number yes Price
nameTranslations object no Translations: {ka, ru, uk, ...}
description string no Item description
status string no Enum: active, paused, archived (default: active)
sortOrder number no Sort order (auto-assigned if omitted)

create_menu_category

Access: USER (own) / ADMIN (any)

Argument Type Required Description
userId string no User ID (admin only, auto-resolved for regular users)
locationId string yes Location ID
categoryId string yes Unique category ID
name string yes Category name (primary language)
nameTranslations object no Translations: {ka, ru, uk, ...}
status string no Enum: active, paused, archived (default: active)
sortOrder number no Sort order (auto-assigned if omitted)

update_menu_category

Access: USER (own) / ADMIN (any)

Argument Type Required Description
userId string no User ID (admin only, auto-resolved for regular users)
locationId string yes Location ID
categoryId string yes Category ID to update
name string no New category name
nameTranslations object no Translations to merge: {ka, ru, uk, ...}
status string no Enum: active, paused, archived
sortOrder number no New sort order

Updates group-item.json (global + user), menu.location.json, and userprofile.json.

move_menu_item

Access: USER (own) / ADMIN (any)

Argument Type Required Description
userId string no User ID (admin only, auto-resolved for regular users)
locationId string yes Location ID
itemId string yes Item ID to move
fromCategoryId string yes Source category ID
toCategoryId string yes Destination category ID

merge_categories

Access: USER (own) / ADMIN (any)

Argument Type Required Description
userId string no User ID (admin only, auto-resolved for regular users)
locationId string yes Location ID
sourceCategoryId string yes Category to merge FROM (deleted after merge)
targetCategoryId string yes Category to merge INTO (receives all items)
keepSourceName boolean no If true, use source category name (default: keep target name)

Atomic operation: moves all items, merges nameTranslations, deletes source category.

delete_menu_category

Access: USER (own) / ADMIN (any)

Argument Type Required Description
userId string no User ID (admin only, auto-resolved for regular users)
locationId string yes Location ID
categoryId string yes Category ID to delete
force boolean no If true, also delete all items (default: false — fail if has items)

Orders

list_orders

Access: USER (own) / ADMIN (any)

Argument Type Required Description
userId string no User ID (reads from data.meni)
domain string no Domain name (reads from o.meni.ge)
limit integer no Max orders (default 50)

get_order

Access: USER (own domain) / ADMIN (any)

Argument Type Required Description
domain string no Domain name (e.g. UKRAINOCHKA)
locationId string no Location ID — used to resolve domain if domain is not provided
orderId string yes Order ID

Domains

check_domain_availability

Access: USER

Argument Type Required Description
domainName string yes Domain name to check (e.g. my-restaurant)
currentDomainName string no Current domain of this location (own domain is always available)

Returns available: true/false with reason. Validates format: 3-63 chars, lowercase alphanumeric and hyphens.

set_location_domain

Access: USER (own) / ADMIN (any)

Argument Type Required Description
locationId string yes Location ID
domainName string yes New domain name (3-63 chars, lowercase alphanumeric and hyphens)

Validates availability, updates profile, renames CDN files, and updates domain mappings.

list_domains

Access: ADMIN

Argument Type Required Description
prefix string no Filter domains by prefix

resolve_domain

Access: USER

Argument Type Required Description
domain string yes The domain to resolve

CDN

get_cdn_profile

Access: USER

Argument Type Required Description
domain string yes The domain

get_cdn_menu

Access: USER

Argument Type Required Description
domain string yes The domain
language string yes Language code (e.g., en, ru, ka)

list_cdn_files

Access: USER

Argument Type Required Description
domain string yes The domain

invalidate_cdn_cache

Access: ADMIN

Argument Type Required Description
paths array of strings yes CDN paths, e.g. ["/locations/DOMAIN/*"]

Images

list_user_images

Access: USER (own) / ADMIN (any)

Argument Type Required Description
userId string yes Cognito user sub
type string no Enum: all, menu-photos, category-photos, locations

get_image_upload_url

Access: USER

Argument Type Required Description
type string yes Enum: menu-photos, category-photos, locations
itemId string no Menu item ID or category ID (required for menu-photos, category-photos)
locationId string no Location ID (required for locations type — hero/logo images)
filename string no Filename (default: original.jpg)
contentType string no Enum: image/jpeg, image/png, image/webp (default: image/jpeg)

Returns a presigned URL valid for 15 minutes. After uploading, the image processing pipeline automatically generates thumbnails and syncs to CDN.

delete_image

Access: USER (own) / ADMIN (any)

Argument Type Required Description
key string yes Full S3 key in i.meni.ge, e.g. users/{userId}/menu-photos/{itemId}/original.jpg

S3 (Low-level Storage)

s3_read

Access: USER (own prefix) / ADMIN (any)

Argument Type Required Description
bucket string yes Enum: data.meni, cdn.meni.ge, i.meni.ge, o.meni.ge
key string yes S3 object key

s3_write

Access: ADMIN

Argument Type Required Description
bucket string yes Enum: data.meni, cdn.meni.ge, o.meni.ge
key string yes S3 object key
data object yes JSON data to write

s3_list

Access: USER (own prefix) / ADMIN (any)

Argument Type Required Description
bucket string yes Enum: data.meni, cdn.meni.ge, i.meni.ge, o.meni.ge
prefix string yes Key prefix to list
limit integer no Max keys (default 100)

s3_delete

Access: ADMIN

Argument Type Required Description
bucket string yes Enum: data.meni, cdn.meni.ge, o.meni.ge
key string yes S3 object key

Cognito (User Management)

cognito_list_users

Access: ADMIN

Argument Type Required Description
filter string no Cognito filter expression
limit integer no Maximum number of results

cognito_get_user

Access: ADMIN

Argument Type Required Description
username string yes Cognito username (sub UUID)

System

get_system_stats

Access: ADMIN — Arguments: none
Returns: user count, location count, domain count, etc.


S3 Bucket Reference

Bucket Purpose Example Keys
data.meni Private user data users/{userId}/profile.json
cdn.meni.ge Published CDN data {domain}/menu-en.json
i.meni.ge Images users/{userId}/menu-photos/...
o.meni.ge Orders {domain}/orders/{orderId}.json

Access Control

  1. Regular users can only access their own data (enforced by userId)
  2. S3 access for regular users is restricted to users/{userId}/ prefix
  3. Admin-only tools: list_users, search_user_by_email, update_user_profile, list_domains, invalidate_cdn_cache, s3_write, s3_delete, cognito_list_users, cognito_get_user, get_system_stats
  4. For location/menu tools, userId is auto-resolved for regular users (only admins need to specify it)
  5. API key management (/api/keys) requires Cognito JWT — API keys cannot manage themselves

Error Handling

HTTP Status Meaning
200 Success (check result.isError for tool-level errors)
400 Invalid JSON or missing method
401 Missing or invalid authentication
405 Wrong HTTP method
500 Internal server error

Tool Error Messages

Error Meaning
🔒 admin access required Tool requires admin role
🔒 access denied: you can only access your own data User tried to access another user's data
missing required argument: <name> Required parameter not provided
unknown tool: <name> Tool name not recognized

Example Session

→ POST /  {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"bot","version":"1.0"}}}
← 200  {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"serverInfo":{"name":"meni-user-data-mcp","version":"1.0.0"}}}

→ POST /  {"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"whoami","arguments":{}}}
← 200  {"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"text","text":"{\"userId\":\"abc-123\",\"email\":\"user@example.com\"}"}]}}

Client Configuration

Claude Desktop

{
  "mcpServers": {
    "meni": {
      "url": "https://api.meni.ge/mcp",
      "headers": {
        "Authorization": "Bearer <API_KEY>"
      }
    }
  }
}

cURL

curl -X POST https://api.meni.ge/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <API_KEY>" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"whoami","arguments":{}}}'

Python

import requests

resp = requests.post("https://api.meni.ge/mcp",
    headers={"Authorization": "Bearer <API_KEY>", "Content-Type": "application/json"},
    json={"jsonrpc": "2.0", "id": 1, "method": "tools/call",
          "params": {"name": "my_profile", "arguments": {}}})
print(resp.json()["result"]["content"][0]["text"])