LimeliJourney MCP server (spec 008)
A tenant-scoped MCP server that exposes the LimeliJourney AdminApi and the Track B
AiApi to AI assistants (Claude Desktop, Claude Code, any MCP client) as typed tools —
list_/get_/create_/update_ per entity plus report_* and the AI-operator surfaces
(list_tenant_ai_fraud_cases, list_tenant_ai_prospects, list_tenant_ai_decisions,
list_tenant_ai_autonomy, list_tenant_ai_sending_domains, list_tenant_ai_report, …).
The tool surface is generated from docs/openapi.yaml (spec 007),
so it tracks the API automatically.
Authenticate with a revocable API key (llj_live_…) over the versioned /v1 surface
(KEY mode, recommended for clients) or a Cognito id token against the AdminApi/AiApi
(TOKEN mode, unchanged). See Two authentication modes.
Install in one command: uvx limelijourney-mcp (see Install).
Why it's different. Competitor affiliate-tracker MCPs (where they exist) are read-only.
Ours exposes the full governed read surface and can trigger the exact same proposals
the dashboard does — fraud-case triage, prospect invite/dismiss, sending-domain attestation,
autonomy, policy — each running the server-side governance spine (autonomy lattice, audit,
reversibility). Those writes stay gated behind LIMELI_ALLOW_DESTRUCTIVE=1; the reads do not.
Two authentication modes
KEY mode (recommended) — authenticate with a revocable API key (llj_live_…,
minted in the dashboard) against the versioned, key-authed /v1 surface. This is the
mode to hand to a client: it is revocable, scoped, and never expires mid-session like a
Cognito token. Enable it by setting LIMELI_API_KEY.
TOKEN mode (unchanged) — forward a short-lived Cognito id token (the dashboard
login token) to the AdminApi + AiApi. Used automatically when LIMELI_API_KEY is unset.
How it stays safe (the boundary)
- This process is a thin client. It holds no database credentials and no tenant
logic. It forwards your credential on every request; the server enforces isolation —
limeli_tenancy(Cognito) orlimeli_api_keys(the/v1key surface). tenant_idis never a tool argument and is never sent in a request body. In KEY mode the tenant comes only from the API key's row, server-side.- Safe by default: only authenticated, non-deprecated operations are exposed.
DELETE, the bulkbackfill/*imports, and the Track B AI write/propose tools (/tenant/ai/*→/v1/ai/<doc>PUT— e.g.update_tenant_ai_fraud_case,update_tenant_ai_prospect,update_tenant_ai_autonomy) are off unless you setLIMELI_ALLOW_DESTRUCTIVE=1. The read surface (incl. every/tenant/ai/*//v1/aiGET) is always on. This client flag is a convenience, NOT the security boundary — the API enforces scopes (write:ai/write:affiliatesfor a key; the role check for a token). A read-only key cannot write even with the flag on. - Super-admin tenant targeting (
X-Tenant-IdviaLIMELI_TENANT_ID) is TOKEN mode only.
Which tools are available
- TOKEN mode: the full generated AdminApi + AiApi surface (~276 read tools by default).
- KEY mode: only tools with a
/v1equivalent are advertised — the entity/report toolslist_offers,get_offer,list_affiliates,create_affiliate,list_campaigns,get_campaign,report_clicks,report_conversions(→ PartnerApi/v1/*) and the AI-operator toolslist_/update_tenant_ai_*(→ AiApi/v1/ai/<doc>). Any other tool has no/v1equivalent; it is hidden from the list and, if called, returns a clearnot_available_with_api_keyerror (never a silent 404) telling you to use a Cognito token.
Configure
KEY mode (API key over /v1)
| Env var | Required | Meaning |
|---|---|---|
LIMELI_API_KEY |
yes | The partner API key (llj_live_…). Setting it selects KEY mode. Sent as X-Api-Key. |
LIMELI_V1_BASE |
yes | PartnerApi /v1 invoke URL (entity/report tools), e.g. https://<id>.execute-api.us-west-2.amazonaws.com/prod |
LIMELI_V1_AI_BASE |
no* | Host for the /v1/ai/<doc> AI-operator tools — the AiApi host (it carries a /v1/ai/{proxy+} route, auth NONE, proxied to partner_api). *Falls back to LIMELI_AI_API_BASE, then to LIMELI_V1_BASE (where /v1/ai 404s — a warning is printed). Set it to use the AI tools. |
LIMELI_ALLOW_DESTRUCTIVE |
no | 1 to also expose the gated /v1/ai PUT propose/triage writes (scope write:ai still required server-side) |
TOKEN mode (Cognito id token)
| Env var | Required | Meaning |
|---|---|---|
LIMELI_API_BASE |
yes | AdminApi invoke URL, e.g. https://mkrirny1c2.execute-api.us-west-2.amazonaws.com/prod |
LIMELI_AI_API_BASE |
no* | AiApi invoke URL for the /tenant/ai/* tools, e.g. https://rim9ajjqmk.execute-api.us-west-2.amazonaws.com/prod. *When unset those tools fall back to LIMELI_API_BASE and 404. |
LIMELI_BEARER_TOKEN |
yes | Cognito id token (the dashboard login token) |
LIMELI_TENANT_ID |
no | Super-admin only: target tenant (sent as X-Tenant-Id) |
LIMELI_ALLOW_DESTRUCTIVE |
no | 1 to also expose the gated write tools: DELETE, backfill, and the /tenant/ai/* propose/triage writes |
LIMELI_OPENAPI_SPEC (both modes, optional) overrides the OpenAPI spec path.
Install (one command)
The package publishes a limelijourney-mcp console entry point. From a git checkout:
# Run straight from the repo with uv (no install), KEY mode:
LIMELI_API_KEY="llj_live_…" LIMELI_V1_BASE="https://<partner-id>.execute-api.us-west-2.amazonaws.com/prod" \
uvx --from git+https://github.com/ReswanMahmood/limelijourney#subdirectory=mcp-server limelijourney-mcp
# Or install it (pip / pipx) and run the entry point:
pip install ./mcp-server # or: pipx install ./mcp-server
LIMELI_API_KEY="llj_live_…" LIMELI_V1_BASE="https://…/prod" limelijourney-mcp
Runnable from a plain checkout too (no install): python mcp-server/server.py.
List the generated tools without running the server: python -m limeli_mcp.tools (from mcp-server/).
Claude Desktop / Claude Code config
KEY mode (recommended) — one command, no local path:
{
"mcpServers": {
"limelijourney": {
"command": "uvx",
"args": ["limelijourney-mcp"],
"env": {
"LIMELI_API_KEY": "llj_live_…",
"LIMELI_V1_BASE": "https://<partner-id>.execute-api.us-west-2.amazonaws.com/prod",
"LIMELI_V1_AI_BASE": "https://rim9ajjqmk.execute-api.us-west-2.amazonaws.com/prod"
}
}
}
}
(Use "args": ["--from", "git+https://github.com/ReswanMahmood/limelijourney#subdirectory=mcp-server", "limelijourney-mcp"] to run straight from the repo before it's published.)
TOKEN mode — a loose checkout:
{
"mcpServers": {
"limelijourney": {
"command": "python",
"args": ["/abs/path/to/mcp-server/server.py"],
"env": {
"LIMELI_API_BASE": "https://mkrirny1c2.execute-api.us-west-2.amazonaws.com/prod",
"LIMELI_AI_API_BASE": "https://rim9ajjqmk.execute-api.us-west-2.amazonaws.com/prod",
"LIMELI_BEARER_TOKEN": "<cognito-id-token>"
}
}
}
}
Layout
limeli_mcp/client.py— HTTP client for both modes/gateways. TOKEN mode:Authorization: Bearer <jwt>(+ optionalX-Tenant-Id),/tenant/ai/*→ai_base_url, rest →base_url. KEY mode:X-Api-Key, entity/report →/v1/*onv1_base_url, AI →/v1/ai/<doc>onv1_ai_base_url, unmapped paths →ApiError(not_available_with_api_key). The mapping ismap_to_v1_path(). Envelope unwrap + error-taxonomy →ApiError. stdlib only; injectable transport for tests.limeli_mcp/tools.py— spec-driven tool registry (re-exports the shared-layer generator; adds the MCP-local/tenant/ai/*write gate — reads open, writes behind the flag). Reads the spec from the repodocs/openapi.yamlor the copy bundled in the wheel.limeli_mcp/cli.py— thelimelijourney-mcpruntime + MCP stdio adapter (needs themcpSDK; the core does not).server.pyis a thin launcher that calls it.pyproject.toml— packaging (console entry point + deps); bundles the spec + canonical generator into the wheel so an install outside the repo is self-contained.- Isolation + KEY-mode test:
local/test_mcp_server.py.
Metadata
Release files for limelijourney-mcp 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| limelijourney_mcp-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Release files / limelijourney_mcp-0.1.0-py3-none-any.whl
| Download URL | limelijourney_mcp-0.1.0-py3-none-any.whl |
|---|---|
| Size | 56.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2bcbdcc8a46dbf6b455eafc2d576cb9fe1825fa3acc136ede3e607e753afcf88
|
|
BLAKE2b-256 checksum How to use checksums |
3f2cfa03437138cf02ee2c9447995b5c63d63013b4401d2c8a107284e430841f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency log