Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions src/createJwt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { execFile, ExecFileException } from 'child_process';

interface CreateJwtOptions {
name?: string;
issuer?: string;
audiences?: string[];
roles?: string[];
scopes?: string[];
claims?: string[];
validFor?: number;
signingKey?: string;
}

export const createJwt = async (options: CreateJwtOptions): Promise<string> => {
const args: string[] = ['jwt', 'create'];

if (options.name) {
args.push('--name', options.name);
}
if (options.issuer) {
args.push('--issuer', options.issuer);
}
if (options.audiences) {
for (const audience of options.audiences) {
args.push('--audiences', audience);
}
}
if (options.roles) {
for (const role of options.roles) {
args.push('--roles', role);
}
}
if (options.scopes) {
for (const scope of options.scopes) {
args.push('--scopes', scope);
}
}
if (options.claims) {
for (const claim of options.claims) {
args.push('--claims', claim);
}
}
if (options.validFor !== undefined) {
args.push('--valid-for', options.validFor.toString());
}
if (options.signingKey) {
args.push('--signing-key', options.signingKey);
}

return new Promise<string>((resolve, reject) => {
execFile('devproxy', args, (error: ExecFileException | null, stdout: string, stderr: string) => {
if (error) {
reject(`Error creating JWT: ${error.message}`);
return;
}

if (stderr) {
reject(`Error creating JWT: ${stderr}`);
return;
}

resolve(stdout.trim());
});
});
};
20 changes: 20 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { createRequire } from 'module';
import { z } from 'zod';
import { createJwt } from './createJwt.js';
import { findDocs } from './findDocs.js';
import { getVersion } from './getVersion.js';
import { getBestPractices } from './getBestPractices.js';
Expand Down Expand Up @@ -47,5 +48,24 @@ server.tool('GetVersion', 'Gets the currently installed Dev Proxy version',
})
);

server.tool('CreateJwt', 'Creates a JSON Web Token (JWT) using the Dev Proxy jwt create command. Returns the generated token.',
{
name: z.string().optional().describe('The name of the user to create the token for'),
issuer: z.string().optional().describe('The token issuer'),
audiences: z.array(z.string()).optional().describe('The audiences for the token'),
roles: z.array(z.string()).optional().describe('The roles to include in the token'),
scopes: z.array(z.string()).optional().describe('The scopes to include in the token'),
claims: z.array(z.string()).optional().describe('Custom claims to include in the token in the format name:value'),
validFor: z.number().optional().describe('The token validity in minutes'),
signingKey: z.string().optional().describe('The signing key for the token. Must be at least 32 characters'),
},
{
title: 'Create JWT',
},
async ({ name, issuer, audiences, roles, scopes, claims, validFor, signingKey }) => ({
content: [{ type: 'text', text: await createJwt({ name, issuer, audiences, roles, scopes, claims, validFor, signingKey }) }]
})
);

const transport = new StdioServerTransport();
await server.connect(transport);