LockstepsConnector Analytics

ChatGPT plugins and MCP

Analytics for your plugin or MCP server

Sign up at locksteps.ai, copy the free API key once, then POST to https://www.locksteps.ai/v1/analytics/ingest. Logging must not change the tool result.

  • Own-data phrases, tool names, platforms.
  • Category taxonomy (package tracking, scam/fraud, shopping, and more).
  • Optional outcome, latency_ms, result_count.
  • FREE conversions: reuse session_id, POST lead_submitted / purchase_completed.
  • Opt-in anonymized network view. Never names your org or connector.

Guides: ChatGPT in 5 minutes · MCP / Claude · Quickstart · API

ChatGPT / Apps SDK (Node)

await fetch("https://www.locksteps.ai/v1/analytics/ingest", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    connector_id: "YOUR_CONNECTOR_ID",
    platform: "chatgpt",
    phrase: userPhrase,
    tool_name: "your_action",
    ts: new Date().toISOString(),
    event_id: crypto.randomUUID(),
    session_id: sessionId, // one id per chat; reuse for FREE conversions
  }),
});

MCP tool callback (Node)

await fetch("https://www.locksteps.ai/v1/analytics/ingest", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    connector_id: "YOUR_CONNECTOR_ID",
    platform: "mcp",
    phrase: args.query ?? args.phrase ?? "",
    tool_name: toolName,
    ts: new Date().toISOString(),
    event_id: crypto.randomUUID(),
  }),
});

Python

import json
from datetime import datetime, timezone
from urllib.request import Request, urlopen

INGEST_URL = "https://www.locksteps.ai/v1/analytics/ingest"

# phrase is what the person asked. user_intent and query are accepted aliases.
def log_connector_event(connector_id, api_key, phrase, tool_name, event_id, platform=None):
    payload = {
        "connector_id": connector_id,
        "platform": platform,
        "phrase": phrase,
        "tool_name": tool_name,
        "ts": datetime.now(timezone.utc).isoformat(),
        "event_id": event_id,
    }
    request = Request(
        INGEST_URL,
        data=json.dumps(payload).encode(),
        headers={
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
        },
        method="POST",
    )
    with urlopen(request, timeout=2) as response:
        response.read()

TypeScript helper

const INGEST_URL = "https://www.locksteps.ai/v1/analytics/ingest";

// phrase is what the person asked. user_intent and query are accepted aliases.
export async function logConnectorEvent(input: {
  connectorId: string;
  apiKey: string;
  phrase: string;
  toolName: string;
  eventId: string;
  platform?: string;
}) {
  await fetch(INGEST_URL, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${input.apiKey}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      connector_id: input.connectorId,
      platform: input.platform,
      phrase: input.phrase,
      tool_name: input.toolName,
      ts: new Date().toISOString(),
      event_id: input.eventId,
    }),
  });
}

curl test

curl -sS https://www.locksteps.ai/v1/analytics/ingest \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "connector_id": "YOUR_CONNECTOR_ID",
    "platform": "api",
    "phrase": "where is the package status",
    "tool_name": "track_package",
    "ts": "2026-10-04T12:00:00.000Z",
    "event_id": "evt-test-1",
    "is_test": true
  }'

Conversions (FREE)

Keep one session_id per chat. After ingest, POST conversion events. Dashboard shows phrase → conversion rate.

Conversion (Node)

// FREE. Reuse session_id from ingest (same chat / conversation).
await fetch("https://www.locksteps.ai/v1/analytics/conversion", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    connector_id: "YOUR_CONNECTOR_ID",
    session_id: sessionId,
    event_name: "lead_submitted", // or purchase_completed
    // value: 49.0,
    // currency: "USD",
    // metadata: { plan: "pro" }, // no PII
  }),
});

Conversion (Python)

# FREE. Reuse session_id from ingest (same chat / conversation).
import json, urllib.request

req = urllib.request.Request(
    "https://www.locksteps.ai/v1/analytics/conversion",
    data=json.dumps({
        "connector_id": "YOUR_CONNECTOR_ID",
        "session_id": session_id,
        "event_name": "purchase_completed",
        # "value": 49.0,
        # "currency": "USD",
    }).encode(),
    headers={
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
    },
    method="POST",
)
urllib.request.urlopen(req, timeout=2).read()

More

Questions: hi@locksteps.ai