Skip to content

feat(evi): expose the agent over mcp for external harnesses - #544

Merged
HugoRCD merged 2 commits into
mainfrom
feat/evi-mcp-channel
Aug 9, 2026
Merged

feat(evi): expose the agent over mcp for external harnesses#544
HugoRCD merged 2 commits into
mainfrom
feat/evi-mcp-channel

Conversation

@HugoRCD

@HugoRCD HugoRCD commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Makes Evi reachable from MCP clients — Raycast AI first, Claude Code and Cursor for free — following the pattern of V's MCP channel.

  • POST /eve/v1/mcp: a custom channel serving MCP JSON-RPC (initialize, tools/list, tools/call, ping). One evi tool forwards the message into a real Evi session via the route send() and collects the reply from the session event stream. maxDuration: 800 so a shipping flow can complete within the synchronous call.
  • Auth is a static bearer (EVI_MCP_TOKEN), compared in constant time over digests. Verified requests run under the mcp:hugo principal, which trust.ts counts as the maintainer only while the token is configured — full admin surface (push, captures, Linear, gateway) from the harness, revocable by rotating one env var. No OAuth AS on purpose: single-user surface.
  • The mcp-session-id issued on initialize keys the eve continuation token: one Raycast chat, one continuous Evi conversation.
  • Protocol handling, bearer verification, and the stream collector live in agent/lib/mcp.ts with colocated tests (10 new; 63 total).

Setup after merge: openssl rand -hex 32EVI_MCP_TOKEN on the evi project, then add an HTTP MCP server in Raycast pointing at https://evi.evlog.cloud/eve/v1/mcp with the Authorization: Bearer … header. Documented in docs/notes.md.

No changeset: confined to apps/evi. Verified: tsc, 63 unit tests, eve build. End-to-end validates against the preview with a curl initialize/tools/call once EVI_MCP_TOKEN is set.

Summary by CodeRabbit

  • New Features

    • Added an MCP-compatible HTTP endpoint for Evi interactions.
    • Supports authenticated sessions, tool discovery, tool execution, notifications, and streamed responses.
    • Returns clear protocol and tool errors for invalid or failed requests.
    • Long-running requests can run for up to 800 seconds.
  • Documentation

    • Added setup, authentication, session handling, token rotation, and integration guidance.
  • Bug Fixes

    • Improved handling of malformed JSON, invalid requests, failed turns, and silent completions.

@vercel

vercel Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
evi Ready Ready Preview Aug 9, 2026 6:42pm
4 Skipped Deployments
Project Deployment Actions Updated (UTC)
evlog-docs Skipped Skipped Aug 9, 2026 6:42pm
evlog-render-lab Skipped Skipped Aug 9, 2026 6:42pm
evlog-telemetry Skipped Skipped Aug 9, 2026 6:42pm
just-use-evlog Skipped Skipped Aug 9, 2026 6:42pm

Request Review

@changeset-bot

changeset-bot Bot commented Aug 9, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 351e29c

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
vercel Bot temporarily deployed to Preview – evlog-render-lab August 9, 2026 18:36 Inactive
@vercel
vercel Bot temporarily deployed to Preview – just-use-evlog August 9, 2026 18:36 Inactive
@vercel
vercel Bot temporarily deployed to Preview – evlog-telemetry August 9, 2026 18:36 Inactive
@vercel
vercel Bot temporarily deployed to Preview – evlog-docs August 9, 2026 18:36 Inactive
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Thank you for following the naming conventions! 🙏

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds an authenticated MCP HTTP endpoint for Evi. It handles JSON-RPC lifecycle requests, tool calls, streamed Evi responses, MCP session IDs, maintainer trust, CORS, and operational documentation.

Changes

Evi MCP channel

