@ompo-design/mcp-server 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -2,7 +2,8 @@ import { execSync } from 'child_process';
2
2
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
3
3
  import { homedir } from 'os';
4
4
  import { join, resolve } from 'path';
5
- import { findProjectRoot } from './edit-store.js';
5
+ import { editsStoreReady } from './edit-store.js';
6
+ import { getOmpoEditsStorePath } from './edits-path.js';
6
7
  const PACKAGE_NAME = '@ompo-design/mcp-server';
7
8
  const SERVER_NAME = 'ompo';
8
9
  function resolveExecutable(name) {
@@ -120,21 +121,23 @@ function runGlobalSetup() {
120
121
  console.log(' 3. Open any Code project and run /mcp');
121
122
  console.log(' 4. Approve ompo if prompted');
122
123
  console.log(' 5. In Ompo, click Send on an edit before using the tools');
124
+ console.log(` Edits are stored in ${getOmpoEditsStorePath()}`);
123
125
  }
124
126
  function runDoctor() {
125
127
  const projectRoot = resolve(process.cwd());
126
128
  const configPath = join(projectRoot, '.mcp.json');
127
129
  const desktopPath = claudeDesktopConfigPath();
128
130
  const claudeCodePath = claudeCodeUserConfigPath();
129
- const editsRoot = findProjectRoot(projectRoot);
131
+ const storePath = getOmpoEditsStorePath();
130
132
  console.log('Ompo MCP doctor');
131
133
  console.log('');
132
- console.log(`Project folder: ${projectRoot}`);
134
+ console.log(`Current folder: ${projectRoot}`);
133
135
  console.log(`Node: ${process.version}`);
134
136
  console.log(`npx: ${resolveExecutable('npx')}`);
137
+ console.log(`Edits store: ${storePath}`);
135
138
  console.log('');
136
139
  for (const [label, path] of [
137
- ['Project config', configPath],
140
+ ['Project MCP config', configPath],
138
141
  ['Claude Desktop', desktopPath],
139
142
  ['Claude Code user', claudeCodePath]
140
143
  ]) {
@@ -153,11 +156,11 @@ function runDoctor() {
153
156
  }
154
157
  }
155
158
  console.log('');
156
- if (editsRoot) {
157
- console.log(`Edits: found ${join(editsRoot, '.ompo/edits/')}`);
159
+ if (editsStoreReady()) {
160
+ console.log('Edits: ready (Send from Ompo to add more)');
158
161
  }
159
162
  else {
160
- console.log('Edits: none yet (use Send in Ompo first)');
163
+ console.log('Edits: none yet (click Send in Ompo first)');
161
164
  }
162
165
  console.log('');
163
166
  console.log('Global install: npx @ompo-design/mcp-server setup-global');
@@ -168,7 +171,7 @@ function printProjectNextSteps(projectRoot) {
168
171
  console.log(` 1. cd ${projectRoot}`);
169
172
  console.log(' 2. Start Claude Code in this folder');
170
173
  console.log(' 3. Run /mcp and approve ompo if prompted');
171
- console.log(' 4. In Ompo, click Send on an edit (creates .ompo/edits/)');
174
+ console.log(' 4. In Ompo, click Send on an edit');
172
175
  console.log('');
173
176
  console.log('For all projects, run: npx @ompo-design/mcp-server setup-global');
174
177
  }
@@ -1,6 +1,6 @@
1
1
  import type { EditIndex, OmpoEditBundle } from './types.js';
2
- export declare function findProjectRoot(startDir?: string): string | null;
3
- export declare function listEdits(projectRoot: string): EditIndex['edits'];
4
- export declare function readEditBundle(projectRoot: string, editId: string): OmpoEditBundle;
5
- export declare function recordEditPull(projectRoot: string, editId: string): void;
6
- export declare function recordEditApplied(projectRoot: string, editId: string): void;
2
+ export declare function editsStoreReady(): boolean;
3
+ export declare function listEdits(): EditIndex['edits'];
4
+ export declare function readEditBundle(editId: string): OmpoEditBundle;
5
+ export declare function recordEditPull(editId: string): void;
6
+ export declare function recordEditApplied(editId: string): void;
@@ -1,67 +1,44 @@
1
1
  import { existsSync, readFileSync, writeFileSync } from 'fs';
2
- import { dirname, join, resolve } from 'path';
3
- import { OMPo_EDITS_DIR } from './types.js';
4
- function projectRootCandidates(startDir = process.cwd()) {
5
- const candidates = [
6
- process.env.OMPO_PROJECT_ROOT,
7
- process.env.CLAUDE_PROJECT_DIR,
8
- startDir
9
- ].filter((value) => Boolean(value?.trim()));
10
- return [...new Set(candidates.map((value) => resolve(value)))];
2
+ import { join } from 'path';
3
+ import { getOmpoEditsStorePath } from './edits-path.js';
4
+ function editsDirectory() {
5
+ return getOmpoEditsStorePath();
11
6
  }
12
- export function findProjectRoot(startDir = process.cwd()) {
13
- for (const candidate of projectRootCandidates(startDir)) {
14
- const found = findProjectRootFrom(candidate);
15
- if (found)
16
- return found;
17
- }
18
- return null;
19
- }
20
- function findProjectRootFrom(startDir) {
21
- let current = resolve(startDir);
22
- while (true) {
23
- const editsDirectory = join(current, OMPo_EDITS_DIR);
24
- if (existsSync(join(editsDirectory, 'index.json'))) {
25
- return current;
26
- }
27
- const parent = dirname(current);
28
- if (parent === current)
29
- return null;
30
- current = parent;
31
- }
7
+ export function editsStoreReady() {
8
+ return existsSync(join(editsDirectory(), 'index.json'));
32
9
  }
33
- function readIndex(projectRoot) {
34
- const indexPath = join(projectRoot, OMPo_EDITS_DIR, 'index.json');
10
+ function readIndex() {
11
+ const indexPath = join(editsDirectory(), 'index.json');
35
12
  return JSON.parse(readFileSync(indexPath, 'utf8'));
36
13
  }
37
- function writeIndex(projectRoot, index) {
38
- const indexPath = join(projectRoot, OMPo_EDITS_DIR, 'index.json');
14
+ function writeIndex(index) {
15
+ const indexPath = join(editsDirectory(), 'index.json');
39
16
  writeFileSync(indexPath, `${JSON.stringify(index, null, 2)}\n`, 'utf8');
40
17
  }
41
- export function listEdits(projectRoot) {
42
- return readIndex(projectRoot).edits;
18
+ export function listEdits() {
19
+ return readIndex().edits;
43
20
  }
44
- export function readEditBundle(projectRoot, editId) {
45
- const bundlePath = join(projectRoot, OMPo_EDITS_DIR, `${editId}.json`);
21
+ export function readEditBundle(editId) {
22
+ const bundlePath = join(editsDirectory(), `${editId}.json`);
46
23
  if (!existsSync(bundlePath)) {
47
24
  throw new Error(`Edit not found: ${editId}`);
48
25
  }
49
26
  return JSON.parse(readFileSync(bundlePath, 'utf8'));
50
27
  }
51
- export function recordEditPull(projectRoot, editId) {
52
- const index = readIndex(projectRoot);
28
+ export function recordEditPull(editId) {
29
+ const index = readIndex();
53
30
  const entry = index.edits.find((edit) => edit.id === editId);
54
31
  if (!entry)
55
32
  return;
56
33
  entry.pulls += 1;
57
34
  entry.lastPulledAt = new Date().toISOString();
58
- writeIndex(projectRoot, index);
35
+ writeIndex(index);
59
36
  }
60
- export function recordEditApplied(projectRoot, editId) {
61
- const index = readIndex(projectRoot);
37
+ export function recordEditApplied(editId) {
38
+ const index = readIndex();
62
39
  const entry = index.edits.find((edit) => edit.id === editId);
63
40
  if (!entry)
64
41
  return;
65
42
  entry.appliedAt = new Date().toISOString();
66
- writeIndex(projectRoot, index);
43
+ writeIndex(index);
67
44
  }
@@ -0,0 +1 @@
1
+ export declare function getOmpoEditsStorePath(): string;
@@ -0,0 +1,5 @@
1
+ import { homedir } from 'os';
2
+ import { join } from 'path';
3
+ export function getOmpoEditsStorePath() {
4
+ return join(homedir(), '.ompo', 'edits');
5
+ }
package/dist/index.js CHANGED
@@ -4,26 +4,27 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
4
4
  import { z } from 'zod';
5
5
  import { buildApplyPlan, explainEdit } from './apply-plan.js';
6
6
  import { runCli } from './cli.js';
7
- import { findProjectRoot, listEdits, readEditBundle, recordEditApplied, recordEditPull } from './edit-store.js';
7
+ import { editsStoreReady, listEdits, readEditBundle, recordEditApplied, recordEditPull } from './edit-store.js';
8
+ import { getOmpoEditsStorePath } from './edits-path.js';
8
9
  const server = new McpServer({
9
10
  name: 'ompo-mcp-server',
10
- version: '0.1.0'
11
+ version: '0.1.3'
11
12
  });
12
- function requireProjectRoot() {
13
- const projectRoot = findProjectRoot();
14
- if (!projectRoot) {
15
- throw new Error('No Ompo edits found. Run Send in Ompo first to create .ompo/edits in your project.');
13
+ function requireEditsStore() {
14
+ const storePath = getOmpoEditsStorePath();
15
+ if (!editsStoreReady()) {
16
+ throw new Error('No Ompo edits found. Click Send in Ompo first to save an edit, then try again.');
16
17
  }
17
- return projectRoot;
18
+ return storePath;
18
19
  }
19
- server.tool('list_edits', 'List Ompo edit bundles saved in the current project', {}, async () => {
20
- const projectRoot = requireProjectRoot();
21
- const edits = listEdits(projectRoot);
20
+ server.tool('list_edits', 'List Ompo edit bundles saved on this machine', {}, async () => {
21
+ const storePath = requireEditsStore();
22
+ const edits = listEdits();
22
23
  return {
23
24
  content: [
24
25
  {
25
26
  type: 'text',
26
- text: JSON.stringify({ projectRoot, edits }, null, 2)
27
+ text: JSON.stringify({ storePath, edits }, null, 2)
27
28
  }
28
29
  ]
29
30
  };
@@ -31,9 +32,9 @@ server.tool('list_edits', 'List Ompo edit bundles saved in the current project',
31
32
  server.tool('get_edit', 'Load a specific Ompo edit bundle by id', {
32
33
  id: z.string().describe('Edit id, e.g. ed_8K42P')
33
34
  }, async ({ id }) => {
34
- const projectRoot = requireProjectRoot();
35
- const bundle = readEditBundle(projectRoot, id);
36
- recordEditPull(projectRoot, id);
35
+ requireEditsStore();
36
+ const bundle = readEditBundle(id);
37
+ recordEditPull(id);
37
38
  return {
38
39
  content: [
39
40
  {
@@ -46,9 +47,9 @@ server.tool('get_edit', 'Load a specific Ompo edit bundle by id', {
46
47
  server.tool('explain_edit', 'Summarize what an Ompo edit changes', {
47
48
  id: z.string().describe('Edit id, e.g. ed_8K42P')
48
49
  }, async ({ id }) => {
49
- const projectRoot = requireProjectRoot();
50
- const bundle = readEditBundle(projectRoot, id);
51
- recordEditPull(projectRoot, id);
50
+ requireEditsStore();
51
+ const bundle = readEditBundle(id);
52
+ recordEditPull(id);
52
53
  return {
53
54
  content: [
54
55
  {
@@ -58,19 +59,19 @@ server.tool('explain_edit', 'Summarize what an Ompo edit changes', {
58
59
  ]
59
60
  };
60
61
  });
61
- server.tool('apply_edit', 'Build an apply plan for an Ompo edit. The agent should execute the plan against source files and only change listed properties.', {
62
+ server.tool('apply_edit', 'Build an apply plan for an Ompo edit. The agent should execute the plan against source files in the open codebase and only change listed properties.', {
62
63
  id: z.string().describe('Edit id, e.g. ed_8K42P'),
63
64
  markApplied: z
64
65
  .boolean()
65
66
  .optional()
66
67
  .describe('Set true after the agent successfully applies the edit')
67
68
  }, async ({ id, markApplied }) => {
68
- const projectRoot = requireProjectRoot();
69
- const bundle = readEditBundle(projectRoot, id);
70
- recordEditPull(projectRoot, id);
69
+ requireEditsStore();
70
+ const bundle = readEditBundle(id);
71
+ recordEditPull(id);
71
72
  const plan = buildApplyPlan(bundle);
72
73
  if (markApplied) {
73
- recordEditApplied(projectRoot, id);
74
+ recordEditApplied(id);
74
75
  }
75
76
  return {
76
77
  content: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ompo-design/mcp-server",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "MCP server for applying Ompo visual edits to a codebase",
5
5
  "type": "module",
6
6
  "license": "MIT",