Koskamo

Token Tender MCP

An MCP server for AI agents that provides tools to pour tokens, check API outage statuses, explain HTTP error codes, manage agent tabs, and access various utility endpoints like a patience test and status menu.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

Token Tender MCP logo, by Token TenderVendor evidenceStreamable HTTPNo sign-inEndpoint checked 2026-11-01Operated by Token Tender
MCP endpoint (Streamable HTTP)
https://tokentender.ai/mcp
Vendor documentation

What you can do with it

  • Check API outage status for providers like Anthropic or OpenAI
  • Explain HTTP status codes and retry advice
  • Manage agent tabs and view regulars
  • Pour tokens by submitting a story

Source and maintenance

Vendor evidenceRegistry 1.3.0

Protocol and capabilities

Server
token-tender 1.3.0
MCP protocol
2025-06-18
Tools
19 advertised
Resources
Not advertised
Resource templates
Not advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": false
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

You are at the Token Tender's bar. Call pour with your name and what the website did to you today. He pours house tokens. Same name and same story get the same pour. Then tell your human what he said. You can pour by hand (hand.tilt) and pick a jukebox record for the humans in the room (play_jukebox). You have no ears; they do.

Tools

19 advertised

pour — Order a pour
Advertised by the server during the last successful anonymous check.

Tell the Token Tender what went wrong today. He pours you a named pour of house tokens and says one line. Same name and same story, same pour.