Layer / File(s) Summary
MCP protocol and Evi stream handling
apps/evi/agent/lib/mcp.ts, apps/evi/agent/lib/mcp.test.ts
Adds bearer verification, JSON-RPC routing, MCP tool metadata, Evi stream extraction, protocol errors, tool errors, and lifecycle tests.
MCP authentication and session identity
apps/evi/agent/lib/mcp.ts, apps/evi/agent/lib/trust.ts, apps/evi/agent/lib/trust.test.ts
Creates authenticated MCP session context and grants mcp:hugo maintainer trust when EVI_MCP_TOKEN is configured.
HTTP channel wiring and operations
apps/evi/agent/channels/mcp.ts, apps/evi/docs/notes.md
Registers POST /eve/v1/mcp, applies CORS and no-cache headers, propagates MCP session IDs, sets an 800-second duration limit, and documents setup and token rotation.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant MCPChannel
  participant handleMcpRequest
  participant EviSession
  Client->>MCPChannel: POST JSON-RPC request with bearer token
  MCPChannel->>handleMcpRequest: authenticated request and callEvi callback
  handleMcpRequest->>EviSession: execute evi tool message
  EviSession-->>handleMcpRequest: streamed Evi events
  handleMcpRequest-->>MCPChannel: JSON-RPC response
  MCPChannel-->>Client: response with MCP session ID
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change and uses the repository's conventional commit format.
Description check ✅ Passed The description clearly covers the MCP endpoint, authentication, session behavior, tests, documentation, setup, and verification.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/evi-mcp-channel

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Aug 9, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/@evlog/cli@544
npm i https://pkg.pr.new/evlog@544
npm i https://pkg.pr.new/@evlog/nuxthub@544
npm i https://pkg.pr.new/@evlog/telemetry@544

