Thanks for the tips, still getting the 403. Might wipe everything and start over.
I have noticed a lot of connection issues after a trial restart. I end up having to shut down all LLMs and doing a ignition gateway restart. I assume its session timeouts or possibly not re-initializing things. Make sure you try those steps frequently as well.
Hi Paul, I get the same error
{"error":{"code":-32600}}
but my project is not inheritable...what else can I check?
From the code, -32600 (a JSON RPC "invalid request") is only thrown for the six methods associated with interacting with tools, resources, or prompts. What does your server config on disk look like? Do you have at least an empty JSON object for each of tools, resources, and prompts?
I followed your instruction at the beginning of the thread:
- I created the folder
[...]/Inductive Automation\Ignition\data\config\resources\core\com.inductiveautomation.mcp\server-config\testing
- Inside that folder I created the files
config.jsonandresource.jsonwith, respectively, the following content
{
"title": "Testing",
"version": "1.0.0",
"permissions": {
"type": "AllOf",
"securityLevels": [
{
"children": [],
"name": "Authenticated"
}
]
},
"tools": {
"project/Test": "*"
},
"resources": {},
"prompts": {}
}
{
"scope": "A",
"version": 1,
"restricted": false,
"overridable": true,
"files": [
"config.json"
],
"attributes": {
"uuid": "4895f9b3-eeb1-436f-b327-e54ab873db86"
}
}
I'm using Claude Desktop and this is its mcp server configuration
"mcpServers": {
"ignition-mcp": {
"command": "cmd",
"args": [
"/c",
"npx",
"-y",
"mcp-remote",
"http://localhost:8088/data/mcp/testing",
"--allow-http",
"--header",
"X-Ignition-API-Token: my_key"
]
}
}
I have created one object for each category on the Designer
but the result doesn't change.
This is the Powershell script I'm using to test the connection (I'm a newby on the topic, so I asked Claude Sonnet 4.6 for help and there might be mistakes)
$uri = "http://localhost:8088/data/mcp/testing"
$headers = @{
"X-Ignition-API-Token" = "my_key"
"Accept" = "application/json, text/event-stream"
"Content-Type" = "application/json"
}
# Step 1 — Initialize
$initResponse = Invoke-WebRequest -Uri $uri -Method POST -Headers $headers `
-Body '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}},"id":1}'
$sessionId = $initResponse.Headers["Mcp-Session-Id"]
Write-Host "Session ID: $sessionId"
$headers["Mcp-Session-Id"] = $sessionId
# Step 2 — notifications/initialized
Invoke-WebRequest -Uri $uri -Method POST -Headers $headers `
-Body '{"jsonrpc":"2.0","method":"notifications/initialized"}' | Out-Null
Start-Sleep -Seconds 3
# Step 3 — tools/list
Write-Host "`n=== TOOLS ==="
(Invoke-WebRequest -Uri $uri -Method POST -Headers $headers `
-Body '{"jsonrpc":"2.0","method":"tools/list","id":2}').Content |
ConvertFrom-Json | ConvertTo-Json -Depth 10
# Step 4 — resources/list
Write-Host "`n=== RESOURCES ==="
(Invoke-WebRequest -Uri $uri -Method POST -Headers $headers `
-Body '{"jsonrpc":"2.0","method":"resources/list","id":3}').Content |
ConvertFrom-Json | ConvertTo-Json -Depth 10
# Step 5 — prompts/list
Write-Host "`n=== PROMPTS ==="
(Invoke-WebRequest -Uri $uri -Method POST -Headers $headers `
-Body '{"jsonrpc":"2.0","method":"prompts/list","id":4}').Content |
ConvertFrom-Json | ConvertTo-Json -Depth 10
Here is the output
Session ID: 68b507b5-ddcc-4976-94d5-e2d0933d655a
=== TOOLS ===
{
"id": 2,
"error": {
"code": -32600
},
"jsonrpc": "2.0"
}
=== RESOURCES ===
{
"id": 3,
"error": {
"code": -32600
},
"jsonrpc": "2.0"
}
=== PROMPTS ===
{
"id": 4,
"error": {
"code": -32600
},
"jsonrpc": "2.0"
}
API key returns 403 Forbidden on /data/mcp/ endpoint even with Authenticated level and secure connections disabled
I am setting up the early-access MCP module on Ignition 8.3 and trying to connect to an MCP client (Claude Desktop). The endpoin is reachable and enforcing auth, but every authenticated request returns 403 Forbiddedn and I've been uable to get a single successful call or establish a connection.
config.json:
{
"title": "Testing",
"version": "1.0.0",
"permissions": {
"type": "AllOf",
"securityLevels": [
{
"children": [],
"name": "mcpApiKeys"
}
]
},
"tools": {
"project/MCP_TEST": "*"
},
"resources": {},
"prompts": {}
}
claude_desktop_conflig.json:
{
"coworkUserFilesPath": "C:\\Users\\apexadmin\\Claude",
"preferences": {
"coworkScheduledTasksEnabled": false,
"coworkHipaaRestricted": false,
"ccdScheduledTasksEnabled": true,
"bypassPermissionsGateByAccount": {
"2e7c7741-22e0-42ab-b9cf-5dd1c4d07d68": true
},
"coworkWebSearchEnabled": true,
"coworkModelAutoFallbackByAccount": {
"2e7c7741-22e0-42ab-b9cf-5dd1c4d07d68": true
},
"remoteToolsDeviceName": "eus2-ign-gw-dev",
"epitaxyPrefs": {
"starred-local-code-sessions": [],
"starred-cowork-spaces": [],
"starred-session-groups": [],
"dframe-local-slice": {
"pinnedOrder": [],
"customGroupAssignments": {},
"customGroupOrder": {}
}
}
},
"mcpServers": {
"ignition": {
"command": "C:\\Program Files\\nodejs\\node.exe",
"args": [
"C:\\Users\\apexadmin\\AppData\\Roaming\\npm\\node_modules\\mcp-remote\\dist\\proxy.js",
"http://localhost:8088/data/mcp/testing",
"--transport", "http-only",
"--allow-http",
"--header", "X-Ignition-API-Token:xxxTOKENxxx"
]
}
}
}
config.json:
{
"scope": "A",
"version": 1,
"restricted": false,
"overridable": true,
"files": [
"config.json"
],
"attributes": {
"uuid": "4895f9b3-eeb1-436f-b327-e54ab873db86"
}
}
this is some text from the mcp-server-ignition.log:
2026-06-22T13:41:50.202Z [ignition] [info] Server started and connected successfully { metadata: undefined }
2026-06-22T13:41:50.315Z [ignition] [info] Message from client: {"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{"extensions":{"io.modelcontextprotocol/ui":{"mimeTypes":["text/html;profile=mcp-app"]}}},"clientInfo":{"name":"claude-ai","version":"0.1.0"}},"jsonrpc":"2.0","id":0} { metadata: undefined }
[15428] Using transport strategy: http-only
[15428] Using automatically selected callback port: 29149
[15428] Using custom headers: {"X-Ignition-API-Token":"xxxTOKENxxx"}
[15428] Discovering OAuth server configuration...
[15428] [15428] Connecting to remote server: http://localhost:8088/data/mcp/testing
[15428] Using transport strategy: http-only
[15428] Connection error: StreamableHTTPError: Streamable HTTP error: Error POSTing to endpoint: {
"message":"Forbidden",
"url":"/data/mcp/testing",
"status":"403"
}
at StreamableHTTPClientTransport.send (file:///C:/Users/apexadmin/AppData/Roaming/npm/node_modules/mcp-remote/dist/chunk-65X3S4HB.js:19897:15)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5) {
code: 403
}
[15428] Fatal error: StreamableHTTPError: Streamable HTTP error: Error POSTing to endpoint: {
"message":"Forbidden",
"url":"/data/mcp/testing",
"status":"403"
}
at StreamableHTTPClientTransport.send (file:///C:/Users/apexadmin/AppData/Roaming/npm/node_modules/mcp-remote/dist/chunk-65X3S4HB.js:19897:15)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5) {
code: 403
}
Assertion failed: !(handle->flags & UV_HANDLE_CLOSING), file src\win\async.c, line 94
2026-06-22T13:41:50.721Z [ignition] [info] Server transport closed { metadata: undefined }
2026-06-22T13:41:50.721Z [ignition] [info] Server transport closed unexpectedly, this is likely due to the process exiting early. If you are developing this MCP server you can add output to stderr (i.e. `console.error('...')` in JavaScript, `print('...', file=sys.stderr)` in python) and it will appear in this log. { metadata: undefined }
2026-06-22T13:41:50.721Z [ignition] [error] Server disconnected. For troubleshooting guidance, please visit our [debugging documentation](https://modelcontextprotocol.io/docs/tools/debugging) { metadata: { context: 'connection', stack: undefined } }
2026-06-22T13:41:50.722Z [ignition] [info] Client transport closed { metadata: undefined }
2026-06-22T13:41:50.722Z [ignition] [info] Client transport closed { metadata: undefined }
I even tried calling the endpoint directly with curl (removing any client from the equation) and it still returns 403.
Curl call:
curl -X POST http://localhost:8088/data/mcp/testing -H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" -H "X-Ignition-API-Token: xxxTOKENxxx" -d "{\"jsonrpc\":\"2.0\",\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2025-06-18\",\"capabilities\":{}},\"id\":1}"
Curl return:
{
"message":"Forbidden",
"url":"/data/mcp/testing",
"status":"403"
}
I guess my main question is this: with a valid key that holds Authenticated, secure connections disabled, and a config requiring only Authenticated, what else is required for the MCP module to authorize a request to /data/mcp/testing? I also tried creating a api key sub-folder called mcpApiKeys and selected that as well as put it in the config file but that, too, returned a 403. I've tried creating fresh keys, trying to enable the core(active) collection, and unchecked the "require secure connections for API keys". Is there any additional backend/gateway permissions that I need to enable or that the MCP module needs in order to accept API-key auth beyond just the security level in config.json.
My environment is a Windows Azure VM running the 8.3 EA gateway, by the way. I am still on the Ignition trial and have to reset it every 2 hours, so I don't know if that could cause this issue.
Some help on this issue would greatly be appreciated.
I tried to download module again - after filing form it gives me a link that returns AccessDenied in XML from.
Am I missing some steps?
-32600 here is almost always a session issue, not your Designer objects. Print $sessionId and confirm it's not blank. If the Mcp-Session-Id header isn't captured and carried onto the list calls, every request gets rejected as invalid. Also make sure notifications/initialized actually lands before tools/list fires. Your config.json looks correct.
The 403 on a raw curl initialize means it's an auth rejection before MCP even runs, not a session/config-schema issue. Your config requires the custom mcpApiKeys level. The known-working setup uses Authenticated. Switch it back to Authenticated, issue a fresh key that maps to that level, and test.
We were having issues with the form previously. Can you try accessing this link directly to download?
Did exactly as suggested: config.json is on Authenticated (AllOf), re-scanned the config filesystem from Platform Overview after the edit, and issued a fresh API key with Authenticated selected in the core (active) collection. A raw curl initialize with the correct headers still returns 403 Forbidden. I've confirmed the request is reaching the auth layer: wrong Accept returns 406, missing Content-Type returns 415, and only a fully-formed request produces the 403 — so it's an auth rejection, not content negotiation.
What security level does the key need to literally hold to satisfy this, and is there a binding step between the API key and the MCP server resource beyond the securityLevels in config.json? Running 8.3 EA build b2026060908 on a Windows VM.
I have integrated ignition mcp to claude. But due to data security we can't use that. It was great that you have an idea to create a basic LLM for ourselves. If possible could you guide me through how you have integrated, your LLM to Ignition. If it OK to send you work, it would help me a lot in the projects with Ignition.
