@sdods/mcp 0.2.0

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.
Files changed (43) hide show
  1. package/LICENSE +17 -0
  2. package/dist/.tsbuildinfo +1 -0
  3. package/dist/cli.d.ts +50 -0
  4. package/dist/cli.js +171 -0
  5. package/dist/fs.d.ts +45 -0
  6. package/dist/fs.js +184 -0
  7. package/dist/index.d.ts +15 -0
  8. package/dist/index.js +15 -0
  9. package/dist/install/index.d.ts +46 -0
  10. package/dist/install/index.js +146 -0
  11. package/dist/prompts/index.d.ts +33 -0
  12. package/dist/prompts/index.js +151 -0
  13. package/dist/proposals.d.ts +71 -0
  14. package/dist/proposals.js +188 -0
  15. package/dist/registry/adapters.d.ts +46 -0
  16. package/dist/registry/adapters.js +76 -0
  17. package/dist/registry/registry.d.ts +96 -0
  18. package/dist/registry/registry.js +141 -0
  19. package/dist/resources.d.ts +5 -0
  20. package/dist/resources.js +130 -0
  21. package/dist/server.d.ts +29 -0
  22. package/dist/server.js +143 -0
  23. package/dist/tools/analyze.d.ts +87 -0
  24. package/dist/tools/analyze.js +820 -0
  25. package/dist/tools/data.d.ts +18 -0
  26. package/dist/tools/data.js +153 -0
  27. package/dist/tools/feature.d.ts +53 -0
  28. package/dist/tools/feature.js +340 -0
  29. package/dist/tools/index.d.ts +12 -0
  30. package/dist/tools/index.js +23 -0
  31. package/dist/tools/issue-schedule.d.ts +22 -0
  32. package/dist/tools/issue-schedule.js +193 -0
  33. package/dist/tools/project.d.ts +11 -0
  34. package/dist/tools/project.js +144 -0
  35. package/dist/tools/proposal.d.ts +19 -0
  36. package/dist/tools/proposal.js +89 -0
  37. package/dist/tools/run.d.ts +49 -0
  38. package/dist/tools/run.js +387 -0
  39. package/dist/transports/http.d.ts +40 -0
  40. package/dist/transports/http.js +151 -0
  41. package/dist/transports/stdio.d.ts +6 -0
  42. package/dist/transports/stdio.js +15 -0
  43. package/package.json +57 -0
