
List every channel and category in a server. This is the tool to call first to find channel IDs for the message, thread, webhook, and invite tools. Use listguilds to find server IDs. Filter with channeltype, e.g. 0 for text channels. Threads are not included — use listactivethreads for those.
Fetch one channel or thread by ID, including its permission overwrites and, for forum channels, the availabletags needed by createthread. Use listguildchannels to find channel IDs.
Create a channel in a server. Requires the Manage Channels permission. Use listguilds for server IDs and listguildchannels to find a category ID for parentid. Returns the new channel ID for use with createmessage. Set channel permissions afterwards with setchannel_permissions.
Modify a channel or thread: rename it, change its topic, slowmode, category, or voice settings, or archive and lock a thread. Requires Manage Channels, or Manage Threads for thread settings. Use listguildchannels to find channel IDs. Only the fields you pass are changed.
Delete a channel, or delete a thread. Requires Manage Channels, or Manage Threads for a thread. Deleting a category does not delete the channels inside it. Use listguildchannels to find channel IDs. This cannot be undone.
Set a role's or member's permission override on a channel, using permission names rather than raw bitfields. Call listpermissions first for the valid names, listroles for role IDs, and searchguildmembers for member IDs. Requires Manage Roles. This replaces the whole override for that role or member.
Remove a role's or member's permission override from a channel, so they fall back to the category and server defaults. Requires Manage Roles. Use getchannel and read permissionoverwrites to see which overrides exist.
Show the bot's typing indicator in a channel for about 10 seconds. Use before a slow operation so users know a reply is coming; not needed before an ordinary createmessage. Use listguild_channels to find channel IDs.
Follow an announcement channel so its published messages are crossposted into one of your own channels. The source must be type 5; use listguildchannels to check. Requires Manage Webhooks on the target channel. Returns the webhook Discord creates to deliver the messages.
List the servers the bot has been added to. This is the tool to call first — almost every other tool needs a server ID from here, or a channel ID from listguildchannels. Each entry also reports the bot's own permissions in that server as permission_names.
Fetch one server's settings by ID. Use listguilds to find server IDs. Set withcounts true for approximate member and online counts. Returns server settings only — use listguildchannels for channels, listroles for roles, and listguild_emojis for emojis.
Read a server's audit log to see who performed moderation and configuration actions. Requires the View Audit Log permission. Filter with actiontype (e.g. 22 member ban, 20 kick, 72 message delete, 10 channel create) or userid. Use list_guilds for server IDs. Referenced users are returned alongside the entries.
List a server's custom emojis. Call this before createreaction to get each emoji's reactionformat ('name:id'), which is the form the reaction tools need. Use list_guilds to find server IDs.
List every active invite for a server, with use counts and expiry. Requires the Manage Guild permission. Use listguilds for server IDs. For one channel's invites only, use listchannelinvites. Returns invite codes usable with getinvite and delete_invite.
List the active invites pointing at one channel. Requires the Manage Channels permission. Use listguildchannels for channel IDs. For every invite in the server, use listguildinvites.
Look up an invite by its code to see which server and channel it leads to. Pass just the code, not the full discord.gg URL. Works for any invite, including servers the bot is not in. Set with_counts true for member counts.
Create an invite link to a channel. Requires the Create Instant Invite permission. Use listguildchannels for channel IDs. Set maxage and maxuses to limit it, or both to 0 for a permanent unlimited invite. Returns the invite code; the shareable link is https://discord.gg/<code>.
Revoke an invite so it can no longer be used. Requires Manage Channels on the channel, or Manage Guild for any invite in the server. Use listguildinvites or listchannelinvites to find codes. This cannot be undone; create a new invite instead.
List a server's members in ID order. Requires the Guild Members privileged intent, enabled on the Bot tab of your application. Use this to enumerate everyone; use searchguildmembers to find someone by name. Use list_guilds for server IDs. Page with after.
Find server members whose username or nickname starts with a string. This is a prefix match, so 'ali' finds 'alice' but 'lice' does not. Use this to resolve a name to a user ID for the member, role, and moderation tools. Use list_guilds for server IDs. Not paginated.
Fetch one member's server profile: nickname, roles, join date, and timeout state. Use searchguildmembers to find user IDs. For the global account instead, use get_user.
Change a member's nickname, roles, voice state, or timeout. Each field needs its own permission (Manage Nicknames, Manage Roles, Moderate Members). roleids REPLACES every role the member has — use addmemberrole or removememberrole for a single change. Use listroles for role IDs and searchguildmembers for user IDs.
Kick a member from a server. Requires the Kick Members permission. A kicked member can rejoin with a new invite — use createban to keep them out. Use searchguild_members to find user IDs.
Give a member one role, leaving their other roles alone. Requires Manage Roles, and the role must sit below the bot's own highest role. Use listroles for role IDs and searchguild_members for user IDs.
Take one role away from a member, leaving their other roles alone. Requires Manage Roles, and the role must sit below the bot's own highest role. Use getguildmember to see which roles a member currently has.
Change the bot's own nickname or bio in a server. This is the only way to do that: updateguildmember targets another member and Discord rejects it with 403 even when the bot aims it at itself. Use list_guilds to find server IDs. Pass an empty string to clear a field.
Read a channel's or thread's message history, newest first. Use this to browse recent messages; use searchmessages to find messages matching a query across a server. Page back with before, or poll for new messages with after. Use listguild_channels to find channel IDs. Content is empty unless the bot has the Message Content privileged intent enabled.
Fetch one message by ID, including its reaction tallies. Use listmessages or searchmessages to find message IDs, and listguildchannels to find channel IDs.
Post a message to a channel, thread, or DM channel. Requires at least one of content, embeds, stickerids, poll, or a forward. Use listguildchannels to find channel IDs, or createdm for a direct message. Set replytomessage_id to reply. Returns the new message ID for follow-up edits, pins, or reactions.
Edit a message the bot itself sent. Content and embeds of another user's message cannot be edited by any token. Use list_messages to find message IDs. Pass embeds as [] to strip embeds while keeping the text.
Permanently delete one message. Deleting another user's message requires the Manage Messages permission. Use listmessages to find message IDs. For 2 to 100 messages at once use bulkdelete_messages instead. This cannot be undone.
Delete 2 to 100 messages from a guild channel in one call. Every message must be under 2 weeks old and every ID unique, or the whole call fails with no deletions. Requires Manage Messages. Does not work in DM channels — use deletemessage there. Use listmessages to find message IDs.
Search a server's messages by content, channel, author, mentions, or attachment type. Use this to find messages across a server; use listmessages to read one channel in order. Requires the Message Content privileged intent. Use listguilds for server IDs. If indexinginprogress is true the index is still building — retry after retryafterseconds.
Publish a message from an announcement channel to every server following it. Only works in channels of type 5; use listguildchannels to check the type. Use list_messages to find message IDs.
List a channel's pinned messages, most recently pinned first. Each entry carries the pin time and the full message. Use listguildchannels to find channel IDs. Page with before, which takes a pin timestamp rather than a message ID.
Pin a message in its channel. Requires the Pin Messages permission. A channel holds at most 50 pins. Use list_messages to find message IDs.
Remove a message from its channel's pins. Requires the Pin Messages permission. The message itself is not deleted. Use list_pins to find pinned message IDs.
List a server's bans, each with the banned user and the reason recorded. Requires the Ban Members permission. Use listguilds for server IDs. Page with after. To check one specific user use getban.
Check whether one user is banned from a server, and read the recorded reason. Requires the Ban Members permission. Returns a not-found error when the user is not banned, which is how you test for a ban. Use list_bans to enumerate every ban instead.
Ban a user from a server, optionally deleting their recent messages. Requires the Ban Members permission. The user need not be a member — banning a non-member pre-empts them joining. Use searchguildmembers to find user IDs. To remove someone without a permanent ban use removeguildmember.
Lift a server ban so the user can be invited back. Requires the Ban Members permission. This does not re-add them to the server. Use list_bans to find banned user IDs.
React to a message as the bot. Pass a standard emoji character, or 'name:id' for a custom server emoji — use listguildemojis to get the 'name:id' form. Requires Add Reactions unless the emoji is already on the message. Use list_messages to find message IDs.
Remove the bot's own reaction from a message. To remove another user's reaction use deleteuserreaction, or deleteallreactions to clear every reaction. Use get_message to see which reactions exist.
Remove one specific user's reaction from a message. Requires the Manage Messages permission. Use listreactions to find which users reacted. To remove the bot's own reaction use deleteown_reaction.
List the users who reacted to a message with a given emoji. Use getmessage first to see which emojis are on the message and their counts. Page with after. Returns user IDs usable with getuser and deleteuserreaction.
Clear reactions from a message. Pass an emoji to clear just that one, or leave it null to clear every reaction. Requires the Manage Messages permission. To remove a single user's reaction use deleteuserreaction.
List every Discord permission name, with its bit and what it allows. Call this before createrole, updaterole, or setchannelpermissions to get the exact names those tools accept — Discord has no API endpoint for this, so the names cannot be discovered any other way. Runs locally with no API call.
List a server's roles, each with its permissions decoded into names. Call this to find role IDs for addmemberrole, updateguildmember, and setchannelpermissions. Use list_guilds for server IDs. Roles with managed=true belong to an integration and cannot be edited or assigned.
Fetch one role by ID, with its permissions decoded into names. Call this before updaterole to read the current permission set, since updaterole replaces it wholesale. Use list_roles to find role IDs.
Create a role in a server. Requires the Manage Roles permission. Pass permissions as names, e.g. ['VIEWCHANNEL', 'SENDMESSAGES'] — call listpermissions first for the valid names. Use listguilds for server IDs. Returns the new role ID for addmemberrole. New roles start at the bottom of the hierarchy.
Modify a role's name, colour, or permissions. Requires Manage Roles, and the role must sit below the bot's own highest role. permissions REPLACES the role's whole permission set, so call getrole first to read the current one. Use listpermissions for valid names and list_roles for role IDs.
Delete a role from a server. Requires Manage Roles, and the role must sit below the bot's own highest role. Every member holding it loses it. Use list_roles to find role IDs. This cannot be undone.
Start a thread attached to an existing message, so the thread appears under it. Requires Create Public Threads. Use listmessages to find message IDs. To open a standalone thread or a forum post use createthread. Returns the thread ID, which createmessage accepts as a channelid.
Open a thread in a text channel, or a post in a forum or media channel. In a forum or media channel the message parameter is required and carries the first post; in a text channel leave it null. Use getchannel on the parent for availabletags before setting appliedtags. Returns the thread ID, which createmessage accepts as a channel_id.
List every thread in a server that is not archived, across all channels. Use listguilds to find server IDs, and channelid to narrow to one channel's threads. For archived threads use listarchivedthreads. Returns thread IDs that createmessage and listmessages accept as channel IDs.
List archived threads under a channel, most recently archived first. Set visibility to 'public' or 'private'; listing private threads requires Manage Threads. Use listguildchannels to find the parent channel ID. Pages by archive timestamp via before, not by ID.
List the users who have joined a thread. Use listactivethreads to find thread IDs. Requires the Guild Members privileged intent. Set withmember true only when you need each user's full server profile, which is much larger. Returns user IDs usable with getuser.
Add a user to a thread. The bot must be able to see the thread, and the user must be a member of the server. Use listactivethreads for thread IDs and searchguildmembers for user IDs.
Remove a user from a thread. Requires Manage Threads, unless the thread is private and the bot created it. Use listthreadmembers to find the users in a thread.
Fetch the account the credential authenticates as, which for a bot token is the bot itself. Use this to learn the bot's own user ID, needed to recognise its own messages in listmessages output. To check whether credentials work at all, use validatecredential.
Fetch a user's global Discord account by ID. Use searchguildmembers to find user IDs, or read author.id from listmessages. Returns the global account only — for their nickname, roles, and join date in a specific server, use getguild_member.
Open a direct message channel with a user, or return the existing one. Use searchguildmembers to find user IDs. Pass the returned channel id to create_message to actually send the message. The user must share a server with the bot and allow DMs from server members.
Validate the Discord bot token by fetching the bot's own account. Use this to confirm setup before calling other tools.
List the webhooks configured on a channel, including each one's token. Requires the Manage Webhooks permission. Use listguildchannels for channel IDs. The returned id and token are what execute_webhook needs — treat the token as a credential, since it alone authorizes posting to the channel.
Create a webhook on a channel so an external system can post to it without a bot token. Requires the Manage Webhooks permission. Use listguildchannels for channel IDs. The name cannot contain 'discord'. Returns the webhook id, token, and full url — all three are credentials that allow posting.
Delete a webhook, immediately breaking anything posting through it. Requires the Manage Webhooks permission. Use listchannelwebhooks to find webhook IDs. This cannot be undone; a new webhook gets a new token.
Post a message through a webhook, optionally under a custom name and avatar. Use createmessage to post as the bot itself; use this when the message should appear from a named external system. Needs the webhook id and token from createwebhook or listchannelwebhooks. At least one of content or embeds is required.

