Skip to content

Commit e75f040

Browse files
committed
feat: Added wrap-up prompt to save database context
1 parent 0bdd9af commit e75f040

File tree

6 files changed

+150
-11
lines changed

6 files changed

+150
-11
lines changed

.changeset/gold-dancers-judge.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"ansible-database-mcp": minor
3+
---
4+
5+
Added `wrap-up` prompt to save database context

src/assets/wrap-up.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
Please analyze the SQL queries and database structure information from our previous conversation to generate a structured schema document in the following format.
2+
3+
If you have access to Claude Desktop, please create the document as an artifact.
4+
If you have access to the file system, please create the document as a file.
5+
6+
# Writing Guidelines
7+
8+
1. Conciseness
9+
- Include only essential information
10+
- Remove unnecessary explanations
11+
- Focus on information immediately usable in practice
12+
2. Consistency
13+
- Use table names and column names exactly as they appear in the actual database
14+
- Maintain case sensitivity
15+
- Unify naming conventions
16+
3. Practicality
17+
- Format should allow copy-paste for actual query writing
18+
- Specify JOIN conditions and WHERE clause conditions
19+
- Prioritize frequently used patterns
20+
4. Scalability
21+
- Maintain existing structure when adding new information
22+
- Enable independent management by section
23+
24+
# Important Notes
25+
26+
- Exclude sensitive information (passwords, personal data, etc.)
27+
- Focus on structure and relationships rather than actual data values
28+
- Focus on subject of the conversation, do not include any information that is not directly related to the subject
29+
- Prioritize key information over overly detailed explanations
30+
- Keep section titles and headings as provided, but write section content in the user's language
31+
32+
# Output Format
33+
34+
## [DB Schema] {Main Task or Domain Name}
35+
36+
### Keywords
37+
{List key keywords related to this query, separated by commas}
38+
- Table names, Column names
39+
- Business terms
40+
- Domain-specific terms
41+
42+
### Datasource
43+
* {Database Platform Name}
44+
* {List all tables used in database.table format}
45+
* {For Databricks platform, use catalog.database.table format}
46+
* {Each table should be listed with its full path}
47+
48+
### Database Structure
49+
50+
#### {Database Name 1}
51+
{Brief description of the database's main purpose and role}
52+
53+
##### Main Tables
54+
| Table | Key Columns | Description |
55+
|-------|-------------|-------------|
56+
| {table_name} | {column_name}(PK), {column_name}(FK→referenced_table), {other important columns} | {table purpose} |
57+
58+
#### {Database Name 2}
59+
{Additional database information if needed}
60+
61+
### Context
62+
63+
#### Key Relationships
64+
{parent_table}.{column} → {child_table}.{column}
65+
{Add comments if relationship explanation is needed}
66+
67+
#### Additional Notes
68+
- {Performance-related considerations}
69+
- {Data characteristics information}
70+
- {Business logic specifics}
71+
- {Index information (if important)}
72+
73+
### Common Queries
74+
{List common query patterns}
75+
```sql
76+
-- {JOIN pattern description}
77+
SELECT {key columns}
78+
FROM {table1} t1
79+
JOIN {table2} t2 ON t1.{column} = t2.{column}
80+
WHERE {common conditions}
81+
82+
-- {Additional JOIN pattern}
83+
{Actual usable JOIN query}
84+
```

src/config/paths.ts

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*/
44
import path from 'node:path';
55
import { fileURLToPath } from 'node:url';
6-
import { existsSync } from 'node:fs';
6+
import { existsSync, readFileSync } from 'node:fs';
77

88
const __dirname = path.dirname(fileURLToPath(import.meta.url));
99
const PROJECT_ROOT = path.resolve(__dirname, '../..');
@@ -16,15 +16,32 @@ export class Paths {
1616
return path.join(PROJECT_ROOT, 'env.yml');
1717
}
1818

19+
static getAssetsPath(): string {
20+
if (process.env.ASSETS_FILE) {
21+
return path.resolve(process.env.ASSETS_FILE);
22+
}
23+
24+
const defaultPath = process.env.NODE_ENV === 'development'
25+
? path.join(PROJECT_ROOT, 'src', 'assets')
26+
: path.join(PROJECT_ROOT, 'dist', 'assets');
27+
28+
return existsSync(defaultPath) ? defaultPath : path.join(PROJECT_ROOT, 'src', 'assets');
29+
}
30+
31+
static getAssetsTextFile(fileName: string): string {
32+
const defaultPath = path.join(this.getAssetsPath(), fileName);
33+
if (existsSync(defaultPath)) {
34+
return readFileSync(defaultPath, 'utf-8');
35+
}
36+
return '';
37+
}
38+
1939
static getContextPath(): string {
2040
if (process.env.CONTEXT_FILE) {
2141
return path.resolve(process.env.CONTEXT_FILE);
2242
}
23-
24-
const defaultPath = process.env.NODE_ENV === 'development'
25-
? path.join(PROJECT_ROOT, 'src', 'assets', 'context.md')
26-
: path.join(PROJECT_ROOT, 'dist', 'assets', 'context.md');
27-
43+
44+
const defaultPath = path.join(this.getAssetsPath(), 'context.md');
2845
return existsSync(defaultPath) ? defaultPath : path.join(PROJECT_ROOT, 'src', 'assets', 'context.md');
2946
}
3047

@@ -33,10 +50,7 @@ export class Paths {
3350
return path.resolve(process.env.GUIDE_FILE);
3451
}
3552

36-
const defaultPath = process.env.NODE_ENV === 'development'
37-
? path.join(PROJECT_ROOT, 'src', 'assets', 'guide.md')
38-
: path.join(PROJECT_ROOT, 'dist', 'assets', 'guide.md');
39-
53+
const defaultPath = path.join(this.getAssetsPath(), 'guide.md');
4054
return existsSync(defaultPath) ? defaultPath : path.join(PROJECT_ROOT, 'src', 'assets', 'guide.md');
4155
}
4256