@@ -0,0 +1,29 @@
1
+ import { McpServer } from '@modelcontextprotocol/server';
2
+ import type { ToolRegistry } from './registry/registry.js';
3
+ import { type Capability, type Principal, type ToolContext, type ToolLogger } from './registry/registry.js';
4
+ export declare const MCP_SERVER_NAME = "sdods";
5
+ export declare const MCP_SERVER_VERSION = "0.1.0";
6
+ export interface BuildServerOptions {
7
+ rootDir?: string;
8
+ cwd?: string;
9
+ project?: string;
10
+ env?: string;
11
+ caps?: Array<Capability | string> | 'all';
12
+ principal?: Principal;
13
+ registry?: ToolRegistry;
14
+ logger?: ToolLogger;
15
+ onProgress?: ToolContext['onProgress'];
16
+ }
17
+ export declare function stderrLogger(prefix?: string): ToolLogger;
18
+ export declare function parseCaps(input?: Array<Capability | string> | string | 'all'): Set<Capability>;
19
+ export declare const LOCAL_ADMIN: Principal;
20
+ export declare function buildToolContext(opts?: BuildServerOptions): ToolContext;
21
+ /** Build a fully wired MCP server (tools + resources + prompts) for a context. */
22
+ export declare function buildSdodsMcpServer(opts?: BuildServerOptions): {
23
+ server: McpServer;
24
+ ctx: ToolContext;
25
+ registry: ToolRegistry;
26
+ toolCount: number;
27
+ };
28
+ export declare function registerPrompts(server: McpServer, ctx: ToolContext): void;
29
+ //# sourceMappingURL=server.d.ts.map
package/dist/server.js ADDED
@@ -0,0 +1,143 @@
1
+ import { z } from 'zod';
2
+ import { McpServer } from '@modelcontextprotocol/server';
3
+ import { cliOrNote } from './cli.js';
4
+ import { findRepoRoot } from './cli.js';
5
+ import { toMcpServer } from './registry/adapters.js';
6
+ import { ALL_CAPABILITIES, DEFAULT_CAPABILITIES, } from './registry/registry.js';
7
+ import { registerResources } from './resources.js';
8
+ import { ROLE_PROMPTS, renderPrompt } from './prompts/index.js';
9
+ import { createRegistry } from './tools/index.js';
10
+ export const MCP_SERVER_NAME = 'sdods';
11
+ export const MCP_SERVER_VERSION = '0.1.0';
12
+ export function stderrLogger(prefix = 'sdods-mcp') {
13
+ const w = (level, msg, data) => {
14
+ if (process.env.SDODS_MCP_QUIET === '1' && level !== 'warn')
15
+ return;
16
+ process.stderr.write(`[${prefix}] ${level} ${msg}${data !== undefined ? ' ' + JSON.stringify(data) : ''}\n`);
17
+ };
18
+ return {
19
+ info: (m, d) => w('info', m, d),
20
+ warn: (m, d) => w('warn', m, d),
21
+ debug: (m, d) => (process.env.SDODS_DEBUG ? w('debug', m, d) : undefined),
22
+ };
23
+ }
24
+ export function parseCaps(input) {
25
+ if (input === 'all')
26
+ return new Set(ALL_CAPABILITIES);
27
+ const list = Array.isArray(input)
28
+ ? input
29
+ : typeof input === 'string'
30
+ ? input.split(',')
31
+ : DEFAULT_CAPABILITIES;
32
+ const caps = new Set();
33
+ for (const raw of list) {
34
+ const c = String(raw).trim();
35
+ if (c === 'all')
36
+ return new Set(ALL_CAPABILITIES);
37
+ if (!c)
38
+ continue;
39
+ if (!ALL_CAPABILITIES.includes(c))
40
+ throw new Error(`Unknown capability "${c}". Known: ${ALL_CAPABILITIES.join(', ')}`);
41
+ caps.add(c);
42
+ }
43
+ return caps;
44
+ }
45
+ export const LOCAL_ADMIN = { name: 'local', scopes: ['*'], via: 'stdio' };
46
+ export function buildToolContext(opts = {}) {
47
+ const rootDir = opts.rootDir ?? findRepoRoot(opts.cwd ?? process.cwd());
48
+ const principal = opts.principal ?? LOCAL_ADMIN;
49
+ return {
50
+ rootDir,
51
+ cwd: opts.cwd ?? rootDir,
52
+ principal: principal.scopes.includes('*') ? { ...principal, scopes: allScopes() } : principal,
53
+ caps: parseCaps(opts.caps),
54
+ project: opts.project,
55
+ env: opts.env,
56
+ onProgress: opts.onProgress,
57
+ logger: opts.logger ?? stderrLogger(),
58
+ };
59
+ }
60
+ function allScopes() {
61
+ // lazy import to avoid a static dependency on the scope list shape
62
+ return [
63
+ 'orgs:read',
64
+ 'orgs:admin',
65
+ 'workspaces:read',
66
+ 'workspaces:write',
67
+ 'projects:read',
68
+ 'projects:write',
69
+ 'envs:read',
70
+ 'envs:write',
71
+ 'datasets:read',
72
+ 'datasets:write',
73
+ 'runs:read',
74
+ 'runs:write',
75
+ 'runs:ingest',
76
+ 'artifacts:read',
77
+ 'features:read',
78
+ 'features:write',
79
+ 'agents:run',
80
+ 'agents:review',
81
+ 'integrations:read',
82
+ 'integrations:write',
83
+ 'schedules:read',
84
+ 'schedules:write',
85
+ 'processes:read',
86
+ 'processes:write',
87
+ 'users:admin',
88
+ 'audit:read',
89
+ ];
90
+ }
91
+ /** Build a fully wired MCP server (tools + resources + prompts) for a context. */
92
+ export function buildSdodsMcpServer(opts = {}) {
93
+ const ctx = buildToolContext(opts);
94
+ const registry = opts.registry ?? createRegistry();
95
+ const server = new McpServer({ name: MCP_SERVER_NAME, version: MCP_SERVER_VERSION }, {
96
+ capabilities: { tools: {}, resources: {}, prompts: {}, logging: {} },
97
+ instructions: 'SDODS is an automation and orchestration platform with a reusable architecture. Tools are grouped by prefix: project_*, workspace_*, process_*, feature_*, step_*, run_*, heal_*, data_*, analyze_*, issue_*, schedule_*, proposal_*. Write tools only create proposals; nothing touches the working tree until a person accepts. Start with project_list, then feature_list / step_list before writing scenarios.',
98
+ });
99
+ const toolCount = toMcpServer(registry, server, ctx);
100
+ registerResources(server, ctx);
101
+ registerPrompts(server, ctx);
102
+ return { server, ctx, registry, toolCount };
103
+ }
104
+ export function registerPrompts(server, ctx) {
105
+ for (const role of Object.keys(ROLE_PROMPTS)) {
106
+ const p = ROLE_PROMPTS[role];
107
+ server.registerPrompt(`sdods-${role === 'planner' ? 'plan' : role === 'generator' ? 'generate' : role === 'healer' ? 'heal' : role === 'upgrader' ? 'upgrade' : 'review'}`, {
108
+ title: p.title,
109
+ description: p.description,
110
+ argsSchema: z.object({
111
+ project: z.string().optional().describe('project slug'),
112
+ env: z.string().optional(),
113
+ goal: z.string().optional().describe('what to plan/generate/heal/upgrade/review'),
114
+ }),
115
+ }, async (args) => {
116
+ const project = args.project ?? ctx.project;
117
+ let steps;
118
+ if (project) {
119
+ const data = await cliOrNote(['steps', 'list', '-p', project], { cwd: ctx.rootDir, timeoutMs: 120_000 }).catch(() => undefined);
120
+ if (Array.isArray(data))
121
+ steps = data.map((s) => `${s.keyword ?? ''} ${s.pattern ?? ''}`.trim());
122
+ }
123
+ return {
124
+ description: p.description,
125
+ messages: [
126
+ {
127
+ role: 'user',
128
+ content: {
129
+ type: 'text',
130
+ text: renderPrompt(role, {
131
+ project,
132
+ env: args.env ?? ctx.env,
133
+ goal: args.goal,
134
+ steps,
135
+ }),
136
+ },
137
+ },
138
+ ],
139
+ };
140
+ });
141
+ }
142
+ }
143
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1,87 @@
1
+ import { z } from 'zod';
2
+ export interface Evidence {
3
+ finding: string;
4
+ confidence: number;
5
+ evidence: string[];
6
+ }
7
+ export declare function analyzeApp(appPath: string): Record<string, unknown>;
8
+ export declare function analyzeCoverage(root: string): {
9
+ routes: {
10
+ route: string;
11
+ path: string;
12
+ scenarios: number;
13
+ viaPageObject: boolean;
14
+ suites: string[];
15
+ }[];
16
+ endpoints: {
17
+ scenarios: number;
18
+ suites: string[];
19
+ module: string;
20
+ endpoint: string;
21
+ }[];
22
+ modules: {
23
+ module: string;
24
+ features: number;
25
+ scenarios: number;
26
+ }[];
27
+ uncoveredRoutes: string[];
28
+ totals: {
29
+ features: number;
30
+ scenarios: number;
31
+ };
32
+ };
33
+ export declare function analyzeBestPractices(root: string): {
34
+ findings: {
35
+ severity: "error" | "warning" | "info";
36
+ rule: string;
37
+ file: string;
38
+ line?: number;
39
+ message: string;
40
+ fix?: string;
41
+ }[];
42
+ stats: {
43
+ features: number;
44
+ errors: number;
45
+ warnings: number;
46
+ };
47
+ frequentSteps: {
48
+ text: string;
49
+ uses: number;
50
+ }[];
51
+ };
52
+ export declare function analyzeLocators(root: string): {
53
+ byKind: Record<string, number>;
54
+ total: number;
55
+ fragile: {
56
+ file: string;
57
+ line: number;
58
+ kind: string;
59
+ snippet: string;
60
+ healed: boolean;
61
+ }[];
62
+ score: number;
63
+ };
64
+ export declare function analyzeChangeImpact(root: string, rootDir: string, range: string): {
65
+ range: string;
66
+ changedFiles: string[];
67
+ impacted: {
68
+ feature: string;
69
+ reasons: string[];
70
+ }[];
71
+ suggestion: string;
72
+ };
73
+ export declare const analyzeTools: (import("../registry/registry.js").SdodsTool<{
74
+ path: z.ZodString;
75
+ }> | import("../registry/registry.js").SdodsTool<{
76
+ project: z.ZodString;
77
+ }> | import("../registry/registry.js").SdodsTool<{
78
+ project: z.ZodString;
79
+ range: z.ZodDefault<z.ZodString>;
80
+ }> | import("../registry/registry.js").SdodsTool<{
81
+ runId: z.ZodString;
82
+ fingerprint: z.ZodString;
83
+ }> | import("../registry/registry.js").SdodsTool<{
84
+ project: z.ZodString;
85
+ limit: z.ZodOptional<z.ZodNumber>;
86
+ }>)[];
87
+ //# sourceMappingURL=analyze.d.ts.map