aie-europe-2026
AI Engineer Europe 2026
Conference data APIs, MCP server, and CLI for AI Engineer Europe 2026 (April 8-10, London).
When to use this skill
- Building apps or dashboards with conference data
- Querying speakers, talks, or schedule programmatically
- Connecting an AI agent to the conference MCP server
- Generating conference summaries, recommendations, or search features
- Looking up who's speaking, what talks are on which day/track, or session details
Endpoints
Base URL: https://ai.engineer
| Endpoint | Format | Description |
|---|---|---|
/europe/llms.txt |
Plain text | Conference overview optimized for LLM consumption |
/europe/llms-full.txt |
Plain text | Full details — every talk, speaker bio, schedule |
/europe/sessions.json |
JSON | All sessions (talks + workshops) with titles, descriptions, speakers, times, rooms, tracks |
/europe/speakers.json |
JSON | All speakers with roles, companies, social links, photos, talks |
/europe/mcp |
JSON-RPC | MCP server — tool calls for querying conference data |
/europe/speakers-embeddings.json |
JSON | All speakers with 128-dim Gemini Embedding 2 vectors |
/europe/sessions-embeddings.json |
JSON | All sessions with 128-dim Gemini Embedding 2 vectors |
All endpoints are public, free, and CORS-enabled. Data is cached (s-maxage=3600, stale-while-revalidate=86400).
Embeddings
Pre-computed Gemini Embedding 2 vectors for semantic search, clustering, and recommendations.
- Model:
gemini-embedding-2-preview - Dimensions: 128 (truncated from 3072 via Matryoshka Representation Learning)
- Task type:
RETRIEVAL_DOCUMENT
The embedding JSON files include full metadata (name, company, role, talks, etc.) alongside the 128-dim vector for each speaker/session.
Fetch embeddings (curl)
# Speaker embeddings (128-dim Gemini Embedding 2, MRL)
curl https://ai.engineer/europe/speakers-embeddings.json | jq '.speakers[:2]'
# Session embeddings
curl https://ai.engineer/europe/sessions-embeddings.json | jq '.sessions[:2]'
JavaScript — cosine similarity search
const res = await fetch('https://ai.engineer/europe/speakers-embeddings.json');
const { speakers } = await res.json();
// Cosine similarity
const dot = (a, b) => a.reduce((s, v, i) => s + v * b[i], 0);
const norm = (a) => Math.sqrt(dot(a, a));
const cosine = (a, b) => dot(a, b) / (norm(a) * norm(b));
// Compare against a query embedding (128-dim from Gemini)
const ranked = speakers
.map(s => ({ name: s.name, score: cosine(queryEmbedding, s.embedding) }))
.sort((a, b) => b.score - a.score)
.slice(0, 5);
console.log(ranked);
Python — cosine similarity search
import json, urllib.request, numpy as np
data = json.loads(urllib.request.urlopen('https://ai.engineer/europe/speakers-embeddings.json').read())
speakers = data['speakers']
def cosine(a, b):
a, b = np.array(a), np.array(b)
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
ranked = sorted(speakers, key=lambda s: cosine(query_emb, s['embedding']), reverse=True)[:5]
for s in ranked:
print(s['name'], s.get('company', ''))
Generate your own query embedding (to search against pre-computed vectors)
# Use the Gemini API with the same model + MRL dimensionality
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-embedding-2-preview:embedContent?key=$GEMINI_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"model": "models/gemini-embedding-2-preview",
"content": { "parts": [{ "text": "autonomous coding agents" }] },
"taskType": "RETRIEVAL_QUERY",
"outputDimensionality": 128
}'
Quick start
curl
# Plain text overview (good for piping to an LLM)
curl https://ai.engineer/europe/llms.txt
# Full conference dump
curl https://ai.engineer/europe/llms-full.txt
# Structured JSON
curl https://ai.engineer/europe/sessions.json | jq '.sessions[:3]'
curl https://ai.engineer/europe/speakers.json | jq '.speakers[:3]'
CLI (@aidotengineer/aie)
No install needed — runs via npx:
npx @aidotengineer/aie --list # List all conferences
npx @aidotengineer/aie europe # Europe conference info
npx @aidotengineer/aie eu speakers # All speakers
npx @aidotengineer/aie eu speakers --search "Anthropic"
npx @aidotengineer/aie eu sessions --day "April 9"
npx @aidotengineer/aie eu sessions --type workshop
npx @aidotengineer/aie eu search "agents" # Full-text search
npx @aidotengineer/aie eu speakers --json # Raw JSON output
npx @aidotengineer/aie eu mcp # MCP connection info
JavaScript / TypeScript
const res = await fetch('https://ai.engineer/europe/speakers.json');
const { speakers, totalSpeakers } = await res.json();
// Find speakers from Anthropic
const anthropic = speakers.filter(s =>
s.company?.toLowerCase().includes('anthropic')
);
console.log(`${anthropic.length} speakers from Anthropic`);
// Get all keynotes
const data = await fetch('https://ai.engineer/europe/sessions.json').then(r => r.json());
const keynotes = data.sessions.filter(t => t.type === 'keynote');
console.log(keynotes.map(k => `${k.time}: ${k.title} — ${k.speakers.join(', ')}`));
Python
import requests
# --- Fetch and explore sessions ---
data = requests.get('https://ai.engineer/europe/sessions.json').json()
print(f"{data['totalSessions']} sessions across {data['dates']}")
# Day 2 sessions
day2 = [s for s in data['sessions'] if s.get('day') == 'April 9']
for s in day2:
speakers = ', '.join(s.get('speakers', []))
print(f"{s.get('time', '?')}: {s.get('title', 'TBA')} — {speakers}")
# Sessions about agents
agent_sessions = [s for s in data['sessions']
if 'agent' in (s.get('title') or '').lower()
or s.get('track', '').lower() == 'ai agents']
print(f"\n{len(agent_sessions)} sessions about agents")
# --- Fetch speakers ---
sp = requests.get('https://ai.engineer/europe/speakers.json').json()
# Speakers with GitHub profiles
with_github = [s for s in sp['speakers'] if s.get('github')]
print(f"\n{len(with_github)} speakers with GitHub profiles")
for s in with_github[:5]:
print(f" {s['name']} ({s.get('company', '?')}): {s['github']}")
# Group speakers by company
from collections import Counter
companies = Counter(s.get('company') for s in sp['speakers'] if s.get('company'))
for company, count in companies.most_common(10):
print(f" {company}: {count} speakers")
Python — MCP tool call
import requests
import json
MCP_URL = 'https://ai.engineer/europe/mcp'
def mcp_call(tool_name: str, arguments: dict = {}) -> dict:
"""Call an MCP tool and return the parsed result."""
resp = requests.post(MCP_URL, json={
'jsonrpc': '2.0',
'id': 1,
'method': 'tools/call',
'params': {'name': tool_name, 'arguments': arguments}
}, headers={'Content-Type': 'application/json', 'Accept': 'application/json'})
result = resp.json()['result']['content'][0]['text']
return json.loads(result)
# Get conference info
info = mcp_call('get_conference_info')
print(f"{info['name']} — {info['dates']} — {info['location']}")
# Search speakers
speakers = mcp_call('list_speakers', {'search': 'Google'})
for s in speakers['speakers']:
print(f" {s['name']}: {s.get('role', '')} @ {s.get('company', '')}")
# Get Day 2 keynotes
keynotes = mcp_call('list_sessions', {'day': 'April 9', 'type': 'keynote'})
for t in keynotes['sessions']:
print(f" {t['time']}: {t['title']} — {', '.join(t['speakers'])}")
# Get schedule for one day
schedule = mcp_call('get_schedule', {'day': 'April 10'})
for session in schedule['days'][0]['sessions']:
print(f" {session.get('time', '?')}: {session.get('title', 'TBA')}")
MCP server
The MCP server at https://ai.engineer/europe/mcp implements JSON-RPC 2.0 over Streamable HTTP.
Client config
Add to your Claude Desktop, Cursor, Windsurf, or any MCP client config:
{
"mcpServers": {
"aie-europe": {
"url": "https://ai.engineer/europe/mcp"
}
}
}
Available tools
| Tool | Description | Optional params |
|---|---|---|
get_conference_info |
Dates, venue, links, metadata | — |
list_speakers |
Speakers with roles, companies, socials, sessions | search |
list_sessions |
Sessions with descriptions, times, rooms, tracks | day, type, track, search |
get_schedule |
Full schedule organized by day | day |
Example tool call (curl)
curl -X POST https://ai.engineer/europe/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_speakers",
"arguments": { "search": "Anthropic" }
}
}'
Example tool call (Python)
import requests, json
resp = requests.post('https://ai.engineer/europe/mcp', json={
'jsonrpc': '2.0', 'id': 1,
'method': 'tools/call',
'params': {'name': 'list_sessions', 'arguments': {'track': 'MCP'}}
}, headers={'Content-Type': 'application/json', 'Accept': 'application/json'})
result = json.loads(resp.json()['result']['content'][0]['text'])
for s in result['sessions']:
print(f"{s['title']} — {', '.join(s['speakers'])}")
Initialize + discover tools
# Initialize session
curl -X POST https://ai.engineer/europe/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"my-client","version":"1.0.0"}}}'
# List tools
curl -X POST https://ai.engineer/europe/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
# GET also returns server info + tool definitions
curl https://ai.engineer/europe/mcp | jq .
See references/MCP.md for full tool schemas and response formats.
Data model
Talk
type PublicTalk = {
title?: string;
description?: string;
day?: string; // "April 8" | "April 9" | "April 10"
time?: string; // "9:00-9:30am"
room?: string; // "Keynote" | "Abbey" | "Fleming" | "Moore" | "St. James" | "Westminster"
type?: string; // "keynote" | "talk" | "workshop" | "panel" | "break"
track?: string; // "AI Agents" | "Coding Agents" | "MCP" | "Open Source" | "GPUs & LLM Infrastructure" | ...
speakers: string[];
};
Speaker
type PublicSpeaker = {
name: string;
role?: string;
company?: string;
companyDescription?: string;
twitter?: string; // Full URL: "https://x.com/handle"
linkedin?: string; // Full URL
github?: string; // Full URL
website?: string;
photoUrl?: string; // "https://ai.engineer/europe-speakers/name.jpg"
sessions: PublicTalk[];
};
See references/SCHEMAS.md for full response envelope structures and real API response examples.
See references/EXAMPLES.md for 4 complete TS + Python recipes: topic index, semantic embed/cluster/retrieve, multi-track day planner, and speaker social graph.
Edge cases
- Some sessions have empty
description— fall back to title + speakers speakersarray can be empty for break/logistics sessionstypefield may be missing for some sessions — treat as "talk"- Speaker photos are served from
ai.engineer/europe-speakers/— some speakers may not have a photo - Social links (twitter, linkedin, github) are full URLs when present,
undefinedwhen absent - The
trackfield only exists on Day 2-3 multi-track sessions; Day 1 workshops don't have tracks
Sensitive fields (never exposed)
These fields exist in the source data but are stripped from all public endpoints:
contact.email— speaker email addressesnotes— internal organizer notesacceleventsSpeakerId— internal Accelevents IDssessionId— internal session identifiersinvited— whether speaker was invited vs CFPcfpData— call for papers submissions and review status
Links
- Website: ai.engineer/europe
- Source code: github.com/aiDotEngineer/aiecode2025
- CLI on npm: @aidotengineer/aie
- Twitter: @aiDotEngineer
- Gemini Embedding 2 docs: ai.google.dev/gemini-api/docs/models/gemini-embedding-2-preview