Skip to content

feat(ensapi): introduce Model Context Protocol (MCP) server for Omnigraph API#2301

Open
djstrong wants to merge 16 commits into
mainfrom
omnigraph-mcp
Open

feat(ensapi): introduce Model Context Protocol (MCP) server for Omnigraph API#2301
djstrong wants to merge 16 commits into
mainfrom
omnigraph-mcp

Conversation

@djstrong

@djstrong djstrong commented Jun 15, 2026

Copy link
Copy Markdown
Member

Lite PR

Tip: Review docs on the ENSNode PR process

Summary

  • Adds a first-party Omnigraph MCP server at /api/mcp on every ENSApi instance (streamable-HTTP), with tools (omnigraph_query, omnigraph_schema), schema/example resources, prompts, and validation hints for common GraphQL mistakes.
  • Adds offline schema lookup helpers in @ensnode/ensnode-sdk/internal (lookupOmnigraphSchema, buildCondensedSchemaReference) with bundled SDL so schema loading works in Vite/Rollup builds (no Node createRequire).
  • Adds docs (omnigraph-mcp.mdx, AI/LLM integration page link) and refactors enscli / ensskills to share the same schema helpers.

Why

  • AI agents (Cursor, Claude Desktop, etc.) need a standard way to query ENS state without bespoke per-use-case tools or hand-maintained GraphQL.
  • MCP gives agents execution against the full Omnigraph; bundled schema lookup + vetted example queries reduce bad first attempts (wrong field names, camelCase filters, subgraph-style patterns).
  • Consolidates schema reference logic in ensnode-sdk so ENSApi MCP, enscli, and ensskills stay in sync.

Testing

  • Manually tested against Cursor/Claude Desktop; docs cover client setup.

Notes for Reviewer (Optional)


Pre-Review Checklist (Blocking)

  • This PR does not introduce significant changes and is low-risk to review quickly.
  • Relevant changesets are included (or are not required)

Copilot AI review requested due to automatic review settings June 15, 2026 13:32
@vercel

vercel Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated (UTC)
admin.ensnode.io Ready Ready Preview, Comment Jun 19, 2026 9:37am
enskit-react-example.ensnode.io Ready Ready Preview, Comment Jun 19, 2026 9:37am
ensnode.io Ready Ready Preview, Comment Jun 19, 2026 9:37am
ensrainbow.io Ready Ready Preview, Comment Jun 19, 2026 9:37am

@changeset-bot

changeset-bot Bot commented Jun 15, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 1509598

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 24 packages
Name Type
ensapi Patch
@ensnode/ensnode-sdk Patch
ensadmin Patch
ensindexer Patch
ensrainbow Patch
fallback-ensapi Patch
@docs/ensnode Patch
@namehash/ens-referrals Patch
enscli Patch
@ensnode/ensdb-sdk Patch
@ensnode/ensrainbow-sdk Patch
ensskills Patch
@ensnode/integration-test-env Patch
@namehash/namehash-ui Patch
@docs/ensrainbow Patch
enssdk Patch
enskit Patch
@ensnode/datasources Patch
@ensnode/ponder-sdk Patch
@ensnode/ponder-subgraph Patch
@ensnode/shared-configs Patch
@ensnode/ensindexer-perf-testing Patch
@ensnode/enskit-react-example Patch
@ensnode/enssdk-example Patch

Not sure what this means? Click here to learn what changesets are.

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

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a new MCP server endpoint (/api/mcp) to ENSApi exposing the Omnigraph GraphQL API via streamable-HTTP, backed by new schema reference and example query utilities in the SDK. Updates the CLI command and skills generation pipeline to use these utilities, restructures the documentation site to source example metadata from the SDK, and documents the integration across multiple platforms.

Changes

Omnigraph MCP Server and Related Infrastructure

