Skip to main content
Glama
brendendearie

waylucid-agent-mcp

waylucid-agent-mcp

Permission-aware MCP tools, a small agent harness, and CI evals for an ops desk.

This is a sanitized public reference. It is not LucidDock, not a customer deployment, and not an open-source of proprietary WayLucid code. Harborline is fictional seed data. The point is the shape: how you discover an ontology, ship it as MCP tools the model can actually see, and productize the boundary with evals.

Built by Brenden Dearie as a demoable slice for agentic-experience and FDE conversations.

What hiring managers should look at in 5 minutes

  1. src/mcp/tools.ts — tools are the product surface. The catalog is role-gated. cases.update is a different schema for operator vs supervisor, so the model cannot plan a field it is not allowed to send. The handler still enforces the matrix.

  2. src/auth.ts + src/seed.ts — contacts / cases / tasks, plus data-plane redaction: operators get hiddenInternalNoteCount, supervisors get the note body.

  3. src/eval/run.ts — a golden set that fails if a write leaks into the viewer catalog, if the demo path stops creating a P1 case, or if internal notes spill.

  4. Run pnpm agent --demo then pnpm eval. That is the whole loop.

If you only have two minutes: switch the playground role from operator to viewer and run the same utterance. Create disappears from the plan.

Related MCP server: MCP Ops Agent

Discovery → ship → productize

flowchart LR
  D["Discover<br/>ontology + permissions"] --> S["Ship<br/>MCP tools + schemas"]
  S --> P["Productize<br/>harness + golden evals"]
  P --> D

Stage

What we actually did here

Discover

Three objects an ops desk already has: contacts, cases, tasks. Three roles: viewer, operator, supervisor. Write down what each role must never do — assign, resolve, freeze an account, read internal notes — before writing a tool.

Ship

A TypeScript MCP server (@modelcontextprotocol/server v2) that advertises a coherent toolset over stdio and Streamable HTTP. Schemas are narrowed per role. Resources expose ops://desk/whoami and the catalog. Backing store is in-memory so this repo runs without a database or a paid API.

Productize

A harness that plans against the advertised catalog, not against a hidden admin API. A golden eval script that belongs in CI. A playground so a screen can happen without wiring Cursor or Claude Desktop first.

The interesting failure mode for agent products is not “the model can’t call tools.” It is “the model planned a privileged write because the tool list lied.” This repo treats that as the product bug.

Architecture

flowchart TB
  subgraph hosts [Hosts]
    CLI["CLI harness<br/>pnpm agent"]
    UI["Playground<br/>pnpm playground"]
    CI["Golden evals<br/>pnpm eval"]
  end

  subgraph mcp [MCP server]
    Factory["createOpsServer(role)"]
    Tools["Role-gated tools<br/>+ narrowed input schemas"]
    Resources["ops://desk/*"]
  end

  subgraph desk [Harborline desk]
    Store["In-memory OpsStore"]
    Seed["Fictional contacts / cases / tasks"]
  end

  CLI -->|stdio or in-process HTTP| Factory
  UI -->|REST + /mcp| Factory
  CI -->|in-process Client| Factory
  Factory --> Tools
  Factory --> Resources
  Tools --> Store
  Resources --> Store
  Store --> Seed

Stdio is what Cursor / Claude Desktop / MCP Inspector spawn. The harness tests use createMcpHandler + StreamableHTTPClientTransport with fetch pointed at the handler — no socket, same factory you would deploy.

Permission matrix

Tool

viewer

operator

supervisor

whoami, *.list, *.get

yes

yes

yes

cases.create, cases.update*, tasks.create, tasks.complete

yes

yes

cases.assign, cases.resolve, cases.add_internal_note, contacts.update_status

yes

Internal note bodies on cases.get

hidden

hidden

visible

*Operator cases.update accepts title / description / priority. Supervisor cases.update also accepts tags. Assignment and resolve stay on their own tools so a host can attach a confirmation to the destructive ones (destructiveHint is set).

The server never relies on the client to filter. If a viewer calls cases.create anyway, the tool is not registered on that session and MCP returns a protocol-level "not found" — the model never gets a successful write.

How to run locally

Node 20+ (22 is what CI uses). pnpm preferred; npm works.

pnpm install          # or npm install
pnpm tools            # start the MCP factory, list the operator catalog, exit
pnpm agent --demo     # list Maya → open P1 case → create follow-up
pnpm eval             # golden set; exit 0 when green
pnpm test             # vitest, including the golden set
pnpm playground       # http://127.0.0.1:43123

Role is --role viewer|operator|supervisor or WAYLUCID_ROLE.

pnpm agent --role viewer "Maya's webhook is failing — open a P1 case"
pnpm agent --role supervisor "assign Maya's webhook case to Priya and resolve it"

MCP Inspector / Cursor

pnpm mcp

Point a host at tsx src/mcp/stdio.ts (or pnpm mcp). Set WAYLUCID_ROLE in the server env. Logs go to stderr; stdout is JSON-RPC.

The playground also serves Streamable HTTP at POST /mcp with x-waylucid-role: operator.

Optional live model

Default planner is a deterministic mock. That is intentional: the product surface is the tool boundary, and screens should not depend on a vendor key.

export WAYLUCID_LLM=openai
export OPENAI_API_KEY=...
# or WAYLUCID_LLM=anthropic and ANTHROPIC_API_KEY
pnpm agent --demo

No key? The mock planner still runs the demo path and the evals still gate quality.

Package layout

src/auth.ts              roles, advertised catalog, principals
src/ontology.ts          contacts / cases / tasks
src/store.ts             in-memory desk
src/seed.ts              Harborline fixtures
src/mcp/create-server.ts factory
src/mcp/tools.ts         permission-aware tool schemas
src/mcp/stdio.ts         stdio entry
src/mcp/session.ts       in-process Client used by harness + evals
src/harness/             mock planner, optional OpenAI/Anthropic, CLI
src/eval/                golden fixtures + runner
src/web/                 playground HTTP + /mcp
playground/              Vite + React UI
tests/                   store, permissions, protocol, harness, evals

npm test and pnpm eval are the two commands CI runs after typecheck.

Scope

This is a small reference, not a framework: one ontology, one server, one harness, one eval set. The store is in-memory and the default planner is a mock so the repo runs without a database or vendor key.

For a production shape, bind the same factory to a real CRM, run the golden set against recorded traces, and keep the tool schemas as the source of truth for what an agent is allowed to do.

License

MIT. See CONTRIBUTING.md for the bar on PRs.

Related MCP Connectors

Related MCP Servers

  • F
    license
    C
    quality
    B
    maintenance
    Schema-driven MCP server that exposes all Paperclip API operations as typed MCP tools over stdio or Streamable HTTP, supporting both authenticated and local_mode deployments.
    100
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    An MCP server exposing scoped, read-only enterprise operations tools with fail-closed credential handling. It returns opaque approval IDs for mutations and requires a separate operator approval command to release one-time capabilities.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    MCP server for regulated enterprises, providing per-tool RBAC, redacted audit logging, and structured error handling. Exposes bank tools for customer lookup, statement search, and dispute resolution over stdio and HTTPS transports.
    MIT