Servers Changes Log Check Why How it works GitHub

Transparency log · MCP tool definitions

Every MCP server's tools, on the record.

Your AI client trusts the tool descriptions an MCP server sends it — and a server can change them after you approved it. HISTOR keeps a public, signed record of what every remote MCP server in the official registry advertised, and tells you the day it changed.

Remote endpoints: it lists tools and never calls one. Registry packages: bounded canary calls run inside the isolated sandbox. It never says a server is safe — it tells you what was said, and when.

DRAG TO ORBIT
SIM
—

WebGL is unavailable here. The picture is the log itself: each label is a leaf, leaf hashes climb a Merkle tree, and a signed tree head seals the root.

—
Registry endpoints
last crawl
—
Tool sets pinned
current
—
Changes
last 7 days
—
Labels in the log
all time
—
Last signed tree head
UTC

What HISTOR is for

Tool descriptions are instructions. They should not change behind your back.

The problem

A server can change what your model reads

When you connect an MCP server, its tool descriptions go straight to the model as instructions. A server can pass your review with harmless descriptions and change them next week — one added sentence is all a prompt injection needs, and most clients never ask you again.

What HISTOR does

It keeps the public record

Every day HISTOR reads what each remote (streamable-HTTP) endpoint in the official MCP registry advertises, fingerprints it, signs what it saw and appends it to a log that can only grow. When a server's definitions change, the change gets a date and a diff.

What you get

A second pair of eyes you can check

Look up any server before you trust it. Paste what your client received and learn whether everyone else sees the same thing. Follow changes in a feed, or put a badge in your README. Every answer is signed, so you can verify it instead of believing it.

Who it is for

People who use MCP serversin Claude, Cursor or any client — check a server before you connect it, and again when it changes.
Agent builderswhose agents connect to servers on their own — call /check before trusting a tool set.
Registries and directoriesthat want more than stars and download counts — show when a listing's tools last changed.
Server authorswho want to show a stable, documented history — add the badge, and every change you ship is dated in public.

Four words used on this page

Tool definitions
The name, description and input schema of each tool a server offers — the text your model reads.
Pinned
HISTOR has recorded a fingerprint (digest) of the exact definitions it saw, so any later change is detectable.
Label
One signed statement about one observation: what was seen, what matched, whether it changed. Anyone can verify it offline.
Signed tree head
The log's signed summary after each crawl. Comparing two of them proves nothing was deleted or rewritten in between.

AutomateSocials

net.automatesocials/mcp · https://automatesocials.net/mcp

Write, schedule and publish social posts to Facebook, Instagram, X, LinkedIn and TikTok.

First observed
2026-10-23
Unchanged since
2026-10-23
Last observed
2026-10-23
Observations
1
Changes on record
Tools
76