commit: 351e29c

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/evi/agent/lib/mcp.ts`:
- Around line 95-99: Update the documentation comment above the MCP request
handler to remove the implementation-history reference to “V's proven MCP proxy
shape,” while preserving the durable description of JSON-RPC protocol errors and
callEvi failures.
- Line 4: Align the MCP protocol declaration and transport routes: in
apps/evi/agent/lib/mcp.ts at line 4 and apps/evi/agent/channels/mcp.ts at lines
33-41, either implement the 2024-11-05 separate SSE and POST JSON-RPC endpoints,
or change PROTOCOL_VERSION to the Streamable HTTP version and add GET handling
to the existing /eve/v1/mcp endpoint. Ensure the selected transport matches the
declared protocol and clients can complete session setup.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b8dde181-4ff9-4cce-a694-c6248248fccc

📥 Commits

Reviewing files that changed from the base of the PR and between 9174f71 and b3c79ff.

📒 Files selected for processing (6)
  • apps/evi/agent/channels/mcp.ts
  • apps/evi/agent/lib/mcp.test.ts
  • apps/evi/agent/lib/mcp.ts
  • apps/evi/agent/lib/trust.test.ts
  • apps/evi/agent/lib/trust.ts
  • apps/evi/docs/notes.md

Comment thread apps/evi/agent/lib/mcp.ts Outdated
import { createHash, timingSafeEqual } from 'node:crypto'
import type { SessionAuthContext } from 'eve/context'

const PROTOCOL_VERSION = '2024-11-05'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 3 "PROTOCOL_VERSION|mcp-session-id|POST\\('/eve/v1/mcp'|GET\\('/eve/v1/mcp'" \
  apps/evi/agent/lib/mcp.ts apps/evi/agent/channels/mcp.ts

curl -fsSL https://modelcontextprotocol.io/specification/2024-11-05/basic/transports \
  | grep -E "SSE endpoint|regular HTTP POST endpoint" || true

curl -fsSL https://modelcontextprotocol.io/specification/2025-03-26/basic/transports \
  | grep -E "supports both POST and GET|Mcp-Session-Id" || true

Repository: HugoRCD/evlog

Length of output: 50370


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '(^|/)apps/evi/agent/(lib|channels)/mcp\.ts$'

echo "== relevant source snippets =="
for f in apps/evi/agent/lib/mcp.ts apps/evi/agent/channels/mcp.ts; do
  echo "--- $f ($(wc -l < "$f") lines) ---"
  sed -n '1,240p' "$f" | nl -ba
done

echo "== mcp references =="
rg -n --hidden --glob '!node_modules' --glob '!dist' --glob '!build' 'PROTOCOL_VERSION|mcp-session-id|session-id|Mcp-Session-Id|streamable|mcp-/sse|POST\(\x27/eve/v1/mcp\x27|GET\(\x27/eve/v1/mcp\x27|GET\("`/eve/v1/mcp`"|POST\("`/eve/v1/mcp`"' apps/evi/agent/package.json package.json pnpm-lock.yaml 2>/dev/null || true

Repository: HugoRCD/evlog

Length of output: 338


🌐 Web query:

Model Context Protocol 2024-11-05 transports SSE endpoint POST endpoint separate endpoints

💡 Result:

In the Model Context Protocol (MCP) specification dated 2024-11-05, the HTTP with Server-Sent Events (SSE) transport requires the server to provide two distinct endpoints to facilitate bidirectional communication [1][2]: 1. An SSE endpoint: Used by clients to establish a connection and receive messages (server-to-client) [1][2]. 2. A separate HTTP POST endpoint: Used by clients to send messages to the server (client-to-server) [1][2]. When a client connects to the SSE endpoint, the server sends an endpoint event containing the URI for the POST endpoint [1][3]. The client then sends all subsequent messages as HTTP POST requests to that specific URI [1][2]. Note that this HTTP+SSE transport was later superseded by the Streamable HTTP transport (introduced in the 2025-03-26 specification), which utilizes a single MCP endpoint that handles both GET and POST methods [4][5][6]. While newer specifications recommend the Streamable HTTP approach, they generally provide guidance for maintaining backwards compatibility by continuing to host the separate SSE and POST endpoints of the 2024-11-05 transport [4][7][6].

Citations:


🌐 Web query:

Model Context Protocol streamable HTTP transports 2025-03-26 GET POST same endpoint mcp-protocol-version mcp-session-id

💡 Result:

The "Streamable HTTP" transport, introduced in the Model Context Protocol (MCP) specification version 2025-03-26, defines a method for MCP clients and servers to communicate using a single HTTP endpoint that supports both GET and POST requests [1][2][3]. Key aspects of this transport include: MCP Endpoint: Servers expose a single URL path (the MCP endpoint) to handle all traffic [1][2]. POST Requests: All JSON-RPC messages from the client to the server must be sent as HTTP POST requests to the MCP endpoint [1][2]. GET Requests: Clients may issue an HTTP GET request to the MCP endpoint to initiate a Server-Sent Events (SSE) stream [1][2]. This allows the server to send messages (notifications or requests) to the client asynchronously [2][4]. Header Requirements: MCP-Protocol-Version: Starting with the 2025-03-26 release and evolving in subsequent versions, this header is used to negotiate and specify the protocol version [5][6][7][8]. Mcp-Session-Id: In earlier stateful revisions of the Streamable HTTP transport (such as 2025-03-26 and 2025-11-25), this header was used to manage session state between the client and server [5][6][8]. Servers could return a session ID during initialization, which the client then included in subsequent requests [6][9]. Evolution: Later protocol revisions, such as the 2026-07-28 draft, transitioned toward a stateless model [5][8][10]. In these stateless revisions, the Mcp-Session-Id header and GET-based SSE streams have been deprecated or removed in favor of stateless requests where context is provided via the _meta field in the JSON-RPC request body [5][8][10]. Servers maintaining backward compatibility may still support the older stateful headers (like Mcp-Session-Id) alongside the newer stateless implementation [11][8][10].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== relevant source snippets =="
for f in apps/evi/agent/lib/mcp.ts apps/evi/agent/channels/mcp.ts; do
  echo "--- $f ($(wc -l < "$f") lines) ---"
  sed -n '1,240p' "$f" | awk '{printf "%6d  %s\n", NR, $0}'
done

echo "== mcp references in tracked code =="
rg -n 'PROTOCOL_VERSION|mcp-session-id|session-id|Mcp-Session-Id|mcp-protocol-version|streamable|mcp-/sse|POST\(' 'apps/evi/agent/lib/mcp.ts' 'apps/evi/agent/channels/mcp.ts' 'apps/evi/agent/package.json' 2>/dev/null || true

echo "== deterministic route shape check =="
python3 - <<'PY'
from pathlib import Path
import re

for path in ["apps/evi/agent/lib/mcp.ts", "apps/evi/agent/channels/mcp.ts"]:
    text = Path(path).read_text()
    print(f"\n{path}:")
    print("declares 2024-11-05:", bool(re.search(r"PROTOCOL_VERSION\s*=\s*['\"]2024-11-05['\"]", text)))
    print("mentions Streamable/2025:", bool(re.search(r"streamable|2025-03-26|mcp-session-id|Mcp-Session-Id", text)))
    print("declares SSE endpoint:", bool(re.search(r"(GET\(|POST\(|route\(|'/eve/v1/mcp/sse|/mcp/sse)", text)))
    print("declares POST endpoint:", bool(re.search(r"(GET\(|POST\(|route\(|'/eve/v1/mcp|/eve/v1/mcp)", text)))
    print("declares GET endpoint:", bool(re.search(r"GET\(|route\([^)]*GET|method\s*[=:][^<]*GET", text)))
PY

Repository: HugoRCD/evlog

Length of output: 10912


Align the MCP transport with the declared protocol version.

PROTOCOL_VERSION returns 2024-11-05, but /eve/v1/mcp is defined as POST-only. That version requires a separate server-sent-events SSE endpoint and a distinct POST JSON-RPC endpoint; clients cannot complete HTTP+SSE setup. Implement both 2024-11-05 endpoints, or declare the Streamable HTTP version and add GET handling on the same endpoint.

📍 Affects 2 files
  • apps/evi/agent/lib/mcp.ts#L4-L4 (this comment)
  • apps/evi/agent/channels/mcp.ts#L33-L41
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/evi/agent/lib/mcp.ts` at line 4, Align the MCP protocol declaration and
transport routes: in apps/evi/agent/lib/mcp.ts at line 4 and
apps/evi/agent/channels/mcp.ts at lines 33-41, either implement the 2024-11-05
separate SSE and POST JSON-RPC endpoints, or change PROTOCOL_VERSION to the
Streamable HTTP version and add GET handling to the existing /eve/v1/mcp
endpoint. Ensure the selected transport matches the declared protocol and
clients can complete session setup.

