Developer reference

Mind the Product MCP

A read-only Model Context Protocol server over 15 years of product management writing, talks, events and jobs. Connect a client in one click on the setup page, or call it directly with the reference below.

Overview

Endpoint
https://www.mindtheproduct.com/api/mcp/
Transport
Streamable HTTP (JSON-RPC 2.0 over POST)
Protocol version
2026-07-28
Authentication
OAuth 2.1 — authorization code + PKCE
Scope
mcp:read
Capabilities
tools, resources
Server name
mind-the-product

The trailing slash matters. This site runs with trailingSlash: true, so /api/mcp 308-redirects — and not every MCP client follows a 308 on POST. Configure the URL exactly as shown.

Quickstart

Every request is a JSON-RPC 2.0 POST. Start unauthenticated to see where to authorize — the 401 tells you.

1. See the auth challenge
curl -isL -X POST https://www.mindtheproduct.com/api/mcp/ \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

# HTTP/2 401
# www-authenticate: Bearer realm="mtp-mcp",
#   resource_metadata="https://www.mindtheproduct.com/.well-known/oauth-protected-resource"
2. Follow the pointer
curl -s https://www.mindtheproduct.com/.well-known/oauth-protected-resource | jq

{
  "resource": "https://www.mindtheproduct.com/api/mcp/",
  "authorization_servers": ["https://www.mindtheproduct.com"],
  "scopes_supported": ["mcp:read"],
  "bearer_methods_supported": ["header"]
}
3. Call a tool with your token
curl -sL -X POST https://www.mindtheproduct.com/api/mcp/ \
  -H "Authorization: Bearer $MTP_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "search_mtp_content",
      "arguments": { "query": "product discovery", "limit": 3 }
    }
  }'

Results come back as MCP content blocks. The text is markdown: a ranked source list with URLs, followed by the matching passages.

Response
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "## Search Results for \"product discovery\"\n\n### Sources\n[1] ..."
      }
    ]
  }
}

Authentication

OAuth 2.1 with PKCE, and no pre-registration: your client registers itself, the user approves once, and you get a token bound to them. There is no API key and no client-credentials grant — every token belongs to a person who clicked approve.

EndpointSpecPurpose
/.well-known/oauth-protected-resourceRFC 9728Which authorization server protects /api/mcp.
/.well-known/oauth-authorization-serverRFC 8414Authorization, token, registration and revocation endpoints.
/api/mcp/oauth/registerRFC 7591Dynamic client registration. No credentials needed.
/oauth/authorizeOAuth 2.1Consent screen. Open this in the user’s browser.
/api/mcp/oauth/tokenOAuth 2.1Authorization code and refresh token grants.
/api/mcp/oauth/revokeRFC 7009Revoke an access or refresh token.

Register a client

POST /api/mcp/oauth/register/
curl -s -X POST https://www.mindtheproduct.com/api/mcp/oauth/register/ \
  -H 'Content-Type: application/json' \
  -d '{
    "client_name": "My Product Research Bot",
    "redirect_uris": ["http://localhost:8765/callback"]
  }'

# { "client_id": "…", "token_endpoint_auth_method": "none", "scope": "mcp:read" }

Public clients only. redirect_uris must be HTTPS, or http://localhost for local development.

Get a token

Send the user to the consent screen with an S256 PKCE challenge, then exchange the code they come back with.

Open in the user's browser
https://www.mindtheproduct.com/oauth/authorize/
  ?client_id=YOUR_CLIENT_ID
  &redirect_uri=http://localhost:8765/callback
  &response_type=code
  &scope=mcp:read
  &state=RANDOM
  &code_challenge=BASE64URL_SHA256_OF_VERIFIER
  &code_challenge_method=S256
POST /api/mcp/oauth/token/
curl -s -X POST https://www.mindtheproduct.com/api/mcp/oauth/token/ \
  -d grant_type=authorization_code \
  -d code=THE_CODE \
  -d redirect_uri=http://localhost:8765/callback \
  -d client_id=YOUR_CLIENT_ID \
  -d code_verifier=YOUR_VERIFIER

