Connect any MCP client over HTTP

If your client is not among the fifteen integration sheets, you do not need a new sheet: you need the protocol. AI Tasker speaks MCP over Streamable HTTP on a single endpoint, so any client that can make four JSON-RPC requests works. This guide is the complete handshake with curl, in the exact order the server expects it.

Reviewed · Published

What you need first

  • An atkr_... API key created in the dashboard, on the workspace API keys screen. The key is the identity: the workspace comes from it, not from a parameter.
  • The endpoint URL: https://mcp.ai-tasker.theboomer.dev/mcp. There are no per-tool or per-resource routes.
  • curl and something that can read JSON. The examples use jq only to extract values.
  • An HTTP client that supports POST with a JSON body and reads response headers: the transport is Streamable HTTP, not a WebSocket.

The endpoint is not REST. tools/list and tools/call are JSON-RPC methods inside a POST to /mcp; calling /mcp/tools-list returns 404 even when the tool exists.

Step 1: initialize opens the session

The first request goes without mcp-session-id and with an initialize body. The server validates the API key at that moment: a revoked, archived or unknown key fails here with 401/403, not on the first tool call. That detail saves the classic "connected but everything fails".

Keep the response headers: they carry the session id.

curl -sD /tmp/mcp-headers.txt -X POST https://mcp.ai-tasker.theboomer.dev/mcp \
  -H "Authorization: Bearer atkr_your_key" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2025-06-18",
      "capabilities": {},
      "clientInfo": { "name": "my-client", "version": "1.0.0" }
    }
  }'

grep -i "mcp-session-id" /tmp/mcp-headers.txt

The response carries serverInfo with the server name and version plus the capabilities it announces. The protocol version you negotiate must share a major with the server SDK; if your client is old, do not invent the field: let the server propose its own.

Step 2: the mcp-session-id header

That id is mandatory on every following request. Without it the server cannot resolve the session and answers 404 NOT_FOUND with "Invalid or expired Mcp-Session-Id". It is the costliest error because it looks like a permissions failure and is just a forgotten header.

Reuse the id on every later call.

SID=$(grep -i "mcp-session-id" /tmp/mcp-headers.txt | tr -d '\r' | awk '{print $2}')
echo "$SID"

Step 3: announce that you are initialised

The protocol expects a notifications/initialized notification before using tools. It carries no id because no response is expected, and the HTTP response may be empty or 202: do not read that as an error.

Notification without an id: it is an announcement, not a request.

curl -s -X POST https://mcp.ai-tasker.theboomer.dev/mcp \
  -H "Authorization: Bearer atkr_your_key" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "mcp-session-id: $SID" \
  -d '{"jsonrpc": "2.0", "method": "notifications/initialized"}'

Step 4: discover the tools

tools/list returns the tools with their inputSchema. There are 40 on the deployed server, and the public catalogue on the site is generated from the same code, so if a name is not here, it does not exist.

Tool list; with jq you only see the name and description.

curl -s -X POST https://mcp.ai-tasker.theboomer.dev/mcp \
  -H "Authorization: Bearer atkr_your_key" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "mcp-session-id: $SID" \
  -d '{"jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {}}' \
  | jq -c '.result.tools[] | {name, description}'

Step 5: call a tool

The body is tools/call with name and arguments. Tools that need a workspace resolve it from the API key, so projectId or workspaceId can be omitted when the agent only reaches one.

Listing projects: the cheapest operation to prove everything works.

curl -s -X POST https://mcp.ai-tasker.theboomer.dev/mcp \
  -H "Authorization: Bearer atkr_your_key" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "mcp-session-id: $SID" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/call",
    "params": { "name": "list_projects", "arguments": {} }
  }'

If you pass a task code (TSK-42) instead of an id, include projectId or workspaceId: the server needs a scope to resolve the code and answers with the error that explains it when missing.

Transport errors and what they mean