Layer / File(s) Summary
Schema reference utilities and core types
packages/ensnode-sdk/src/omnigraph-api/schema-reference.ts, packages/ensnode-sdk/src/omnigraph-api/schema-reference.test.ts, packages/ensnode-sdk/package.json
Adds getOmnigraphSchema() to cache the bundled GraphQL schema, lookupOmnigraphSchema() to query types/fields/search results, and buildCondensedSchemaReference() to generate Markdown reference with core types and remaining major types. Exports OMNIGRAPH_CORE_TYPES allowlist. Adds graphql dependency. Tests verify schema lookup and condensed output generation.
Enhanced GraphQL example queries with metadata
packages/ensnode-sdk/src/omnigraph-api/example-queries.ts
Extends GraphqlApiExampleQuery with title and description fields, updates all example entries with metadata, and adds listGraphqlApiExampleQueryIds() and resolveGraphqlApiExampleQuery() helper functions for namespace-aware variable resolution.
SDK internal exports
packages/ensnode-sdk/src/internal.ts
Re-exports schema reference functions via internal.ts to expose them under @ensnode/ensnode-sdk/internal.
EnsSdk schema SDL export and build configuration
packages/enssdk/package.json, packages/enssdk/scripts/inline-schema-sdl.mjs, packages/enssdk/tsup.config.ts, docs/ensnode.io/package.json
Extends packages/enssdk/package.json to export bundled GraphQL schema as TypeScript via ./omnigraph/schema-sdl, includes generated artifacts in published files, and adds publish config mappings. Adds inline-schema-sdl.mjs script that reads generated schema.graphql and wraps it in a TypeScript module, enabling schema consumption in Vite/Rollup without Node createRequire. Updates build and doc site prebuild configurations.
MCP support utilities for query execution and validation hints
apps/ensapi/src/handlers/api/mcp/omnigraph-mcp-support.ts, apps/ensapi/src/handlers/api/mcp/omnigraph-mcp-support.test.ts
Implements example URI construction, example indexing, query resolution with variable overrides, in-process GraphQL execution against Yoga, and validation-hint generation by matching GraphQL errors against regex patterns. Exports OMNIGRAPH_MCP_INSTRUCTIONS for agent guidance.
MCP server implementation and HTTP session handling
apps/ensapi/src/handlers/api/mcp/mcp-api.ts, apps/ensapi/src/handlers/api/mcp/mcp-api.test.ts, apps/ensapi/src/handlers/api/mcp/mcp-api.integration.test.ts
Implements createOmnigraphMcpServer() registering omnigraph_query (Zod-validated, supporting query/exampleId modes) and omnigraph_schema tools, plus prompts for account/domain queries. Wraps in Hono app managing MCP sessions via mcp-session-id header: POST creates new sessions with UUID ids and StreamableHTTPTransport, GET/POST dispatch to existing sessions, DELETE closes sessions. Returns HTTP 202 for SSE notifications, JSON-RPC errors for invalid sessions/methods. Unit and integration tests verify tool execution, error handling, and end-to-end session flow.
Router registration and package setup
apps/ensapi/src/handlers/api/router.ts, apps/ensapi/package.json
Registers /mcp route and adds @hono/mcp/@modelcontextprotocol/sdk dependencies.
CLI command refactoring to use SDK schema functions
packages/enscli/src/commands/ensnode/omnigraph-schema.ts
Refactors to use getOmnigraphSchema() and lookupOmnigraphSchema() from SDK instead of local introspection, removes local GraphQL helpers, updates render functions to accept explicit structural descriptions, and changes control flow paths to use SDK functions.
Skills generation pipeline updates
packages/ensskills/scripts/generate.ts, packages/ensskills/skills/omnigraph/SKILL.md
Updates schema rendering to use buildCondensedSchemaReference() from SDK, validates example title/description presence, changes example markdown to include titled headings and descriptions. Regenerates SKILL.md with expanded example headings (21 examples with titles and purpose descriptions).
Documentation site integration and example config restructuring
docs/ensnode.io/src/content/docs/docs/integrate/integration-options/omnigraph-mcp.mdx, docs/ensnode.io/src/content/docs/docs/integrate/ai-llm.mdx, docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts, docs/ensnode.io/src/data/omnigraph-examples/config.ts, docs/ensnode.io/src/data/omnigraph-examples/examples.ts, docs/ensnode.io/src/data/omnigraph-examples/config.test.ts
Adds new omnigraph-mcp.mdx page documenting /api/mcp endpoint, tool contract, Cursor/Claude Desktop mcp.json config examples, MCP Inspector verification, and query authoring guidance. Adds LinkCard to AI/LLM integration index and sidebar navigation entry. Restructures OMNIGRAPH_EXAMPLES_CONFIG to drop local title/description, sourcing them from SDK via getGraphqlApiExampleQueryById(), updating sidebar label generation and examples wiring.
OpenAPI exclusion and gitignore configuration
apps/ensapi/src/openapi-document.ts, .gitignore
Excludes /api/mcp from OpenAPI document generation. Adds ignore rules for npm-managed agent skills and data-* directories.

