elvanto-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@elvanto-mcpWhen am I next rostered?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
elvanto-mcp
Summary
A personal, self-hosted MCP server for your
Elvanto account. It runs as a single AWS Lambda
behind a free Function URL — nothing is running (or billing) between requests,
and continuous deployment ships every push to main straight to AWS.
For a couple of calls a week the AWS cost is effectively $0 (Lambda, DynamoDB and SSM sit comfortably inside the always-free tier; the only guaranteed spend is CloudWatch log storage, i.e. cents per month).
Related MCP server: mcp-connect
Usage
Once connected, ask Claude things like:
"Ask Elvanto when I'm next rostered on at church."
"Use the Elvanto tool to check which songs will be played this Sunday."
"Check Elvanto to tell me who's rostered on the band this week."
"Ask Elvanto for my upcoming roster."
"Use the Elvanto MCP to submit an unavailability for 19–23 June, reason: Away."
These map onto five tools:
Tool | What it answers |
| "When am I next on?" / "My upcoming roster" — services you're rostered on, soonest first |
| "Songs this Sunday" — song list per service for a date (defaults to upcoming Sunday) |
| "Who's on the band this week?" — everyone rostered for a date, filterable by department |
| Upcoming published services |
| Registers an all-day, non-repeating, all-locations unavailability (see caveat below) |
Unavailability caveat: Elvanto's public API documents no unavailability endpoint. The tool attempts
unavailabilities/addand, if your account rejects it, responds with a clear message and the exact details to enter manually. Everything else uses documented endpoints (services/getAll,people/search).
"You" are identified automatically as the logged-in Elvanto user (OAuth mode),
or by the optional person-email parameter (API-key mode).
Requirements
An Elvanto account, plus ONE of two credential modes:
Elvanto OAuth (recommended — works without admin access): ask a church admin to register an OAuth application once (Elvanto → Settings → Integrations → API, register application) and give you its Client ID and Client Secret. The app itself grants nothing — access is created only when you later sign in to Elvanto through this server, and every request then runs with your own member permissions.
API key (admins only): Elvanto → Settings → Account Settings → API.
An AWS account, with the AWS CLI configured locally and the SAM CLI installed (
brew install aws-sam-cli).A GitHub repository (for continuous deployment) and a Claude plan that supports custom connectors.
Installation
All commands assume region ap-southeast-2; change it in
samconfig.toml and the commands if you prefer another.
Local: run and test
npm ci
npm run check # typecheck + unit tests
npm test # tests only
npm run build # bundle sanity check
sam build # bundle exactly as production doesThe unit tests cover the OAuth flow, the MCP endpoint and the Elvanto response parsing with a stubbed Elvanto API — no credentials needed.
Production: manual deploy
1. Create the setup password parameter (once — secrets never touch git):
aws ssm put-parameter --region ap-southeast-2 --type SecureString \
--name /elvanto-mcp/oauth-password --value 'A_STRONG_PASSWORD_YOU_CHOOSE'The setup password is what protects your data during connector approval — pick a strong one.
2. Deploy:
npm ci && npm run check
sam build && sam deployThe stack output McpEndpoint is your connector URL, e.g.
https://abc123.lambda-url.ap-southeast-2.on.aws/mcp.
If your church isn't in Australia/Sydney, deploy with
sam deploy --parameter-overrides ChurchTimezone=Pacific/Auckland.
3a. Elvanto credentials — OAuth mode (no admin access needed):
Give your church admin the callback URL
https://YOUR_FUNCTION_URL/elvanto/callback and ask them to register an OAuth
application with it (Elvanto → Settings → Integrations → API). Then store the
credentials they give you:
aws ssm put-parameter --region ap-southeast-2 --type SecureString \
--name /elvanto-mcp/elvanto-client-id --value 'CLIENT_ID_FROM_ADMIN'
aws ssm put-parameter --region ap-southeast-2 --type SecureString \
--name /elvanto-mcp/elvanto-client-secret --value 'CLIENT_SECRET_FROM_ADMIN'Finally, open https://YOUR_FUNCTION_URL/elvanto/connect in a browser, enter
your setup password, and sign in to Elvanto once. The server stores your
Elvanto session (auto-refreshed from then on) and identifies "you"
automatically — no person-email needed.
3b. Elvanto credentials — API-key mode (admins only):
aws ssm put-parameter --region ap-southeast-2 --type SecureString \
--name /elvanto-mcp/elvanto-api-key --value 'YOUR_ELVANTO_API_KEY'
aws ssm put-parameter --region ap-southeast-2 --type SecureString \
--name /elvanto-mcp/person-email --value 'you@example.com'person-email must match the email on your Elvanto profile; it tells the
server who "me" is, since an API key is account-wide.
Production: continuous deployment (GitHub Actions + OIDC)
One-time bootstrap of the deploy role — no AWS keys are ever stored in GitHub (replace the repo name):
aws cloudformation deploy --region ap-southeast-2 \
--template-file infra/github-oidc.yaml \
--stack-name elvanto-mcp-github-oidc \
--capabilities CAPABILITY_NAMED_IAM \
--parameter-overrides GitHubRepo=YOUR_GITHUB_USER/elvanto-mcp(If your AWS account already has the GitHub OIDC provider, add
CreateOidcProvider=false.)
Then in the GitHub repo → Settings → Secrets and variables → Actions → Variables, set:
AWS_ROLE_ARN— theDeployRoleArnoutput of the stack aboveAWS_REGION— optional, defaults toap-southeast-2CHURCH_TIMEZONE— optional, e.g.Pacific/Auckland
Every push to main now runs typecheck + tests, then sam deploy
(.github/workflows/deploy.yml).
Integration: Claude
Claude (web/desktop/mobile): Settings → Connectors → Add custom connector, paste the
McpEndpointURL. Claude discovers the OAuth endpoints, registers itself and opens the approval page — enter your setup password. Done.Claude Code:
claude mcp add --transport http elvanto https://YOUR_URL/mcp
Integration: ChatGPT
ChatGPT custom connectors (Settings → Connectors → Advanced → Developer mode) use a different OAuth callback domain, which this server blocks by default. To allow it, redeploy with:
sam deploy --parameter-overrides AllowedRedirectHosts=chatgpt.com,openai.comthen add the McpEndpoint URL as a connector in ChatGPT and approve with the
same setup password.
Technical Detail
Claude (custom connector)
│ OAuth 2.1: dynamic registration + PKCE + password-gated consent
▼
Lambda Function URL ──► Hono router on Lambda (Node 22, ARM)
├── /.well-known/* OAuth discovery metadata
├── /oauth/* register / authorize / token (Claude-facing)
├── /elvanto/connect one-time Elvanto sign-in (password-gated)
└── /mcp MCP Streamable HTTP (stateless JSON)
│
├── DynamoDB (elvanto-mcp-oauth): hashed tokens, TTL-expired,
│ plus the server's own Elvanto OAuth session
├── SSM SecureString: setup password + Elvanto credentials
└── api.elvanto.com/v1 (HTTPS; Bearer user token or API key)AWS services used:
Service | Role | Cost at this usage |
Lambda (ARM, 512 MB) + Function URL | The entire server; URL is free, no API Gateway needed | Free tier |
DynamoDB (on-demand) | OAuth clients, codes and hashed tokens, auto-expired via TTL | Free tier |
SSM Parameter Store (SecureString) | Setup password + Elvanto credentials (OAuth client or API key) | Free |
CloudWatch Logs (30-day retention) | Error logs only | Cents/month |
IAM + GitHub OIDC | Keyless continuous deployment | Free |
Code layout:
src/app.ts — Hono app: bearer-guarded
/mcp+ OAuth routessrc/mcp/server.ts — the five MCP tools
src/mcp/transport.ts — stateless buffered MCP transport for Lambda
src/oauth/ — minimal OAuth 2.1 authorization server + DynamoDB store
src/elvanto/ — Elvanto REST client and roster/song parsing
template.yaml — SAM stack (Lambda, Function URL, DynamoDB, IAM)
infra/github-oidc.yaml — one-time CD bootstrap
Security
Your Elvanto credentials never leave AWS. The client secret / API key live in SSM SecureStrings (KMS-encrypted), readable only by the Lambda role, and are never included in MCP responses. Claude only ever sees tool output (roster/song data).
OAuth mode is least-privilege by construction: the server acts as you in Elvanto, so it can never see more than your own member account can. The one-time sign-in at
/elvanto/connectis password-gated and CSRF-protected with single-use state tokens, so nobody else can bind an Elvanto session to your server.OAuth 2.1 for the connector: dynamic client registration, authorization code + PKCE (S256 required), single-use codes, refresh-token rotation.
Consent is password-gated. Registering a client grants nothing; the authorize page requires your setup password, with a lockout after 20 failed attempts per hour.
Redirect URIs are restricted to
claude.ai/claude.com/anthropic.com(HTTPS only) unless you opt in to more, so tokens can't be sent to arbitrary sites.Tokens are stored as SHA-256 hashes in DynamoDB with TTLs — a leaked table can't be replayed. Expiry is enforced on read, not just by DynamoDB TTL.
CD uses GitHub OIDC — no long-lived AWS keys in GitHub, and the deploy role is scoped to this stack's resources and the
mainbranch only.
Troubleshooting
"Missing SSM parameter(s)" in tool output → the parameters weren't created in the same region as the stack.
"Not connected to Elvanto yet" → OAuth mode needs the one-time sign-in: open
/elvanto/connecton the Function URL and log in."Elvanto session has expired" → repeat the
/elvanto/connectsign-in (e.g. after the church admin revoked the app, or a long idle period).No person found → API-key mode:
person-emaildoesn't match your Elvanto profile email.Connector auth loop → remove and re-add the connector; if you redeployed to a fresh stack the DynamoDB table (registered clients) was reset.
Logs:
sam logs -n McpFunction --stack-name elvanto-mcp --tail(tool inputs/outputs are not logged; only errors are).
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/mcnamee/elvanto-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server