Skip to content

API Reference

Complete guide to LexSocket MCP Server authentication, schemas, error handling, and limits.

Authentication

The unified LexSocket MCP server supports multiple authentication methods:

OAuth2 is the default for most MCP clients. No API key needed — authentication happens automatically on first use.

{
    "mcpServers": {
        "lexsocket": {
            "url": "https://mcp.lexsocket.ai/"
        }
    }
}

How it works: 1. Client connects to https://mcp.lexsocket.ai/ 2. MCP server redirects to Auth0 login page 3. You authenticate with your LexSocket account 4. OAuth token is cached locally 5. All subsequent requests include the token

Supported clients: Claude Desktop, Claude Code, Cursor, Windsurf, and any MCP client supporting OAuth


API Key (For Clients Without OAuth Support)

Get your API key from the LexSocket DashboardDashboardCreate key.

{
    "mcpServers": {
        "lexsocket": {
            "url": "https://mcp.lexsocket.ai/",
            "headers": {
                "x-api-key": "<YOUR_API_KEY>"
            }
        }
    }
}

Supported clients: Le Chat, Cherry Studio, ChatGPT, custom integrations

Security best practices: - Never commit API keys to version control - Use environment variables in production: export LEXSOCKET_API_KEY=sk-... - Rotate keys regularly - Revoke compromised keys immediately in the dashboard


Local Development (No Auth)

For testing the server locally with AUTH_ENABLED=false:

cd src/mcp
AUTH_ENABLED=false python -m src.main

Request Format

All requests follow the Model Context Protocol (MCP) standard. The server accepts JSON-RPC 2.0 requests:

Basic Request Structure

{
    "jsonrpc": "2.0",
    "method": "tools/call",
    "params": {
        "name": "search_ted",
        "arguments": {
            "query": "hospital construction",
            "country": "POL",
            "limit": 5
        }
    },
    "id": 1
}

Request Parameters

Field Type Required Description
jsonrpc string Must be "2.0"
method string Must be "tools/call"
params.name string Tool name (e.g., search_ted, search_tenders)
params.arguments object Tool-specific parameters (varies per tool)
id number Request ID for matching responses (any integer)

Response Format

Success Response

{
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
        "type": "text",
        "text": "[{\"title\": \"Hospital Construction\", \"notice_id\": \"...\", ...}]"
    }
}

Error Response

{
    "jsonrpc": "2.0",
    "id": 1,
    "error": {
        "code": 400,
        "message": "Invalid parameter: country code 'XX' not recognized"
    }
}

HTTP Status Codes & Error Codes

200 OK

Request succeeded. Check the JSON-RPC response body for result or error.

400 Bad Request

Invalid parameter, malformed request, or unsupported value.

Common causes: - Missing required parameter - Invalid country code (use ISO 3166-1 alpha-3, e.g., POL, FRA, DEU) - Invalid CPV code format - Invalid date format (use ISO 8601: YYYY-MM-DD) - limit outside valid range (1-100)

Example error:

{
    "error": {
        "code": 400,
        "message": "Invalid parameter: cpv_code must be 8 digits (e.g., '72000000')"
    }
}


401 Unauthorized

Authentication failed or missing credentials.

Common causes: - Expired OAuth token (will be automatically refreshed) - Invalid or missing API key - API key revoked or disabled - OAuth session expired

Example error:

{
    "error": {
        "code": 401,
        "message": "Invalid or expired authentication credentials"
    }
}

Fix: Re-authenticate or request a new API key from the dashboard.


429 Too Many Requests

Rate limit exceeded.

Limits: - Requests per minute: 60 per user - Requests per day: 10,000 per user - Concurrent requests: 10 per user

Response headers: - X-RateLimit-Limit — Requests allowed per window - X-RateLimit-Remaining — Requests remaining - X-RateLimit-Reset — Unix timestamp when limit resets

Example error:

{
    "error": {
        "code": 429,
        "message": "Rate limit exceeded: 60 requests per minute. Try again in 45 seconds."
    }
}

Fix: Implement exponential backoff retry logic. Wait for the duration specified in the error message.


500 Internal Server Error

Server error. Retryable with exponential backoff.

Common causes: - Database connection issue (temporary) - Embedding service timeout - GCS sync in progress - Unexpected error in tool execution

Example error:

{
    "error": {
        "code": 500,
        "message": "Internal server error: Failed to complete search"
    }
}

Fix: Retry after 5-30 seconds with exponential backoff (5s, 10s, 20s, 30s...).


Valid Parameter Values

Country Codes (ISO 3166-1 Alpha-3)

Use 3-letter country codes for all country parameters.

TED coverage (all EU/EEA):

