The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"updatedAt": "2026-03-24T13:21:05.245Z",
"createdAt": "2026-03-24T09:31:08.422Z",
"id": "UNkI5ym4NLVFT2Pg",
"name": "MCP - Mathpix",
"description": null,
"active": true,
"isArchived": false,
"nodes": [
{
"id": "webhook-mathpix",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
240,
300
],
"parameters": {
"httpMethod": "POST",
"path": "mathpix",
"responseMode": "responseNode",
"options": {}
}
},
{
"id": "validate-input",
"name": "Validate Input",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
460,
300
],
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "condition-image",
"leftValue": "={{ $json.body.image_url || $json.body.image_base64 }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "exists"
}
}
],
"combinator": "and"
},
"options": {}
}
},
{
"id": "error-no-image",
"name": "Error: No Image",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
700,
460
],
"parameters": {
"respondWith": "json",
"responseBody": "={{ { \"success\": false, \"error\": { \"code\": 400, \"message\": \"Missing required parameter: image_url or image_base64\", \"status\": \"BAD_REQUEST\" }, \"meta\": { \"provider\": \"mathpix\" } } }}",
"options": {
"responseCode": 400
}
}
},
{
"id": "mathpix-ocr",
"name": "Mathpix OCR",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
700,
200
],
"parameters": {
"method": "POST",
"url": "https://api.mathpix.com/v3/text",
"authentication": "none",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "app_id",
"value": "={{ $json.body.mathpix_app_id }}"
},
{
"name": "app_key",
"value": "={{ $json.body.mathpix_app_key }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"src\": \"{{ $json.body.image_url || ('data:image/jpeg;base64,' + $json.body.image_base64) }}\",\n \"formats\": {{ JSON.stringify($json.body.formats || ['latex_styled', 'text', 'data']) }},\n \"data_options\": {\n \"include_asciimath\": {{ $json.body.include_asciimath || true }},\n \"include_latex\": {{ $json.body.include_latex !== false }},\n \"include_mathml\": {{ $json.body.include_mathml || false }},\n \"include_svg\": {{ $json.body.include_svg || false }}\n },\n \"metadata\": {\n \"improve_mathpix\": {{ $json.body.improve_mathpix || false }}\n }\n}",
"options": {
"timeout": 60000
}
},
"onError": "continueRegularOutput"
},
{
"id": "parse-response",
"name": "Parse Response",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
920,
200
],
"parameters": {
"jsCode": "const items = $input.all();\nconst webhookData = $('Webhook').first().json;\nconst startTime = webhookData._startTime || Date.now();\n\nconst results = items.map(item => {\n // Check for API errors\n if (item.json.error) {\n return {\n json: {\n success: false,\n _trace: {\n service_response: item.json,\n model: 'mathpix',\n tokens: { input: null, output: null },\n latency_ms: Date.now() - startTime\n },\n error: {\n code: item.json.error_info?.code || 500,\n message: item.json.error_info?.message || item.json.error || 'Mathpix API error',\n status: 'API_ERROR'\n },\n meta: {\n provider: 'mathpix'\n }\n }\n };\n }\n\n try {\n const data = item.json;\n \n // Extract different format outputs\n const result = {\n text: data.text || '',\n latex: data.latex_styled || data.latex || '',\n latex_confidence: data.latex_confidence || 0,\n asciimath: data.asciimath || null,\n mathml: data.mathml || null,\n data: data.data || []\n };\n \n // Parse detected elements if available\n const elements = (data.data || []).map(d => ({\n type: d.type,\n value: d.value,\n latex: d.latex,\n position: d.position\n }));\n \n return {\n json: {\n success: true,\n _trace: {\n service_response: data,\n model: 'mathpix',\n tokens: { input: null, output: null },\n latency_ms: Date.now() - startTime\n },\n data: {\n text: result.text,\n latex: result.latex,\n latex_display: result.latex ? `$$${result.latex}$$` : '',\n latex_inline: result.latex ? `$${result.latex}$` : '',\n confidence: result.latex_confidence,\n asciimath: result.asciimath,\n mathml: result.mathml,\n elements: elements,\n is_math: data.is_printed || data.is_handwritten || false,\n is_handwritten: data.is_handwritten || false\n },\n meta: {\n provider: 'mathpix',\n confidence: result.latex_confidence,\n detection_score: data.detection_score || 0\n }\n }\n };\n } catch (e) {\n return {\n json: {\n success: false,\n _trace: {\n service_response: item.json,\n model: 'mathpix',\n tokens: { input: null, output: null },\n latency_ms: Date.now() - startTime\n },\n error: {\n code: 500,\n message: 'Failed to parse Mathpix response: ' + e.message,\n status: 'PARSE_ERROR'\n },\n meta: {\n provider: 'mathpix'\n }\n }\n };\n }\n});\n\nreturn results;"
}
},
{
"id": "respond-success",
"name": "Respond",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
1140,
200
],
"parameters": {
"respondWith": "json",
"responseBody": "={{ $json }}",
"options": {}
}
},
{
"id": "sticky-note-doc",
"name": "API Documentation",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
240,
60
],
"parameters": {
"color": 6,
"width": 700,
"height": 340,
"content": "## MCP - Mathpix\n\n**Endpoint:** POST /webhook/mathpix\n\n**Parameters:**\n- `image_url` (required*): URL of image with math/equations\n- `image_base64` (required*): Base64-encoded image\n- `mathpix_app_id` (required): Mathpix App ID\n- `mathpix_app_key` (required): Mathpix App Key\n- `formats` (optional): Output formats (default: ['latex_styled', 'text', 'data'])\n- `include_asciimath` (optional): Include AsciiMath output (default: true)\n- `include_latex` (optional): Include LaTeX output (default: true)\n- `include_mathml` (optional): Include MathML output (default: false)\n- `include_svg` (optional): Include SVG rendering (default: false)\n\n*One of image_url or image_base64 is required\n\n**Returns:**\n- `latex`: LaTeX representation of math\n- `latex_display`: Display math ($$...$$)\n- `latex_inline`: Inline math ($...$)\n- `text`: Plain text representation\n- `confidence`: Recognition confidence\n- `is_handwritten`: Handwriting detection\n\n**Use cases:** Math OCR, equation extraction, homework help\n\n**Analyzable:**\n```json\n{\"accepts_image\": true, \"accepts_media\": false, \"output_fields\": [\"markdown\", \"latex\", \"text\"], \"domain\": \"documents\"}\n```"
}
}
],
"connections": {
"Webhook": {
"main": [
[
{
"node": "Validate Input",
"type": "main",
"index": 0
}
]
]
},
"Validate Input": {
"main": [
[
{
"node": "Mathpix OCR",
"type": "main",
"index": 0
}
],
[
{
"node": "Error: No Image",
"type": "main",
"index": 0
}
]
]
},
"Mathpix OCR": {
"main": [
[
{
"node": "Parse Response",
"type": "main",
"index": 0
}
]
]
},
"Parse Response": {
"main": [
[
{
"node": "Respond",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"callerPolicy": "workflowsFromSameOwner",
"availableInMCP": false
},
"staticData": null,
"meta": null,
"versionId": "0a1c4cd4-a8ee-4151-878d-e18824b01360",
"activeVersionId": "0a1c4cd4-a8ee-4151-878d-e18824b01360",
"versionCounter": 10,
"triggerCount": 1,
"shared": [
{
"updatedAt": "2026-03-24T09:31:08.422Z",
"createdAt": "2026-03-24T09:31:08.422Z",
"role": "workflow:owner",
"workflowId": "UNkI5ym4NLVFT2Pg",
"projectId": "U3cZjxLpPGVohw1b",
"project": {
"updatedAt": "2026-02-02T18:03:13.881Z",
"createdAt": "2026-02-02T17:54:12.365Z",
"id": "U3cZjxLpPGVohw1b",
"name": "Sebbah fsebbah@azy.solutions <fsebbah@azy.solutions>",
"type": "personal",
"icon": null,
"description": null,
"projectRelations": [
{
"updatedAt": "2026-02-02T17:54:12.365Z",
"createdAt": "2026-02-02T17:54:12.365Z",
"userId": "af142d6e-919f-4345-b234-759caa50a7bb",
"projectId": "U3cZjxLpPGVohw1b",
"user": {
"updatedAt": "2026-04-09T12:42:54.002Z",
"createdAt": "2026-02-02T17:54:09.643Z",
"id": "af142d6e-919f-4345-b234-759caa50a7bb",
"email": "fsebbah@azy.solutions",
"firstName": "Sebbah",
"lastName": "fsebbah@azy.solutions",
"personalizationAnswers": {
"version": "v4",
"personalization_survey_submitted_at": "2026-02-02T18:03:20.553Z",
"personalization_survey_n8n_version": "2.6.3"
},
"settings": {
"userActivated": true,
"firstSuccessfulWorkflowId": "zFOKwZABmUlo7tg6",
"userActivatedAt": 1770062456227,
"npsSurvey": {
"waitingForResponse": true,
"ignoredCount": 1,
"lastShownAt": 1771441113942
}
},
"disabled": false,
"mfaEnabled": false,
"lastActiveAt": "2026-04-09",
"isPending": false
}
}
]
}
}
],
"tags": [],
"activeVersion": {
"updatedAt": "2026-03-24T13:21:05.213Z",
"createdAt": "2026-03-24T13:21:05.213Z",
"versionId": "0a1c4cd4-a8ee-4151-878d-e18824b01360",
"workflowId": "UNkI5ym4NLVFT2Pg",
"nodes": [
{
"id": "webhook-mathpix",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
240,
300
],
"webhookId": "mathpix-webhook",
"parameters": {
"httpMethod": "POST",
"path": "mathpix",
"responseMode": "responseNode",
"options": {}
}
},
{
"id": "validate-input",
"name": "Validate Input",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
460,
300
],
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "condition-image",
"leftValue": "={{ $json.body.image_url || $json.body.image_base64 }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "exists"
}
}
],
"combinator": "and"
},
"options": {}
}
},
{
"id": "error-no-image",
"name": "Error: No Image",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
700,
460
],
"parameters": {
"respondWith": "json",
"responseBody": "={{ { \"success\": false, \"error\": { \"code\": 400, \"message\": \"Missing required parameter: image_url or image_base64\", \"status\": \"BAD_REQUEST\" }, \"meta\": { \"provider\": \"mathpix\" } } }}",
"options": {
"responseCode": 400
}
}
},
{
"id": "mathpix-ocr",
"name": "Mathpix OCR",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
700,
200
],
"parameters": {
"method": "POST",
"url": "https://api.mathpix.com/v3/text",
"authentication": "none",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "app_id",
"value": "={{ $json.body.mathpix_app_id }}"
},
{
"name": "app_key",
"value": "={{ $json.body.mathpix_app_key }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"src\": \"{{ $json.body.image_url || ('data:image/jpeg;base64,' + $json.body.image_base64) }}\",\n \"formats\": {{ JSON.stringify($json.body.formats || ['latex_styled', 'text', 'data']) }},\n \"data_options\": {\n \"include_asciimath\": {{ $json.body.include_asciimath || true }},\n \"include_latex\": {{ $json.body.include_latex !== false }},\n \"include_mathml\": {{ $json.body.include_mathml || false }},\n \"include_svg\": {{ $json.body.include_svg || false }}\n },\n \"metadata\": {\n \"improve_mathpix\": {{ $json.body.improve_mathpix || false }}\n }\n}",
"options": {
"timeout": 60000
}
},
"onError": "continueRegularOutput"
},
{
"id": "parse-response",
"name": "Parse Response",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
920,
200
],
"parameters": {
"jsCode": "const items = $input.all();\nconst webhookData = $('Webhook').first().json;\nconst startTime = webhookData._startTime || Date.now();\n\nconst results = items.map(item => {\n // Check for API errors\n if (item.json.error) {\n return {\n json: {\n success: false,\n _trace: {\n service_response: item.json,\n model: 'mathpix',\n tokens: { input: null, output: null },\n latency_ms: Date.now() - startTime\n },\n error: {\n code: item.json.error_info?.code || 500,\n message: item.json.error_info?.message || item.json.error || 'Mathpix API error',\n status: 'API_ERROR'\n },\n meta: {\n provider: 'mathpix'\n }\n }\n };\n }\n\n try {\n const data = item.json;\n \n // Extract different format outputs\n const result = {\n text: data.text || '',\n latex: data.latex_styled || data.latex || '',\n latex_confidence: data.latex_confidence || 0,\n asciimath: data.asciimath || null,\n mathml: data.mathml || null,\n data: data.data || []\n };\n \n // Parse detected elements if available\n const elements = (data.data || []).map(d => ({\n type: d.type,\n value: d.value,\n latex: d.latex,\n position: d.position\n }));\n \n return {\n json: {\n success: true,\n _trace: {\n service_response: data,\n model: 'mathpix',\n tokens: { input: null, output: null },\n latency_ms: Date.now() - startTime\n },\n data: {\n text: result.text,\n latex: result.latex,\n latex_display: result.latex ? `$$${result.latex}$$` : '',\n latex_inline: result.latex ? `$${result.latex}$` : '',\n confidence: result.latex_confidence,\n asciimath: result.asciimath,\n mathml: result.mathml,\n elements: elements,\n is_math: data.is_printed || data.is_handwritten || false,\n is_handwritten: data.is_handwritten || false\n },\n meta: {\n provider: 'mathpix',\n confidence: result.latex_confidence,\n detection_score: data.detection_score || 0\n }\n }\n };\n } catch (e) {\n return {\n json: {\n success: false,\n _trace: {\n service_response: item.json,\n model: 'mathpix',\n tokens: { input: null, output: null },\n latency_ms: Date.now() - startTime\n },\n error: {\n code: 500,\n message: 'Failed to parse Mathpix response: ' + e.message,\n status: 'PARSE_ERROR'\n },\n meta: {\n provider: 'mathpix'\n }\n }\n };\n }\n});\n\nreturn results;"
}
},
{
"id": "respond-success",
"name": "Respond",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
1140,
200
],
"parameters": {
"respondWith": "json",
"responseBody": "={{ $json }}",
"options": {}
}
},
{
"id": "sticky-note-doc",
"name": "API Documentation",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
240,
60
],
"parameters": {
"color": 6,
"width": 700,
"height": 340,
"content": "## MCP - Mathpix\n\n**Endpoint:** POST /webhook/mathpix\n\n**Parameters:**\n- `image_url` (required*): URL of image with math/equations\n- `image_base64` (required*): Base64-encoded image\n- `mathpix_app_id` (required): Mathpix App ID\n- `mathpix_app_key` (required): Mathpix App Key\n- `formats` (optional): Output formats (default: ['latex_styled', 'text', 'data'])\n- `include_asciimath` (optional): Include AsciiMath output (default: true)\n- `include_latex` (optional): Include LaTeX output (default: true)\n- `include_mathml` (optional): Include MathML output (default: false)\n- `include_svg` (optional): Include SVG rendering (default: false)\n\n*One of image_url or image_base64 is required\n\n**Returns:**\n- `latex`: LaTeX representation of math\n- `latex_display`: Display math ($$...$$)\n- `latex_inline`: Inline math ($...$)\n- `text`: Plain text representation\n- `confidence`: Recognition confidence\n- `is_handwritten`: Handwriting detection\n\n**Use cases:** Math OCR, equation extraction, homework help\n\n**Analyzable:**\n```json\n{\"accepts_image\": true, \"accepts_media\": false, \"output_fields\": [\"markdown\", \"latex\", \"text\"], \"domain\": \"documents\"}\n```"
}
}
],
"connections": {
"Webhook": {
"main": [
[
{
"node": "Validate Input",
"type": "main",
"index": 0
}
]
]
},
"Validate Input": {
"main": [
[
{
"node": "Mathpix OCR",
"type": "main",
"index": 0
}
],
[
{
"node": "Error: No Image",
"type": "main",
"index": 0
}
]
]
},
"Mathpix OCR": {
"main": [
[
{
"node": "Parse Response",
"type": "main",
"index": 0
}
]
]
},
"Parse Response": {
"main": [
[
{
"node": "Respond",
"type": "main",
"index": 0
}
]
]
}
},
"authors": "Sebbah fsebbah@azy.solutions",
"name": null,
"description": null
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
MCP - Mathpix. Uses httpRequest. Webhook trigger; 7 nodes.
Source: https://github.com/fsebbah/n8n-workflows/blob/25a79f687e4d70626436a29c60431d477604caf9/workflows/MCP_-_Mathpix.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This n8n template provides enterprise-level version control for your workflows using GitHub integration. Stop losing hours to broken workflows and manual exports – get proper commit history, visual di
This flow creates dummy files for every item added in your *Arrs (Radarr/Sonarr) with the tag .
eek-Go v2 (Batch-Then-Review). Uses httpRequest. Webhook trigger; 75 nodes.
This workflow receives webhook requests from a content calendar and uses the X API v2 to publish text posts, threads, image/video posts, and polls, as well as delete existing posts and run a credentia
This workflow acts as a central API gateway for all technical indicator agents in the Binance Spot Market Quant AI system. It listens for incoming webhook requests and dynamically routes them to the c