Sequence Diagram

sequenceDiagram
  participant MCPClient
  participant HonoRouter
  participant StreamableHTTPTransport
  participant McpServer
  participant omnigraph_query
  participant Yoga
  
  MCPClient->>HonoRouter: POST /api/mcp (initialize request)
  HonoRouter->>StreamableHTTPTransport: Create new transport with UUID
  HonoRouter->>McpServer: Create and connect server
  HonoRouter->>StreamableHTTPTransport: handleRequest(initialize)
  StreamableHTTPTransport->>McpServer: Process initialize
  McpServer-->>StreamableHTTPTransport: Initialized response
  HonoRouter-->>MCPClient: HTTP 200 + mcp-session-id header
  
  MCPClient->>HonoRouter: POST /api/mcp (omnigraph_query tool call)
  HonoRouter->>StreamableHTTPTransport: handleRequest(tool call) using session-id
  StreamableHTTPTransport->>McpServer: Invoke tool
  McpServer->>omnigraph_query: Execute query or resolve exampleId
  omnigraph_query->>Yoga: POST /api/omnigraph { query, variables }
  Yoga-->>omnigraph_query: { data, errors }
  omnigraph_query-->>McpServer: Append hints, return GraphQL JSON
  McpServer-->>StreamableHTTPTransport: Tool result
  HonoRouter-->>MCPClient: HTTP 200 with result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

  • namehash/ensnode#2112: Both PRs update the Starlight sidebar topic config (docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts) by adding new "Integration Options" entries for API integration guides.

Poem

🐰 A rabbit hops through /api/mcp,
Schema lookups and examples in its pack.
Yoga brews GraphQL, Hono routes the way,
While Claude and Cursor query ENS all day.
From SDK to skills, the pieces align—
A streamable HTTP protocol so fine! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.83% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely describes the main change: introducing a Model Context Protocol (MCP) server for the Omnigraph API at /api/mcp, which is the primary feature delivered by this changeset.
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.
Description check ✅ Passed The PR description closely follows the required template with all major sections present: Summary (3 bullets on MCP server, schema lookup, docs), Why (2 bullets on AI agent needs), Testing (manual testing noted), and pre-review checklist completed.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch omnigraph-mcp

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 and usage tips.

Copilot AI 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.

Pull request overview

This PR adds a first-party Model Context Protocol (MCP) server surface to ENSApi so MCP clients can execute ENS Omnigraph GraphQL queries via a single omnigraph_query tool at /api/mcp, and updates docs + dependencies accordingly.

