Skip to content

Conversation

@rgraulus
Copy link

Summary

This PR hardens the existing MCP server runtime and adds a minimal, gated Agent-to-Agent (A2A) adapter for future multi-agent interoperability.
It builds on the Developerayo/concordium-mcp-server baseline and introduces a production-ready container, strict runtime posture, health checks, and foundational observability.
A2A support is behind a feature flag and can be enabled via environment variables.


Rationale

  • Improve security and operational posture before extending MCP functionality.

  • Prepare the Concordium MCP Server for agentic commerce and multi-agent (A2A) protocols such as Google A2A and AP2.

  • Maintain backward compatibility while introducing extensibility for future PLT/XCF tools.


Scope (v1)

New features

  • Hardened Express runtime

    • HTTPS-only expectation; HSTS handled at edge.

    • CORS allowlist, bearer-token authentication.

    • Global timeouts, per-tool rate limits, structured JSON logging.

  • Health & readiness endpoints

    • /healthz – liveness

    • /readyz – readiness (stub; passes until finality lag probe added in PR 2)

  • A2A adapter (feature-flagged)

    • /.well-known/agent-card.json for discovery

    • /a2a/jsonrpc minimal JSON-RPC 2.0 endpoint (message/send, tasks/get, tasks/cancel)

    • In-memory task store (non-persistent)

    • Disabled by default (A2A_ENABLED=false)

  • Configuration

    • Centralized src/config.ts for environment variables.

    • Example .env.example included.

  • Observability

    • Pino JSON logging (trace ID, tool, latency).

    • Trace middleware (withTrace).

  • Security

    • Helmet, CORS, rate limiting, deadline middleware.

    • Non-root runtime user, distroless container, pinned base digest.

  • CI / Ops

    • Dependabot weekly scans for npm + GitHub Actions.

    • CodeQL workflow (JavaScript) enabled.


Configuration (environment variables)

Variable | Purpose | Default -- | -- | -- PORT | Server port | 8080 CCD_NODE | Concordium gRPC endpoint | — MCP_AUTH_TOKEN | Bearer token for protected routes | — CORS_ALLOWLIST | Comma-separated allowed origins | — A2A_ENABLED | Enable A2A adapter | false A2A_PUBLIC_URL | Public A2A JSON-RPC URL | — XCF_ENABLED | Future XCF integration (off) | false SCAN_MAX_BLOCKS | Scan block-range cap | 2000

Files Added / Modified

Dockerfile .env.example src/config.ts src/middleware/security.ts src/observability.ts src/health.ts src/a2a/* src/tools/router.ts src/server.ts (hardened) src/http-server.ts (simplified entry) .github/dependabot.yml .github/workflows/codeql.yml

Future Work (PR #2)

  • Implement PLT (CIS-7) finalized transfer tool (getFinalizedTransfers).

  • Add PLT registry and resolvePlt.

  • Introduce XCF helpers (watchChallenge, verifyReceipt).

  • Extend structured logging with finality lag probe.

@rgraulus
Copy link
Author

rgraulus commented Oct 17, 2025

👋 Question #1 for Maintainer
I noticed the existing Dockerfile contained steps for both npm and pnpm.
Would you prefer that we standardize the build to use pnpm (since a pnpm-lock.yaml is already present), or keep it strictly npm for consistency with the current repo setup?
I can update the Dockerfile immediately once you confirm your preference.

👋 Question #2 for Maintainer
I noticed that src/server.ts currently mixes the original MCP stdio server logic with the new Express HTTP runtime (health, tools, A2A).
Would you prefer that we:
1️⃣ keep both as separate entrypoints (e.g., server.ts for HTTP and mcp-stdio.ts for stdio),
2️⃣ fully migrate to the new Express runtime, or
3️⃣ unify them behind a feature flag?

I can refactor accordingly once you confirm your preferred structure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant