Skip to content

Commit a20cf35

Browse files
committed
feat: add MCP resources for documentation
- Add examples and response format as MCP resources - Create build script to handle version and resource files - Add custom instructions for REST API testing - Update server name to 'rest-api' in configuration examples - Add version tracking through build-time generation
1 parent 6a26651 commit a20cf35

File tree

10 files changed

+302
-8
lines changed

10 files changed

+302
-8
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
node_modules/
22
build/
3+
src/version.ts
4+
.DS_Store
35
*.log
4-
.env*

CLINE-CUSTOM-INSTRUCTIONS.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# REST API Testing Instructions
2+
3+
Use this tool when testing, debugging, or interacting with REST API endpoints. The tool provides comprehensive request/response information and handles authentication automatically.
4+
5+
## When to Use
6+
7+
- Testing specific API endpoints
8+
- Debugging API responses
9+
- Verifying API functionality
10+
- Checking response times
11+
- Validating request/response formats
12+
- Testing local development servers
13+
- Testing API sequences
14+
- Verifying error handling
15+
16+
## Key Features
17+
18+
- Supports GET, POST, PUT, DELETE methods
19+
- Handles authentication (Basic, Bearer, API Key)
20+
- Normalizes endpoints automatically
21+
- Provides detailed response information
22+
- Configurable SSL verification
23+
24+
## Getting Started
25+
26+
1. Check available examples:
27+
```typescript
28+
<access_mcp_resource>
29+
<server_name>rest-api</server_name>
30+
<uri>rest-api://examples</uri>
31+
</access_mcp_resource>
32+
```
33+
34+
2. Review response format:
35+
```typescript
36+
<access_mcp_resource>
37+
<server_name>rest-api</server_name>
38+
<uri>rest-api://response-format</uri>
39+
</access_mcp_resource>
40+
```
41+
42+
## Important Notes
43+
44+
- Review API implementation for expected behavior
45+
- Handle sensitive data appropriately
46+
- Consider rate limits and API constraints

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Add to `C:\Users\<YourUsername>\AppData\Roaming\Code\User\globalStorage\saoudriz
3636
```json
3737
{
3838
"mcpServers": {
39-
"rest": {
39+
"rest-api": {
4040
"command": "node",
4141
"args": [
4242
"C:/Users/<YourUsername>/AppData/Roaming/npm/node_modules/dkmaker-mcp-rest-api/build/index.js"
@@ -64,7 +64,7 @@ Add to `~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude
6464
```json
6565
{
6666
"mcpServers": {
67-
"rest": {
67+
"rest-api": {
6868
"command": "npx",
6969
"args": [
7070
"-y",

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@
99
},
1010
"files": [
1111
"build",
12+
"scripts",
1213
"README.md",
1314
"LICENSE"
1415
],
1516
"scripts": {
17+
"prebuild": "node scripts/build.js",
1618
"build": "tsc",
19+
"postbuild": "node scripts/build.js",
1720
"prepare": "npm run build",
1821
"watch": "tsc --watch",
1922
"inspector": "npx @modelcontextprotocol/inspector build/index.js"

scripts/build.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/usr/bin/env node
2+
import fs from 'fs/promises';
3+
import path from 'path';
4+
import { fileURLToPath } from 'url';
5+
6+
const __filename = fileURLToPath(import.meta.url);
7+
const __dirname = path.dirname(__filename);
8+
9+
async function main() {
10+
const pkg = JSON.parse(
11+
await fs.readFile(
12+
path.join(__dirname, '..', 'package.json'),
13+
'utf8'
14+
)
15+
);
16+
17+
const versionPath = path.join(__dirname, '..', 'src', 'version.ts');
18+
19+
// Always generate version.ts with actual values during build
20+
const content = `// Auto-generated by build script
21+
export const VERSION = '${pkg.version}';
22+
export const PACKAGE_NAME = '${pkg.name}';
23+
export const SERVER_NAME = '${pkg.name.split('-').slice(-2).join('-')}';
24+
`;
25+
26+
await fs.writeFile(versionPath, content);
27+
console.log('Generated version.ts with package values');
28+
29+
// Copy resources to build directory
30+
const resourcesSrcDir = path.join(__dirname, '..', 'src', 'resources');
31+
const resourcesBuildDir = path.join(__dirname, '..', 'build', 'resources');
32+
33+
try {
34+
await fs.mkdir(resourcesBuildDir, { recursive: true });
35+
const files = await fs.readdir(resourcesSrcDir);
36+
37+
for (const file of files) {
38+
await fs.copyFile(
39+
path.join(resourcesSrcDir, file),
40+
path.join(resourcesBuildDir, file)
41+
);
42+
}
43+
console.log('Copied resources to build directory');
44+
} catch (error) {
45+
console.error('Error copying resources:', error);
46+
throw error;
47+
}
48+
}
49+
50+
main().catch(console.error);

src/index.ts

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ import {
55
CallToolRequestSchema,
66
ErrorCode,
77
ListToolsRequestSchema,
8+
ListResourcesRequestSchema,
9+
ReadResourceRequestSchema,
810
McpError,
911
} from '@modelcontextprotocol/sdk/types.js';
1012
import axios, { AxiosInstance, AxiosRequestConfig, Method } from 'axios';
13+
import { VERSION, PACKAGE_NAME, SERVER_NAME } from './version.js';
1114

1215
if (!process.env.REST_BASE_URL) {
1316
throw new Error('REST_BASE_URL environment variable is required');
@@ -49,12 +52,13 @@ class RestTester {
4952
private async setupServer() {
5053
this.server = new Server(
5154
{
52-
name: 'rest-tester',
53-
version: '0.1.0',
55+
name: SERVER_NAME,
56+
version: VERSION,
5457
},
5558
{
5659
capabilities: {
5760
tools: {},
61+
resources: {},
5862
},
5963
}
6064
);
@@ -69,6 +73,7 @@ class RestTester {
6973
});
7074

7175
this.setupToolHandlers();
76+
this.setupResourceHandlers();
7277

7378
this.server.onerror = (error) => console.error('[MCP Error]', error);
7479
process.on('SIGINT', async () => {
@@ -77,6 +82,65 @@ class RestTester {
7782
});
7883
}
7984

85+
private setupResourceHandlers() {
86+
this.server.setRequestHandler(ListResourcesRequestSchema, async () => ({
87+
resources: [
88+
{
89+
uri: `${SERVER_NAME}://examples`,
90+
name: 'REST API Usage Examples',
91+
description: 'Detailed examples of using the REST API testing tool',
92+
mimeType: 'text/markdown'
93+
},
94+
{
95+
uri: `${SERVER_NAME}://response-format`,
96+
name: 'Response Format Documentation',
97+
description: 'Documentation of the response format and structure',
98+
mimeType: 'text/markdown'
99+
}
100+
]
101+
}));
102+
103+
this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
104+
const uriPattern = new RegExp(`^${SERVER_NAME}://(.+)$`);
105+
const match = request.params.uri.match(uriPattern);
106+
107+
if (!match) {
108+
throw new McpError(
109+
ErrorCode.InvalidRequest,
110+
`Invalid resource URI format: ${request.params.uri}`
111+
);
112+
}
113+
114+
const resource = match[1];
115+
const fs = await import('fs');
116+
const path = await import('path');
117+
118+
try {
119+
const url = await import('url');
120+
const __filename = url.fileURLToPath(import.meta.url);
121+
const __dirname = path.dirname(__filename);
122+
123+
// In the built app, resources are in build/resources
124+
// In development, they're in src/resources
125+
const resourcePath = path.join(__dirname, 'resources', `${resource}.md`);
126+
const content = await fs.promises.readFile(resourcePath, 'utf8');
127+
128+
return {
129+
contents: [{
130+
uri: request.params.uri,
131+
mimeType: 'text/markdown',
132+
text: content
133+
}]
134+
};
135+
} catch (error) {
136+
throw new McpError(
137+
ErrorCode.InvalidRequest,
138+
`Resource not found: ${resource}`
139+
);
140+
}
141+
});
142+
}
143+
80144
private setupToolHandlers() {
81145
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
82146
tools: [

src/resources/examples.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# REST API Testing Examples
2+
3+
## Basic GET Request
4+
```typescript
5+
{
6+
"method": "GET",
7+
"endpoint": "/users"
8+
}
9+
```
10+
11+
## GET with Query Parameters
12+
```typescript
13+
{
14+
"method": "GET",
15+
"endpoint": "/users?role=admin&status=active"
16+
}
17+
```
18+
19+
## POST Request with Body
20+
```typescript
21+
{
22+
"method": "POST",
23+
"endpoint": "/users",
24+
"body": {
25+
"name": "John Doe",
26+
"email": "john@example.com"
27+
}
28+
}
29+
```
30+
31+
## Request with Custom Headers
32+
```typescript
33+
{
34+
"method": "GET",
35+
"endpoint": "/secure-resource",
36+
"headers": {
37+
"Custom-Header": "value",
38+
"Another-Header": "another-value"
39+
}
40+
}
41+
```
42+
43+
## PUT Request Example
44+
```typescript
45+
{
46+
"method": "PUT",
47+
"endpoint": "/users/123",
48+
"body": {
49+
"name": "Updated Name",
50+
"status": "inactive"
51+
}
52+
}
53+
```
54+
55+
## DELETE Request Example
56+
```typescript
57+
{
58+
"method": "DELETE",
59+
"endpoint": "/users/123"
60+
}

src/resources/response-format.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Response Format Documentation
2+
3+
The REST API testing tool returns a comprehensive JSON response containing request details, response information, and validation results.
4+
5+
## Response Structure
6+
7+
```json
8+
{
9+
"request": {
10+
"url": "http://api.example.com/users",
11+
"method": "GET",
12+
"headers": {},
13+
"body": null,
14+
"authMethod": "none"
15+
},
16+
"response": {
17+
"statusCode": 200,
18+
"statusText": "OK",
19+
"timing": "123ms",
20+
"headers": {},
21+
"body": {}
22+
},
23+
"validation": {
24+
"isError": false,
25+
"messages": ["Request completed successfully"]
26+
}
27+
}
28+
```
29+
30+
## Response Fields
31+
32+
### Request Details
33+
- `url`: Full URL including base URL and endpoint
34+
- `method`: HTTP method used
35+
- `headers`: Request headers sent
36+
- `body`: Request body (if applicable)
37+
- `authMethod`: Authentication method used (none, basic, bearer, or apikey)
38+
39+
### Response Details
40+
- `statusCode`: HTTP status code
41+
- `statusText`: Status message
42+
- `timing`: Request duration in milliseconds
43+
- `headers`: Response headers received
44+
- `body`: Response body content
45+
46+
### Validation
47+
- `isError`: true if status code >= 400
48+
- `messages`: Array of validation or error messages
49+
50+
## Error Response Example
51+
52+
```json
53+
{
54+
"error": {
55+
"message": "Connection refused",
56+
"code": "ECONNREFUSED",
57+
"request": {
58+
"url": "http://api.example.com/users",
59+
"method": "GET",
60+
"headers": {},
61+
"body": null
62+
}
63+
}
64+
}

src/version.ts.template

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Template file for TypeScript during development
2+
// The actual version.ts will be generated during build
3+
4+
export const VERSION = '0.0.0';
5+
export const PACKAGE_NAME = 'dkmaker-mcp-rest-api';
6+
export const SERVER_NAME = 'rest-api';

0 commit comments

Comments
 (0)