Connect your AI Agents to Ordinal in minutes

Merge lets you securely connect your agents to Ordinal and thousands of tools instantly

Available tools

get_linkedin_follower_growth

Retrieve follower counts over time for a connected LinkedIn profile, as one data point per recorded day. Use listschedulingprofiles to find the profile ID. For per-post engagement instead, use getlinkedinpost_analytics. Not paginated.

get_linkedin_post_analytics

Retrieve per-post LinkedIn metrics for a connected profile: impressions, reactions, comments, shares, clicks, video views, engagement rate, and earned media value. Each row links back to its Ordinal post when it was published from Ordinal. Use listschedulingprofiles for the profile ID.

get_x_follower_growth

Retrieve follower counts over time for a connected X profile, as one data point per recorded day. Use listschedulingprofiles to find the profile ID. For per-post engagement instead, use getxpost_analytics. Not paginated.

get_x_post_analytics

Retrieve per-post X metrics for a connected profile: impressions, likes, replies, retweets, quotes, bookmarks, engagement rate, and earned media value. Each row links back to its Ordinal post when it was published from Ordinal. Use listschedulingprofiles for the profile ID.

get_analytics_cpm

Read the workspace's cost-per-mille values per platform. These are the multiplier behind the emv figure on every post-analytics row (impressions / 1000 * CPM), so read this to know what an earned-media-value number assumes.

update_analytics_cpm

Set the workspace's cost-per-mille values, one or more platforms at a time. This retroactively changes the emv figure reported by getlinkedinpostanalytics and getxpostanalytics for every post, so read getanalyticscpm first.

list_post_approvals

List the approval requests on a post, showing who was asked, who has signed off, and which requests block publishing. Use list_posts to find post IDs. Not paginated.

create_approvals

Ask one or more workspace members to approve a post, optionally with a note, due date, and a blocking flag that stops publishing until they sign off. Call listusers for userIds and listposts for the postId. Members who already have an open request come back under existingApprovals.

delete_approval

Withdraw an approval request from a post. If it was blocking, the post can publish again. Use listpostapprovals to find approval IDs.

list_post_comments

List the team's comments on a post, oldest first, with who wrote each one. These are internal review comments, not comments on the published social post. For comments anchored to specific draft text, use listpostinline_comments. Not paginated.

create_post_comment

Add an internal comment to a post for the team to see. To notify someone, mention them as '@Display Name' using an ID from listusers. Use listposts to find post IDs. This does not comment on the published social post.

delete_comment

Delete an internal comment from a post. Use listpostcomments to find comment IDs.

list_post_inline_comments

List inline comment threads on a post, each anchored to a highlighted piece of draft copy, with its replies and whether it is resolved. Filter by channel or resolved state. For post-level comments instead, use listpostcomments. Not paginated.

list_company_workspaces

List every workspace in the company. Requires a company API key, not a workspace key. Returns the workspace IDs that getcompanyworkspace, listworkspaceapikeys, and createworkspaceapikey take. Not paginated.

create_company_workspace

Create a new workspace in the company, optionally seeding it with members. Requires a company API key. Returns the new workspace ID, which createworkspaceapi_key takes to mint a workspace key for it.

get_company_workspace

Retrieve one workspace in the company by ID, including its timezone. Requires a company API key. Use listcompanyworkspaces to find workspace IDs.

list_workspace_api_keys

List the API keys issued for one workspace, with their names and last-used times. The key values are never returned, only a masked hint. Requires a company API key. Use listcompanyworkspaces to find workspace IDs. Not paginated.

create_workspace_api_key

Mint a new API key for one workspace. Requires a company API key. The key value is returned once here and never again, so store it immediately. Use listcompanyworkspaces to find workspace IDs.

list_post_engagements

List the likes, comments, and reposts queued on a post for teammates' profiles to perform after it publishes, with their delays. Use list_posts to find post IDs. Not paginated.

create_post_engagements

Queue likes, comments, or reposts that teammates' profiles perform automatically after a post publishes. Call listengagementprofiles for profileIds, a different set from the scheduling profiles. Comment and Repost need copy and delaySeconds; Like must omit both, and may set reactionType on LinkedIn only.

update_engagement

Change a queued engagement's comment text, delay, profile, or LinkedIn reaction. Only the fields you pass change. Use listpostengagements to find engagement IDs and listengagementprofiles for profileIds.

delete_engagement

Remove a queued engagement so that profile will not like, comment, or repost when the post publishes. Use listpostengagements to find engagement IDs.

list_ideas

List unscheduled ideas, newest first. Filters by channel, profile, label, and creation date are applied by Ordinal. Ideas have copy but no publish time. Use addideatocalendar to turn one into a post. Cursor-paginated via pageinfo.

create_idea

