Skip to content

Add @shopify/mcp — MCP server for Admin API#6923

Open
tizmagik wants to merge 2 commits intomainfrom
jg/mcp
Open

Add @shopify/mcp — MCP server for Admin API#6923
tizmagik wants to merge 2 commits intomainfrom
jg/mcp

Conversation

@tizmagik
Copy link

@tizmagik tizmagik commented Mar 2, 2026

Summary

  • Adds @shopify/mcp, a standalone MCP server that exposes the Shopify Admin API to AI coding agents (Claude, Cursor, etc.)
  • Adds cli-kit/src/public/node/mcp.ts — non-interactive device auth API for MCP's stdio context
  • Two tools: shopify_auth_login (device auth flow) and shopify_graphql (Admin API queries/mutations)

Install:

claude mcp add shopify -- npx -y -p @shopify/mcp

How it works

  1. Agent calls shopify_auth_login → gets device auth URL
  2. User visits URL in browser and approves
  3. Agent calls shopify_graphql → background polling completes auth, executes query
  4. Sessions are cached in-memory for the lifetime of the MCP server process

Key decisions

  • Standalone package — no dependency added to @shopify/cli, published independently as @shopify/mcp
  • In-process auth — uses cli-kit's existing device auth + token exchange, wrapped in a non-interactive API
  • Mutation safety — mutations require explicit allowMutations: true parameter
  • Session management — caches sessions in-memory, clears on 401, guards against concurrent auth races

Test plan

Details

Quick overview

This PR adds @shopify/mcp — a standalone MCP server that lets AI coding agents (Claude, Cursor, etc.) query the Shopify Admin API. Two tools: shopify_auth_login
(device auth) and shopify_graphql (Admin API queries/mutations).

Setup

  git checkout jg/mcp
  pnpm install
  cd packages/mcp
  pnpm build

Run tests

  pnpm vitest run     # 30 tests
  pnpm eslint "src/**/*.ts"
  pnpm tsc --noEmit

Manual testing

Option 1: Test with Claude Code

  claude mcp add shopify -- node /path/to/cli/packages/mcp/bin/shopify-mcp.js

Then in Claude: "List the products on my-store.myshopify.com"

The agent should:

  1. Call shopify_auth_login → you'll see a URL to open
  2. Open the URL, approve in browser
  3. Call shopify_graphql → get results

Option 2: Test the server directly with MCP Inspector

  npx @modelcontextprotocol/inspector node packages/mcp/bin/shopify-mcp.js

This opens a web UI where you can call tools manually.

Option 3: Test server startup only

  node packages/mcp/bin/shopify-mcp.js

Should hang (waiting for stdio input). Ctrl+C to exit — should shut down cleanly.

New `@shopify/mcp` package that exposes the Shopify Admin API to AI
coding agents via the Model Context Protocol (MCP). Uses cli-kit's
existing auth and GraphQL infrastructure.

Tools:
- shopify_auth_login: device auth flow for non-interactive MCP context
- shopify_graphql: execute Admin API queries/mutations

Install:
  claude mcp add shopify -- npx -y -p @shopify/mcp

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@tizmagik tizmagik requested review from a team as code owners March 2, 2026 14:55
@github-actions
Copy link
Contributor

github-actions bot commented Mar 2, 2026

Coverage report

St.
Category Percentage Covered / Total
🟡 Statements 78.29% 14520/18546
🟡 Branches 72.8% 7222/9920
🟡 Functions 78.69% 3692/4692
🟡 Lines 78.6% 13726/17462

Test suite run success

3785 tests passing in 1448 suites.

Report generated by 🧪jest coverage report action from aea6854

@binks-code-reviewer
Copy link

binks-code-reviewer bot commented Mar 2, 2026

🤖 Code Review · #projects-dev-ai for questions
React with 👍/👎 or reply — all feedback helps improve the agent.

Complete - 1 findings

📋 History

✅ 2 findings → ✅ No issues → ✅ 1 findings

@ryancbahan
Copy link
Contributor

We have a separate package dev-mcp and are currently looking at how cli <> mcp integration should be handled. Would love to chat more about your use case, but overall we'll need to discuss the long-term strategy here.


const server = createServer()
const transport = new StdioServerTransport()
await server.connect(transport)

Choose a reason for hiding this comment

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

Unhandled startup failure can crash the MCP process (missing connect error handling)

await server.connect(transport) runs at top-level without try/catch. If connect() rejects (stdio issues, SDK incompatibility, permissions), Node will treat it as an unhandled rejection during module initialization and terminate the process, making the tool disappear in agent environments.

@tizmagik tizmagik force-pushed the jg/mcp branch 4 times, most recently from a990132 to 3bb8072 Compare March 2, 2026 20:56
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Contributor

github-actions bot commented Mar 2, 2026

Differences in type declarations

We detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:

  • Some seemingly private modules might be re-exported through public modules.
  • If the branch is behind main you might see odd diffs, rebase main into this branch.

New type declarations

packages/cli-kit/dist/public/node/mcp.d.ts
import type { AdminSession } from './session.js';
export interface DeviceCodeResponse {
    deviceCode: string;
    userCode: string;
    verificationUri: string;
    verificationUriComplete: string;
    expiresIn: number;
    interval: number;
}
/**
 * Requests a device authorization code for MCP non-interactive auth.
 *
 * @returns The device code response with verification URL.
 */
export declare function requestDeviceCode(): Promise<DeviceCodeResponse>;
/**
 * Completes device authorization by polling for approval and exchanging tokens.
 *
 * @param deviceCode - The device code from requestDeviceCode.
 * @param interval - Polling interval in seconds.
 * @param storeFqdn - The normalized store FQDN.
 * @returns An admin session with token and store FQDN.
 */
export declare function completeDeviceAuth(deviceCode: string, interval: number, storeFqdn: string): Promise<AdminSession>;

Existing type declarations

We found no diffs with existing type declarations

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