Install
$ agentstack add mcp-ricauts-servo ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Servo
[](https://github.com/ricauts/servo/actions/workflows/ci.yml)
An open-source, self-hostable AI-powered service desk. Email becomes tickets; AI agents triage them, draft every reply and work requests with real tools (SQL, device inventory, real GitHub repos/branches/PRs, live Azure queries), pause for human approval before anything risky, get an automated QA review afterwards — and everything feeds a KPI dashboard, including how many AI replies ship untouched.
Bring your own model — Anthropic, Z.AI GLM, or any OpenAI-compatible endpoint — or evaluate entirely offline with the built-in deterministic mock provider. Self-host it with real SSO (any OIDC IdP), per-requester data isolation, secrets encrypted at rest, and a first-run wizard that takes a clean install to a working desk in one screen.
> Status: production-ready for self-hosting. Fresh installs start clean (no demo data), sign in through your identity provider, and store secrets encrypted. Follow the [production checklist](#production-checklist) and read [SECURITY.md](SECURITY.md) before exposing an install to real users.
Features
- Tickets for humans and AI — assign any ticket to a human agent or to the AI resolver; the resolver works the ticket end to end.
- Automatic triage — new tickets are categorized, prioritized, and routed by an AI triage agent (toggleable in Settings).
- Tool-using resolver — the AI resolver operates a registry of built-in tools plus any custom ones you define: read-only and mutating SQL against a sandboxed ops database, device inventory lookups, password resets, GitHub read/commit/PR/merge operations, page screenshots, Azure resource listing, and cloud deployment plan/apply.
- Readable audit trail — a run is one entry in the ticket story: who acted, the outcome, the tools it used and who approved what. Unfold it and every step is there verbatim — folded by default so a ticket reads like a conversation, never truncated.
- Human-approval gates — each tool carries a risk level (LOW/MEDIUM/HIGH) and an editable requires approval policy. When the agent reaches a gated tool, the run pauses, an approval lands in the Approvals inbox, and the run resumes exactly where it left off after a decision. Rejections flow back to the agent, which adapts instead of retrying.
- Automated QA review — after a run that executed medium/high-risk tools, a QA agent reviews the transcript and issues a PASS/FAIL verdict; failures reassign the ticket to a human with an explanatory comment.
- KPI dashboard — open tickets, resolution times, first-response times, AI-vs-human resolution split, approval stats, ticket volume over 30 days, and AI reply acceptance (sent as-is vs edited vs discarded) so you can see exactly how much typing the AI is saving.
- BYOK with offline mock mode — plug in an Anthropic API key via Settings or environment variable, or run fully offline with the deterministic mock provider.
- API key pool with per-agent assignment and throughput metering — register multiple named credentials (any provider mix), assign one per specialized agent from the Agents page, and every model call is logged (tokens in/out, latency, key, agent). A throughput panel on Agents aggregates the last 7 days per key and agent.
- SLA targets with automatic escalation — per-priority response and resolution targets (editable in Settings). Every ticket carries live SLA state on the queue and detail views, the dashboard tracks breaches, and a scan escalates missed targets one tier up the group hierarchy — assigning the least-loaded eligible member and logging why. Schedule
POST /api/sla/scanto run it unattended. - Groups & escalation hierarchy — assignment groups (Development, Analytics, Engineering…) own ticket categories; members carry JUNIOR → MID → SENIOR tiers per group, or STANDALONE for specialists outside the ladder. Priority sets the minimum tier, and any agent can escalate a ticket up a tier or across to another group — the least-loaded eligible member picks it up and the move is logged on the timeline.
- Real Azure integration (read-only) — a service principal with
Readeris enough:azure_list_resourcesruns live Resource Manager queries (subscription-wide or scoped to a resource group), with a Test-connection button that acquires a token and lists resources. Mutating cloud actions stay simulated behind the approval gate. - Ships code, gated by humans — the GitHub tools go past "open an empty branch":
github_read_fileinspects the real source,github_edit_filecommits a precise find/replace on a feature branch (the approval card shows the exact before/after, and an ambiguous match is refused rather than guessed),github_open_prraises the PR andgithub_merge_prlands it — which triggers whatever deployment workflow the repo already has. Both write steps require human approval. - The desk remembers — before it acts, the resolver searches the tickets this desk has already closed:
search_ticketsranks past tickets by relevance (title, description and the resolution someone actually recorded, preferring tickets that reached an outcome),read_ticketopens one in full — replies sent, tools used, resolution — andrequester_historyshows what else this person has filed, so the third replacement dock in two months reads as a hardware fault instead of a new request. Precedent without the privacy leak: another requester's name and email are withheld unless the past ticket is the same person's, so nothing gets quoted back to the wrong requester. No embedding model, no vector store, no configuration — it works on a fresh install and offline. - Reads the web, safely —
fetch_urlopens an http(s) page and hands the agent readable text (HTML flattened to headings, bullets and links), so a resolver can quote the vendor status page or the release notes a requester linked to instead of guessing. Because tickets arrive by email, the URL may be attacker-chosen: every outbound request — this tool, screenshots and custom HTTP integrations alike — resolves the host first and refuses loopback, private, CGNAT and link-local addresses (169.254.169.254included), then re-checks each redirect. An optional allowlist in Integrations narrows it to named hosts, and a literal entry there is how you deliberately reach an intranet host. - Screenshots for review —
take_screenshotrenders a page in a real browser on the server and attaches the image to the ticket, so a reviewer sees a proposed UI change before approving it. It renders a raw branch file too, which means the "after" image exists before anything is merged. Needs a Chrome/Chromium on the host (PUPPETEER_EXECUTABLE_PATH); without one the tool says so instead of pretending. - Real GitHub integration — add a personal access token (env
GITHUB_TOKENor Settings, with a Test-token button) andgithub_create_repo/github_create_branch/github_open_prhit the real GitHub API — still behind their risk levels and approval gates. A ticket like "implement feature X" becomes a real feature branch (and PR) created by the resolver. Without a token they stay simulated so the offline demo keeps working. A base-URL override supports GitHub Enterprise. - Outbound webhooks — stream
ticket.created/resolved/escalatedandapproval.pending/decidedto any endpoint as signed JSON (x-servo-signature: sha256=HMAC(secret, body)). Manage endpoints and subscriptions from Settings, send test pings, and watch a per-endpoint delivery log with latencies. - Command palette (Ctrl/⌘ K) — search tickets by number, title, or text and jump to any page from the keyboard, anywhere in the app.
- Email in and out — outbound: ticket received / resolved to the requester and pending approvals to every admin, over any SMTP server (
SMTP_URLor Settings, with a test-send button); sending is best-effort so a broken mail setup never blocks ticket flows. Inbound: point a provider webhook (SendGrid Inbound Parse, Mailgun, Postmark) atPOST /api/inbound/email— or, for Gmail / Google Workspace, run the bundledscripts/imap-relay.mjsagainst the mailbox — and mail becomes tickets — unknown senders are created as requesters, and a subject carrying#1029files the message as a comment on that ticket instead. Bounces and auto-replies never become tickets: a delivery failure is posted on the ticket of the person it failed to reach ("the requester has not received the last reply"), so a dead address surfaces where it matters instead of as noise — or a mail loop. - AI reply drafts with human approval — the everyday support loop: when an email opens a ticket, the AI drafts the answer (in the requester's language, using the category's specialized agent and its own API key) and a human reviews it — edit in place, approve, or discard. Approving posts it as a public comment and emails it to the requester with a subject that threads their reply back onto the same ticket; the first-response SLA clock starts on send. Pending drafts queue on Approvals next to tool sign-offs; a requester follow-up regenerates a stale pending draft with the new context, and closing a ticket auto-discards its draft. Toggle auto-drafting in Settings → AI (
Draft replies for inbound email), or draft on demand from any ticket. - MCP server — Servo speaks the Model Context Protocol: point any MCP client (Claude Code, Claude Desktop, other agents) at
POST /api/mcpwith a bearer token (Integrations -> MCP server) and it can file, search and read tickets (create_ticket,search_tickets,read_ticket,requester_history) and operate the whole tool registry — custom tools included, excluding ticket-bound core tools, policy-disabled tools and anything gated on human approval (no human is in the loop over MCP, so those stay behind a ticket). - Custom tools & integrations — admins define new HTTP tools from Settings (method, URL, headers, body template with
{input.field}placeholders, and a stored secret injected via{secret}). They join the resolver's registry like built-in tools, with the same risk levels and human-approval gates — the fastest path to integrating a webhook, an internal API, or a SaaS endpoint. - Specialized agents as
.mdfiles — resolver personas (Analytics, Developer, Cybersecurity…) are Markdown documents with YAML frontmatter (name,categories,tools) and a system-prompt body. Drop files intoagents/or create/edit them from the UI; the resolver automatically uses the enabled specialist covering the ticket's category. A visual tool picker per agent (checkboxes with each tool's risk and approval policy) narrows what it may call — no YAML editing — while core tools stay always-on and the .md frontmatter is rewritten to match. - Desk skills as
.mdfiles — the procedures the desk has agreed to follow (how a lockout is handled, what to check before a database change, when to escalate instead of resolving), versioned asskills//SKILL.mdand editable from the Skills page. Progressive disclosure, the way Claude Code loads skills: the resolver's prompt carries only each skill's name and description, and the body costs oneread_skillcall — so a desk can hold dozens of procedures without bloating every prompt.categories: []makes a skill desk-wide; a skill never overrides an approval gate; and QA is told which skills applied and which the run actually read, so an agreed procedure that gets ignored is caught before the ticket closes. External MCP clients can read them too. - Role-based permissions — ADMIN, AGENT, and REQUESTER roles with a permission matrix; HIGH-risk approvals and group management are admin-only.
- Offline evaluation mode — without an OIDC tenant Servo runs a demo user switcher, so you can experience every role (and the whole agent loop, on the mock provider) with no auth provider, no API key and no network.
- shadcn/ui frontend — Tailwind v4 + shadcn/ui components and charts (Recharts), themed with Servo's green-accent OKLCH palette; light mode by default with a dark-mode toggle.
- Docker-ready — one
docker compose up --buildgives you a self-contained instance with persistent SQLite volumes.
A real ticket, end to end
Someone emailed the desk to say a button on our own landing page was unreadable. Servo triaged it, the frontend specialist read the source, diagnosed the CSS, and captured what it looked like before and after its fix — from the branch, before anything was merged — so a human could approve on evidence rather than on a diff:
Both screenshots land on the ticket, next to the AI-drafted reply waiting for review. The run itself folds into one line — agent, outcome, QA verdict, the tools it used and who approved what — and unfolds to the full step-by-step trace:
The commit and the merge each stopped for a human. Approvals — tool sign-offs and reply drafts — share one queue:
Screenshots
| Integrations — SSO, mail, GitHub, MCP connected | Specialized agents, their tools and throughput | |---|---| | | |
| Ticket queue | Settings — BYOK & tool permissions | |---|---| | | |
Fully responsive — same app on mobile.
Quickstart
Requires Node.js 20+.
npm install
npm run setup # prisma generate + db push + core bootstrap (no sample data)
npm run dev
Open http://localhost:3000 — the first-run wizard creates your admin account (and, optionally, connects your SSO tenant). You start with a clean desk: zero tickets, no sample users, nobody else's data. The database is SQLite — no external services needed.
Want a populated playground instead? npm run demo loads a fictional showcase dataset (~28 tickets, completed AI runs, pending approvals) so every screen is meaningful instantly. It wipes the database — demo evaluation only, never a live install.
Run the unit tests with npm test, the RBAC matrix with node scripts/permissions-audit.mjs, and the responsive check with node scripts/responsive-audit.mjs (both need the dev server running).
Run with Docker
docker compose up --build
The container bootstraps its SQLite databases on a named volume (/data) on first boot, then serves on http://localhost:3000 — visit it to run the setup wizard. Set SERVO_DEMO=1 for the showcase dataset instead, and ANTHROPIC_API_KEY (or configure a key in Settings) for real model calls; without one Servo runs in mock mode.
Production checklist
Before exposing an install to real users, set these (see [SECURITY.md](SECURITY.md) for the full model):
AUTH_SECRET— session signing (any long random string).SERVO_ENCRYPTION_KEY— encrypts stored secrets (API keys, tokens, SMTP URLs) at rest with AES-256-GCM. Existing plaintext rows migrate withnode scripts/encrypt-secrets.cjs.- An OIDC tenant (wizard or Integrations → SSO) plus
AUTH_ALLOWED_DOMAINS— real sign-in, scoped to your org. - HTTPS in front (reverse proxy) and
APP_URLset to your public URL. - Scoped credentials for integrations: a fine-grained GitHub PAT, a Reader-role Azure service principal, an app password for the mailbox.
Authentication (SSO / OIDC)
Servo ships with real sign-in for self-hosted deployments: connect any OIDC identity provider (Entra ID, Google, Okta, Keycloak, Auth0...) via env vars or from Integrations -> Single sign-on. Users are provisioned on first sign-in (REQUESTER by default; AUTH_ADMIN_EMAILS keeps admins), roles are managed from Settings -> Team, and a first-run setup wizard (/setup) bootstraps fresh installs: the first admin, the system AI agents, default policies, and (optionally) your SSO tenant. Without OIDC config Servo stays in the offline demo mode with the user switcher. For local development, node scripts/mock-idp.mjs you@x.com starts a
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: ricauts
- Source: ricauts/Servo
- License: MIT
- Homepage: https://servoai.org
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.