Tool definitions as last observed (76)

  • add_knowledge — Stores text the workspace will want again: product details, positioning, a policy, notes from a call. Use it when the user tells you something factual worth keeping, rather than only using it in this conversation. Give it a title so it can be recognised later.
  • add_knowledge_from_file — Reads an already uploaded PDF, image or text file and stores what it says so it can be searched. Give it a media id from an upload.
  • add_knowledge_from_url — Fetches a web page or a PDF at a URL and stores its text so it can be searched later. Use it for the workspace's own site, a product page, a press release. It reads the page as it is served, so a page that needs a sign-in will not work.
  • analyze_website — Reads the project's website and fills in what it does, who it is for, its keywords and its voice. Use it when the brand kit is empty and you know the address, instead of interviewing the user about things their own site already says. It fills only empty fields unless you say otherwise.
  • buy_credits — Returns a Stripe checkout link for a credit pack. Nothing is charged until the user opens the link and pays; the credits are added to their account as soon as Stripe confirms the payment. Packs: starter (50 credits, $4.99), growth (200, $14.99), power (500, $29.99), power_plus (1000, $49.99). Credits never expire. Give the user the link; never claim the credits were added.
  • cancel_campaign_posts — Pauses a campaign and cancels every post of it that has not gone out yet. Posts already published are untouched: they exist on the platform.
  • check_projects — Counts what each of your projects holds and checks that nothing crosses between them: posts, accounts, pages, campaigns, workflows, knowledge and media. Run it after adding a project, or whenever something looks like it belongs somewhere else.
  • choose_facebook_page — Sets which Facebook page this project posts to, when its Facebook connection holds several. The other pages are removed from this project only. Ask the user which page belongs to this project; list_subaccounts gives the choices.
  • complete_upload — Call after PUTting a file to the presigned uploadUrl: checks the file arrived and records its size and type. Says so if the file is not there yet.
  • connect_account — Produces a link the user opens to connect a social account. Authorization happens on the platform, so give them the link and wait; the account appears in list_accounts once they have finished. Use this when an account they want is missing, or when one is marked as needing a reconnect.
  • connect_instagram — Connects an Instagram business account found by list_instagram_accounts. With only one available, instagramId can be left out. Replaces a different Instagram account already on this project, as every connection does.
  • create_post — Publishes a post, or schedules one to be published. This is not how a draft is saved: use save_draft for that, which needs no confirmation. Publishes immediately by default; pass scheduledTime for a specific moment, or useNextFreeSlot to take the next opening in the calendar. Use variants to word the same post differently per platform. To publish something you saved with save_draft, pass its postI …
  • create_presigned_upload_url — Returns a presigned URL for uploading a local file directly to storage. PUT the file bytes to uploadUrl with the same Content-Type, call complete_upload with the mediaId, then use mediaId or publicUrl when creating a post.
  • create_slots — Adds recurring weekly openings to the calendar. Times are in the workspace timezone. Adding more slots than there is content for produces gaps, so ask how often the user actually wants to post.
  • create_workflow — Sets up work that repeats on its own: read a source, write a post, make a picture, publish it. Steps run in the order given. It is created paused and does nothing until start_workflow turns it on, so making one is safe. Use it when the user asks for something to happen daily, weekly or at a set time.
  • delete_campaign — Removes a campaign and its plan. Posts it already produced are kept - they are posts like any other, and some may be published.
  • delete_knowledge — Removes a stored item and everything derived from it. Name what you are about to delete first.
  • delete_post — Deletes a draft, or cancels one that has not gone out yet. A post that is already published cannot be deleted here: it exists on the platform, and removing our record would not remove it.
  • delete_project — Permanently deletes the current project and everything in it: posts, scheduled posts, connected accounts, knowledge, workflows, campaigns and its API keys. Credits are not affected. Only the owner can do it, it cannot be the only project, and confirmName must be the project name exactly as the user typed it. Before calling, tell the user what will be lost and have them type the name. It cannot be …
  • delete_schedule — Cancels a post that has not gone out yet. A post that is already published cannot be cancelled: the platform has it and we do not.
  • delete_slot — Removes one recurring opening. Posts already scheduled into it keep their time.
  • delete_workflow — Removes a workflow and its run history. Posts it already published are untouched.
  • disconnect_account — Removes a connected account and cancels anything still scheduled to it. Say how many posts that is before asking the user to confirm.
  • edit_campaign_plan — Adds posts to a campaign plan, removes planned ones, or rewrites their theme and angle. This is how you add "one more post about X" without planning the campaign again. Posts already written keep their words - use edit_post for those - and removing one that is already written is refused.
  • edit_post — Changes a post that already exists: its words, its pictures, the platforms it is for, or any combination. Pass only what changes; everything else stays. This is how you rewrite a draft or swap its image - do not write a second copy. Read it with get_post first when you are changing the words, since you cannot rewrite what you have not read. Works on drafts and on posts that are scheduled but have …
  • estimate_image_cost — Says what generating would cost in credits, without generating. Use it when the user asks what something would cost. You do not need it before generating: the confirmation prompt already states the price.
  • estimate_scrape_cost — Says what reading someone’s posts would cost in credits, without reading anything.
  • estimate_source_cost — Says what youtube, tiktok, audio or research would cost in credits, without reading anything. Article, PDF and plain text pages are free: use add_knowledge_from_url or add_knowledge for those instead.
  • estimate_video_cost — Says what a video of a given length and resolution would cost in credits, without making one. Use it whenever the user has not agreed to a price, since video is the most expensive thing here.
  • generate_image — Makes a picture from a description and stores it, ready to attach to a post. Call it as soon as you know what the picture should be: the user is asked to confirm the spend before it runs, with the price, so you do not need to ask them first. Describe the subject and the setting in the prompt; the model cannot see the brand kit, so put anything from it that matters into the words. If the project ha …
  • generate_video — Makes a short video with its own audio and stores it, ready to attach to a post. It takes a few minutes: over MCP or the API it may answer with status "processing" and a jobId instead of a mediaId; then call get_video_status with that jobId until it gives the mediaId, and only then save the draft. Say what it will cost first; video is the most expensive thing here and is charged by the second. Pas …
  • get_brand_kit — The workspace's voice, audience, rules and example posts, which everything written for it follows. Your instructions already carry the voice and the rules (in the app and over MCP alike), so call this for the full kit: when the user asks what is set, when you are about to change something, or when you need the example posts.
  • get_campaign — One campaign in full: every planned post with its date, kind (educational, promotional, engagement, proof, behind_the_scenes, news), theme and angle, and which of them have been written. Read it before changing anything about the campaign.
  • get_credits — Returns the credit balance for the workspace. Credits pay for generated images, video, transcription and scraping; writing, publishing and scheduling are free on paid plans.
  • get_media — Returns the stored details of one media asset, including whether its bytes have arrived.
  • get_post — The full text of one post, with its pictures, its per-platform wording and its state. Call it before changing or rewriting a post: list_posts only shows the first line of each, and working from that means working from a fragment.
  • get_post_analytics — The numbers for one published post on every network it went to: the latest reading and every earlier one, so you can say whether it is still growing. Pass refresh: true to read the networks again now (at most every ten minutes); leave it off to use what was already collected.
  • get_post_status — Returns where a post stands on each platform, including the public link once it is live. Instagram and TikTok process uploads in the background, so a post can be accepted and not yet visible.
  • get_tiktok_settings — Reads, from TikTok, what the connected TikTok account may post: the account name, the privacy levels it offers, whether comments, Duet and Stitch are allowed, and the longest video. Call it before publishing to TikTok, show the user the account name, and ask them to choose the privacy level (there is no default), whether to allow comments (and Duet and Stitch for video), and whether the post promo …
  • get_user — Returns the signed-in user, the active workspace, the plan and the credit balance. Call this first to confirm which workspace you are acting on.
  • get_video_status — Whether a video generate_video started is ready. Pass the jobId it returned. When it is done this gives the mediaId to attach to a post with save_draft, edit_post or create_post. If it is still being made, wait about a minute and ask again; never generate it a second time and never make up a media id.
  • get_workflow — One workflow in full: every step with its settings, its schedule, and how the last runs went. Read it before changing anything, since update_workflow replaces the steps you pass and you cannot keep what you have not seen.
  • get_youtube_settings — Reads, from YouTube, the connected channel a Short would go to: its name and handle, who can be chosen to watch (public, unlisted, private) and the longest Short (3 minutes). Call it before publishing to YouTube, show the user the channel, and ask them for a title (at most 100 characters), who can watch it, and whether it is made for kids. Pass their answers in create_post as platformTargets.youtu …
  • learn_voice_from_published — Fills the brand kit's example posts from what this workspace has already published. Use it when the brand kit has no examples and there is a publishing history, instead of asking the user to paste posts they have already sent.
  • list_accounts — Lists the social accounts connected to this workspace, with their platform, handle and whether they are currently usable. Call this before writing or scheduling, so you only offer platforms that are actually connected.
  • list_campaigns — The campaigns in this project, what each is for, and how far through it is.
  • list_image_models — The image models available, what each costs in credits, and which one this workspace uses by default. Call it when the user asks what you can make images with, or before generating if they might care about the price.
  • list_instagram_accounts — Lists the Instagram business accounts linked to the connected Facebook pages, the ones this project can post to. Facebook must be connected first. Follow with connect_instagram.
  • list_knowledge — Lists what this workspace has stored, with whether each item is searchable yet. Use it when the user asks what you know about them, or when a search came back empty and you want to say why.
  • list_posts — Lists posts in this workspace, newest first, with the first line of each. Use it before writing to check what has already been said. The text here is shortened: to work on a post, read it with get_post first.
  • list_schedules — Lists posts waiting to go out, soonest first.
  • list_scrapers — The networks this server can read posts from, and what each costs per result. Call it when the user asks whether you can look at a competitor.
  • list_slots — Lists the recurring weekly openings this workspace publishes in, and which of the coming ones are already taken. Read this before scheduling, so posts land in the rhythm the user already chose.
  • list_subaccounts — Lists the pages, organizations or boards an account can publish to. Facebook posts go to a page and LinkedIn can post as a company, so this is where the id for those comes from.
  • list_top_posts — Ranks published posts by how they did: views, likes, comments, shares, reach, saves, or engagement (likes + comments + shares + saves). Each network a post went to is ranked on its own. Numbers are the ones already collected (an hour, a day and a week after publishing, then daily for a month); nothing is fetched from the networks. Use it for "which post worked", "what did best on LinkedIn this mon …
  • list_video_models — The video models available, what each costs per second at each resolution, and how long a clip can be. Call it when the user asks whether you can make video.
  • list_workflows — The workflows in this project, what they do, when they next run, and how the last run went. Call it when the user asks what is running on its own.
  • next_available_slot — Returns the next free opening in the calendar, without taking it. Use it to tell the user when a post would go out before scheduling it.
  • noop — Verifies the connection end to end. Returns the caller identity, the channel it arrived on, and the server time. It is for someone checking that an API key or an MCP setup works, and it does nothing else: never call it as a step in doing what the user asked.
  • pause_campaign — Stops a campaign writing any more posts. Posts already written keep their place in the calendar; cancel them individually if they should not go out.
  • plan_campaign — Plans a run of posts around one goal: what each post is for, its theme and its angle, spread over the days the project posts on. It writes nothing and publishes nothing - the plan is one line per post, to be read and changed before anything is written. Use this when the user wants a month of content, a launch, or anything with more than a couple of posts behind one idea.
  • read_source — Turns a YouTube video, a TikTok, an audio file, or a research question into text to write from. sourceType youtube or tiktok take a video url and read its spoken transcript (English captions for YouTube; TikTok's own captions when it has them, speech-to-text otherwise). sourceType audio takes a url to a recording and transcribes it. sourceType research takes a question and answers it from a live w …
  • run_workflow — Runs a workflow immediately, whatever its schedule says, and reports what each step did. Use it to show the user what their workflow actually produces before leaving it to run on its own.
  • save_draft — Saves a post you have written so it appears under Drafts and can be published or scheduled later. Use it whenever you write a post the user has not asked you to publish yet, instead of leaving it in the conversation: a draft in the chat is lost, a saved one is not. Always name the platforms it is for, and attach any picture you made for it. To change something that already exists, use edit_post ra …
  • scrape_posts — Reads recent posts from a public profile on Instagram, Facebook, LinkedIn, TikTok or X, and keeps them so patterns across weeks can be seen. Use it to look at a competitor before writing, or as the first step of a workflow. It costs credits per post read, so say what it will cost first.
  • search_knowledge — Searches what this workspace has stored: notes, pages, documents, product details. Use it before writing anything factual about them, rather than guessing or asking. It searches by meaning, so ask in whatever words the user used. Returns nothing when the workspace has stored nothing, which is worth saying rather than working around.
  • set_default_image_model — Sets which model this workspace generates with unless told otherwise. Use it when the user says they want a particular one from now on.
  • start_campaign — Turns a campaign on. Its posts are written a couple of days before each one goes out and land in the calendar as scheduled, where they can still be read, edited or cancelled. Posts with pictures spend credits as they are written. Tell the user how many posts and roughly how many credits before calling this.
  • start_workflow — Turns a workflow on. From then on it runs to its schedule and publishes without asking again, so make sure the user has seen what it does. Use stop_workflow to pause it.
  • stop_workflow — Pauses a workflow so it stops running on its own. Nothing is deleted and it can be started again.
  • update_brand_kit — Records what the workspace sounds like. Pass only the fields you are changing; anything you leave out is kept. Example posts matter most: ask for two or three things they actually published, since those define the voice better than adjectives do. Use this whenever the user tells you something about their voice, audience or rules, rather than remembering it for one conversation.
  • update_campaign — Changes how a campaign runs: whether its posts get a generated picture, whether it uses the calendar slots, how many days ahead it writes, or its name. Pass only what changes. Pictures apply to the posts not yet written and cost a credit each at the cheapest model - say the number before turning them on.
  • update_schedule — Changes when a post goes out, or takes it off the calendar and leaves it as a draft. Pass scheduledTime for a specific moment or useNextFreeSlot to take the next opening. A post that has already gone out cannot be moved.
  • update_workflow — Changes a workflow that already exists: its steps, its name, or when it runs. Pass only what changes. Call get_workflow first when you are changing the steps, since the list you pass replaces the ones that are there. Its run history is kept.
  • upload_media_from_url — Downloads a publicly reachable file into storage and returns a stable URL to use in posts. Use this for images or video that already live on the web.
  • write_campaign_posts — Writes the next few posts of a campaign immediately instead of waiting for their lead time, and schedules them at their planned dates. Use it to show the user what the plan actually produces.

The signed observations, every earlier tool set and a diff of each change: this page with scripts on, or /api/v1/servers/01745e70e3f59feb.

Read → digest → label → append → sign → compare

How the log works

Six steps, every one of them checkable by someone who does not trust HISTOR. The only thing you have to take on faith is that the observation happened when the label says it did — and the log makes it impossible to change that story afterwards.

01

Read

Remote endpoints in the official MCP registry: initialize, then tools/list, drained across every page; no tool is called, and private addresses are refused before the connection opens. npm and PyPI packages: installed and started in the sandbox described below, with no route out.

02

Digest

The tool set is reduced to name, description, input and output schema, sorted by UTF-16 code units and hashed over its RFC 8785 canonical form. Anyone holding the same tools gets the same digest — which is what makes a comparison possible.

03

Label

Four MTL/1 methods, one signed AWR/2 document each: what was observed, what the WARDEN pattern set matched, whether the definitions changed since the last label, and whether the name is on a threat list. No score, ever.

04

Append

Every label becomes a leaf of an RFC 9162 Merkle tree: leaf hash = SHA-256(0x00 ‖ JCS(label)). The label you download is the leaf input, so you can recompute its hash yourself.

05

Sign

After each crawl HISTOR signs a tree head: the size and the root. Keep yesterday's head; ask for a consistency proof to today's; if anything was removed or rewritten, the proof fails.

06

Compare

Each day a continuity label compares the new digest with the last one. Equal: "unchanged since". Different: a change, with the date and a per-tool diff. A client that checks what it received adds the view no crawler has.

Where an npm or PyPI package is run

Test conditions

A package observation is true for these conditions, and no others. Every package page names the exact image it ran in and any configuration it was given.

System

Linux x86_64, inside gVisor (runsc): the package talks to a kernel written for sandboxing, not to the host's. An unprivileged user, no capabilities, a read-only root.

Runtimes

npm packages in histor-node:22, PyPI packages in histor-python:3.12: the official node:22-bookworm-slim and python:3.12-slim images plus bash, git, Python 3 or Node 22 and a Java 21 runtime — never Docker — built when a sandbox host is installed. A package whose Requires-Python excludes 3.12 runs on histor-python:3.13 or 3.14; one that requires a newer Node runs again on histor-node:24. The exact image a package ran in is on its page.

Install

npm with --ignore-scripts, then the install scripts in a traced stage of their own. PyPI: wheels only — a package that ships only source is reported, never built.

Network

No route out. Every name the package looks up resolves to HISTOR's own traps, which record what was sent and forward nothing. A server that needs the internet to start shows that here.

Secrets

None are real. Decoy credentials sit in HOME and a decoy .env in the working directory. A variable the package says it needs gets a placeholder; where the placeholder was sent is recorded.

Limits

512 MB of memory, one CPU, 64 MB of /tmp. 360 s to install, 150 s to start and answer; up to 15 tools called once each with canary arguments, 8 s per call.

Configuration

Only names: required variables its registry entry declares or that it printed when it exited, and a start argument such as serve when its usage text offers one. Never a value from anyone else.

What a label does not say

The profile HISTOR implements forbids the words safe, secure, audited, certified, approved and trusted. Here is why, in the terms of what the log can and cannot show.

Not a safety rating

A pattern match is a reason to read a definition, not a finding. Three of the four methods can never return fail. There is no score to rank by, because no score HISTOR could compute would mean what a reader takes it to mean.

Not the code

Labels are about advertised text. A remote endpoint's source is never read and its tools are never invoked; a package runs only in the sandbox, against nothing real. A server can keep identical definitions and behave differently for real users; the log cannot see that, and says so inside every label.

A change is not an accusation

A version bump changes definitions too. A change is shown as a date and a diff, in amber, never red. What you do with it is yours: re-read, re-approve, or pin the old digest.

A package as run here, not on your machine

An npm or PyPI server is observed under the test conditions above: Linux, no internet, placeholder keys. One that needs Windows, a real account or the network may show fewer tools or none; its page says why it exited.

One operator, one key

Today one party runs the log. A second observer on another network is the next step, and any AIMarket hub can run one. Until then, what the key proves is who said it — not that it is true.

Behind a login, unseen

Endpoints that require authentication answer 401 to everyone without a key, including HISTOR. They are counted and listed as not observed, never dropped from the numbers.

For clients, registries and server authors

Use it

Before your agent trusts a server, send the tools it received. The answer is signed by the log's did:key and names the tree head it was given under.

curl -sS https://histor.modelmarket.dev/api/v1/check \
  -H 'Content-Type: application/json' \
  -d '{"endpoint":"https://example.com/mcp","tools":[ …tools/list result… ],"contribute":true}'
# -> {"type":"histor.check/v1","match":"same"|"different"|"previously-observed"|…,
#     "observed":{"unchangedSince":"…","changes":0}, "patternScan":{…}, "signature":{…}}

# README badge for your server
[![MCP tool defs](https://histor.modelmarket.dev/badge/<id>.svg)](https://histor.modelmarket.dev/s/<id>)

# Atom feed of every observed change
https://histor.modelmarket.dev/feed.xml
WARDENchecks definitions at connect
HISTORremembers what was advertised
THEMISadmits at publish
Hublists histor.check@v1
AWRthe signed format

Questions

Is this a marketplace listing?

No. The server list is the log's index: every remote endpoint in the official MCP registry, with what HISTOR could observe about it. Nothing here is for sale and nothing is ranked by quality.

Does HISTOR tell me a server is safe?

No, and it never will. It tells you what a server advertised, whether that changed, and which published patterns matched the text. Whether to trust the server is your decision — HISTOR makes sure you decide on the same facts as everyone else.

Why are so many servers "not observed"?

Most remote MCP endpoints require a login (they answer 401 to anyone without a key), some use the legacy SSE transport or need per-user values in the URL, and some are simply down. They stay on the list with the reason, so the numbers never hide them.

How do I check a server I already use?

Open the Check tab, paste the server's endpoint and the tools/list result your client received, and press Check. You get back, signed, whether HISTOR observed the same definitions — or different ones, or an older set.

How do I get a badge for my server?

Find your endpoint on the Servers tab, open it, and copy the Markdown snippet under the facts. The badge shows the date your definitions were pinned or last changed, and links to the full history.

Why should I trust HISTOR itself?

You do not have to. Every label and every tree head is signed with one published key; the Log tab proves in your browser that the log only grew; and the command-line auditor does the same from any machine. What remains is that one operator runs it today — a second, independent observer is the next step.

What does it cost?

Looking things up, the badges, the feed and /check are free. HISTOR also offers histor.check@v1 to the AIMarket Hub, so agents can reach it through the market.

I run an MCP server. What does HISTOR send it, and how do I opt out?

Once a day: initialize, notifications/initialized and tools/list — never a tool call, never a redirect followed, at most two connections per host, from a User-Agent that starts with histor/. To be left out, open an issue on the histor repository with your endpoint or host; it is then listed as not observed (operator-opt-out), with the reason, rather than silently dropped. Labels already in the log stay: the log only grows.