GraphQL MCP
Why not just return the whole GraphQL schema?
Swan's GraphQL schema is 200 000+ characters long (it's HUGE)
- It's over the context limit of most LLMs
- It would waste many tokens with irrelevant parts of the schema
- Longer context = lower accuracy
How it works
The server runs a standard introspection query against our GraphQL endpoint.
Step 1: Introspection
Step 2: Indexing
Step 2: Indexing
type Query {
user: User
account: Account
}type User {
account: Account
}type Account {
iban: String
}Query
User
Account
String
user
account
account
iban
Step 2: Indexing
To prepare for the indexing, we traverse the graph (BFS - Breadth-First Search) and for each field, we:
- assign a score based on its depth
- store its:
- path
- description
- parent type
- type
- the description of its type
... and put everything in FlexSearch, an in-memory full-text search engine
For Account.iban, we index: iban, account, string, plus its description.
Step 2: Indexing
Query
User
Account
String
user
account
account
iban
Depth 1:
user(Query, User)account(Query, Account)
Depth 2:
user.account(User, Account)account.iban(Account, String)
Depth 3:
user.account.iban(Account, String)
Step 3: Scoring
Step 3: Scoring
When the AI searches for ["IBAN"], FlexSearch returns all matching fields.
We then rank them:
score = (3*name + 2*description + parent_type)/depth
- Walk up to
Query/Mutationto include all intermediaries - Rince and repeat until we hit a size limit (configurable by the agent, with a default to 10000 characters)
Final touch:
Docs MCP
Semantic Search
Step 1: Scraping https://docs.swan.io (sitemap.xml)
Step 2: Chunking
- by html section
- recursing splitting
Step 3: Embedding (vectorization)
- Qdrant database
- index all words of each chunk, keep link to original doc url and content
- index rebuilt every 6 hours
Step 4: Semantic search
- vector distance, handled by Qdrant
Semantic Search

Thank you
MCP @Swan
By antogyn
MCP @Swan
- 17