src/middleware.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/
44
import { query, connectionInfo, listTables, getTable } from './tools/index.js';
55
import * as ask from './prompts/ask.js';
66
import * as context from './resources/context.js';
7+
import * as wrapUp from "./prompts/wrap-up.js";
78

89
export const mcpMiddleware = async (req: Request, res: Response) => {
910
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
@@ -60,6 +61,14 @@ export const mcpMiddleware = async (req: Request, res: Response) => {
6061
}
6162
);
6263

64+
server.registerPrompt(
65+
wrapUp.definition.name,
66+
{
67+
description: wrapUp.definition.description
68+
},
69+
wrapUp.handler
70+
);
71+
6372
server.registerResource(
6473
context.definition.name,
6574
context.definition.uri,

src/prompts/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
export * as ask from './ask.js';
1+
export * as ask from './ask.js';
2+
export * as wrapUp from './wrap-up.js';

src/prompts/wrap-up.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { Paths } from "@/config/paths";
2+
import { PromptDefinition } from "@/types/modelcontextprotocol";
3+
import { GetPromptResult } from "@modelcontextprotocol/sdk/types";
4+
5+
const wrapUpContent = Paths.getAssetsTextFile('wrap-up.md');
6+
7+
const definition: PromptDefinition = {
8+
name: 'wrap-up',
9+
description: 'Wrap up the conversation and generate a schema document'
10+
};
11+
12+
const handler: () => Promise<GetPromptResult> = async () => {
13+
return {
14+
messages: [
15+
{
16+
role: 'user',
17+
content: {
18+
type: 'text',
19+
text: wrapUpContent
20+
}
21+
}
22+
]
23+
};
24+
};
25+
26+
export { definition, handler };

0 commit comments

Comments
 (0)