In an mcp.json file, add the configuration below, and restart Cursor.
Learn more in the official documentation ↗
1{
2 "mcpServers": {
3 "agent-handler": {
4 "url": "https://ah-api-develop.merge.dev/api/v1/tool-packs/{TOOL_PACK_ID}/registered-users/{REGISTERED_USER_ID}/mcp",
5 "headers": {
6 "Authorization": "Bearer yMt*****"
7 }
8 }
9 }
10}
11Open your Claude Desktop configuration file and add the server configuration below. You'll also need to restart the application for the changes to take effect.
Make sure Claude is using the Node v20+.
Learn more in the official documentation ↗
1{
2 "mcpServers": {
3 "agent-handler": {
4 "command": "npx",
5 "args": [
6 "-y",
7 "mcp-remote@latest",
8 "https://ah-api-develop.merge.dev/api/v1/tool-packs/{TOOL_PACK_ID}/registered-users/{REGISTERED_USER_ID}/mcp",
9 "--header",
10 "Authorization: Bearer ${AUTH_TOKEN}"
11 ],
12 "env": {
13 "AUTH_TOKEN": "yMt*****"
14 }
15 }
16 }
17}Open your Windsurf MCP configuration file and add the server configuration below.
Click on the refresh button in the top right of the Manage MCP server page or in the top right of the chat box in the box icon.
Learn more in the official documentation ↗
1{
2 "mcpServers": {
3 "agent-handler": {
4 "command": "npx",
5 "args": [
6 "-y",
7 "mcp-remote@latest",
8 "https://ah-api.merge.dev/api/v1/tool-packs/<tool-pack-id>/registered-users/<registered-user-id>/mcp",
9 "--header",
10 "Authorization: Bearer ${AUTH_TOKEN}"
11 ],
12 "env": {
13 "AUTH_TOKEN": "<ah-production-access-key>"
14 }
15 }
16 }
17 }In Command Palette (Cmd+Shift+P on macOS, Ctrl+Shift+P on Windows), run "MCP: Open User Configuration".
You can then add the configuration below and press "start" right under servers. Enter the auth token when prompted.
Learn more in the official documentation ↗
1{
2 "inputs": [
3 {
4 "type": "promptString",
5 "id": "agent-handler-auth",
6 "description": "Agent Handler AUTH_TOKEN", // "yMt*****" when prompt
7 "password": true
8 }
9 ],
10 "servers": {
11 "agent-handler": {
12 "type": "stdio",
13 "command": "npx",
14 "args": [
15 "-y",
16 "mcp-remote@latest",
17 "https://ah-api-develop.merge.dev/api/v1/tool-packs/{TOOL_PACK_ID}/registered-users/{REGISTERED_USER_ID}/mcp",
18 "--header",
19 "Authorization: Bearer ${input:agent-handler-auth}"
20 ]
21 }
22 }
23}Whether you're an engineer experimenting with agents or a product manager looking to add tools, you can get started for free now