{
  "id": "5eglr5Z0WCErDn3R",
  "meta": null,
  "name": "BikeWise API v2 MCP Server",
  "tags": [],
  "nodes": [
    {
      "id": "9c63f65b-fe8e-4589-af2e-c6494ed2cc23",
      "name": "Setup Instructions",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1380,
        -240
      ],
      "parameters": {
        "color": 4,
        "height": 1060,
        "content": "### \u2699\ufe0f Setup Instructions\n\n1. **Import Workflow**: \nLoad this workflow into your n8n instance\n\n2. **Authentication**: \nNo authentication required\n\n3. **Activate Workflow**:\nEnable the workflow to start the MCP server\n\n4. **Get MCP URL**: \nCopy the webhook URL from the MCP trigger\n\n5. **Connect AI Agent**:\nUse the MCP URL in your AI agent configuration\n\n\n### \ud83d\udca1 Usage Notes\n\u2022 Parameters are auto-populated by AI using $fromAI() expressions\n\u2022 With 4 API endpoints available as tools\n\u2022 Responses maintain original API structure\n\n\n### \ud83d\udee0\ufe0f Customization\n\u2022 Add data transformation nodes if needed\n\u2022 Implement custom error handling\n\u2022 Add logging or monitoring nodes\n\n\u2022 Modify parameter defaults in any HTTP request node as needed\n\n### \ud83d\udcac Need Help?\nPing me on [discord](https://discord.me/cfomodz) for integration guidance and custom automations. Check the [n8n documentation](https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolmcp/) for more information."
      },
      "typeVersion": 1
    },
    {
      "id": "a59fbca1-c0ae-4b1f-9b96-770127a503a7",
      "name": "Workflow Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1120,
        -240
      ],
      "parameters": {
        "width": 420,
        "height": 920,
        "content": "## \ud83d\udee0\ufe0f BikeWise API v2 MCP Server \u2705 4 operations\n\n### About\nThis is an API for accessing information about bicycling related incidents. You can find the source code on GitHub.\n\n### \ud83d\udd27 How it Works\n\nThis workflow converts the BikeWise API v2 API into an MCP-compatible interface for AI agents.\n\n\u2022 **MCP Trigger**: Serves as your server endpoint for AI agent requests\n\u2022 **HTTP Request Nodes**: Handle API calls to https://bikewise.org/api\n\u2022 **AI Expressions**: Automatically populate parameters via `$fromAI()` placeholders\n\u2022 **Native Integration**: Returns responses directly to the AI agent\n\n\n### \ud83d\udccb Available Operations (4 endpoints)\n\n**Incidents (2 operations)**\npaginated, get incident\n\n**Locations (2 operations)**\nunpaginated\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "5ae7a51a-cdb8-4894-a459-ab6d2768fec9",
      "name": "BikeWise API v2 MCP Server",
      "type": "@n8n/n8n-nodes-langchain.mcpTrigger",
      "position": [
        -620,
        -240
      ],
      "parameters": {
        "path": "bikewise-api-v2-mcp"
      },
      "typeVersion": 1
    },
    {
      "id": "8a8f750b-47b0-44a5-a426-6bf2922b81dd",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -660,
        -100
      ],
      "parameters": {
        "color": 2,
        "width": 500,
        "height": 200,
        "content": "## Incidents"
      },
      "typeVersion": 1
    },
    {
      "id": "183655c7-a526-408e-ad65-5defb32736ed",
      "name": "Paginated incidents matching parameters",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        -520,
        -60
      ],
      "parameters": {
        "url": "=https://bikewise.org/api/v2/incidents",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "page",
              "value": "={{ $fromAI('page', 'Page of results to fetch.', 'number', 1) }}"
            },
            {
              "name": "per_page",
              "value": "={{ $fromAI('per_page', 'Number of results to return per page.', 'number') }}"
            },
            {
              "name": "occurred_before",
              "value": "={{ $fromAI('occurred_before', 'End of period', 'number') }}"
            },
            {
              "name": "occurred_after",
              "value": "={{ $fromAI('occurred_after', 'Start of period', 'number') }}"
            },
            {
              "name": "incident_type",
              "value": "={{ $fromAI('incident_type', 'Only incidents of specific type', 'string') }}"
            },
            {
              "name": "proximity",
              "value": "={{ $fromAI('proximity', 'Center of location for proximity search', 'string') }}"
            },
            {
              "name": "proximity_square",
              "value": "={{ $fromAI('proximity_square', 'Size of the proximity search', 'number', 100) }}"
            },
            {
              "name": "query",
              "value": "={{ $fromAI('query', 'Full text search of incidents', 'string') }}"
            }
          ]
        },
        "toolDescription": "Paginated incidents matching parameters\n\nParameters:\n- Query parameters:\n  \u2022 page (optional) - Page of results to fetch.\n  \u2022 per_page (optional) - Number of results to return per page.\n  \u2022 occurred_before (optional) - End of period\n  \u2022 occurred_after (optional) - Start of period\n  \u2022 incident_type (optional) - Only incidents of specific type\n  \u2022 proximity (optional) - Center of location for proximity search\n  \u2022 proximity_square (optional) - Size of the proximity search\n  \u2022 query (optional) - Full text search of incidents"
      },
      "typeVersion": 4.2
    },
    {
      "id": "fe64c701-e2d5-4e92-9cff-c9d14f089201",
      "name": "Get incident",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        -320,
        -60
      ],
      "parameters": {
        "url": "=https://bikewise.org/api/v2/incidents/{{ $fromAI('id', 'Incident ID', 'number') }}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "toolDescription": "GET--version-incidents--id---format-\n\nParameters:\n- Path parameters:\n  \u2022 id (required) - Incident ID"
      },
      "typeVersion": 4.2
    },
    {
      "id": "8ad79cc0-cc10-42ce-84a4-7768150d43ec",
      "name": "Description - incidents",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -120,
        -60
      ],
      "parameters": {
        "width": 500,
        "height": 120,
        "content": "## \ud83d\udccb Incidents\n\nIncidents matching parameters"
      },
      "typeVersion": 1
    },
    {
      "id": "e1739cdf-de05-4259-b6fc-78fdf7f84dc2",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -660,
        140
      ],
      "parameters": {
        "color": 3,
        "width": 500,
        "height": 200,
        "content": "## Locations"
      },
      "typeVersion": 1
    },
    {
      "id": "85ea58a8-599f-4db5-bbfd-022d49284082",
      "name": "Unpaginated geojson response",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        -520,
        180
      ],
      "parameters": {
        "url": "=https://bikewise.org/api/v2/locations",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "occurred_before",
              "value": "={{ $fromAI('occurred_before', 'End of period', 'number') }}"
            },
            {
              "name": "occurred_after",
              "value": "={{ $fromAI('occurred_after', 'Start of period', 'number') }}"
            },
            {
              "name": "incident_type",
              "value": "={{ $fromAI('incident_type', 'Only incidents of specific type', 'string') }}"
            },
            {
              "name": "proximity",
              "value": "={{ $fromAI('proximity', 'Center of location for proximity search', 'string') }}"
            },
            {
              "name": "proximity_square",
              "value": "={{ $fromAI('proximity_square', 'Size of the proximity search', 'number', 100) }}"
            },
            {
              "name": "query",
              "value": "={{ $fromAI('query', 'Full text search of incidents', 'string') }}"
            },
            {
              "name": "limit",
              "value": "={{ $fromAI('limit', 'Max number of results to return. Defaults to 100', 'number') }}"
            },
            {
              "name": "all",
              "value": "={{ $fromAI('all', 'Give \u00e2em all to me. Will ignore limit', 'boolean') }}"
            }
          ]
        },
        "toolDescription": "Unpaginated geojson response\n\nParameters:\n- Query parameters:\n  \u2022 occurred_before (optional) - End of period\n  \u2022 occurred_after (optional) - Start of period\n  \u2022 incident_type (optional) - Only incidents of specific type\n  \u2022 proximity (optional) - Center of location for proximity search\n  \u2022 proximity_square (optional) - Size of the proximity search\n  \u2022 query (optional) - Full text search of incidents\n  \u2022 limit (optional) - Max number of results to return. Defaults to 100\n  \u2022 all (optional) - Give \u00e2em all to me. Will ignore limit"
      },
      "typeVersion": 4.2
    },
    {
      "id": "cd37d253-b9ae-40b7-be61-a62adb3b1338",
      "name": "Unpaginated geojson response with simplestyled markers",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        -320,
        180
      ],
      "parameters": {
        "url": "=https://bikewise.org/api/v2/locations/markers",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "occurred_before",
              "value": "={{ $fromAI('occurred_before', 'End of period', 'number') }}"
            },
            {
              "name": "occurred_after",
              "value": "={{ $fromAI('occurred_after', 'Start of period', 'number') }}"
            },
            {
              "name": "incident_type",
              "value": "={{ $fromAI('incident_type', 'Only incidents of specific type', 'string') }}"
            },
            {
              "name": "proximity",
              "value": "={{ $fromAI('proximity', 'Center of location for proximity search', 'string') }}"
            },
            {
              "name": "proximity_square",
              "value": "={{ $fromAI('proximity_square', 'Size of the proximity search', 'number', 100) }}"
            },
            {
              "name": "query",
              "value": "={{ $fromAI('query', 'Full text search of incidents', 'string') }}"
            },
            {
              "name": "limit",
              "value": "={{ $fromAI('limit', 'Max number of results to return. Defaults to 100', 'number') }}"
            },
            {
              "name": "all",
              "value": "={{ $fromAI('all', 'Give \u00e2em all to me. Will ignore limit', 'boolean') }}"
            }
          ]
        },
        "toolDescription": "Unpaginated geojson response with simplestyled markers\n\nParameters:\n- Query parameters:\n  \u2022 occurred_before (optional) - End of period\n  \u2022 occurred_after (optional) - Start of period\n  \u2022 incident_type (optional) - Only incidents of specific type\n  \u2022 proximity (optional) - Center of location for proximity search\n  \u2022 proximity_square (optional) - Size of the proximity search\n  \u2022 query (optional) - Full text search of incidents\n  \u2022 limit (optional) - Max number of results to return. Defaults to 100\n  \u2022 all (optional) - Give \u00e2em all to me. Will ignore limit"
      },
      "typeVersion": 4.2
    },
    {
      "id": "b9463aea-103f-4de0-b00e-ef0bc3a2b9ed",
      "name": "Description - locations",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -120,
        180
      ],
      "parameters": {
        "width": 500,
        "height": 120,
        "content": "## \ud83d\udccb Locations\n\nGeoJSON response for matching incidents"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "shared": [
    {
      "role": "workflow:owner",
      "project": {
        "id": "G5fce9xGuBAsWBXe",
        "icon": null,
        "name": "David Ashby <david.ashby.lds@gmail.com>",
        "type": "personal",
        "createdAt": "2025-06-04T02:55:02.013Z",
        "updatedAt": "2025-06-04T02:56:01.361Z",
        "projectRelations": [
          {
            "role": "project:personalOwner",
            "user": {
              "id": "715c1c00-cb48-4712-9a32-f1f4b6db2b30",
              "role": "global:owner",
              "email": "david.ashby.lds@gmail.com",
              "disabled": false,
              "lastName": "Ashby",
              "settings": {
                "npsSurvey": {
                  "responded": true,
                  "lastShownAt": 1749357655581
                },
                "userActivated": true,
                "userActivatedAt": 1749075994495,
                "easyAIWorkflowOnboarded": true,
                "firstSuccessfulWorkflowId": "3N3vVikZb3MckFYm"
              },
              "createdAt": "2025-06-04T02:55:01.745Z",
              "firstName": "David",
              "isPending": false,
              "updatedAt": "2025-06-08T04:40:58.399Z",
              "mfaEnabled": false,
              "personalizationAnswers": {
                "version": "v4",
                "personalization_survey_n8n_version": "1.95.3",
                "personalization_survey_submitted_at": "2025-06-04T02:56:07.075Z"
              }
            },
            "userId": "715c1c00-cb48-4712-9a32-f1f4b6db2b30",
            "createdAt": "2025-06-04T02:55:02.013Z",
            "projectId": "G5fce9xGuBAsWBXe",
            "updatedAt": "2025-06-04T02:55:02.013Z"
          }
        ]
      },
      "createdAt": "2025-07-01T21:27:46.720Z",
      "projectId": "G5fce9xGuBAsWBXe",
      "updatedAt": "2025-07-01T21:27:46.720Z",
      "workflowId": "5eglr5Z0WCErDn3R"
    }
  ],
  "settings": {
    "timezone": "America/New_York"
  },
  "createdAt": "2025-07-01T21:27:46.717Z",
  "updatedAt": "2025-07-01T21:28:02.000Z",
  "versionId": "0564f0fd-027c-45e7-b3a8-884d54985f7d",
  "isArchived": false,
  "staticData": null,
  "connections": {
    "Get incident": {
      "ai_tool": [
        [
          {
            "node": "BikeWise API v2 MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Unpaginated geojson response": {
      "ai_tool": [
        [
          {
            "node": "BikeWise API v2 MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Paginated incidents matching parameters": {
      "ai_tool": [
        [
          {
            "node": "BikeWise API v2 MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Unpaginated geojson response with simplestyled markers": {
      "ai_tool": [
        [
          {
            "node": "BikeWise API v2 MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    }
  },
  "triggerCount": 0
}