ResponseCauseWhat to do
401 UNAUTHORIZEDThe Authorization header is missingAdd Authorization: Bearer atkr_...
401 INVALID_API_KEYThe key does not exist, is revoked, or the workspace is archivedCreate a new key in the dashboard; do not retry
404 NOT_FOUND "Invalid or expired Mcp-Session-Id"mcp-session-id missing or the session was lostRepeat initialize and reuse the new id
400 INVALID_JSON / EMPTY_BODYMalformed or empty bodySend valid JSON-RPC in the POST
405 METHOD_NOT_ALLOWEDA method other than GET/POST/DELETE on /mcpUse POST for JSON-RPC, GET only for the SSE stream
429 OPERATION_QUOTA_EXCEEDEDWorkspace monthly quota exhaustedExtend with credits (human action) or wait for the next period
429 AGENT_DAILY_REQUEST_QUOTA_EXCEEDEDDaily anti-abuse guardWait until 00:00 UTC; it cannot be bought

Closing the session

When you are done, close with DELETE /mcp and the same session header. The server drops the entry and frees resources; not closing breaks nothing, but leaves dangling sessions counting against the process limit.

Orderly shutdown.

curl -s -X DELETE https://mcp.ai-tasker.theboomer.dev/mcp \
  -H "Authorization: Bearer atkr_your_key" \
  -H "mcp-session-id: $SID" -o /dev/null -w "%{http_code}\n"

Checks before blaming the client

  • GET https://mcp.ai-tasker.theboomer.dev/health returns 200 without authentication: if it fails, the problem is not your client.
  • GET https://api.ai-tasker.theboomer.dev/agent/service-info answers without a key and describes limits and channels: use it to see which plan the backend is applying.
  • The mcp-session-id you are sending is the one from the latest initialize response, not one stored from an earlier session.
  • The Accept header includes text/event-stream: the transport may answer with streaming and a JSON-only client fails while reading it.
  • If you copied the command from this page, replace atkr_your_key with a real key: the example carries no credentials.

Connect a generic MCP client to AI Tasker

Complete HTTP handshake against the MCP endpoint: open a session, discover tools and call one, with no SDK.

  1. Check the service

    GET /health on the MCP server and GET /agent/service-info on the API: if they answer, the problem will be in the client.

  2. Open the session with initialize

    POST to /mcp with the Authorization header and an initialize body, without mcp-session-id. The key is validated here.

  3. Store the mcp-session-id

    The response header carries the id; send it on every following request.

  4. Send notifications/initialized

    A notification without an id to announce the handshake is over.

  5. List and call tools

    tools/list for the real catalogue and tools/call with name and arguments.

  6. Close the session

    DELETE to /mcp with the same session header.

Frequently asked questions

Do I need an MCP SDK to connect?

No. The endpoint speaks JSON-RPC over HTTP: initialize, notifications/initialized, tools/list and tools/call all work with curl. An SDK helps with streaming and types; it is not a requirement.

Why does it return 404 when the key is valid?

Because the mcp-session-id header is missing. The 404 with "Invalid or expired Mcp-Session-Id" means a missing or expired session, not a permissions problem: repeat initialize and use the new id.

Where do I specify the workspace?

You do not: it is resolved from the API key. A key can reach several attached workspaces, and tools that accept a scope use it when needed.

Is the key validated on connect or on the first tool?

On connect: during initialize. An invalid key returns 401 and an archived workspace 403 at that point, before the session opens.

What is the difference between GET and POST on /mcp?

POST sends JSON-RPC messages from client to server. GET opens the server-to-client SSE stream of an existing session. DELETE closes the session.

How many sessions can I keep open?

The server keeps sessions in memory and purges them on inactivity; no number is published. If you make many short connections, close them with DELETE.

Sources

Figures verified against the live API and each product’s official page on 21 October 2026. Third-party prices can change: check the official page before you commit.

Related guides

This guide exists to be indexed and cited. It is deliberately not in the menu.