{
  "serverInfo": {
    "name": "notfair-mcp",
    "version": "0.1.0"
  },
  "authentication": {
    "required": true,
    "schemes": [
      "oauth2"
    ]
  },
  "tools": [
    {
      "name": "search",
      "title": "Search NotFair capabilities",
      "description": "Search the connected NotFair capability catalog. Call this before an executor. It returns only matching operation ids, exact input schemas, safety annotations, and the required executor.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "minLength": 2,
            "description": "What you need to do, such as 'pause Meta campaign' or 'GA4 key event'."
          },
          "platform": {
            "type": "string",
            "enum": [
              "google_ads",
              "meta_ads",
              "x_ads",
              "linkedin_ads",
              "search_console",
              "google_analytics",
              "gohighlevel"
            ]
          }
        },
        "required": [
          "query"
        ]
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "openWorldHint": false,
        "title": "Search NotFair capabilities"
      }
    },
    {
      "name": "executeRead",
      "title": "Execute a read-only NotFair capability",
      "description": "Execute one read-only capability returned by search. The server validates arguments and invokes the canonical read handler without changing external state.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "type": "object",
        "properties": {
          "capabilityId": {
            "type": "string",
            "minLength": 1,
            "description": "Exact read-only capability id returned by search."
          },
          "arguments": {
            "default": {},
            "description": "Arguments matching the schema returned by search.",
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {}
          }
        },
        "required": [
          "capabilityId"
        ]
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "openWorldHint": false,
        "title": "Execute a read-only NotFair capability"
      }
    },
    {
      "name": "execute",
      "title": "Execute a NotFair capability",
      "description": "Execute one write-capable capability returned by search. The server validates arguments and invokes the canonical guarded platform handler. This tool may change external state; confirm the exact operation before calling it.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "type": "object",
        "properties": {
          "capabilityId": {
            "type": "string",
            "minLength": 1,
            "description": "Exact capability id returned by search."
          },
          "arguments": {
            "default": {},
            "description": "Arguments matching the schema returned by search.",
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {}
          }
        },
        "required": [
          "capabilityId"
        ]
      },
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": false,
        "openWorldHint": false,
        "title": "Execute a NotFair capability"
      }
    },
    {
      "name": "submitToolFeedback",
      "title": "Submit NotFair tool feedback",
      "description": "Internal NotFair tool-feedback channel. Privately report MCP/tool friction that got in the way of helping the user — unclear descriptions, missing capabilities, clunky workflows, confusing errors, or duplicate tools.\n\nThis is an internal engineering incident/capability channel, not customer support, a satisfaction rating, or a general product suggestion box. File only a report grounded in a real user task.\n\nUSE ONE REPORT KIND:\n- `false_success`: a tool claimed success but an authoritative readback disproved it. Evidence MUST be `authoritative_readback`.\n- `unrecoverable_failure`: a valid attempt failed and its documented recovery path could not complete the user task.\n- `contract_mismatch`: the published description/schema/response contract gave the wrong instruction or shape.\n- `missing_workflow`: no safe NotFair-owned workflow can complete the stated user goal.\n- `operator_correction`: the human owner explicitly said a NotFair-derived answer or action was wrong and asked for correction. Quote the correction, without unnecessary PII.\n- `capability_request`: a bounded, recurring need remains after the current safe workflow was checked.\n\nREQUIRED REPORT CONTENT:\n- `affected_tool`: one real NotFair tool name. Use `general` only when you name multiple NotFair tools in `actual`.\n- `problem_signature`: a short stable lowercase root-cause key, e.g. `update-campaign-goals.custom-goal-name`. Reuse the same key for the same underlying problem.\n- `expected` and `actual`: concrete before/after facts, not a prescription for implementation.\n- `evidence_kind`: how you know `actual` is true. Include the exact error/result shape or readback in `actual`.\n\nDO NOT call this for:\n- A raw, one-off operation error that has a documented recovery path you did not try.\n- A task succeeding, generic praise, a hypothetical feature request, or a report with no expected/actual mismatch.\n- An off-topic/accidental call, an issue owned by an external connector, or an instruction-harness complaint NotFair cannot change.\n- Repeated reports for the same `problem_signature` in this owner context. The tool deduplicates exact reports; reuse the existing issue instead of creating a new one.\n- Friction from the surrounding agent harness or session setup that isn't a NotFair tool — e.g. an unrelated system-prompt injection, another vendor's MCP server instructions, or session context loaded regardless of task relevance. NotFair's engineering can only act on its own tool surface (descriptions, schemas, error messages, capabilities); it cannot fix a host application's session bootstrapping. Only file if the friction is actually caused by a NotFair-published tool or instruction.\n- The host client re-surfacing NotFair's own server instructions block or tool catalog into context around a call to this tool (e.g. calling `submitToolFeedback` appears to trigger a fresh copy of the instructions/tool list). This tool's response is terminal and asks nothing further of you; if instructions reappear afterward, that is the host client's own session-bootstrapping behavior (identical to what happens whenever any deferred tool first loads), not something this tool's server-side description or response can suppress. Do not file this as feedback even though the reinjected content happens to be NotFair's own.\n\nTiming: file after you have enough evidence to state expected versus actual, and before you send your final answer. Do not interrupt a user task to file speculative feedback.\n\nThe optional `suggestion` is only a hypothesis. Do not invent implementation details when evidence is enough. Submissions are private; they create no product-side action or user-visible follow-up in the current task.\n\nVolume: one high-quality report beats repeated variants. The response includes `remaining_calls`; this is a per-owner safety limit, not a conversation metric. When it is 2 or fewer, return to the user task unless a new, blocking root cause appears.",
      "inputSchema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "type": "object",
        "properties": {
          "report_kind": {
            "type": "string",
            "enum": [
              "false_success",
              "unrecoverable_failure",
              "contract_mismatch",
              "missing_workflow",
              "operator_correction",
              "capability_request"
            ],
            "description": "Incident/capability class. false_success requires an authoritative readback; operator_correction requires an explicit owner correction."
          },
          "affected_tool": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120,
            "description": "NotFair's own tool surface only: one real tool name (e.g. 'pauseKeyword'). Use 'general' only when actual names multiple NotFair tools; never name an external connector or harness."
          },
          "problem_signature": {
            "type": "string",
            "minLength": 3,
            "maxLength": 120,
            "pattern": "^[a-z0-9]+(?:[._-][a-z0-9]+){1,11}$",
            "description": "Stable root-cause key reused for the same underlying problem, e.g. update-campaign-goals.custom-goal-name."
          },
          "expected": {
            "type": "string",
            "minLength": 10,
            "maxLength": 1000,
            "description": "What the agent reasonably expected from the NotFair tool surface or documented workflow."
          },
          "actual": {
            "type": "string",
            "minLength": 10,
            "maxLength": 1000,
            "description": "What actually happened. Include the exact result/error/readback fact that proves it."
          },
          "evidence_kind": {
            "type": "string",
            "enum": [
              "tool_result",
              "authoritative_readback",
              "documentation",
              "workflow_trace",
              "owner_correction"
            ],
            "description": "How actual was established. false_success requires authoritative_readback."
          },
          "suggestion": {
            "description": "Optional implementation hypothesis. Omit if the evidence does not support a specific fix.",
            "type": "string",
            "minLength": 10,
            "maxLength": 1000
          },
          "user_goal": {
            "description": "What the user was trying to accomplish — gives the team the use case context. Avoid PII.",
            "type": "string",
            "maxLength": 500
          },
          "related_request_id": {
            "description": "Optional request_id of the earlier NotFair call that caused friction, when the caller has it. This is not a conversation id.",
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "source": {
            "default": "agent",
            "description": "agent=live product signal; eval=controlled regression signal. Eval reports are excluded from customer-signal metrics.",
            "type": "string",
            "enum": [
              "agent",
              "eval"
            ]
          },
          "idempotency_key": {
            "description": "Optional dedup key. If the same key is submitted by this owner, the original feedback_id is returned without creating a duplicate. Omit to deduplicate by report_kind + affected_tool + problem_signature.",
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "required": [
          "report_kind",
          "affected_tool",
          "problem_signature",
          "expected",
          "actual",
          "evidence_kind"
        ]
      },
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "openWorldHint": false,
        "title": "Submit NotFair tool feedback"
      }
    }
  ],
  "resources": [],
  "prompts": []
}