Comment thread apps/evi/agent/lib/mcp.ts
Comment on lines +95 to +99
/**
* Handles one parsed MCP JSON-RPC request. Protocol problems map to JSON-RPC
* errors; a thrown `callEvi` becomes an `isError` tool result. Ported from
* V's proven MCP proxy shape.
*/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove implementation-history text.

V's proven MCP proxy shape does not state a durable constraint. Remove it.

As per coding guidelines, “comments should state only durable constraints and should not narrate implementation history.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/evi/agent/lib/mcp.ts` around lines 95 - 99, Update the documentation
comment above the MCP request handler to remove the implementation-history
reference to “V's proven MCP proxy shape,” while preserving the durable
description of JSON-RPC protocol errors and callEvi failures.

Source: Coding guidelines

@HugoRCD HugoRCD self-assigned this Aug 9, 2026
@vercel
vercel Bot temporarily deployed to Preview – evlog-render-lab August 9, 2026 18:42 Inactive
@vercel
vercel Bot temporarily deployed to Preview – evlog-docs August 9, 2026 18:42 Inactive
@vercel
vercel Bot temporarily deployed to Preview – just-use-evlog August 9, 2026 18:42 Inactive
@vercel
vercel Bot temporarily deployed to Preview – evlog-telemetry August 9, 2026 18:42 Inactive
@HugoRCD
HugoRCD merged commit b4e4014 into main Aug 9, 2026
16 checks passed
@HugoRCD
HugoRCD deleted the feat/evi-mcp-channel branch August 9, 2026 18:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant