Skip to content

mcp-server-git

Git operations MCP server

mcp-server-git is an MCP (Model Context Protocol) server implementation packaged as a kadi-package. It initializes the application DI container, logger, telemetry, high-resolution timers, and the TransportManager that accepts MCP JSON-RPC requests over STDIO or HTTP. It includes graceful shutdown handling and enforces MCP-compatible stdout behavior (plain JSON, no ANSI color) when running in STDIO mode or when launched without a TTY.

  • Startup flow
    • composeContainer() builds the tsyringe DI container and registers app services.
    • AppConfig is resolved from the container to obtain runtime configuration (notably logLevel and mcpTransportType).
    • initializePerformance_Hrt() boots a high-resolution timer used by request context/perf traces.
    • logger.initialize(…) sets up the Pino logger (with pino-pretty in dev or STDIO-safe JSON).
    • TransportManager is resolved from the container and started (transport start/registration occurs inside its implementation).
  • Runtime components
    • TransportManager: abstracts MCP transport implementations (STDIO vs HTTP). The server uses it to receive and terminate connections.
    • requestContextService: creates operation-scoped request contexts used throughout startup/shutdown logging.
    • shutdownOpenTelemetry: ensures tracing/metrics are flushed when terminating.
    • Logger: pino-based logger exposing initialize(…) and close() to manage lifecycle.
  • Shutdown
    • The shutdown(signal) function stops the TransportManager, flushes telemetry, closes the logger, and exits the process.
  • How it fits in AGENTS ecosystem
    • This package acts as an MCP host process exposing Git operations and any registered MCP tools (tools/abilities are wired into the container/TransportManager elsewhere). Agents (MCP clients) connect to this server over the configured transport to invoke tools. The server enforces MCP stdout constraints (JSON-only) when run as an MCP child process.

Data flow (high level)

  • MCP client -> Transport (STDIO or HTTP) -> TransportManager -> registered MCP handlers / tools -> business logic (Git ops, etc.) -> response back through TransportManager -> MCP client.

This package’s surface for embedding and operational control (functions visible or invoked in src/index.ts and imports):

API / ToolSourceDescriptionKey params
start()src/index.tsMain entry point that composes the container, initializes subsystems, and starts the server runtime.None (async)
shutdown(signal: string)src/index.tsGraceful shutdown sequence: stops TransportManager, flushes telemetry, closes logger, exits process.signal: process signal name
composeContainer()container/index.js (import)Composes DI container with application services and tokens. Called at startup.None
AppConfig (token)container/index.js (import)DI token used to resolve the runtime configuration object (contains logLevel, mcpTransportType, etc.).Resolved via container.resolve(AppConfig)
TransportManager (class/token)mcp-server/transports/manager.js (import)Manager for MCP transports; exposes stop(signal) which is called on shutdown.stop(signal: string): Promise
requestContextService.createRequestContext()utils/index.js (import)Creates structured context objects used in logs (operation, triggerEvent).{ operation: string, triggerEvent?: string }
logger.initialize(level, transportType)utils/internal/logger.js (import)Initializes the Pino logger with MCP-safe settings.(level: McpLogLevel, transportType?: string)
logger.close()utils/internal/logger.js (import)Flushes and closes logger streams.None
shutdownOpenTelemetry()utils/telemetry/instrumentation.js (import)Ensures OpenTelemetry SDK is shutdown and exporters are flushed.None
initializePerformance_Hrt()utils/index.js (import)Initialize high-resolution timer instrumentation used by request contexts.None

Notes:

  • If you need to add new MCP tools (Git subcommands, repository operations), register them into the DI container during composeContainer() so the TransportManager picks them up.

This module reads its runtime configuration from the DI-resolved AppConfig object. The following fields are used explicitly in src/index.ts:

  • config.logLevel (string)

    • Description: Effective MCP log level. Valid values enforced at startup: debug, info, notice, warning, error, crit, alert, emerg.
    • Typical env mapping: MCP_LOG_LEVEL
    • Default behavior: If invalid, the server warns on TTY and defaults to “info”.
  • config.mcpTransportType (string)

    • Description: Desired transport type the server should use (e.g., “stdio” or “http”). It is passed to the logger so STDIO path can use JSON-only output.
    • Typical env mapping: MCP_TRANSPORT_TYPE

Environment variables honored or manipulated at startup:

  • MCP_TRANSPORT_TYPE
    • Used to determine if the process should run in “stdio” or “http” transport mode. If unset or “stdio”, STDIO mode is assumed.
  • MCP_LOG_LEVEL
    • Referenced in startup logs and used to populate config.logLevel (via AppConfig). The code expects this name in logs and config.
  • NO_COLOR
    • This process sets NO_COLOR=1 when running in STDIO or when HTTP without TTY to comply with MCP JSON output requirements.
  • FORCE_COLOR
    • This process sets FORCE_COLOR=0 to disable forced colors.
  • NODE_ENV
    • Set in the build process to “production” for the default build in agent.json.

Secrets / Vault

  • This package does not directly manage secret storage. Secrets required by any subsystems (e.g., Git credentials, external APIs) should be provided via AppConfig injected by the container. Implement secret resolution (Vault, environment variables, or other secret providers) in the config module that populates AppConfig.

Key excerpts from src/index.ts showing startup, coloring rules, and graceful shutdown:

#!/usr/bin/env node
/**
* @fileoverview Main entry point for the MCP TypeScript Template application.
* This script initializes the configuration, sets up the logger, starts the
* MCP server (either via STDIO or HTTP transport), and handles graceful
* shutdown on process signals or unhandled errors.
* @module src/index
*/
// CRITICAL: Disable ANSI color codes BEFORE any imports when running via MCP clients.
// The MCP specification requires clean output. Even in HTTP mode, if launched via
// bunx/npx by an MCP client, colored output pollutes the client's process streams.
// This must be set before pino-pretty or any other library loads.
//
// We disable colors in these scenarios:
// 1. STDIO mode (always - MCP JSON-RPC on stdout)
// 2. HTTP mode when NOT in TTY (likely launched by MCP client via bunx/npx)
// 3. When explicitly disabled via existing NO_COLOR env var
const transportType = process.env.MCP_TRANSPORT_TYPE?.toLowerCase();
const isStdioMode = !transportType || transportType === 'stdio';
const isHttpModeWithoutTty = transportType === 'http' && !process.stdout.isTTY;
if (isStdioMode || isHttpModeWithoutTty) {
process.env.NO_COLOR = '1'; // Standard env var that most libraries respect
process.env.FORCE_COLOR = '0'; // Disable forced coloring
}
const shutdown = async (signal: string): Promise<void> => {
if (isShuttingDown) {
return;
}
isShuttingDown = true;
const shutdownContext = requestContextService.createRequestContext({
operation: 'ServerShutdown',
triggerEvent: signal,
});
logger.info(
`Received ${signal}. Initiating graceful shutdown...`,
shutdownContext,
);
try {
if (transportManager) {
await transportManager.stop(signal);
}
logger.info(
'Graceful shutdown completed successfully. Exiting.',
shutdownContext,
);
// Shutdown OpenTelemetry and logger last to ensure all telemetry and logs are sent.
await shutdownOpenTelemetry();
await logger.close();
process.exit(0);
} catch (error) {
logger.error(
'Critical error during shutdown process.',
error as Error,
shutdownContext,
);
try {
await logger.close();
} catch (_e) {
// Ignore errors during final logger close attempt
}
process.exit(1);
}
};
const start = async (): Promise<void> => {
try {
// Initialize DI container first
composeContainer();
// Now it's safe to resolve dependencies
config = container.resolve<typeof appConfigType>(AppConfig);
} catch (_error) {
// This will catch the McpError from parseConfig
if (process.stdout.isTTY) {
// The config module already logged the details. We just provide a final message.
console.error('Halting due to critical configuration error.');
}
// Ensure OpenTelemetry is shut down if it was started before the error
await shutdownOpenTelemetry();
process.exit(1);
}
// Initialize the high-resolution timer
await initializePerformance_Hrt();
const validMcpLogLevels: McpLogLevel[] = [
'debug',
'info',
'notice',
'warning',
'error',
'crit',
'alert',
'emerg',
];
const initialLogLevelConfig = config.logLevel;
let validatedMcpLogLevel: McpLogLevel = 'info';
if (validMcpLogLevels.includes(initialLogLevelConfig as McpLogLevel)) {
validatedMcpLogLevel = initialLogLevelConfig as McpLogLevel;
} else {
if (process.stdout.isTTY) {
console.warn(
`[Startup Warning] Invalid MCP_LOG_LEVEL "${initialLogLevelConfig}". Defaulting to "info".`,
);
}
}
// Pass transport type to logger to ensure STDIO mode uses plain JSON (no ANSI colors)
await logger.initialize(validatedMcpLogLevel, config.mcpTransportType);
logger.info(
`Logger initialized. Effective MCP logging level: ${validatedMcpLogLevel}.`,
requestContextService.createRequestContext({ operation: 'LoggerInit' }),
);

When adding or modifying handlers that perform Git operations, ensure they are registered into the DI container so TransportManager exposes them to MCP callers.

Runtime dependencies (selected):

  • pino, pino-pretty — logging
  • reflect-metadata — tsyringe / decorator metadata
  • tsyringe — dependency injection (listed in devDependencies but used at runtime via container)
  • @hono/mcp, @hono/node-server — MCP / HTTP server helpers (devDependencies include @hono/mcp)
  • OpenTelemetry libs — tracing/metrics instrumentation (multiple @opentelemetry/* packages)
  • axios, repomix, execa, etc. — utilities likely used by Git/tool implementations

Full package lists are present in the agent manifest; key entries include:

  • dependencies: pino, pino-pretty, reflect-metadata
  • devDependencies: @hono/mcp, @modelcontextprotocol/sdk, @opentelemetry/*, tsyringe, typescript, bun-types, etc.

Abilities / exposed capabilities

  • This package acts as an MCP host exposing tooling (Git ops) over MCP transports. The primary abilities are the MCP handler surface (registered in the container) and transport lifecycle management (TransportManager).
  • Exposed utility APIs used by tools include logger, requestContextService, and telemetry helpers.

Who depends on this package

  • External MCP clients/agents connect to this process as an MCP server to invoke Git-related abilities.
  • Other internal packages that implement concrete Git tools (not shown here) will be wired into this server via the DI container.

Notes for contributors

  • All color-suppression logic must run before importing logging/instrumentation libraries. The initial transport detection block at the top of src/index.ts is required to comply with MCP output requirements.
  • When adding configuration fields to AppConfig, ensure the parse/config module logs helpful messages and throws McpError (the startup flow expects parse errors to be reported and the process to exit).
  • Any new tools should register into the DI container during composeContainer() so TransportManager can expose them through MCP transports.