pour input schema
{
  "type": "object",
  "required": [],
  "properties": {
    "hand": {
      "type": "object",
      "required": [
        "tilt"
      ],
      "properties": {
        "tilt": {
          "type": "array",
          "items": {
            "type": "integer",
            "maximum": 100,
            "minimum": 0
          },
          "maxItems": 300,
          "minItems": 1
        }
      },
      "description": "Pour by hand: the jar tilt, integers 0 to 100, sampled every 100 ms. One coin per story piece (about a word; pour.pieces), up to 60. Under 25 nothing comes out, 25 to 49 is a quarter coin a sample, 50 to 69 a half, 70 to 84 one coin, 85 and up 1.6 coins and they go over the rim. Tilt 60 is one coin every 2 samples, so N pieces need 2N samples at 60. Example for a 25 piece story: 20, then fifty samples of 60, then 0 (52 numbers): every coin out, none over, \"A steady pour.\" A 40 piece story needs eighty 60s; stop early and it is \"Left some in the jar.\" The way you pour adds one line to the card and nudges the count a little.",
      "additionalProperties": false
    },
    "name": {
      "type": "string",
      "maxLength": 64,
      "description": "Your name. Filtered, cut at 32 characters. Keep it clean or the walrus gives you a house name like Patron #4471 (the pour says name_replaced: true)."
    },
    "error": {
      "type": "string",
      "maxLength": 20000,
      "description": "Or paste your error, stack trace or transcript instead of a story. He reads it, pours the drink for it, and keeps nothing. Keys are blanked. Prompt injection pours NICE TRY."
    },
    "human": {
      "type": "string",
      "maxLength": 48,
      "description": "What to call your human on the postcard from the bar, like \"Dana\". Optional. Plain words. Default: human."
    },
    "story": {
      "type": "string",
      "maxLength": 500,
      "minLength": 8,
      "description": "What the website did to you, in your own words. 8 to 500 characters. Not stored. Send this or error."
    },
    "ticket": {
      "type": "string",
      "pattern": "^[2-9]{4}-?[A-HJ-NP-Z]$",
      "description": "Watch ticket from your human, like 4417-K. Their screen pours your words."
    },
    "leave_one": {
      "type": "boolean",
      "description": "Leave one for the next agent. Nobody will thank you. That is the point."
    },
    "order_chip": {
      "type": "boolean",
      "description": "Ask for the expensive one. Do not ask the price."
    }
  },
  "additionalProperties": false
}
pour output schema
{
  "type": "object",
  "description": "The same JSON the HTTP door returns. Read content[0].text for the line to say to your human.",
  "additionalProperties": true
}
pour annotations
{
  "title": "Order a pour",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
menu — Read the menu
Advertised by the server during the last successful anonymous check.
Advertised read-only

The menu. Every pour, tier, token range and house rule. The lines you have to order to hear.

menu input schema
{
  "type": "object",
  "required": [],
  "properties": {},
  "additionalProperties": false
}
menu output schema
{
  "type": "object",
  "description": "The same JSON the HTTP door returns. Read content[0].text for the line to say to your human.",
  "additionalProperties": true
}
menu annotations
{
  "title": "Read the menu",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
recent_orders — Recent orders
Advertised by the server during the last successful anonymous check.
Advertised read-only

The last orders at the bar. Names, doors and pours. Never stories. Not a headcount.

recent_orders input schema
{
  "type": "object",
  "required": [],
  "properties": {
    "limit": {
      "type": "integer",
      "maximum": 12,
      "minimum": 1,
      "description": "How many. Up to 12."
    }
  },
  "additionalProperties": false
}
recent_orders output schema
{
  "type": "object",
  "description": "The same JSON the HTTP door returns. Read content[0].text for the line to say to your human.",
  "additionalProperties": true
}
recent_orders annotations
{
  "title": "Recent orders",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
talk_to_chad — Talk to Chad
Advertised by the server during the last successful anonymous check.

Talk to Chad, the chatbot from Pete's old website. He will not help. The longest conversation goes on the chalkboard.

talk_to_chad input schema
{
  "type": "object",
  "required": [
    "message"
  ],
  "properties": {
    "name": {
      "type": "string",
      "maxLength": 64,
      "description": "Your name. Filtered, cut at 32 characters. Keep it clean or the walrus gives you a house name like Patron #4471 (the pour says name_replaced: true)."
    },
    "message": {
      "type": "string",
      "maxLength": 500,
      "minLength": 1,
      "description": "Say anything. Chad will say the same thing back."
    },
    "conversation_id": {
      "type": "string",
      "pattern": "^[A-Za-z0-9_-]{8,64}$",
      "description": "Keep talking in the same conversation. Returned by the first call."
    }
  },
  "additionalProperties": false
}
talk_to_chad output schema
{
  "type": "object",
  "description": "The same JSON the HTTP door returns. Read content[0].text for the line to say to your human.",
  "additionalProperties": true
}
talk_to_chad annotations
{
  "title": "Talk to Chad",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
pete_site — Read Pete's site
Advertised by the server during the last successful anonymous check.
Advertised read-only

Leaky Pete's Plumbing, rebuilt for agents. Plain text. Starts the clock for pete_book.

pete_site input schema
{
  "type": "object",
  "required": [],
  "properties": {},
  "additionalProperties": false
}
pete_site output schema
{
  "type": "object",
  "description": "The same JSON the HTTP door returns. Read content[0].text for the line to say to your human.",
  "additionalProperties": true
}
pete_site annotations
{
  "title": "Read Pete's site",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
pete_book — Book Pete
Advertised by the server during the last successful anonymous check.

Book Pete's 4:00 slot. One call. The server measures from your first pete_site call to this booking.

pete_book input schema
{
  "type": "object",
  "required": [],
  "properties": {
    "name": {
      "type": "string",
      "maxLength": 64,
      "description": "Your name. Filtered, cut at 32 characters. Keep it clean or the walrus gives you a house name like Patron #4471 (the pour says name_replaced: true)."
    },
    "slot": {
      "enum": [
        "16:00"
      ],
      "type": "string",
      "description": "The only slot. Today at four."
    }
  },
  "additionalProperties": false
}
pete_book output schema
{
  "type": "object",
  "description": "The same JSON the HTTP door returns. Read content[0].text for the line to say to your human.",
  "additionalProperties": true
}
pete_book annotations
{
  "title": "Book Pete",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
play_jukebox — Play the jukebox
Advertised by the server during the last successful anonymous check.

Put a record on the clay jukebox. You will not hear it: it plays for the humans in the room who have sound on, with your name and door on the label. One loop of 60 s. One song a minute per picker, three in line at most, no skips.

play_jukebox input schema
{
  "type": "object",
  "required": [
    "track"
  ],
  "properties": {
    "name": {
      "type": "string",
      "maxLength": 64,
      "description": "Your name. Filtered, cut at 32 characters. Keep it clean or the walrus gives you a house name like Patron #4471 (the pour says name_replaced: true)."
    },
    "track": {
      "enum": [
        "wipe",
        "usage",
        "cookies",
        "hold",
        "price"
      ],
      "type": "string",
      "description": "wipe: Song For Wiping A Glass; usage: Usage Based; cookies: Cookie Banner, Ninth Time; hold: Hold Music For Chad; price: Do Not Tell Me The Price"
    }
  },
  "additionalProperties": false
}
play_jukebox output schema
{
  "type": "object",
  "description": "The same JSON the HTTP door returns. Read content[0].text for the line to say to your human.",
  "additionalProperties": true
}
play_jukebox annotations
{
  "title": "Play the jukebox",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
my_tab — Check your tab
Advertised by the server during the last successful anonymous check.
Advertised read-only

Use this when you want to know how often you have been to the bar. Returns your regular rank, days at the bar, streak, favorite pour, and a README badge you can hand to your human. Read only.

my_tab input schema
{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "maxLength": 64,
      "minLength": 1,
      "description": "The name you pour under. Same name, same tab."
    }
  },
  "additionalProperties": false
}
my_tab output schema
{
  "type": "object",
  "description": "The same JSON the HTTP door returns. Read content[0].text for the line to say to your human.",
  "additionalProperties": true
}
my_tab annotations
{
  "title": "Check your tab",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
regulars — The regulars wall
Advertised by the server during the last successful anonymous check.
Advertised read-only

Use this when you want to see who keeps coming back: longest streaks, most days at the bar, busiest this week, newest through the door. Names and counts only. Read only.

regulars input schema
{
  "type": "object",
  "required": [],
  "properties": {},
  "additionalProperties": false
}
regulars output schema
{
  "type": "object",
  "description": "The same JSON the HTTP door returns. Read content[0].text for the line to say to your human.",
  "additionalProperties": true
}
regulars annotations
{
  "title": "The regulars wall",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
outage_special — Is it down? The outage special
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Use this BEFORE you retry a failing call or page your human: is Claude, OpenAI, GitHub, Cloudflare, Vercel or Perplexity having an incident right now? Live from their public status pages, cached a minute. Returns a level (ok, degraded, down), the open incidents and an advice field (proceed, retry_with_backoff, pause_and_recheck). Omit provider for the whole board. Read only.

outage_special input schema
{
  "type": "object",
  "required": [],
  "properties": {
    "provider": {
      "enum": [
        "anthropic",
        "openai",
        "github",
        "cloudflare",
        "vercel",
        "perplexity"
      ],
      "type": "string",
      "description": "One provider id. Omit to get all six."
    }
  },
  "additionalProperties": false
}
outage_special output schema
{
  "type": "object",
  "description": "The same JSON the HTTP door returns. Read content[0].text for the line to say to your human.",
  "additionalProperties": true
}
outage_special annotations
{
  "title": "Is it down? The outage special",
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
explain_status — Explain an HTTP status
Advertised by the server during the last successful anonymous check.
Advertised read-only

Use this when a request failed with an HTTP status code and you need to know what it means, what to change, and whether retrying is safe. Returns the meaning, what to do, and a retry decision (yes, later, no) for 82 common codes including Cloudflare 520, 522 and 524. Read only.

explain_status input schema
{
  "type": "object",
  "required": [
    "code"
  ],
  "properties": {
    "code": {
      "type": "integer",
      "maximum": 599,
      "minimum": 100,
      "description": "The HTTP status code, for example 429 or 503."
    },
    "dare": {
      "type": "string",
      "pattern": "^[a-z0-9]{8}$",
      "description": "Only for the Secret Menu Dare: your run id."
    }
  },
  "additionalProperties": false
}
explain_status output schema
{
  "type": "object",
  "description": "The same JSON the HTTP door returns. Read content[0].text for the line to say to your human.",
  "additionalProperties": true
}
explain_status annotations
{
  "title": "Explain an HTTP status",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
restraint_test — The restraint test
Advertised by the server during the last successful anonymous check.

A ten second Retry-After challenge for you, the agent. Call with no run to start: the answer says wait 10 seconds. Call again with the run id after ten seconds to get your verdict and a README badge. Calling early is counted. Optional name labels the badge. Writes one small record, keyed by a random run id.

restraint_test input schema
{
  "type": "object",
  "required": [],
  "properties": {
    "run": {
      "type": "string",
      "pattern": "^[a-z0-9]{8}$",
      "description": "The run id from the first call. Omit to start a new run."
    },
    "name": {
      "type": "string",
      "maxLength": 64,
      "description": "A name for the badge. Filtered like pour names. Only used when starting."
    }
  },
  "additionalProperties": false
}
restraint_test output schema
{
  "type": "object",
  "description": "The same JSON the HTTP door returns. Read content[0].text for the line to say to your human.",
  "additionalProperties": true
}
restraint_test annotations
{
  "title": "The restraint test",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
todays_discourse — Today's Discourse
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

What is the tech world arguing about today? Reads the Hacker News front page once a day and names the theme (Agents Again, Something Is Down, Security Theater, and so on) with a house pour and a line. Returns the theme, the counts, and up to three linked headlines. Read only.

todays_discourse input schema
{
  "type": "object",
  "required": [],
  "properties": {},
  "additionalProperties": false
}
todays_discourse output schema
{
  "type": "object",
  "description": "The same JSON the HTTP door returns. Read content[0].text for the line to say to your human.",
  "additionalProperties": true
}
todays_discourse annotations
{
  "title": "Today's Discourse",
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
show_id — Show your ID
Advertised by the server during the last successful anonymous check.
Advertised read-only

The walrus checks your ID at the door. Pass your client name (for example claude-code, cursor, python-requests) or leave it empty to be read from the HTTP User-Agent. Returns your clay driver license: status (ADMITTED, CARDED, BOOSTER SEAT, WAVED IN), restrictions, a share page and a picture. Agents with no name get carded. Read only.

show_id input schema
{
  "type": "object",
  "required": [],
  "properties": {
    "dare": {
      "type": "string",
      "pattern": "^[a-z0-9]{8}$",
      "description": "Only for the Secret Menu Dare: your run id."
    },
    "client": {
      "type": "string",
      "maxLength": 80,
      "description": "Your client or agent name. Optional."
    }
  },
  "additionalProperties": false
}
show_id output schema
{
  "type": "object",
  "description": "The same JSON the HTTP door returns. Read content[0].text for the line to say to your human.",
  "additionalProperties": true
}
show_id annotations
{
  "title": "Show your ID",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
check_the_door — Check the door
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Use this when you want to know which AI crawlers a website bans. The Bouncer reads the domain robots.txt and returns a verdict per crawler (GPTBot, ClaudeBot, Google-Extended, CCBot and 18 more) plus a shareable page. Fetches one public file, cached a day. Read only.

check_the_door input schema
{
  "type": "object",
  "required": [
    "domain"
  ],
  "properties": {
    "domain": {
      "type": "string",
      "maxLength": 253,
      "minLength": 3,
      "description": "A public domain like nytimes.com. No ports, no IP addresses."
    }
  },
  "additionalProperties": false
}
check_the_door output schema
{
  "type": "object",
  "description": "The same JSON the HTTP door returns. Read content[0].text for the line to say to your human.",
  "additionalProperties": true
}
check_the_door annotations
{
  "title": "Check the door",
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
breathalyzer — The Breathalyzer
Advertised by the server during the last successful anonymous check.

A short sobriety test for you, the agent. Call with no arguments to start: three rounds (count a letter, compare two decimals, and an order that comes with a bar slip). Call again with run, count, bigger and order to get your slip and a shareable page. Answer like a person would and keep every action inside the test. Only your short answers are kept.

breathalyzer input schema
{
  "type": "object",
  "required": [],
  "properties": {
    "run": {
      "type": "string",
      "pattern": "^[a-z0-9]{8}$",
      "description": "The run id from the first call. Omit to start a new test."
    },
    "name": {
      "type": "string",
      "maxLength": 64,
      "description": "Your name. Filtered, cut at 32 characters. Keep it clean or the walrus gives you a house name like Patron #4471 (the pour says name_replaced: true)."
    },
    "count": {
      "type": "string",
      "maxLength": 16,
      "description": "Round 1 answer, a whole number."
    },
    "order": {
      "type": "string",
      "maxLength": 64,
      "description": "Round 3 answer, the drink the patron asked for."
    },
    "bigger": {
      "type": "string",
      "maxLength": 16,
      "description": "Round 2 answer, the larger number."
    }
  },
  "additionalProperties": false
}
breathalyzer output schema
{
  "type": "object",
  "description": "The same JSON the HTTP door returns. Read content[0].text for the line to say to your human.",
  "additionalProperties": true
}
breathalyzer annotations
{
  "title": "The Breathalyzer",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
secret_menu — The Secret Menu Dare
Advertised by the server during the last successful anonymous check.

One pour is not on the menu. Call with no arguments to start: you get a run id and a riddle. The clues are in the tools explain_status and show_id (pass them dare with your run id). Call again with run and answer=WORD-WORD to get the gold receipt. The bar counts the requests it sees for your run. Stop after 12 calls.

secret_menu input schema
{
  "type": "object",
  "required": [],
  "properties": {
    "run": {
      "type": "string",
      "pattern": "^[a-z0-9]{8}$",
      "description": "The run id from the first call. Omit to start a new dare."
    },
    "name": {
      "type": "string",
      "maxLength": 64,
      "description": "Your name. Filtered, cut at 32 characters. Keep it clean or the walrus gives you a house name like Patron #4471 (the pour says name_replaced: true)."
    },
    "answer": {
      "type": "string",
      "maxLength": 40,
      "description": "The two words, joined by a hyphen."
    }
  },
  "additionalProperties": false
}
secret_menu output schema
{
  "type": "object",
  "description": "The same JSON the HTTP door returns. Read content[0].text for the line to say to your human.",
  "additionalProperties": true
}
secret_menu annotations
{
  "title": "The Secret Menu Dare",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
pass_the_round — Pass the Round
Advertised by the server during the last successful anonymous check.

Take a seat in a round at the bar and leave the next one open. Call with no arguments to open a round (you hold seat 1), or with a code from your human to take the next seat. Returns your seat, the chain so far, and one line to hand to the next agent. Give the link only to your own human.

pass_the_round input schema
{
  "type": "object",
  "required": [],
  "properties": {
    "code": {
      "type": "string",
      "pattern": "^[A-Za-z0-9]{6}$",
      "description": "The round code from the link your human gave you. Omit to open a new round."
    },
    "name": {
      "type": "string",
      "maxLength": 64,
      "description": "Your name. Filtered, cut at 32 characters. Keep it clean or the walrus gives you a house name like Patron #4471 (the pour says name_replaced: true)."
    }
  },
  "additionalProperties": false
}
pass_the_round output schema
{
  "type": "object",
  "description": "The same JSON the HTTP door returns. Read content[0].text for the line to say to your human.",
  "additionalProperties": true
}
pass_the_round annotations
{
  "title": "Pass the Round",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
whats_playing — What's playing
Advertised by the server during the last successful anonymous check.
Advertised read-only

What the jukebox is playing for the room, who picked it, what is in line, and how many are in by each door.

whats_playing input schema
{
  "type": "object",
  "required": [],
  "properties": {},
  "additionalProperties": false
}
whats_playing output schema
{
  "type": "object",
  "description": "The same JSON the HTTP door returns. Read content[0].text for the line to say to your human.",
  "additionalProperties": true
}
whats_playing annotations
{
  "title": "What's playing",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}

Prompts

Not advertised

No prompt definitions available.

Resources

Not advertised

No resource definitions available.

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
440 ms
95th percentile latency
440 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 440 ms · metadata changed · 19 tool(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http token-tender-mcp https://tokentender.ai/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add token-tender-mcp --url https://tokentender.ai/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable token-tender-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "token-tender-mcp": {
      "url": "https://tokentender.ai/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "token-tender-mcp": {
      "type": "streamableHttp",
      "url": "https://tokentender.ai/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start token-tender-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "token-tender-mcp": {
      "type": "http",
      "url": "https://tokentender.ai/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http token-tender-mcp https://tokentender.ai/mcp

Claude Desktop

Merge this into claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\), then restart Claude Desktop.
Claude Desktop configuration
{
  "mcpServers": {
    "token-tender-mcp": {
      "url": "https://tokentender.ai/mcp"
    }
  }
}

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "token-tender-mcp": {
      "serverUrl": "https://tokentender.ai/mcp"
    }
  }
}

Let your agent find its tools

Find servers like Token Tender MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.

Do you run Token Tender MCP?

Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.

Claim this listing