Create an unscheduled idea with copy for LinkedIn, X, TikTok, or YouTube Shorts. Ideas have no publish time; use addideatocalendar to schedule one. Call listschedulingprofiles for profileIds and listlabels for labelIds. Returns the new idea ID.

get_idea

Retrieve one idea with its per-channel copy and media. Use list_ideas to find idea IDs.

update_idea

Update an idea's title, labels, campaign, notes, or per-channel copy. Only the fields you pass change. Use listideas to find idea IDs, listschedulingprofiles for profileIds, and listlabels for labelIds.

archive_idea

Archive an idea, moving it out of the idea list into the trash. Use unarchiveidea to restore it, and listideas to find idea IDs.

unarchive_idea

Restore an archived idea back to the idea list. Use list_ideas to find idea IDs.

add_idea_to_calendar

Promote an idea to a calendar post on a given date, carrying its copy across. Returns the new post ID, which getpost and schedulepost take. This does not publish the post. Use list_ideas to find idea IDs.

list_invites

List workspace invitations that have not been accepted yet, with who sent each one. For members who have already joined, use list_users instead. Not paginated.

create_invite

Invite someone to the workspace by email. Ordinal emails them immediately, so only call this for a real teammate. Check listinvites and listusers first to avoid a duplicate invitation.

delete_invite

Revoke a pending workspace invitation so the link stops working. Use list_invites to find invite IDs.

list_labels

List the labels defined in the workspace, with their IDs and colors. Call this before createpost, updatepost, createidea, or a labelIds filter on listposts, since label IDs are workspace-specific and cannot be guessed. Not paginated.

create_label

Create a workspace label that can then be assigned to posts and ideas. Returns the new label ID for use as a labelIds value. Check list_labels first so you do not duplicate an existing label.

delete_label

Delete a workspace label. It is removed from every post and idea that carried it. Use list_labels to find label IDs.

get_linkedin_mention_format

Resolve a LinkedIn vanity name into the '@Name' string LinkedIn post copy needs to tag a person or company. Call this before writing copy with an @ mention, since the URN cannot be guessed. A vanity name may match a person, a company, or neither, so both fields can be null.

get_linkedin_profile

Look up a LinkedIn person or company by URN and get their display name, vanity name, and avatar. Use getlinkedinmention_format when you have a vanity name and need the URN, which is the reverse of this lookup.

search_instagram_locations

Search Instagram locations by name for the pageId that tagging a location on an Instagram Feed or Reel post needs, e.g. 'Ferry Building San Francisco'. There is no other way to obtain a pageId.

list_posts

List posts on the Ordinal calendar, newest first. Filters by status, channel, profile, label, publish date, and creation date are applied by Ordinal. Use this to browse or filter; use getpost for one post's full content. Cursor-paginated via pageinfo.

create_post

Create a post with copy for one or more channels. Call listschedulingprofiles for profileIds, listlabels for labelIds, and uploadfilefromurl for media assetIds first. Use getlinkedinmentionformat for '@Name' mentions. Returns the new post ID. The echo is partial: labels, publishAt, notes and the channel profile may read back empty, so treat getpost as authoritative.

get_post

Retrieve one post with its full per-channel copy, media, labels, and schedule. Use listposts to find post IDs. For a post's draft history instead, use listpost_versions.

update_post

Update a post's title, publish time, status, labels, notes, or per-channel copy. Only the fields you pass change. Use listposts to find post IDs, listschedulingprofiles for profileIds, and listlabels for labelIds. Labels are not echoed back: confirm them with list_posts and a labelIds filter.

archive_post

Archive a post, moving it off the calendar into the trash without publishing it. Use unarchivepost to restore it, and listposts to find post IDs.

unarchive_post

Restore an archived post back onto the calendar. Its schedule is not restored, so follow with schedulepost if it should publish. Use listposts to find post IDs.

schedule_post

Queue a post to publish, optionally at a new time. This makes the post go live on the connected social accounts at that time. Use unschedulepost to pull it back to a draft, and listposts to find post IDs.

unschedule_post

Remove a post from the publishing queue and return it to a draft status. The copy is kept. Use schedulepost to queue it again, and listposts to find post IDs.

list_post_versions

List saved draft versions of a post's copy, grouped by channel, with who edited each one. Returns metadata only, so it is far cheaper than reading every version. Pass a version ID to getpostversion for the text. Pagination is per channel, so send the same channel with a cursor.

get_post_version

Read the plain-text copy of one saved draft version for one channel. Use listpostversions to find version IDs and which channels have history. Cheaper than get_post when you only need the text of a past draft.

list_scheduling_profiles

List the connected social accounts posts can publish from, with the profile IDs that createpost, updatepost, create_idea, and the analytics tools require. Call this first when composing a post: profile IDs are workspace-specific and cannot be guessed. Not paginated.

list_engagement_profiles

List the connected social accounts that can like, comment, and repost on behalf of the team, with the profile IDs createpostengagements and updateengagement require. These are a different set from listscheduling_profiles. Not paginated.