Code Country Code Country
AUT Austria NLD Netherlands
BEL Belgium NOR Norway
BGR Bulgaria POL Poland
HRV Croatia PRT Portugal
CYP Cyprus ROU Romania
CZE Czech Republic SVK Slovakia
DNK Denmark SVN Slovenia
EST Estonia ESP Spain
FIN Finland SWE Sweden
FRA France CHE Switzerland
DEU Germany GBR United Kingdom
GRC Greece IRL Ireland
HUN Hungary ITA Italy
LVA Latvia LTU Lithuania
LUX Luxembourg

National Tenders coverage (below-threshold): - FRA (France), GBR (UK), DEU (Germany), ESP (Spain), ITA (Italy), NLD (Netherlands), IRL (Ireland), PRT (Portugal), DNK (Denmark), POL (Poland), AUT (Austria)


Procurement Types

Valid values for procurement_type parameter (TED only):

  • open — Open procedure
  • restricted — Restricted procedure
  • negotiated — Negotiated procedure
  • competitive_dialogue — Competitive dialogue
  • innovation_partnership — Innovation partnership

Currency Codes

Valid values for currency parameter:

Code Currency
EUR Euro (primary)
GBP British Pound

Search Modes

Valid values for mode parameter in search tools:

Mode Description
hybrid Combine FTS + vector search (default, recommended)
fts Full-text search only (BM25 via Tantivy)
vector Semantic vector search only (BGE-M3)

Status Values (National Tenders Only)

Valid values for status parameter:

Status Description
active Tender is currently open for bids
awarded Contract has been awarded
cancelled Tender was cancelled

Tender Source (National Tenders Only)

Valid values for source parameter:

Source Country Platform
BOAMP France Bulletin Officiel des Annonces de Marchés Publics
Contracts Finder UK UK Government Contracts Finder
oeffentlichevergabe.de Germany German procurement portal
PLACSP Spain Plataforma de Contratación del Sector Público
ANAC Italy Autorità Nazionale Anticorruzione
TenderNed Netherlands Dutch tender platform
eTenders Ireland Irish eTenders platform
BASE Portugal Portal de contratos públicos
udbud.dk Denmark Danish procurement portal
ezamowienia.gov.pl Poland Polish procurement platform
ausschreibungen.usp.gv.at Austria Austrian procurement portal

CPV Codes (Common Procurement Vocabulary)

CPV codes classify tenders. Use exact 8-digit codes or broad prefixes.

Structure: - 2 digits (e.g., 45) — Division (broad category) - 4 digits (e.g., 4521) — Group (subcategory) - 8 digits (e.g., 45210000) — Class (specific service)

Key categories:

Code Category
45000000 Construction work
72000000 IT services
71000000 Architectural & engineering
79000000 Business services
33000000 Medical equipment
34000000 Transport equipment

For a complete CPV code list, see the official European Commission CPV database.


NUTS Codes (Regional Nomenclature)

NUTS codes identify regions where work is performed. Use country prefix (NUTS-1) or more specific regional codes (NUTS-2/3).

Examples:

Code Region
FR All France
FR10 Ile-de-France
DE All Germany
DE300 Berlin
ES All Spain
IT All Italy
GB All UK
NL All Netherlands

Rate Limits & Quotas

Tier: Standard (Free)

  • Requests per minute: 60
  • Requests per day: 10,000
  • Concurrent requests: 10
  • Result limit: Max 100 results per request
  • Data freshness: Updates twice daily

Rate Limit Headers

All responses include rate limit information:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1679390400

Retry Strategy

Implement exponential backoff for rate limits:

import time
import random

def retry_with_backoff(request_fn, max_retries=3):
    for attempt in range(max_retries):
        try:
            return request_fn()
        except RateLimitError:
            wait_time = (2 ** attempt) + random.uniform(0, 1)
            time.sleep(wait_time)
    raise Exception("Max retries exceeded")

Data Freshness & Update Schedule

TED

  • Update frequency: Twice daily (06:00 UTC, 18:00 UTC)
  • Index rebuild: Weekly on Sunday 03:00 UTC
  • Data source: Official Journal of the European Union (TED)
  • Latency: Published notices available within 2-4 hours

National Tenders

  • Update frequency: Staggered per country collection (01:00-04:45 UTC), embed at 05:00 UTC
  • Data sources: 11 national platforms (BOAMP, Contracts Finder, etc.)
  • Latency: Platform-dependent (typically same-day to next-day)
  • Index rebuild: Weekly on Sunday 06:00 UTC

Pagination

Most tools support limit parameter (default: 10, max: 100).

{
    "method": "search_ted",
    "params": {
        "query": "hospital",
        "limit": 50
    }
}

Note: Full pagination support (offset/cursor) is not currently available. Use limit to control result count.


Next Steps