safe-mcp sign in

One safe door between your AI and everything it can touch.

Let an agent work the ads account, the CRM or the repo overnight, and let it learn the job the way a new colleague would. safe-mcp gives it what you would give a person: a number to be judged by, keys to some doors and not others, a logbook it cannot edit, and feedback from what actually happened.

Point Claude, Codex, Cursor or ChatGPT at one URL. First sign-in creates your account and one project.

one call, in the order it is written
the entry, as written
pending14:02:07.118 · ads.pauseCampaign
refused14:02:07.401 · outcome appended

Example, not real data.

It is 03:00 and an agent acting for Maria has just paused a campaign.

Nobody was watching. Three questions arrive with the morning coffee, and without a harness none of them has an answer.

was it allowed?Maria may pause campaigns and may not touch budgets. The agent ran on her token, so her rule held at 03:00 exactly as it does at noon.
what did it send?The full request is in the log, written before the answer came back, with the one-sentence reason the agent gave for it.
did it help?Cost per lead is read every twelve hours. If it went the wrong way after that pause, the next identical call is refused, with the evidence.

Example, not real data.

your ai clients
Claude
Codex
Cursor
+ any client or agent
safe-mcp gateway
https://api.safe-mcp.com/mcp/<project>
what the agent sees
meta.searchToolsfind the right tool
meta.callToolcall it, with a reason
meta.goalthe number to move
meta.recommendwhat worked, from your history
what happens to every call
loggedbefore anything is decided
checkedyour rules, in a fixed order
ran or refusedokrefused
your mcp servers
Marketing Reporting
Linear authorize →
Notion oauth
GitHub oauth
Sentry oauth
Context7 open
+ any http server

Marketing Reporting, Linear, Notion, GitHub, Sentry and Context7 are in the library and take two clicks to add. Anything else that speaks MCP over HTTP takes one JSON entry. the server library →

What the agent gets that a chat window never gives it.

A number to move. A memory of what it already tried. A brake on repeating what did not go well. A new hire gets all three from the team around them. An agent gets them from your own history, in one record.

  1. 1 · goalYou declare it in plain terms and name the read-only tool that measures it. The gateway reads a baseline immediately. A goal it cannot measure is refused before any work starts.
  2. 2 · gateThe agent works through the one URL. Each call is logged, then checked in a fixed order, then run or refused.
  3. 3 · measureThe number is read again every twelve hours and at the end of every session, so no write is left without a reading after it.
  4. 4 · bracketEvery write between two readings shares that interval's movement, toward the goal or away from it. The gateway cannot tell which write did it, so all of them carry it.
  5. 5 · adviseAdvice comes back as do, avoid, check, expect, each with its count and its last date. A write whose earlier runs sat in intervals that went the wrong way is refused, with the evidence.
the whole loop, and what it cannot claim →

Hand the agent the ads account, minus the budget field.

Access is a rule about a person: which servers, which tools on them, which arguments, and which values. An agent inherits the rule from whoever's token it runs on, so there is no second policy to keep in sync and nothing an agent can do that its person cannot.

A server nobody assigned you is invisible to you. Revoke a token and everything running on it stops at the next call.

presets, assignments and tokens →

who may do what
whoserverpreset
user dana@acme.coadsbudget-pinned
group reportingadsread-only

an agent has no row of its own. it runs on a person's token, so this table governs it at 03:00 too. a server with no assignment is invisible to everyone else.

Example, not real data.

The request is on the record before the answer exists.

Every call lands in the project's log with its full arguments first. Then the decision. Then the result. Refused and failed calls stay in the log exactly like the ones that ran.

Entries are only appended, never edited: not by the model, not by an admin. Next morning you argue about whether it was right, not about what happened.

the record, isolation and what fails how →

app.safe-mcp.com/history
history~1,284 events · / filters · esc closes
time server.tooloutcomems
just nowslack.postMessage pending
2m agoads.pauseCampaign refused 12 ms
4m agocrm.listSegments ok 181 ms
9m agosheets.appendRow failed 4.6 s
14m agometa.goal ok 1.2 s
Example, not real data. The real history page filters, expands any row, and exports the lot.

It stops before repeating what did not go well.

Before a write it can match to earlier calls, same tool, same shape of arguments, same goal, the gateway reads your own history. If the goal moved away from its target in the intervals those calls sat in, the call is refused and the evidence comes back inside the tool result: what matched, how many intervals, how thin the history is.

That is an observation, not a verdict, and the refusal says so. The agent is told to put it to you. Resend the same call with the acknowledgement tied to that evidence and it runs, stamped as acknowledged. Two limits: the check needs enough arguments to match on, and it has two seconds. Past either, the call goes ahead, stamped, never silently.

refused evidence gate

"ads.pauseCampaign" has been called this way before on this goal. The goal moved AWAY from its target over 2 of the 3 measurement interval(s) those calls sat in. Nothing about this call is invalid. This is disconfirming evidence from this account's own history. Put it to the user and let them decide.

acknowledgedEvidence: "e3f19c4a"

re-issue the call exactly as sent plus that acknowledgement and it runs, stamped evidenceGate: acknowledged.

Example, not real data. The gate answers inside the call, not on a screen.

Over weeks, it tells you what worked. With the numbers.

Every rule it hands an agent is compiled from calls that ran and readings that followed: do this, avoid that, check this, with the count and the last date underneath. A model writes the sentence; the count and the date come from the log.

Where there is no evidence the answer is "nothing yet", with the threshold that was not met. It does not fill a gap with something plausible.

what it tells your agent
do · strongsend follow-ups before noon

replies up · 41 actions (last 2026-08-21)

avoid · strongpausing brand-search on this goal

cost per lead up · 12 actions (last 2026-08-14)

check · suggestiveraising budget on weekends

confounded on review · association, not causal

observational, not causal

Example, not real data.

Why we built it.

We run agents on ad accounts ourselves, unattended, every morning. This gateway is what it took to be comfortable with that: a record we can read on Tuesday, a rule per person, and a number that says whether the work was worth doing. Everything on this site is live, except the secure plan, which is marked coming soon.

Start with one client and one server.

First sign-in creates an account and one project with Marketing Reporting already in it. A teammate skips all of that: they get a token, the config that comes with it, and their own history.