list_slack_webhooks

List the Slack channels connected to the workspace, with the slackWebhookId values createslackboost and updateslackboost require, and whether each notifies by default. Call this before creating a boost. Not paginated.

list_post_slack_boosts

List the Slack notifications queued on a post, which channel each goes to, and whether Ordinal added it automatically. Use list_posts to find post IDs. Not paginated.

create_slack_boost

Queue a Slack notification asking a channel to go engage with a post when it publishes. Call listslackwebhooks for slackWebhookId and list_posts for the postId. Returns the new boost ID.

get_slack_boost

Retrieve one Slack boost with its message text and target channel. Use listpostslack_boosts to find boost IDs.

update_slack_boost

Change a Slack boost's message text or move it to a different channel. Only the fields you pass change. Use listpostslackboosts to find boost IDs and listslack_webhooks for slackWebhookId values.

delete_slack_boost

Remove a Slack boost so no notification is sent for the post. Use listpostslack_boosts to find boost IDs.

list_post_subscribers

List the workspace members subscribed to notifications about a post, and who added each of them. Use list_posts to find post IDs. Not paginated.

add_post_subscribers

Subscribe workspace members to notifications about a post. Call listusers for userIds and listposts for the postId. Read BOTH result lists: a member already subscribed comes back under existingSubscribers with createdSubscribers empty, which is common because the post's creator is auto-subscribed.

delete_subscriber

Unsubscribe a member from a post's notifications. Use listpostsubscribers to find subscriber record IDs, which are not the same as user IDs.

upload_file_from_url

Import an image or video from a public URL so it can be attached to a post. Returns an upload job, not an asset: poll getuploadstatus until the status is 'ready', then use the assetId it returns in a channel's assets array on createpost or updatepost.

prepare_file_upload

Reserve an upload slot and get signed credentials for sending local file bytes to Ordinal yourself, as a multipart POST to the returned uploadUrl. It does not transfer any file. When the media already lives at a URL, use uploadfilefrom_url instead, which needs no second request.

get_upload_status

Check an upload job and read its assetId once processing finishes. Status is 'pending' or 'processing' while Ordinal works, 'ready' when the assetId is available for a post, and 'failed' or 'expired' otherwise. Use the ID from uploadfilefromurl or preparefile_upload.

validate_credential

Validate the Ordinal API key with one lightweight read. Checks a workspace key against the workspace endpoint, or a company key against the company workspace list.

list_webhooks

List the webhooks configured in the workspace, with their delivery URLs and subscribed event topics. Use get_webhook for one webhook's custom headers. Not paginated.

create_webhook

Create a webhook that POSTs Ordinal events to a URL. Subscribe to topics such as post.published, post.publishfailed, post.approval.requested, or invite.accepted. Returns the new webhook ID. Check listwebhooks first so you do not duplicate an existing subscription.

get_webhook

Retrieve one webhook with its delivery URL, subscribed topics, and custom headers. Use list_webhooks to find webhook IDs.

update_webhook

Change a webhook's name, delivery URL, subscribed topics, description, or custom headers. Passing topics or headers replaces the whole list, it does not merge. Use list_webhooks to find webhook IDs.

delete_webhook

Delete a webhook so Ordinal stops delivering events to it. Use list_webhooks to find webhook IDs.

get_workspace

Retrieve the workspace this API key belongs to: name, slug, and the IANA timezone that publishDate values and the calendar are expressed in. Read this before interpreting or setting publish dates.

list_users

List workspace members with the user IDs that createapprovals, addpostsubscribers, and '@Name' comment mentions require. For people who have been invited but have not joined, use listinvites. Not paginated.

View all tools by creating a free accountSee more tools

How to set up Merge Agent Handler

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}
11
Copy Code

Open 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}
Copy Code
Copied!

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  }
Copy Code

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}
Copy Code

FAQs on using Merge's Ordinal  MCP server

FAQs on using Merge's Ordinal  MCP server

Explore other MCP servers built and managed by Merge

make
Make
metabase
Metabase
excel
Microsoft Excel
microsoft_graph_security
Microsoft Graph Security
microsoft_planner
Microsoft Planner
microsoft_teams
Microsoft Teams
microsoft_teams_gcc
Microsoft Teams GCC High
miro
Miro
monday
Monday.com
n8n
n8n
netsuite
NetSuite
nextech
Nextech Practice+
nooks
Nooks
notion
Notion
npi_registry
NPI Registry
okta
Okta
onedrive
OneDrive
onedrive_gcc
OneDrive GCC High
onenote
OneNote
oracle_hcm
Oracle HCM
oracle_sales_cloud
Oracle Sales Cloud
oracle_scm
Oracle SCM
oura
Oura
outlook
Outlook

Ready to try it out?

Whether you're an engineer experimenting with agents or a product manager looking to add tools, you can get started for free now