lambda-erp 1.1.3__tar.gz → 1.1.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/PKG-INFO +1 -1
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/routers/mcp.py +15 -4
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/pyproject.toml +1 -1
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/.gitignore +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/LICENSE +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/README.md +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/__init__.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/attachments.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/auth.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/bootstrap.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/chat.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/chat_links.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/demo_limits.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/deps.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/errors.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/list_values.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/main.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/mcp_oauth.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/oauth.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/pdf.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/pdf_contract.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/pdf_exports.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/pdf_profiles.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/providers.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/remarks_md.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/routers/__init__.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/routers/accounting.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/routers/actions.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/routers/admin.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/routers/analytics.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/routers/availability.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/routers/bank_reconciliation.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/routers/bank_statements.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/routers/chat_api.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/routers/documents.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/routers/masters.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/routers/proposals.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/routers/reports.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/routers/setup.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/services.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/templates/_proposal_totals.html +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/templates/_record_base.html +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/templates/document.html +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/templates/proposal.html +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/templates/record.html +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/time_filters.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/api/tool_permissions.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/docs/agents/README.md +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/frontend/LICENSE +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/frontend/README.md +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/frontend/src/api/client.ts +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/__init__.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/__init__.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/bank_account.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/bank_reconciliation.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/bank_statement_import.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/bank_transaction.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/budget.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/camt.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/chart_of_accounts.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/general_ledger.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/journal_entry.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/payment_entry.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/pos_invoice.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/purchase_invoice.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/revaluation.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/sales_invoice.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/settlement.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/setup/__init__.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/setup/engine.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/setup/pack.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/setup/packs/__init__.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/setup/packs/ch.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/setup/packs/de_common.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/setup/packs/de_skr03.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/setup/packs/de_skr04.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/setup/packs/generic.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/setup/profiles.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/setup/spine.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/accounting/subscription.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/assets/__init__.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/assets/asset.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/assets/lifecycle.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/assets/reservation.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/buying/__init__.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/buying/purchase_order.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/controllers/__init__.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/controllers/currency.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/controllers/defaults.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/controllers/item_price.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/controllers/item_prices.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/controllers/pricing_rule.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/controllers/taxes_and_totals.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/database.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/exceptions.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/hooks.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/master_integrity.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/model.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/selling/__init__.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/selling/proposal.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/selling/quotation.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/selling/sales_order.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/simulation.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/stock/__init__.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/stock/delivery_note.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/stock/purchase_receipt.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/stock/stock_entry.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/stock/stock_ledger.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/timestamps.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/utils.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/validation.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/lambda_erp/workflow.py +0 -0
- {lambda_erp-1.1.3 → lambda_erp-1.1.4}/terraform/README.md +0 -0
|
@@ -33,6 +33,7 @@ from api.tool_permissions import tool_allowed
|
|
|
33
33
|
router = APIRouter(tags=["mcp"])
|
|
34
34
|
|
|
35
35
|
PROTOCOL_VERSION = "2025-06-18"
|
|
36
|
+
SUPPORTED_PROTOCOL_VERSIONS = frozenset({'2025-03-26', PROTOCOL_VERSION})
|
|
36
37
|
|
|
37
38
|
# Chat-session-only tools have no meaning without a chat session — keep them out
|
|
38
39
|
# of the MCP surface (an MCP client owns its own context).
|
|
@@ -158,8 +159,12 @@ def _handle(msg: dict, user: dict):
|
|
|
158
159
|
return None if is_notification else {"jsonrpc": "2.0", "id": mid, "result": payload}
|
|
159
160
|
|
|
160
161
|
if method == "initialize":
|
|
162
|
+
requested_version = (msg.get('params') or {}).get('protocolVersion', PROTOCOL_VERSION)
|
|
163
|
+
if not isinstance(requested_version, str):
|
|
164
|
+
return _rpc_error(mid, -32602, 'Expected a string protocolVersion')
|
|
161
165
|
return result({
|
|
162
|
-
"protocolVersion":
|
|
166
|
+
"protocolVersion": (requested_version if requested_version in SUPPORTED_PROTOCOL_VERSIONS
|
|
167
|
+
else PROTOCOL_VERSION),
|
|
163
168
|
"capabilities": {"tools": {"listChanged": False}},
|
|
164
169
|
"serverInfo": {"name": "lambda-erp", "version": get_app_version()},
|
|
165
170
|
})
|
|
@@ -194,9 +199,9 @@ async def mcp_endpoint(request: Request):
|
|
|
194
199
|
allowed_origins = {issuer(request), *os.environ.get('MCP_ALLOWED_ORIGINS', '').split(',')}
|
|
195
200
|
if origin and origin not in allowed_origins:
|
|
196
201
|
raise HTTPException(403, 'Invalid Origin')
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
202
|
+
# Authentication discovery must work before the client has negotiated an
|
|
203
|
+
# MCP version. Otherwise a newer connector gets 400 instead of the 401
|
|
204
|
+
# challenge that tells it how to sign in.
|
|
200
205
|
user = _require_caller(request)
|
|
201
206
|
try:
|
|
202
207
|
body = await request.json()
|
|
@@ -206,6 +211,12 @@ async def mcp_endpoint(request: Request):
|
|
|
206
211
|
# Keep legacy batch support, but reject malformed messages rather than 500.
|
|
207
212
|
if not isinstance(body, (dict, list)) or (isinstance(body, list) and (not body or any(not isinstance(m, dict) for m in body))):
|
|
208
213
|
return JSONResponse(_rpc_error(None, -32600, "Invalid Request"), status_code=400)
|
|
214
|
+
# initialize negotiates the revision in its JSON-RPC payload. The version
|
|
215
|
+
# header is enforced on subsequent calls, after the client has our answer.
|
|
216
|
+
initializing = isinstance(body, dict) and body.get('method') == 'initialize'
|
|
217
|
+
version = request.headers.get('mcp-protocol-version')
|
|
218
|
+
if not initializing and version and version not in SUPPORTED_PROTOCOL_VERSIONS:
|
|
219
|
+
raise HTTPException(400, 'Unsupported MCP protocol version')
|
|
209
220
|
if isinstance(body, list):
|
|
210
221
|
responses = [r for r in (_handle(m, user) for m in body) if r is not None]
|
|
211
222
|
return JSONResponse(responses) if responses else Response(status_code=202)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|