Skip to main content
Glama
leyriel

Fake Pennylane MCP Server

by leyriel

Fake Pennylane MCP Server

An open-source fake server that emulates the Pennylane MCP experience for local development, automated tests, demos, and CI pipelines — without requiring a real Pennylane account or real accounting data.

Status: working early implementation. The repository now includes a runnable Streamable HTTP MCP server, deterministic fixtures, scenario packs, static bearer auth, and a fake OAuth flow for callback/integration testing.

Why this project exists

Pennylane MCP is useful, but it is hard to validate an integration when you do not have:

  • a real Pennylane account,

  • a portfolio of test companies and customers,

  • deterministic accounting fixtures,

  • a safe environment for demos and CI.

This project solves that gap by providing a predictable, developer-friendly test double for a Pennylane-like MCP server.

Related MCP server: Local Financial MCP Mock Server

Current capabilities

The current implementation provides:

  • a Streamable HTTP MCP server,

  • deterministic fixture loading from JSON,

  • scenario-pack selection,

  • optional static bearer token authentication,

  • a fake OAuth authorization-code flow for end-to-end callback testing,

  • automated local tests for runtime, scenarios, and auth.

Exposed tools

  • get_context

  • get_company

  • list_companies

  • list_customers

  • get_customer

  • list_customer_invoices

Quickstart

Requirements

  • Python 3.11+

  • uv

Install dependencies

cd /home/leyriel/dev/fake-pennylane-mcp-server
uv sync

Run the server

Default fixture dataset, no auth:

uv run python -m fake_pennylane_mcp_server --host 127.0.0.1 --port 8000

With a scenario pack:

uv run python -m fake_pennylane_mcp_server \
  --host 127.0.0.1 \
  --port 8000 \
  --scenario unpaid_invoice

With static bearer auth:

uv run python -m fake_pennylane_mcp_server \
  --host 127.0.0.1 \
  --port 8000 \
  --auth-mode static_bearer \
  --bearer-token test-secret-token

With fake OAuth flow:

uv run python -m fake_pennylane_mcp_server \
  --host 127.0.0.1 \
  --port 8000 \
  --auth-mode fake_oauth

Run with Docker Compose

Build and start the default server:

docker compose up --build

Run detached:

docker compose up --build -d

Stop it:

docker compose down

Compose now defaults to a more exotic host port (18080) to avoid common collisions. If you still need a different host port, override it explicitly:

PUBLISHED_PORT=28080 docker compose up --build -d

Use a scenario pack:

SCENARIO_NAME=unpaid_invoice docker compose up --build

Use static bearer auth:

AUTH_MODE=static_bearer BEARER_TOKEN=test-secret-token docker compose up --build

Compose now defaults to AUTH_MODE=fake_oauth for easier browser-based local integration tests. To switch explicitly:

AUTH_MODE=fake_oauth docker compose up --build

By default Compose exposes the server on http://127.0.0.1:${PUBLISHED_PORT:-18080}/mcp, publishes OAuth metadata on the same host port, and mounts ./fixtures read-only into the container.

Scenario packs

The default fixture file currently exposes these scenario packs:

  • default

  • customer_found

  • customer_not_found

  • unpaid_invoice

  • multi_company

Each scenario narrows the deterministic dataset to a stable business situation.

Authentication modes

none

No Authorization header is required.

static_bearer

Requires a bearer token on MCP HTTP requests.

Example header:

Authorization: Bearer ***

fake_oauth

Exposes a minimal fake OAuth authorization server alongside the MCP resource server.

Included endpoints:

  • /.well-known/oauth-authorization-server

  • /.well-known/oauth-protected-resource/mcp

  • /authorize

  • /token

Current fake client contract:

  • client_id: fake-public-client

  • token endpoint auth method: none

  • redirect URIs:

    • http://127.0.0.1:9999/callback

    • http://localhost:9999/callback

    • http://127.0.0.1:3800/api/settings/pennylane/callback

    • http://localhost:3800/api/settings/pennylane/callback

  • scope: mcp:access

Useful Compose defaults for MissionGuard local OAuth validation:

  • AUTH_MODE=fake_oauth

  • ISSUER_URL=http://127.0.0.1:${PUBLISHED_PORT:-18080}

  • RESOURCE_SERVER_URL=http://127.0.0.1:${PUBLISHED_PORT:-18080}/mcp

This flow is meant for local integration tests and fake callback simulations — not as a production OAuth server.

Compatibility and status tracking

See:

  • docs/compatibility-matrix.md

  • docs/README.md

Example clients

See:

  • examples/basic_client.py

  • examples/bearer_client.py

  • examples/README.md

Running tests

uv run pytest -q

Development workflow

Typical local loop:

  1. update fixtures / scenarios / auth behavior,

  2. run uv run pytest -q,

  3. run one of the example clients against a local server,

  4. commit the change.

Project structure

.
├── docs/
├── examples/
├── fixtures/
├── src/
├── tests/
├── CONTRIBUTING.md
├── Dockerfile
├── docker-compose.yml
├── LICENSE
├── README.md
└── pyproject.toml

Roadmap

Bootstrap

  • Create Plane project

  • Create public GitHub repository

  • Publish initial detailed README

  • Prepare repo structure for implementation handoff

Implementation milestones

  • Implement fake Streamable HTTP MCP runtime

  • Add deterministic fixture loading

  • Add fake customer / invoice queries

  • Add scenario packs

  • Add auth modes for integration testing

  • Add runnable example clients

  • Add fake OAuth flow for end-to-end callback testing

  • Publish a compatibility matrix

  • Add Docker and Docker Compose local runtime

Next useful milestones

  • add GitHub Actions CI once a token with workflow scope is available

  • enrich compatibility with more Pennylane-like tools

  • add more domain fixture packs

  • add standalone OAuth example client

  • document additional integration recipes

Open-source direction

The intent is for this project to be genuinely useful to a broader audience, not just a one-off internal spike.

That means we optimize for:

  • clarity of documentation,

  • ease of local setup,

  • stable deterministic fixtures,

  • transparent scope,

  • simple contribution paths.

Project origin

This repository was spun out from work around a MissionGuard integration effort, where a Pennylane MCP replacement strategy needed a realistic test environment without depending on a real Pennylane tenant.

License

MIT.

Disclaimer

This project is not affiliated with or endorsed by Pennylane. It is an independent open-source testing utility intended to emulate part of a Pennylane-like MCP integration surface for development and testing purposes only.

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    A mock MCP server for testing MCP client implementations and development workflows. Supports tools, prompts, and resources across multiple transport protocols (stdio, HTTP, SSE).
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A lightweight MCP server that simulates financial data interactions with dummy authentication and static JSON datasets for testing financial applications.
    2
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    A minimal local HTTP MCP mock server for development and testing, providing predictable tool responses with OAuth token support and zero dependencies.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    A local MCP server that breaks on demand, allowing you to test your client against auth failures, disappearing tools, flaky responses, and token expiry from a web UI.
    59 npm
    10
    MIT