afpnews-mcp-server 1.3.11 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +6 -0
- package/.env.example +12 -0
- package/.serena/project.yml +149 -0
- package/CLAUDE.md +154 -0
- package/Dockerfile +19 -0
- package/README.md +39 -17
- package/bun.lock +305 -0
- package/docs/plans/2026-03-08-auth-refactor.md +740 -0
- package/docs/superpowers/plans/2026-03-17-bun-elysia-migration.md +1067 -0
- package/docs/superpowers/plans/2026-03-17-media-tools.md +1259 -0
- package/docs/superpowers/specs/2026-03-17-bun-elysia-migration-design.md +220 -0
- package/docs/superpowers/specs/2026-03-17-media-tools-design.md +404 -0
- package/package.json +23 -23
- package/skills-lock.json +10 -0
- package/src/__tests__/create-server.test.ts +72 -0
- package/src/__tests__/fixtures.ts +39 -0
- package/src/__tests__/format-media.test.ts +216 -0
- package/src/__tests__/format.test.ts +66 -0
- package/src/__tests__/get-media-handler.test.ts +120 -0
- package/src/__tests__/get-media.test.ts +65 -0
- package/src/__tests__/index-auth.test.ts +45 -0
- package/src/__tests__/list-facets.test.ts +52 -0
- package/src/__tests__/server.test.ts +396 -0
- package/src/__tests__/tool-defaults.test.ts +53 -0
- package/src/__tests__/types-media.test.ts +49 -0
- package/{build/definitions.js → src/definitions.ts} +6 -4
- package/src/http/login-page.ts +113 -0
- package/src/http/server.ts +289 -0
- package/src/http/tokens.ts +45 -0
- package/src/index.ts +17 -0
- package/src/mcp-server.ts +62 -0
- package/src/prompts/comprehensive-analysis.ts +23 -0
- package/src/prompts/country-news.ts +20 -0
- package/src/prompts/daily-briefing.ts +23 -0
- package/src/prompts/factcheck.ts +22 -0
- package/src/prompts/index.ts +26 -0
- package/src/resources/index.ts +18 -0
- package/src/resources/topics.ts +139 -0
- package/src/stdio/server.ts +27 -0
- package/src/tools/find-similar.ts +63 -0
- package/{build/tools/get-article.js → src/tools/get-article.ts} +20 -16
- package/src/tools/get-media.ts +188 -0
- package/src/tools/index.ts +38 -0
- package/src/tools/list-facets.ts +99 -0
- package/src/tools/search-articles.ts +143 -0
- package/src/tools/search-media.ts +123 -0
- package/src/tools/shared.ts +112 -0
- package/src/utils/format-media.ts +159 -0
- package/src/utils/format.ts +215 -0
- package/src/utils/types.ts +86 -0
- package/tsconfig.json +13 -0
- package/tsconfig.test.json +9 -0
- package/build/index.js +0 -103
- package/build/prompts/comprehensive-analysis.js +0 -22
- package/build/prompts/country-news.js +0 -19
- package/build/prompts/daily-briefing.js +0 -22
- package/build/prompts/factcheck.js +0 -21
- package/build/prompts/index.js +0 -19
- package/build/resources/index.js +0 -10
- package/build/resources/topics.js +0 -15
- package/build/server.js +0 -23
- package/build/tools/find-similar.js +0 -52
- package/build/tools/index.js +0 -26
- package/build/tools/list-facets.js +0 -73
- package/build/tools/search-articles.js +0 -116
- package/build/tools/shared.js +0 -63
- package/build/utils/format.js +0 -149
- package/build/utils/topics.js +0 -119
- package/build/utils/types.js +0 -8
package/.dockerignore
ADDED
package/.env.example
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# AFP API
|
|
2
|
+
APICORE_API_KEY=your-afp-api-key
|
|
3
|
+
APICORE_BASE_URL= # optionnel
|
|
4
|
+
|
|
5
|
+
# Authentification
|
|
6
|
+
JWT_SECRET= # générer avec: openssl rand -base64 32 (min 32 chars)
|
|
7
|
+
|
|
8
|
+
# Serveur
|
|
9
|
+
MCP_SERVER_URL=https://news-mcp.example.com
|
|
10
|
+
PORT=3000 # optionnel, défaut: 3000
|
|
11
|
+
MCP_TRANSPORT=http # stdio ou http
|
|
12
|
+
MCP_SESSION_TTL=3600000 # optionnel, ms, défaut: 1h
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# the name by which the project can be referenced within Serena
|
|
2
|
+
project_name: "afpnews-mcp-server"
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# list of languages for which language servers are started; choose from:
|
|
6
|
+
# al bash clojure cpp csharp
|
|
7
|
+
# csharp_omnisharp dart elixir elm erlang
|
|
8
|
+
# fortran fsharp go groovy haskell
|
|
9
|
+
# java julia kotlin lua markdown
|
|
10
|
+
# matlab nix pascal perl php
|
|
11
|
+
# php_phpactor powershell python python_jedi r
|
|
12
|
+
# rego ruby ruby_solargraph rust scala
|
|
13
|
+
# swift terraform toml typescript typescript_vts
|
|
14
|
+
# vue yaml zig
|
|
15
|
+
# (This list may be outdated. For the current list, see values of Language enum here:
|
|
16
|
+
# https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py
|
|
17
|
+
# For some languages, there are alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.)
|
|
18
|
+
# Note:
|
|
19
|
+
# - For C, use cpp
|
|
20
|
+
# - For JavaScript, use typescript
|
|
21
|
+
# - For Free Pascal/Lazarus, use pascal
|
|
22
|
+
# Special requirements:
|
|
23
|
+
# Some languages require additional setup/installations.
|
|
24
|
+
# See here for details: https://oraios.github.io/serena/01-about/020_programming-languages.html#language-servers
|
|
25
|
+
# When using multiple languages, the first language server that supports a given file will be used for that file.
|
|
26
|
+
# The first language is the default language and the respective language server will be used as a fallback.
|
|
27
|
+
# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored.
|
|
28
|
+
languages:
|
|
29
|
+
- typescript
|
|
30
|
+
|
|
31
|
+
# the encoding used by text files in the project
|
|
32
|
+
# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings
|
|
33
|
+
encoding: "utf-8"
|
|
34
|
+
|
|
35
|
+
# The language backend to use for this project.
|
|
36
|
+
# If not set, the global setting from serena_config.yml is used.
|
|
37
|
+
# Valid values: LSP, JetBrains
|
|
38
|
+
# Note: the backend is fixed at startup. If a project with a different backend
|
|
39
|
+
# is activated post-init, an error will be returned.
|
|
40
|
+
language_backend:
|
|
41
|
+
|
|
42
|
+
# whether to use project's .gitignore files to ignore files
|
|
43
|
+
ignore_all_files_in_gitignore: true
|
|
44
|
+
|
|
45
|
+
# list of additional paths to ignore in this project.
|
|
46
|
+
# Same syntax as gitignore, so you can use * and **.
|
|
47
|
+
# Note: global ignored_paths from serena_config.yml are also applied additively.
|
|
48
|
+
ignored_paths: []
|
|
49
|
+
|
|
50
|
+
# whether the project is in read-only mode
|
|
51
|
+
# If set to true, all editing tools will be disabled and attempts to use them will result in an error
|
|
52
|
+
# Added on 2025-04-18
|
|
53
|
+
read_only: false
|
|
54
|
+
|
|
55
|
+
# list of tool names to exclude. We recommend not excluding any tools, see the readme for more details.
|
|
56
|
+
# Below is the complete list of tools for convenience.
|
|
57
|
+
# To make sure you have the latest list of tools, and to view their descriptions,
|
|
58
|
+
# execute `uv run scripts/print_tool_overview.py`.
|
|
59
|
+
#
|
|
60
|
+
# * `activate_project`: Activates a project by name.
|
|
61
|
+
# * `check_onboarding_performed`: Checks whether project onboarding was already performed.
|
|
62
|
+
# * `create_text_file`: Creates/overwrites a file in the project directory.
|
|
63
|
+
# * `delete_lines`: Deletes a range of lines within a file.
|
|
64
|
+
# * `delete_memory`: Deletes a memory from Serena's project-specific memory store.
|
|
65
|
+
# * `execute_shell_command`: Executes a shell command.
|
|
66
|
+
# * `find_referencing_code_snippets`: Finds code snippets in which the symbol at the given location is referenced.
|
|
67
|
+
# * `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type).
|
|
68
|
+
# * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type).
|
|
69
|
+
# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes.
|
|
70
|
+
# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file.
|
|
71
|
+
# * `initial_instructions`: Gets the initial instructions for the current project.
|
|
72
|
+
# Should only be used in settings where the system prompt cannot be set,
|
|
73
|
+
# e.g. in clients you have no control over, like Claude Desktop.
|
|
74
|
+
# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol.
|
|
75
|
+
# * `insert_at_line`: Inserts content at a given line in a file.
|
|
76
|
+
# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol.
|
|
77
|
+
# * `list_dir`: Lists files and directories in the given directory (optionally with recursion).
|
|
78
|
+
# * `list_memories`: Lists memories in Serena's project-specific memory store.
|
|
79
|
+
# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building).
|
|
80
|
+
# * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context).
|
|
81
|
+
# * `read_file`: Reads a file within the project directory.
|
|
82
|
+
# * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store.
|
|
83
|
+
# * `remove_project`: Removes a project from the Serena configuration.
|
|
84
|
+
# * `replace_lines`: Replaces a range of lines within a file with new content.
|
|
85
|
+
# * `replace_symbol_body`: Replaces the full definition of a symbol.
|
|
86
|
+
# * `restart_language_server`: Restarts the language server, may be necessary when edits not through Serena happen.
|
|
87
|
+
# * `search_for_pattern`: Performs a search for a pattern in the project.
|
|
88
|
+
# * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase.
|
|
89
|
+
# * `switch_modes`: Activates modes by providing a list of their names
|
|
90
|
+
# * `think_about_collected_information`: Thinking tool for pondering the completeness of collected information.
|
|
91
|
+
# * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task.
|
|
92
|
+
# * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed.
|
|
93
|
+
# * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store.
|
|
94
|
+
excluded_tools: []
|
|
95
|
+
|
|
96
|
+
# list of tools to include that would otherwise be disabled (particularly optional tools that are disabled by default)
|
|
97
|
+
included_optional_tools: []
|
|
98
|
+
|
|
99
|
+
# fixed set of tools to use as the base tool set (if non-empty), replacing Serena's default set of tools.
|
|
100
|
+
# This cannot be combined with non-empty excluded_tools or included_optional_tools.
|
|
101
|
+
fixed_tools: []
|
|
102
|
+
|
|
103
|
+
# list of mode names to that are always to be included in the set of active modes
|
|
104
|
+
# The full set of modes to be activated is base_modes + default_modes.
|
|
105
|
+
# If the setting is undefined, the base_modes from the global configuration (serena_config.yml) apply.
|
|
106
|
+
# Otherwise, this setting overrides the global configuration.
|
|
107
|
+
# Set this to [] to disable base modes for this project.
|
|
108
|
+
# Set this to a list of mode names to always include the respective modes for this project.
|
|
109
|
+
base_modes:
|
|
110
|
+
|
|
111
|
+
# list of mode names that are to be activated by default.
|
|
112
|
+
# The full set of modes to be activated is base_modes + default_modes.
|
|
113
|
+
# If the setting is undefined, the default_modes from the global configuration (serena_config.yml) apply.
|
|
114
|
+
# Otherwise, this overrides the setting from the global configuration (serena_config.yml).
|
|
115
|
+
# This setting can, in turn, be overridden by CLI parameters (--mode).
|
|
116
|
+
default_modes:
|
|
117
|
+
|
|
118
|
+
# initial prompt for the project. It will always be given to the LLM upon activating the project
|
|
119
|
+
# (contrary to the memories, which are loaded on demand).
|
|
120
|
+
initial_prompt: ""
|
|
121
|
+
|
|
122
|
+
# time budget (seconds) per tool call for the retrieval of additional symbol information
|
|
123
|
+
# such as docstrings or parameter information.
|
|
124
|
+
# This overrides the corresponding setting in the global configuration; see the documentation there.
|
|
125
|
+
# If null or missing, use the setting from the global configuration.
|
|
126
|
+
symbol_info_budget:
|
|
127
|
+
|
|
128
|
+
# list of regex patterns which, when matched, mark a memory entry as read‑only.
|
|
129
|
+
# Extends the list from the global configuration, merging the two lists.
|
|
130
|
+
read_only_memory_patterns: []
|
|
131
|
+
|
|
132
|
+
# line ending convention to use when writing source files.
|
|
133
|
+
# Possible values: unset (use global setting), "lf", "crlf", or "native" (platform default)
|
|
134
|
+
# This does not affect Serena's own files (e.g. memories and configuration files), which always use native line endings.
|
|
135
|
+
line_ending:
|
|
136
|
+
|
|
137
|
+
# list of regex patterns for memories to completely ignore.
|
|
138
|
+
# Matching memories will not appear in list_memories or activate_project output
|
|
139
|
+
# and cannot be accessed via read_memory or write_memory.
|
|
140
|
+
# To access ignored memory files, use the read_file tool on the raw file path.
|
|
141
|
+
# Extends the list from the global configuration, merging the two lists.
|
|
142
|
+
# Example: ["_archive/.*", "_episodes/.*"]
|
|
143
|
+
ignored_memory_patterns: []
|
|
144
|
+
|
|
145
|
+
# advanced configuration option allowing to configure language server-specific options.
|
|
146
|
+
# Maps the language key to the options.
|
|
147
|
+
# Have a look at the docstring of the constructors of the LS implementations within solidlsp (e.g., for C# or PHP) to see which options are available.
|
|
148
|
+
# No documentation on options means no options are available.
|
|
149
|
+
ls_specific_settings: {}
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
MCP (Model Context Protocol) server that exposes AFP news tools for LLM-based editors (Continue, Claude Code, etc.). Supports stdio and HTTP (Streamable HTTP) transports.
|
|
8
|
+
|
|
9
|
+
## Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
bun install # Install dependencies
|
|
13
|
+
bun src/index.ts # Run the MCP server (stdio transport by default)
|
|
14
|
+
bun test # Run tests
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Architecture
|
|
18
|
+
|
|
19
|
+
TypeScript project organized in `src/`:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
src/
|
|
23
|
+
├── index.ts # Entry point — dispatches to stdio or HTTP transport
|
|
24
|
+
├── mcp-server.ts # createServer + ServerContext
|
|
25
|
+
├── definitions.ts # Server-agnostic exports (tools/prompts/resources)
|
|
26
|
+
├── tools/
|
|
27
|
+
│ ├── index.ts # registerTools() MCP glue
|
|
28
|
+
│ ├── shared.ts # Shared enums/constants/helpers
|
|
29
|
+
│ ├── search-articles.ts
|
|
30
|
+
│ ├── get-article.ts
|
|
31
|
+
│ ├── find-similar.ts
|
|
32
|
+
│ ├── list-facets.ts
|
|
33
|
+
│ ├── search-media.ts
|
|
34
|
+
│ └── get-media.ts
|
|
35
|
+
├── prompts/
|
|
36
|
+
│ ├── index.ts # registerPrompts() MCP glue
|
|
37
|
+
│ ├── daily-briefing.ts
|
|
38
|
+
│ ├── comprehensive-analysis.ts
|
|
39
|
+
│ ├── factcheck.ts
|
|
40
|
+
│ └── country-news.ts
|
|
41
|
+
├── resources/
|
|
42
|
+
│ ├── index.ts # registerResources() MCP glue
|
|
43
|
+
│ └── topics.ts # TOPICS inline + resource handler
|
|
44
|
+
├── http/
|
|
45
|
+
│ ├── server.ts # Elysia HTTP server + OAuth2 PKCE auth
|
|
46
|
+
│ ├── tokens.ts # JWT helpers (encrypt/decrypt AFP tokens)
|
|
47
|
+
│ └── login-page.ts # OAuth login page + redirect URI helpers
|
|
48
|
+
├── stdio/
|
|
49
|
+
│ └── server.ts # stdio transport entry
|
|
50
|
+
└── utils/
|
|
51
|
+
├── format.ts # formatDocument, textContent, toolError, truncateIfNeeded, buildPaginationLine
|
|
52
|
+
├── format-media.ts # extractRenditions, formatMediaDocument
|
|
53
|
+
└── types.ts # AFPDocument, TextContent, FormattedContent, constants
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
1. Creates an `ApiCore` client from `afpnews-api` using `APICORE_API_KEY`
|
|
57
|
+
2. Registers MCP tools via `@modelcontextprotocol/sdk`: `afp_search_articles`, `afp_get_article`, `afp_find_similar`, `afp_list_facets`, `afp_search_media`, `afp_get_media`
|
|
58
|
+
3. Authenticates with username/password on first call, then reuses or refreshes the token for subsequent queries
|
|
59
|
+
4. Supports two transports: stdio (default) and HTTP (`MCP_TRANSPORT=http`, uses Elysia + Streamable HTTP with OAuth2 PKCE per-session)
|
|
60
|
+
|
|
61
|
+
### Definitions-First Pattern
|
|
62
|
+
|
|
63
|
+
- Tool/prompt/resource files are server-agnostic definitions only.
|
|
64
|
+
- MCP-specific glue (`server.registerTool`, `server.registerPrompt`, `server.registerResource`) lives only in each domain `index.ts`.
|
|
65
|
+
- Aggregated non-MCP exports are provided in `src/definitions.ts`.
|
|
66
|
+
- Published subpath export: `afpnews-mcp-server/definitions`.
|
|
67
|
+
|
|
68
|
+
## Environment Variables
|
|
69
|
+
|
|
70
|
+
### Stdio mode
|
|
71
|
+
|
|
72
|
+
Required:
|
|
73
|
+
- `APICORE_API_KEY` — AFP API key
|
|
74
|
+
- `APICORE_USERNAME` — AFP account username
|
|
75
|
+
- `APICORE_PASSWORD` — AFP account password
|
|
76
|
+
|
|
77
|
+
Optional:
|
|
78
|
+
- `APICORE_BASE_URL` — AFP API base URL (overrides SDK default)
|
|
79
|
+
|
|
80
|
+
### HTTP mode
|
|
81
|
+
|
|
82
|
+
Required:
|
|
83
|
+
- `APICORE_API_KEY` — AFP API key
|
|
84
|
+
- `APICORE_BASE_URL` — AFP API base URL
|
|
85
|
+
- `JWT_SECRET` — Secret for JWT signing/encryption (min 32 characters)
|
|
86
|
+
- `MCP_SERVER_URL` — Public URL of the server (e.g. `https://news-mcp.example.com`)
|
|
87
|
+
- `MCP_TRANSPORT=http`
|
|
88
|
+
|
|
89
|
+
Optional:
|
|
90
|
+
- `PORT` — HTTP server port (default: 3000)
|
|
91
|
+
- `MCP_SESSION_TTL` — Session duration in milliseconds (default: 3600000 = 1h)
|
|
92
|
+
- `MCP_ALLOWED_REDIRECT_URIS` — Comma-separated list of allowed OAuth redirect URIs
|
|
93
|
+
|
|
94
|
+
## Key Details
|
|
95
|
+
|
|
96
|
+
- **Package manager**: bun (v1.3.10)
|
|
97
|
+
- **Runtime**: Bun — TypeScript executed directly, no build step
|
|
98
|
+
- **Module system**: ESM (`"type": "module"`)
|
|
99
|
+
- **Tests**: `bun test`
|
|
100
|
+
- Document types from `afpnews-api` are untyped — the code uses `(doc as any)` casts
|
|
101
|
+
- Package exports:
|
|
102
|
+
- `afpnews-mcp-server` → MCP runtime entry (`src/index.ts`)
|
|
103
|
+
- `afpnews-mcp-server/definitions` → pure definitions (`src/definitions.ts`)
|
|
104
|
+
|
|
105
|
+
## Outils MCP disponibles
|
|
106
|
+
|
|
107
|
+
| Outil | Description |
|
|
108
|
+
|------------------------|--------------------------------------------------------------------|
|
|
109
|
+
| `afp_search_articles` | Outil principal de recherche d'articles (filtres + presets + mode fullText) |
|
|
110
|
+
| `afp_get_article` | Récupération d'un article complet par UNO (texte non tronqué) |
|
|
111
|
+
| `afp_find_similar` | Articles similaires (More Like This) à partir d'un UNO |
|
|
112
|
+
| `afp_list_facets` | Liste des valeurs d'une facette (slug, genre, country) avec fréquence (preset disponible) |
|
|
113
|
+
| `afp_search_media` | Recherche de médias AFP (photos, vidéos, graphiques) |
|
|
114
|
+
| `afp_get_media` | Récupération d'un média complet par UNO, avec embed base64 optionnel |
|
|
115
|
+
|
|
116
|
+
### Presets
|
|
117
|
+
|
|
118
|
+
#### `afp_search_articles.preset`
|
|
119
|
+
|
|
120
|
+
Presets disponibles:
|
|
121
|
+
- `a-la-une`
|
|
122
|
+
- `agenda`
|
|
123
|
+
- `previsions`
|
|
124
|
+
- `major-stories`
|
|
125
|
+
|
|
126
|
+
Comportement:
|
|
127
|
+
- Chaque preset applique automatiquement un jeu de filtres `afp_search_articles` adapté.
|
|
128
|
+
- Le preset force `fullText=true`.
|
|
129
|
+
- Le preset peut être affiné via les autres paramètres (`lang`, `size`, etc.), selon les champs déjà fixés par le preset.
|
|
130
|
+
|
|
131
|
+
#### `afp_list_facets.preset`
|
|
132
|
+
|
|
133
|
+
Preset disponible:
|
|
134
|
+
- `trending-topics` (équivalent de la logique "topics tendance")
|
|
135
|
+
|
|
136
|
+
Comportement:
|
|
137
|
+
- Si `preset=trending-topics`, `facet` est ignoré et remplacé en interne par `slug`.
|
|
138
|
+
- Sans preset, `facet` est requis.
|
|
139
|
+
|
|
140
|
+
### Paramètre `fullText` (tool `afp_search_articles`)
|
|
141
|
+
|
|
142
|
+
- Type: `boolean`
|
|
143
|
+
- Défaut global: `false`
|
|
144
|
+
- Overridé à `true` par les presets
|
|
145
|
+
|
|
146
|
+
Règles:
|
|
147
|
+
- `fullText=false` -> extrait (premiers paragraphes)
|
|
148
|
+
- `fullText=true` -> texte complet de la dépêche
|
|
149
|
+
|
|
150
|
+
## Roadmap — Améliorations fonctionnelles
|
|
151
|
+
|
|
152
|
+
### Priorité basse
|
|
153
|
+
|
|
154
|
+
- **Notifications / veille** — exploiter le Notification Center de l'API (`registerService`, `addSubscription`) pour créer des alertes par webhook ou email (bloqué : l'API côté serveur ne fonctionne pas actuellement)
|
package/Dockerfile
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
FROM oven/bun:1.3.10-alpine
|
|
2
|
+
|
|
3
|
+
WORKDIR /app
|
|
4
|
+
|
|
5
|
+
# 1. Installer les deps
|
|
6
|
+
COPY package.json bun.lock ./
|
|
7
|
+
RUN bun install --frozen-lockfile --production
|
|
8
|
+
|
|
9
|
+
# 2. Copier le code de l’app
|
|
10
|
+
COPY . .
|
|
11
|
+
|
|
12
|
+
# 3. User non-root
|
|
13
|
+
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
|
|
14
|
+
USER appuser
|
|
15
|
+
|
|
16
|
+
ENV MCP_TRANSPORT=http
|
|
17
|
+
EXPOSE 3000
|
|
18
|
+
|
|
19
|
+
CMD ["bun", "src/index.js"]
|
package/README.md
CHANGED
|
@@ -6,8 +6,7 @@ The package can also be used as a library without MCP server glue via `afpnews-m
|
|
|
6
6
|
|
|
7
7
|
## Prerequisites
|
|
8
8
|
|
|
9
|
-
-
|
|
10
|
-
- [pnpm](https://pnpm.io/)
|
|
9
|
+
- [Bun](https://bun.sh/) 1.3+
|
|
11
10
|
- An AFP API account (API key + username/password)
|
|
12
11
|
|
|
13
12
|
## Setup
|
|
@@ -15,8 +14,7 @@ The package can also be used as a library without MCP server glue via `afpnews-m
|
|
|
15
14
|
```bash
|
|
16
15
|
git clone https://github.com/julesbonnard/afpnews-mcp-server.git
|
|
17
16
|
cd afpnews-mcp-server
|
|
18
|
-
|
|
19
|
-
pnpm run build
|
|
17
|
+
bun install
|
|
20
18
|
```
|
|
21
19
|
|
|
22
20
|
Create a `.env` file:
|
|
@@ -37,8 +35,8 @@ For local MCP clients like Claude Code or Claude Desktop:
|
|
|
37
35
|
{
|
|
38
36
|
"mcpServers": {
|
|
39
37
|
"afpnews": {
|
|
40
|
-
"command": "
|
|
41
|
-
"args": ["
|
|
38
|
+
"command": "bun",
|
|
39
|
+
"args": ["src/index.ts"],
|
|
42
40
|
"cwd": "/absolute/path/to/afpnews-mcp-server",
|
|
43
41
|
"env": {
|
|
44
42
|
"APICORE_API_KEY": "your-api-key",
|
|
@@ -52,22 +50,41 @@ For local MCP clients like Claude Code or Claude Desktop:
|
|
|
52
50
|
|
|
53
51
|
### HTTP transport
|
|
54
52
|
|
|
55
|
-
For remote or multi-user deployments.
|
|
53
|
+
For remote or multi-user deployments. Users authenticate via OAuth2 PKCE using their AFP credentials.
|
|
54
|
+
|
|
55
|
+
Required environment variables for HTTP mode:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
APICORE_API_KEY=your-api-key
|
|
59
|
+
APICORE_BASE_URL=https://api.afp.com
|
|
60
|
+
MCP_SERVER_URL=https://news-mcp.example.com
|
|
61
|
+
JWT_SECRET=a-random-string-of-at-least-32-characters
|
|
62
|
+
MCP_TRANSPORT=http
|
|
63
|
+
PORT=3000
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Optional:
|
|
67
|
+
- `MCP_SESSION_TTL` — session duration in milliseconds (default: 3600000 = 1h)
|
|
68
|
+
- `MCP_ALLOWED_REDIRECT_URIS` — comma-separated list of allowed OAuth redirect URIs
|
|
56
69
|
|
|
57
70
|
```bash
|
|
58
|
-
|
|
71
|
+
bun src/index.ts
|
|
59
72
|
```
|
|
60
73
|
|
|
61
|
-
|
|
62
|
-
- Keep `APICORE_API_KEY` set in the server environment (`.env` or runtime env).
|
|
63
|
-
- If you expose the server remotely, use HTTPS.
|
|
74
|
+
If you expose the server remotely, use HTTPS.
|
|
64
75
|
|
|
65
76
|
### Docker
|
|
66
77
|
|
|
67
78
|
```bash
|
|
68
|
-
pnpm run build
|
|
69
79
|
docker build -t afpnews-mcp .
|
|
70
|
-
docker run
|
|
80
|
+
docker run \
|
|
81
|
+
-e APICORE_API_KEY=your-api-key \
|
|
82
|
+
-e APICORE_BASE_URL=https://api.afp.com \
|
|
83
|
+
-e MCP_SERVER_URL=https://news-mcp.example.com \
|
|
84
|
+
-e JWT_SECRET=your-secret-32-chars-minimum \
|
|
85
|
+
-e MCP_TRANSPORT=http \
|
|
86
|
+
-p 3000:3000 \
|
|
87
|
+
afpnews-mcp
|
|
71
88
|
```
|
|
72
89
|
|
|
73
90
|
### As a library (without MCP server dependency)
|
|
@@ -103,6 +120,8 @@ Each definition is framework-agnostic:
|
|
|
103
120
|
| `afp_get_article` | Get a full article by its UNO identifier |
|
|
104
121
|
| `afp_find_similar` | Find similar articles (More Like This) from a UNO |
|
|
105
122
|
| `afp_list_facets` | List facet values (topics, genres, countries) with frequency counts |
|
|
123
|
+
| `afp_search_media` | Search AFP media documents (photos, videos, graphics) |
|
|
124
|
+
| `afp_get_media` | Get a full media document by UNO, with optional base64 image embed |
|
|
106
125
|
|
|
107
126
|
### Search presets
|
|
108
127
|
|
|
@@ -119,7 +138,11 @@ The `afp_search_articles` tool supports presets that apply predefined filters:
|
|
|
119
138
|
|
|
120
139
|
### Full text
|
|
121
140
|
|
|
122
|
-
By default, `afp_search_articles` returns excerpts (first
|
|
141
|
+
By default, `afp_search_articles` returns excerpts (first 2 paragraphs). Set `fullText: true` to get the complete article body. Presets default to full text.
|
|
142
|
+
|
|
143
|
+
### Pagination
|
|
144
|
+
|
|
145
|
+
Use `offset` to paginate through results (e.g. `offset: 10` to skip the first 10). For large chronological scans, prefer narrowing `dateFrom`/`dateTo` ranges in `facets` over high offsets. Keep `size` small (10–20) for best performance.
|
|
123
146
|
|
|
124
147
|
## Prompts
|
|
125
148
|
|
|
@@ -139,9 +162,8 @@ By default, `afp_search_articles` returns excerpts (first 4 paragraphs). Set `fu
|
|
|
139
162
|
## Development
|
|
140
163
|
|
|
141
164
|
```bash
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
pnpm test
|
|
165
|
+
bun install
|
|
166
|
+
bun test
|
|
145
167
|
```
|
|
146
168
|
|
|
147
169
|
## Internal Architecture
|