Changes:

  • Add /api/mcp endpoint backed by @hono/mcp + @modelcontextprotocol/sdk, exposing the omnigraph_query tool.
  • Add unit + integration tests for the MCP server/tool behavior.
  • Add documentation pages/links describing how to connect MCP clients to the new endpoint.

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pnpm-lock.yaml Locks new MCP-related dependencies (@hono/mcp, @modelcontextprotocol/sdk) and their transitive deps.
apps/ensapi/package.json Adds MCP server dependencies to ensapi.
apps/ensapi/src/handlers/api/router.ts Mounts the new MCP sub-router at /api/mcp.
apps/ensapi/src/handlers/api/mcp/mcp-api.ts Implements MCP server + omnigraph_query tool and streamable-HTTP transport handler.
apps/ensapi/src/handlers/api/mcp/mcp-api.test.ts Unit tests for tool registration and yoga delegation via in-memory transport.
apps/ensapi/src/handlers/api/mcp/mcp-api.integration.test.ts End-to-end integration tests against a live ENSApi instance.
.changeset/ensapi-omnigraph-mcp.md Changeset documenting the new MCP feature as a minor bump for ensapi.
docs/ensnode.io/src/content/docs/docs/integrate/integration-options/omnigraph-mcp.mdx New documentation page for the MCP endpoint and client setup.
docs/ensnode.io/src/content/docs/docs/integrate/integration-options/omnigraph-graphql-api.mdx Cross-links GraphQL docs to the new MCP surface.
docs/ensnode.io/src/content/docs/docs/integrate/integration-options/index.mdx Adds MCP as an integration option in the index page.
docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts Adds MCP page to the Integrate sidebar.
docs/ensnode.io/src/content/docs/docs/integrate/why-ensnode/keep-ens-working.mdx Adds MCP to the “ENS AI Agents” dependency table.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/ensapi/src/handlers/api/mcp/mcp-api.ts Outdated
Comment on lines +45 to +48
// NOTE: this bypasses the indexing-status middleware on the `/api/omnigraph` HTTP route, so
// queries run against whatever the index currently holds. `canAccelerate` only affects the
// Resolution API, so `false` is correct for generic Omnigraph queries.
const response = await yoga.fetch(
Comment thread apps/ensapi/src/handlers/api/mcp/mcp-api.ts Outdated
Comment thread apps/ensapi/src/handlers/api/mcp/mcp-api.ts Outdated
Comment thread apps/ensapi/src/handlers/api/mcp/mcp-api.ts Outdated
…tation

- Introduced a new MCP server for handling Omnigraph queries at the `/api/mcp` endpoint.
- Updated OpenAPI document to exclude the new MCP endpoint from generated documentation.
- Added documentation for integrating with the Omnigraph MCP, including usage instructions for clients like Cursor and Claude.
- Enhanced existing documentation with a new link card for the Omnigraph MCP.

@vercel vercel 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.

Additional Suggestion:

Missing sidebar configuration for the ENS Omnigraph MCP documentation page causes Astro build failure

Fix on Vercel

Copilot AI 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.

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.

Comment thread apps/ensapi/src/handlers/api/mcp/mcp-api.ts Outdated
Comment thread apps/ensapi/src/handlers/api/mcp/mcp-api.ts

@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: 1

🤖 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 @.gitignore:
- Around line 50-52: The `data-*` pattern on line 52 is too broad and will
ignore matching files or directories anywhere in the repository, potentially
hiding legitimate assets or fixtures. Scope this pattern more narrowly by
placing it under the same directory constraint as the npm skills entry above it
(the `**/skills/npm-*` pattern), so that `data-*` files are only ignored when
they exist within the npm-managed skills directory tree, not globally across the
entire repository.
🪄 Autofix (Beta)

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

Run ID: 5580846c-9e8a-4819-ba3b-6c101e38393a

📥 Commits

Reviewing files that changed from the base of the PR and between 71a3fd4 and b419590.

📒 Files selected for processing (5)
  • .gitignore
  • apps/ensapi/src/handlers/api/mcp/mcp-api.ts
  • apps/ensapi/src/openapi-document.ts
  • docs/ensnode.io/src/content/docs/docs/integrate/ai-llm.mdx
  • docs/ensnode.io/src/content/docs/docs/integrate/integration-options/omnigraph-mcp.mdx

Comment thread .gitignore
Comment on lines +50 to +52
# Agent skills from npm packages (managed by skills-npm)
**/skills/npm-*
data-*

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Scope the new data-* ignore entry more narrowly.

As written, data-* ignores any matching file or directory anywhere in the repo, which can accidentally hide legitimate fixtures or docs assets. If these artifacts are only generated under the npm-managed skill tree, keep the pattern scoped there.

Proposed fix
- data-*
+ **/skills/npm-*/data-*
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Agent skills from npm packages (managed by skills-npm)
**/skills/npm-*
data-*
# Agent skills from npm packages (managed by skills-npm)
**/skills/npm-*
**/skills/npm-*/data-*
🤖 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 @.gitignore around lines 50 - 52, The `data-*` pattern on line 52 is too
broad and will ignore matching files or directories anywhere in the repository,
potentially hiding legitimate assets or fixtures. Scope this pattern more
narrowly by placing it under the same directory constraint as the npm skills
entry above it (the `**/skills/npm-*` pattern), so that `data-*` files are only
ignored when they exist within the npm-managed skills directory tree, not
globally across the entire repository.

@vercel vercel 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.

Additional Suggestion:

Missing MCP dependencies in apps/ensapi/package.json - @hono/mcp and @modelcontextprotocol/sdk are imported but not declared

Fix on Vercel

Copilot AI 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.

Pull request overview

Copilot reviewed 24 out of 27 changed files in this pull request and generated 4 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Generated file


The server exposes a single, read-only tool:

- **`omnigraph_query`** — accepts a GraphQL `query` (and optional `variables`) and returns the raw `{ data, errors }` JSON, exactly as the [HTTP endpoint](/docs/integrate/integration-options/omnigraph-graphql-api#1-the-endpoint) does. Because it's the full Omnigraph behind one tool, an agent can answer any question the Omnigraph can — resolve records, search Domains, list a user's Domains, and much more — without a fixed, hand-written tool per use case.
Comment on lines +116 to +129
"Before writing custom GraphQL:",
"1. Read omnigraph://schema/condensed or call omnigraph_schema.",
"2. Prefer omnigraph_query with exampleId (vetted queries) over guessing field names.",
"3. Read omnigraph://examples/index for available exampleId values.",
"",
"Entry points:",
"- account(by: { address }) — address-owned domains, permissions, reverse resolution",
"- domain(by: { name }) — a single name",
"- domains(where: { … }, first: N) — search canonical domains",
"",
"Common patterns:",
"- Address overview (primary name + profile + ENSv1/v2 counts): exampleId account-profile",
"- Primary name: account.resolve.primaryName(by: { chainName: ETHEREUM })",
"- Profile: domain.resolve.profile or primaryName.resolve.profile",
Comment thread .changeset/omnigraph-schema-reference.md
Comment on lines +252 to +256
/** Active MCP sessions keyed by `mcp-session-id` (one server + transport pair per client). */
const sessions = new Map<string, McpSession>();

/** Cap stored sessions to limit memory growth from repeated initialize requests. */
const MAX_MCP_SESSIONS = 200;
Copilot AI review requested due to automatic review settings June 18, 2026 20:39
@djstrong djstrong marked this pull request as ready for review June 18, 2026 20:42
@djstrong djstrong requested a review from a team as a code owner June 18, 2026 20:42

Copilot AI 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.

Pull request overview

Copilot reviewed 24 out of 27 changed files in this pull request and generated 4 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

Comment thread apps/ensapi/src/handlers/api/mcp/omnigraph-mcp-support.ts
Comment on lines +84 to +86
export function listGraphqlApiExampleQueryIds(): string[] {
return GRAPHQL_API_EXAMPLE_QUERIES.map((example) => example.id);
}
Comment on lines +270 to +275
if (sessions.size > MAX_MCP_SESSIONS) {
const oldestId = sessions.keys().next().value;
if (typeof oldestId === "string" && oldestId !== id) {
void closeSession(oldestId);
}
}
Comment thread .changeset/omnigraph-schema-reference.md Outdated
Comment thread apps/ensapi/src/handlers/api/mcp/omnigraph-mcp-support.ts Outdated
Comment thread apps/ensapi/src/handlers/api/mcp/mcp-api.ts
Comment thread packages/ensnode-sdk/src/omnigraph-api/example-queries.ts Outdated
Comment thread apps/ensapi/src/handlers/api/mcp/mcp-api.ts Outdated
@greptile-apps

greptile-apps Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR introduces a first-party MCP (Model Context Protocol) server at /api/mcp on every ENSApi instance, giving AI agents (Cursor, Claude Desktop, etc.) a standard, read-only GraphQL interface over ENS Omnigraph state. It also consolidates schema-reference and example-query logic into @ensnode/ensnode-sdk/internal so ENSApi MCP, enscli, and ensskills share one source of truth.

  • MCP server (mcp-api.ts): Streamable-HTTP sessions with LRU + 30-minute idle-TTL eviction, omnigraph_query and omnigraph_schema tools, and validation-hint injection for common GraphQL mistakes.
  • SDK helpers (schema-reference.ts, example-queries.ts): Bundled SDL for Vite/Rollup compatibility, condensed schema reference, vetted example queries with namespace-aware variables, and an account-profilehello-world alias now surfaced in all discoverable ID lists.
  • Docs and refactors: New omnigraph-mcp.mdx integration guide, ensskills/enscli refactored to use the shared SDK helpers, CI extended to verify the generated schema-SDL file.

Confidence Score: 4/5

Safe to merge with one fix: the condensed schema resource served to MCP agents tells them to run npx enscli for additional type lookups, when they should be using the omnigraph_schema MCP tool.

The MCP session lifecycle, eviction logic, validation hints, and example-query alias handling are all well-implemented and thoroughly tested. The one concrete issue is in buildCondensedSchemaReference: its "Other types" footer hardcodes npx enscli ensnode omnigraph schema <Type> — guidance that is meaningless to an AI agent reading the omnigraph://schema/condensed resource, since MCP clients cannot execute shell commands. The omnigraph_schema tool is the correct in-context replacement but is not mentioned in that section, leaving agents with a list of types they cannot explore via the prescribed method.

packages/ensnode-sdk/src/omnigraph-api/schema-reference.ts — the "Other types" section in buildCondensedSchemaReference

Important Files Changed

Filename Overview
apps/ensapi/src/handlers/api/mcp/mcp-api.ts New Hono app implementing the streamable-HTTP MCP endpoint; session management with LRU+idle-TTL eviction, proper double-close guards, and fire-and-forget cleanup with logged rejections.
apps/ensapi/src/handlers/api/mcp/omnigraph-mcp-support.ts MCP tool/resource helpers: examples index builder, validation-hint injection, and internal Hono dispatch for query execution — all well-encapsulated with DI namespace fallback.
packages/ensnode-sdk/src/omnigraph-api/schema-reference.ts New schema lookup helpers and buildCondensedSchemaReference; the "Other types" footer hardcodes an npx enscli instruction that is wrong when the output is served as an MCP resource where agents must use the omnigraph_schema tool instead.
packages/ensnode-sdk/src/omnigraph-api/example-queries.ts Adds title/description fields to all example queries, introduces GRAPHQL_API_EXAMPLE_ID_ALIASES (account-profilehello-world), and exposes listGraphqlApiExampleQueryIds + resolveGraphqlApiExampleQuery helpers; aliases are now included in the discoverable list, addressing the previous discoverability gap.
apps/ensapi/src/handlers/api/mcp/mcp-api.test.ts Comprehensive unit tests covering tool advertisement, resource reads, query execution, example resolution, validation hints, whitespace trimming, alias handling, and HTTP session lifecycle.
packages/ensnode-sdk/src/shared/zod-schemas.ts Adds makeOptionalTrimmedNonEmptyStringSchema — trims and coerces whitespace-only strings to undefined; cleanly placed alongside existing schema utilities.
packages/ensnode-sdk/scripts/inline-schema-sdl.mjs Build script that reads the enssdk GraphQL SDL and writes it as a TypeScript string constant, enabling bundler-safe static schema access without createRequire.
.github/workflows/test_ci.yml Extends the "verify generated files" CI step to also check the newly added packages/ensnode-sdk/src/omnigraph-api/generated/ directory.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Agent as AI Agent (MCP Client)
    participant ENSApi as ENSApi /api/mcp
    participant Session as McpSession (Server+Transport)
    participant Omnigraph as /api/omnigraph (Yoga)

    Agent->>ENSApi: POST initialize (no session header)
    ENSApi->>Session: createOmnigraphMcpServer() + StreamableHTTPTransport
    Session-->>ENSApi: onsessioninitialized(sessionId) → storeSession
    ENSApi-->>Agent: 200 mcp-session-id: id

    Agent->>ENSApi: GET (SSE stream, mcp-session-id header)
    ENSApi->>Session: touchSession + evictIdleSessions
    Session-->>Agent: text/event-stream open

    Agent->>ENSApi: POST omnigraph_query (mcp-session-id header)
    ENSApi->>Session: transport.handleRequest
    Session->>Omnigraph: internal fetch POST /api/omnigraph
    Omnigraph-->>Session: "{ data, errors } JSON"
    Session->>Session: appendValidationHints
    Session-->>Agent: "tool result { content: [text] }"

    Agent->>ENSApi: DELETE (mcp-session-id header)
    ENSApi->>Session: transport.handleRequest + closeSession
    Session->>Session: sessions.delete, transport.close, server.close
    ENSApi-->>Agent: 202
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Agent as AI Agent (MCP Client)
    participant ENSApi as ENSApi /api/mcp
    participant Session as McpSession (Server+Transport)
    participant Omnigraph as /api/omnigraph (Yoga)

    Agent->>ENSApi: POST initialize (no session header)
    ENSApi->>Session: createOmnigraphMcpServer() + StreamableHTTPTransport
    Session-->>ENSApi: onsessioninitialized(sessionId) → storeSession
    ENSApi-->>Agent: 200 mcp-session-id: id

    Agent->>ENSApi: GET (SSE stream, mcp-session-id header)
    ENSApi->>Session: touchSession + evictIdleSessions
    Session-->>Agent: text/event-stream open

    Agent->>ENSApi: POST omnigraph_query (mcp-session-id header)
    ENSApi->>Session: transport.handleRequest
    Session->>Omnigraph: internal fetch POST /api/omnigraph
    Omnigraph-->>Session: "{ data, errors } JSON"
    Session->>Session: appendValidationHints
    Session-->>Agent: "tool result { content: [text] }"

    Agent->>ENSApi: DELETE (mcp-session-id header)
    ENSApi->>Session: transport.handleRequest + closeSession
    Session->>Session: sessions.delete, transport.close, server.close
    ENSApi-->>Agent: 202
Loading

Reviews (5): Last reviewed commit: "feat(ensapi): refine Omnigraph MCP serve..." | Re-trigger Greptile

Comment thread apps/ensapi/src/handlers/api/mcp/mcp-api.ts
Comment thread apps/ensapi/src/handlers/api/mcp/mcp-api.ts Outdated
Comment thread packages/ensnode-sdk/src/omnigraph-api/example-queries.ts

Copilot AI 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.

Pull request overview

Copilot reviewed 25 out of 28 changed files in this pull request and generated 4 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

Comment thread apps/ensapi/src/handlers/api/mcp/mcp-api.ts
Comment thread packages/ensnode-sdk/package.json
Comment thread packages/ensnode-sdk/src/omnigraph-api/example-queries.ts

Copilot AI 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.

Pull request overview

Copilot reviewed 27 out of 30 changed files in this pull request and generated 2 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

Comment thread apps/ensapi/src/handlers/api/mcp/mcp-api.ts Outdated
Comment thread packages/ensnode-sdk/src/omnigraph-api/schema-reference.ts Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants