Skip to main content

Compare

Custom MCP server vs emisar

Building your own MCP server is a reasonable thing to do — and for a narrow surface, the right one. This is the honest version of what changes between the afternoon you ship the prototype and the quarter you spend making it safe to point an agent at production.

The prototype is the easy 20%

Wiring up tools/list and a handler that shells out is genuinely a few hours' work. If that's the whole job — one team, one target that's already an API, your existing auth and audit already cover it — build the adapter and move on; emisar would be overkill. The work that doesn't show up in the demo is everything between the model's request and a safe, attributable execution on a real host. That part is never done: every new host, pack, client, and edge case reopens the list, and it's your pager.

your-mcp-server.ts · an afternoon

server.tool("pg_kill", async ({ pid }) => {

  return ssh.exec(

    `psql -c "…terminate_backend(${pid})"`)

})

// then everything you still own:

//  validate pid · redact secrets

//  risk gate → human approval

//  audit: who · what · why

//  reconnect · orphans · per-user scope

//  OAuth + transport per client

postgres.yml · declared once

id: postgres.terminate_backend

kind: exec

risk: high   # → policy gates it

args:

  - name: pid

    type: integer

    required: true

execution:

  command:

    binary: psql

    argv: ["-tAc", "SELECT

      pg_terminate_backend({{ args.pid }})"]

Both run the same query — but the left drops an unvalidated ${pid} straight into a SQL string, one slip from injection; the right declares pid an integer the runner re-validates before psql ever sees it. That gap, plus the other 80% — redaction, approval, audit, reconnect — is what emisar ships once, for every host, pack, and client you add.

What you'd build and own

A capable team can build every row of this. The column on the left isn't "what custom servers lack" — it's the code you write, test, and carry. The column on the right is what emisar ships so you don't.

Argument validation

You build it

Reject undeclared args, coerce types, enforce bounds — and do it on the host, since the model's output is untrusted

emisar

Typed YAML schemas the runner re-validates before exec; argv arrays, never a shell string

Tool integrity

You build it

Your deploy pipeline is the only thing stopping a changed handler

emisar

Content-addressed packs; a changed SHA-256 blocks dispatch until an admin re-trusts

Host transport

You build it

Credentials and routing you design and secure

emisar

Outbound-only runners, single-use enrollment, revocable per-runner tokens — nothing listens on the host

Policy & approval

You build it

Conditional logic in code plus a homemade approval queue

emisar

Risk-tier defaults + per-action overrides, human approval, and standing grants that expire

Per-user access

You build it

Hand-rolled, and easy to get subtly wrong

emisar

Per-member runner scopes in UI, API, and dispatch; keys inherit the creator's scope at call time

Multi-client access

You build it

Auth and transport work per client (Claude, ChatGPT, Cursor, CLIs)

emisar

OAuth 2.1 remote MCP plus a stdio bridge, one catalog behind both

Output safety

You build it

Your redaction regexes, your output caps, your bug if one leaks

emisar

20+ built-in patterns plus your own, masked on the host before egress; output bytes clamped

Audit

You build it

Logs you design, store, and have to prove weren't edited

emisar

Hash-chained host journal (emisar audit verify), searchable cloud audit, NDJSON SIEM export

Failure modes

You build it

Reconnect, orphaned runs, leaked child processes — yours to handle

emisar

Run-state reconciled on reconnect; children reaped on disconnect; orphans marked, not lost

None of these are hard in isolation. They're a product because they have to hold together, forever, across every host and client you add.

What emisar costs you

Not buying the boring 80% isn't free either. The honest tradeoffs:

  • It's a vendor in your path. The control plane is hosted by us; there's no supported self-hosted or air-gapped deployment today (the source is available for evaluation, not production self-hosting). Your runner stays on your host, dials out, and keeps its own tamper-evident journal — and a host-side admission list lets an operator veto any action even if our cloud is wrong — but the dispatch decision still rides through our service.
  • It's opinionated. Actions are YAML packs, the policy model is risk-tiers-plus-overrides, the transport is MCP. If your workflow doesn't fit that shape, a server you control will fit it better than one you bend to.
  • It's finite on purpose. emisar exists to let an agent run a reviewed catalog, not arbitrary commands. If you want the model to do anything it can think of, that's raw SSH — and we wrote that comparison too.
  • It's another bill, and another vendor in your path. Team is $20 per runner per month, and you're putting a young product on part of your ops path. We try to earn it with the on-host guarantees above — and the runner stays useful even if our cloud is unreachable.

Build it yourself when

The surface is narrow, one team owns it, the target is already an API sitting behind your existing authorization and audit, and you don't expect to add hosts or clients. A small MCP adapter is exactly enough, and a second system would only be in the way.

Reach for emisar when

Tools reach real hosts, more than one agent or client needs access, security wants a reviewable action contract, operators want one approval and audit surface across the fleet, and you'd rather not own the failure modes above for the life of the project.

Skip building — and securing — your own MCP server.

emisar is the policy engine, approvals, audit trail, and runner trust you'd otherwise build and maintain yourself. Connect a runner and you're done.

Three runners. Seven-day audit. No credit card.