# { "access_token": "mtp_at_…", "token_type": "Bearer",
#   "expires_in": 3600, "refresh_token": "mtp_rt_…", "scope": "mcp:read" }

Access tokens last an hour. Refresh tokens last 30 days and rotate on every use — keep the newest one, and expect a replayed refresh token to revoke the whole grant.

Tools

Six read-only tools. Call them with tools/call, or list them at runtime with tools/list. The four content tools also return structuredContent matching their outputSchema, so you can parse results instead of scraping the markdown.

search_mtp_content

Hybrid semantic + keyword search across 1,500+ articles, conference talks and guides. Returns ranked sources with URLs, plus the matching passages.

query*stringNatural language search query.
source_type"article" | "video" | "podcast"Filter by content type. Omit to search everything.
limitnumberDefault 6, capped at 20.
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_mtp_content",
    "arguments": {
      "query": "how to run a discovery sprint",
      "source_type": "article",
      "limit": 3
    }
  }
}

get_article

Fetch the full text of one article, with author and date metadata.

slug*stringURL path, with or without the leading slash.
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_article",
    "arguments": {
      "slug": "/what-is-product-management"
    }
  }
}

list_recent

Recently published articles, newest first.

limitnumberDefault 10, capped at 20.
topicstringOptional topic filter.
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "list_recent",
    "arguments": {
      "topic": "AI",
      "limit": 5
    }
  }
}

search_events

MTP conferences, training workshops and ProductTank meetups worldwide.

querystringOmit to get upcoming events generally.
upcoming_onlybooleanDefault true. Set false to include past events.
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_events",
    "arguments": {
      "query": "ProductTank London"
    }
  }
}

search_jobs

Live listings from the Mind the Product job board.

query*stringRole, skill or keyword.
locationstringCity, country, or "remote".
limitnumberDefault 10, capped at 20.
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_jobs",
    "arguments": {
      "query": "senior product manager",
      "location": "remote",
      "limit": 5
    }
  }
}

* required

Resources

Articles are exposed as resources, so getting full text does not need a second tool call or a guessed slug. Every search hit comes back with a resource_link alongside the prose — read that URI and you get the whole article.

A search result's resource link
{
  "type": "resource_link",
  "uri": "mtp://article/why-great-product-managers-think-like-therapists",
  "name": "Why great product managers think like therapists",
  "mimeType": "text/markdown"
}
Read it
curl -sL -X POST https://www.mindtheproduct.com/api/mcp/ \
  -H "Authorization: Bearer $MTP_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "resources/read",
    "params": { "uri": "mtp://article/some-article-slug" }
  }'

The scheme is mtp:// rather than https:// deliberately: articles render through a CMS, so the markdown only exists once the server has extracted it — a client cannot fetch it unaided.resources/templates/list advertises mtp://article/{slug}, and resources/list pages through recent articles.

Errors

Transport problems come back as HTTP status codes. Problems inside a call come back as JSON-RPC errors, or as a content block with isError: true when a tool itself fails.

401HTTPNo or invalid credentials. Read WWW-Authenticate for where to authorize.
429HTTPRate limited. Back off and retry.
-32600JSON-RPCMalformed request — missing or wrong jsonrpc envelope.
-32601JSON-RPCUnknown method.
-32602JSON-RPCInvalid params, e.g. a tools/call with no tool name.

Rate limits

Limits are per IP, per minute. tools/call is limited harder than the rest because each search runs an embedding and a vector query.

  • tools/call — 30 requests per minute
  • everything else — 120 requests per minute

Exceeding a limit returns 429. Building something that needs more? Email support@mindtheproduct.com.

Become a better product manager
Learn from product experts and become part of the world’s most engaged community for product managers
Join the community

Free Resources

  • Articles

Popular Content

Follow us
  • LinkedIn

© 2026 Pendo.io, Inc. All rights reserved. Pendo trademarks, product names, logos and other marks and designs are trademarks of Pendo.io, Inc. or its subsidiaries and may not be used without permission.