clingo-mcp 0.1.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.
package/README.md ADDED
@@ -0,0 +1,81 @@
1
+ # Clingo-MCP Server
2
+
3
+ A neurosymbolic AI server combining Clingo's Answer Set Programming (ASP) solver with Model Context Protocol (MCP) for hybrid AI applications.
4
+
5
+ **Features:**
6
+ - Answer Set Programming solver via WebAssembly
7
+ - In-memory program session: build up programs incrementally
8
+ - Session management: save/load ASP programs to disk
9
+ - Six core tools:
10
+ - `solve`: Run an ASP program and get answer sets
11
+ - `addToProgram`: Add facts/rules to current session
12
+ - `clearProgram`: Clear the current session
13
+ - `getProgram`: View the current program
14
+ - `saveSession`: Persist program to disk
15
+ - `loadSession`: Restore previous sessions
16
+ - Type safety via Zod schema validation for all I/O
17
+ - WebAssembly runtime: Clingo compiled to WASM
18
+
19
+ **Integration with Cline/Roo/Copilot:**
20
+ ```json
21
+ {
22
+ "mcpServers": {
23
+ "clingo-mcp": {
24
+ "command": "node",
25
+ "args": [
26
+ "clingo-mcp/dist/index.js"
27
+ ],
28
+ "disabled": false,
29
+ "alwaysAllow": [
30
+ "solve",
31
+ "addToProgram",
32
+ "clearProgram",
33
+ "getProgram",
34
+ "saveSession",
35
+ "loadSession"
36
+ ],
37
+ "timeout": 30
38
+ }
39
+ }
40
+ }
41
+ ```
42
+
43
+ **Development:**
44
+ ```bash
45
+ git clone https://github.com/NewJerseyStyle/clingo-mcp
46
+ cd clingo-mcp
47
+ npm install
48
+ npm run build
49
+ ```
50
+
51
+ **Example ASP Program:**
52
+ ```asp
53
+ % Define persons
54
+ person(alice).
55
+ person(bob).
56
+ person(carol).
57
+
58
+ % Define friendships
59
+ friend(alice, bob).
60
+ friend(bob, carol).
61
+
62
+ % Rule: friendship is symmetric
63
+ friend(X, Y) :- friend(Y, X).
64
+
65
+ % Rule: transitive friendship
66
+ indirect_friend(X, Z) :- friend(X, Y), friend(Y, Z), X != Z.
67
+ ```
68
+
69
+ **Example Usage:**
70
+ ```javascript
71
+ // Using the solve tool
72
+ const result = await solve({
73
+ program: "a. b :- a. {c; d}.",
74
+ models: 0 // 0 = all models
75
+ });
76
+ ```
77
+
78
+ ---
79
+
80
+ **Acknowledgements:**
81
+ Built with [clingo-wasm](https://github.com/domoritz/clingo-wasm) and [MCP Protocol](https://modelcontextprotocol.io)
@@ -0,0 +1,214 @@
1
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ import { CallToolRequestSchema, ListToolsRequestSchema, ToolSchema, } from "@modelcontextprotocol/sdk/types.js";
3
+ import { z } from "zod";
4
+ import { zodToJsonSchema } from "zod-to-json-schema";
5
+ import clingo from "clingo-wasm";
6
+ const ToolInputSchema = ToolSchema.shape.inputSchema;
7
+ import * as fs from 'fs';
8
+ import * as path from 'path';
9
+ /* Schemas for Clingo tools */
10
+ const SolveSchema = z.object({
11
+ program: z.string().describe("The ASP (Answer Set Programming) program to solve"),
12
+ models: z.number().optional().default(0).describe("Number of models to compute (0 = all models)"),
13
+ });
14
+ const AddToProgramSchema = z.object({
15
+ code: z.string().describe("ASP facts or rules to add to the current program"),
16
+ });
17
+ const SaveSessionSchema = z.object({
18
+ filename: z.string().describe("The name to save the session under"),
19
+ });
20
+ const LoadSessionSchema = z.object({
21
+ filename: z.string().describe("The name of the session to load"),
22
+ });
23
+ var ToolName;
24
+ (function (ToolName) {
25
+ ToolName["SOLVE"] = "solve";
26
+ ToolName["ADD_TO_PROGRAM"] = "addToProgram";
27
+ ToolName["CLEAR_PROGRAM"] = "clearProgram";
28
+ ToolName["GET_PROGRAM"] = "getProgram";
29
+ ToolName["SAVE_SESSION"] = "saveSession";
30
+ ToolName["LOAD_SESSION"] = "loadSession";
31
+ })(ToolName || (ToolName = {}));
32
+ // Sessions directory path relative to project root
33
+ const SESSIONS_DIR = './clingo-sessions';
34
+ export const createServer = async () => {
35
+ // In-memory program storage (since clingo-wasm doesn't maintain state)
36
+ let currentProgram = "";
37
+ // Ensure sessions directory exists
38
+ if (!fs.existsSync(SESSIONS_DIR)) {
39
+ fs.mkdirSync(SESSIONS_DIR, { recursive: true });
40
+ }
41
+ const server = new Server({
42
+ name: "clingo-mcp",
43
+ version: "0.1.0",
44
+ }, {
45
+ capabilities: {
46
+ tools: {},
47
+ },
48
+ });
49
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
50
+ const tools = [
51
+ {
52
+ name: ToolName.SOLVE,
53
+ description: "Solves an ASP (Answer Set Programming) program using Clingo and returns the answer sets. The program can include the current session program.",
54
+ inputSchema: zodToJsonSchema(SolveSchema),
55
+ },
56
+ {
57
+ name: ToolName.ADD_TO_PROGRAM,
58
+ description: "Adds ASP facts or rules to the current in-memory program session",
59
+ inputSchema: zodToJsonSchema(AddToProgramSchema),
60
+ },
61
+ {
62
+ name: ToolName.CLEAR_PROGRAM,
63
+ description: "Clears the current in-memory program session",
64
+ inputSchema: { type: "object", properties: {}, required: [] },
65
+ },
66
+ {
67
+ name: ToolName.GET_PROGRAM,
68
+ description: "Returns the current in-memory ASP program",
69
+ inputSchema: { type: "object", properties: {}, required: [] },
70
+ },
71
+ {
72
+ name: ToolName.SAVE_SESSION,
73
+ description: "Saves the current ASP program session to a file for later loading",
74
+ inputSchema: zodToJsonSchema(SaveSessionSchema),
75
+ },
76
+ {
77
+ name: ToolName.LOAD_SESSION,
78
+ description: "Loads a previously saved ASP program session",
79
+ inputSchema: zodToJsonSchema(LoadSessionSchema),
80
+ },
81
+ ];
82
+ return { tools };
83
+ });
84
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
85
+ const { name, arguments: args } = request.params;
86
+ if (name === ToolName.SOLVE) {
87
+ const validatedArgs = SolveSchema.parse(args);
88
+ const { program, models } = validatedArgs;
89
+ try {
90
+ // Combine current session program with the provided program
91
+ const fullProgram = currentProgram ? `${currentProgram}\n${program}` : program;
92
+ // Run clingo with the combined program
93
+ const result = await clingo.run(fullProgram, models);
94
+ return {
95
+ content: [{
96
+ type: "text",
97
+ text: JSON.stringify(result, null, 2),
98
+ }]
99
+ };
100
+ }
101
+ catch (e) {
102
+ return {
103
+ content: [{
104
+ type: "text",
105
+ text: `Error solving program: ${e}`,
106
+ annotations: { priority: 1.0 }
107
+ }]
108
+ };
109
+ }
110
+ }
111
+ if (name === ToolName.ADD_TO_PROGRAM) {
112
+ const validatedArgs = AddToProgramSchema.parse(args);
113
+ const { code } = validatedArgs;
114
+ try {
115
+ // Append to current program with a newline separator
116
+ if (currentProgram) {
117
+ currentProgram += "\n" + code;
118
+ }
119
+ else {
120
+ currentProgram = code;
121
+ }
122
+ return {
123
+ content: [{
124
+ type: "text",
125
+ text: `Added to program. Current program:\n${currentProgram}`
126
+ }]
127
+ };
128
+ }
129
+ catch (e) {
130
+ return {
131
+ content: [{
132
+ type: "text",
133
+ text: `Error adding to program: ${e}`,
134
+ annotations: { priority: 1.0 }
135
+ }]
136
+ };
137
+ }
138
+ }
139
+ if (name === ToolName.CLEAR_PROGRAM) {
140
+ currentProgram = "";
141
+ return {
142
+ content: [{
143
+ type: "text",
144
+ text: "Program cleared successfully"
145
+ }]
146
+ };
147
+ }
148
+ if (name === ToolName.GET_PROGRAM) {
149
+ return {
150
+ content: [{
151
+ type: "text",
152
+ text: currentProgram ? `Current program:\n${currentProgram}` : "No program loaded"
153
+ }]
154
+ };
155
+ }
156
+ if (name === ToolName.SAVE_SESSION) {
157
+ const validatedArgs = SaveSessionSchema.parse(args);
158
+ const filename = validatedArgs.filename;
159
+ try {
160
+ if (!currentProgram.trim()) {
161
+ throw new Error("No program content to save");
162
+ }
163
+ const sessionPath = path.join(SESSIONS_DIR, `${filename}.lp`);
164
+ fs.writeFileSync(sessionPath, currentProgram);
165
+ return {
166
+ content: [{
167
+ type: "text",
168
+ text: `Session saved to ${sessionPath}`
169
+ }]
170
+ };
171
+ }
172
+ catch (e) {
173
+ return {
174
+ content: [{
175
+ type: "text",
176
+ text: `Error saving session: ${e}`,
177
+ annotations: { priority: 1.0 }
178
+ }]
179
+ };
180
+ }
181
+ }
182
+ if (name === ToolName.LOAD_SESSION) {
183
+ const validatedArgs = LoadSessionSchema.parse(args);
184
+ const filename = validatedArgs.filename;
185
+ try {
186
+ const sessionPath = path.join(SESSIONS_DIR, `${filename}.lp`);
187
+ if (!fs.existsSync(sessionPath)) {
188
+ throw new Error(`Session file ${sessionPath} not found`);
189
+ }
190
+ currentProgram = fs.readFileSync(sessionPath, 'utf8');
191
+ return {
192
+ content: [{
193
+ type: "text",
194
+ text: `Session loaded from ${sessionPath}\nCurrent program:\n${currentProgram}`
195
+ }]
196
+ };
197
+ }
198
+ catch (e) {
199
+ return {
200
+ content: [{
201
+ type: "text",
202
+ text: `Error loading session: ${e}`,
203
+ annotations: { priority: 1.0 }
204
+ }]
205
+ };
206
+ }
207
+ }
208
+ throw new Error(`Unknown tool: ${name}`);
209
+ });
210
+ const cleanup = async () => {
211
+ // Clean up any resources if needed when server shuts down
212
+ };
213
+ return { server, cleanup };
214
+ };
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { createServer } from "./clingoServer.js";
4
+ async function main() {
5
+ const transport = new StdioServerTransport();
6
+ const { server, cleanup } = await createServer();
7
+ await server.connect(transport);
8
+ // Cleanup on exit
9
+ process.on("SIGINT", async () => {
10
+ await cleanup();
11
+ await server.close();
12
+ process.exit(0);
13
+ });
14
+ }
15
+ main().catch((error) => {
16
+ console.error("Server error:", error);
17
+ process.exit(1);
18
+ });
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "clingo-mcp",
3
+ "version": "0.1.0",
4
+ "description": "MCP server for interacting with Clingo ASP solver via WebAssembly",
5
+ "license": "MIT",
6
+ "author": "NewJerseyStyle",
7
+ "homepage": "https://github.com/NewJerseyStyle/clingo-mcp",
8
+ "bugs": "https://github.com/NewJerseyStyle/clingo-mcp/issues",
9
+ "type": "module",
10
+ "bin": {
11
+ "mcp-server-clingo": "dist/index.js"
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "scripts": {
17
+ "build": "tsc -p tsconfig.json && shx chmod +x dist/*.js",
18
+ "prepare": "npm run build",
19
+ "watch": "tsc --watch",
20
+ "start": "node dist/index.js"
21
+ },
22
+ "dependencies": {
23
+ "@modelcontextprotocol/sdk": "1.0.1",
24
+ "clingo-wasm": "latest",
25
+ "zod": "^3.23.8",
26
+ "zod-to-json-schema": "^3.23.5"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^22.14.1",
30
+ "shx": "^0.3.4",
31
+ "typescript": "^5.6.2",
32
+ "vite": "^6.3.0"
33
+ }
34
+ }