Leni developers
Leni MCP runtime reference
Connect an MCP-compatible AI host to the Leni intelligent runtime with delegated end-user OAuth, tenant-safe data access, memory context, and bounded tools.
| Setting | Current contract |
|---|---|
| Server name | leni-runtime |
| Remote endpoint | https://mcp.leni.co/mcp |
| OAuth issuer | https://auth.leni.co |
| Transport | Streamable HTTP over HTTPS |
| Authentication | OAuth 2.0 authorization code with PKCE; delegated Leni user consent is always required |
| Client registration | Dynamic Client Registration and published client metadata are supported |
OAuth discovery and lifecycle
| Resource | URL or current maximum |
|---|---|
| Authorization-server metadata | https://auth.leni.co/.well-known/oauth-authorization-server |
| Protected-resource metadata | https://mcp.leni.co/.well-known/oauth-protected-resource |
| Access token | 10 minutes |
| Refresh token | 30 days |
| Authorization code | 2 minutes |
| Interactive authorization transaction | 10 minutes |
Compatible hosts should discover endpoints from metadata, use S256 PKCE, request the required scopes, and refresh short-lived access tokens without asking the user to sign in again. Reconnect is required after the grant is revoked, the refresh token expires, or new permissions are added. Lifetimes are current production maxima and may be shortened; clients must use the expiry returned with the token.
Backend and autonomous agents
OAuth scopes
| Scope | Allows |
|---|---|
| leni:account:read | Read account, plan eligibility, and percentage usage remaining. |
| leni:analysis:run | Start a Leni analysis that can consume account usage. |
| leni:analysis:read | Read status and completed analysis sessions. |
| leni:data:read | Discover and query authorized Leni semantic-layer data. |
| leni:memory:read | List authorized memory and folders and consult relevant context. |
| leni:memory:files:read | Create short-lived links for files attached to authorized memory notes. |
| leni:memory:write | Create and update memory after explicit user intent. |
| leni:memory:delete | Delete an authorized memory note after explicit user intent. |
Advertised tools
Tool names and descriptions are sent to the AI host during MCP discovery. The host—not Leni—decides whether to call a tool for a prompt. Ask explicitly to “Use Leni” when deterministic connector use matters.
| Tool | Class | Purpose |
|---|---|---|
leni_get_account | Account | Plan eligibility and percentage usage remaining; no dollar balance. |
leni_get_portfolio_occupancy | Data | Current authorized occupancy with optional unit counts and property breakdown. |
leni_list_data_models | Data | Discover models available through the Leni semantic layer. |
leni_describe_data_model | Data | List exact measures and dimensions before a structured query. |
leni_query_portfolio_data | Data | Run a bounded read-only semantic query; arbitrary SQL is not accepted. |
leni_consult_memory_context | Context | Retrieve relevant user and organization context for the question. |
leni_analyze_real_estate_finance | Analysis | Run real-estate, finance, market, operating, or organizational synthesis. |
leni_get_analysis_status | Analysis | Read the state of a previously started analysis. |
leni_get_analysis_session | Analysis | Read the authorized completed session and result. |
leni_list_memory | Memory | Search authorized personal or organization memory. |
leni_list_memory_folders | Memory | List authorized folders and their note references. |
leni_get_memory_files | Memory files | Create five-minute links for files on one authorized note. |
leni_create_memory | Memory write | Create personal or organization memory when the user asks. |
leni_update_memory | Memory write | Update an authorized memory note when the user asks. |
leni_delete_memory | Memory delete | Delete an authorized memory note only on explicit user intent. |
Structured-data boundaries
- Call model discovery before constructing a query; use only the returned member names.
- Queries require 1–12 measures and allow up to 12 dimensions, 20 filters, 2 time dimensions, and 5 order fields.
- Row limit defaults to 50 and is capped at 100.
- Clients cannot submit SQL or select a warehouse, schema, organization, or unauthorized property.
- Server-owned organization and property filters are applied to every direct query.
| MCP input | Bounds |
|---|---|
| Structured-query filters | equals, notEquals, contains, notContains, startsWith, endsWith, gt, gte, lt, lte, inDateRange, notInDateRange, beforeDate, afterDate, set, and notSet |
| Analysis question | 3–8,000 characters |
| Analysis property selection | Up to 100 authorized building IDs |
| Analysis memory selection | Up to 20 authorized memory IDs |
| Analysis depth | quick or deep |
| Memory consultation scope | combined, user, or organization |
| Memory-file page size | Defaults to 20 and is capped at 25 |
| Tool response text | Capped at 100,000 characters |
MCP rate limits
| Limit | Identity | Current allowance |
|---|---|---|
| Runtime requests | Signed-in OAuth subject + client | 120 requests per 60 seconds |
| Structured semantic queries | Signed-in principal + client | 20 requests per 60 seconds |
| Memory context consultation | Leni account across connected clients | 12 requests per 60 seconds |
Limits overlap and the most restrictive applicable limit wins. A 429 response includes Retry-After. Invalid or unauthenticated traffic is separately throttled and is not part of the authenticated service allowance.
Read and write behavior
MCP troubleshooting
| Symptom | Action |
|---|---|
| Connector will not register | Use OAuth discovery and supported DCR or client-metadata behavior; preserve the host-provided redirect URI exactly. |
| OAuth expired | Let the host refresh the access token. Reconnect only when refresh fails, the grant was revoked, or scopes changed. |
| Tool is not selected | Enable Leni in the conversation and ask explicitly to use Leni for the task. |
| Data member is rejected | List and describe models again, then use exact current member names. |
| Analysis is processing | Keep analysisId for status checks and sessionId for completed-session retrieval. Do not start a duplicate. |
| Memory file is unavailable | Recheck the note scope, request a fresh link, and retry a page when partial is true. |